Compare commits
	
		
			40 Commits
		
	
	
		
			ec1f1031cc
			...
			master
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						
						
							
						
						977d1a7120
	
				 | 
					
					
						|||
| 
						
						
							
						
						9b274417c5
	
				 | 
					
					
						|||
| 
						
						
							
						
						cc14a9f735
	
				 | 
					
					
						|||
| 
						
						
							
						
						b070df6010
	
				 | 
					
					
						|||
| 
						
						
							
						
						3075d47aeb
	
				 | 
					
					
						|||
| 
						
						
							
						
						85b2d8a2ee
	
				 | 
					
					
						|||
| 
						
						
							
						
						272ee62ad8
	
				 | 
					
					
						|||
| 
						
						
							
						
						a85426541a
	
				 | 
					
					
						|||
| 
						
						
							
						
						c9b003735d
	
				 | 
					
					
						|||
| 
						
						
							
						
						52a28f01c8
	
				 | 
					
					
						|||
| 
						
						
							
						
						3607757554
	
				 | 
					
					
						|||
| 
						
						
							
						
						6eb216a40a
	
				 | 
					
					
						|||
| 
						
						
							
						
						9ce6f47716
	
				 | 
					
					
						|||
| 
						
						
							
						
						c9662f1a7b
	
				 | 
					
					
						|||
| 
						
						
							
						
						9ddeb03652
	
				 | 
					
					
						|||
| 
						
						
							
						
						acb187c6b1
	
				 | 
					
					
						|||
| 
						
						
							
						
						9427df62e7
	
				 | 
					
					
						|||
| 
						
						
							
						
						4d6999c415
	
				 | 
					
					
						|||
| 
						
						
							
						
						30ed61fdd2
	
				 | 
					
					
						|||
| 
						
						
							
						
						2df916c9b3
	
				 | 
					
					
						|||
| 
						
						
							
						
						24401825b4
	
				 | 
					
					
						|||
| 
						
						
							
						
						2bfb490798
	
				 | 
					
					
						|||
| 
						
						
							
						
						338d00d605
	
				 | 
					
					
						|||
| 
						
						
							
						
						015652e379
	
				 | 
					
					
						|||
| 
						
						
							
						
						c298b6fc97
	
				 | 
					
					
						|||
| 
						
						
							
						
						7c2ab8ab59
	
				 | 
					
					
						|||
| 
						
						
							
						
						e423a3a1b1
	
				 | 
					
					
						|||
| 
						
						
							
						
						916f354c9b
	
				 | 
					
					
						|||
| 
						
						
							
						
						050f875c47
	
				 | 
					
					
						|||
| 
						
						
							
						
						aeffe40efc
	
				 | 
					
					
						|||
| 
						
						
							
						
						536aa57761
	
				 | 
					
					
						|||
| 
						
						
							
						
						0d10ae06e6
	
				 | 
					
					
						|||
| 
						
						
							
						
						e1b0831854
	
				 | 
					
					
						|||
| 
						
						
							
						
						4e93dfbb8d
	
				 | 
					
					
						|||
| 
						
						
							
						
						8a6bb54eb5
	
				 | 
					
					
						|||
| 
						
						
							
						
						4ef7c9edf7
	
				 | 
					
					
						|||
| 
						
						
							
						
						3eea106c3c
	
				 | 
					
					
						|||
| 
						
						
							
						
						7de8c84e8f
	
				 | 
					
					
						|||
| 
						
						
							
						
						e17c5e2083
	
				 | 
					
					
						|||
| 
						
						
							
						
						9bd3739122
	
				 | 
					
					
						
							
								
								
									
										14
									
								
								.clang-format
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								.clang-format
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					BasedOnStyle: LLVM
 | 
				
			||||||
 | 
					ColumnLimit: 80
 | 
				
			||||||
 | 
					IndentWidth: 4
 | 
				
			||||||
 | 
					TabWidth: 4
 | 
				
			||||||
 | 
					UseTab: ForContinuationAndIndentation
 | 
				
			||||||
 | 
					SpaceAfterCStyleCast: true
 | 
				
			||||||
 | 
					SpaceBeforeParens: Always
 | 
				
			||||||
 | 
					AlignAfterOpenBracket: DontAlign
 | 
				
			||||||
 | 
					AlignEscapedNewlines: DontAlign
 | 
				
			||||||
 | 
					AlignOperands: DontAlign
 | 
				
			||||||
 | 
					AlignConsecutiveMacros: Consecutive
 | 
				
			||||||
 | 
					BreakBeforeTernaryOperators: true
 | 
				
			||||||
 | 
					SpacesBeforeTrailingComments: 2
 | 
				
			||||||
 | 
					WhitespaceSensitiveMacros: ['XX', 'ACTIONS', 'LS']
 | 
				
			||||||
@@ -1,32 +1,42 @@
 | 
				
			|||||||
# target_compile_features has been introduced in that version
 | 
					# target_compile_features has been introduced in that version
 | 
				
			||||||
cmake_minimum_required (VERSION 3.1)
 | 
					cmake_minimum_required (VERSION 3.1...3.27)
 | 
				
			||||||
project (sdn VERSION 0.1 LANGUAGES CXX)
 | 
					project (sdn VERSION 1.0 LANGUAGES CXX)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
 | 
					if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
 | 
				
			||||||
	set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic")
 | 
						set (CMAKE_CXX_FLAGS
 | 
				
			||||||
endif ()
 | 
							"${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-misleading-indentation -pedantic")
 | 
				
			||||||
 | 
					 | 
				
			||||||
# Since we use a language with slow compilers, let's at least use a fast linker
 | 
					 | 
				
			||||||
execute_process (COMMAND ${CMAKE_CXX_COMPILER} -fuse-ld=gold -Wl,--version
 | 
					 | 
				
			||||||
	ERROR_QUIET OUTPUT_VARIABLE ld_version)
 | 
					 | 
				
			||||||
if ("${ld_version}" MATCHES "GNU gold")
 | 
					 | 
				
			||||||
	set (CMAKE_EXE_LINKER_FLAGS "-fuse-ld=gold ${CMAKE_EXE_LINKER_FLAGS}")
 | 
					 | 
				
			||||||
endif ()
 | 
					endif ()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
find_package (PkgConfig REQUIRED)
 | 
					find_package (PkgConfig REQUIRED)
 | 
				
			||||||
pkg_check_modules (NCURSESW QUIET ncursesw)
 | 
					pkg_check_modules (ACL libacl)
 | 
				
			||||||
 | 
					pkg_check_modules (NCURSESW ncursesw)
 | 
				
			||||||
 | 
					if (NOT NCURSESW_FOUND)
 | 
				
			||||||
 | 
						find_library (NCURSESW_LIBRARIES NAMES ncursesw)
 | 
				
			||||||
 | 
						find_path (NCURSESW_INCLUDE_DIRS ncurses.h PATH_SUFFIXES ncurses)
 | 
				
			||||||
 | 
					endif ()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_executable (${PROJECT_NAME} ${PROJECT_NAME}.cpp)
 | 
					add_executable (${PROJECT_NAME} ${PROJECT_NAME}.cpp)
 | 
				
			||||||
target_include_directories (${PROJECT_NAME} PUBLIC ${NCURSESW_INCLUDE_DIRS})
 | 
					target_include_directories (${PROJECT_NAME}
 | 
				
			||||||
target_link_libraries (${PROJECT_NAME} PUBLIC ${NCURSESW_LIBRARIES} acl)
 | 
						PUBLIC ${NCURSESW_INCLUDE_DIRS} ${ACL_INCLUDE_DIRS})
 | 
				
			||||||
 | 
					target_link_directories (${PROJECT_NAME}
 | 
				
			||||||
 | 
						PUBLIC ${NCURSESW_LIBRARY_DIRS} ${ACL_LIBRARY_DIRS})
 | 
				
			||||||
 | 
					target_link_libraries (${PROJECT_NAME}
 | 
				
			||||||
 | 
						PUBLIC ${NCURSESW_LIBRARIES} ${ACL_LIBRARIES})
 | 
				
			||||||
target_compile_features (${PROJECT_NAME} PUBLIC cxx_std_14)
 | 
					target_compile_features (${PROJECT_NAME} PUBLIC cxx_std_14)
 | 
				
			||||||
target_compile_definitions (${PROJECT_NAME} PUBLIC
 | 
					target_compile_definitions (${PROJECT_NAME} PUBLIC
 | 
				
			||||||
	-DPROJECT_NAME=\"${PROJECT_NAME}\" -DPROJECT_VERSION=\"${PROJECT_VERSION}\")
 | 
						-DPROJECT_NAME=\"${PROJECT_NAME}\" -DPROJECT_VERSION=\"${PROJECT_VERSION}\")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_executable (${PROJECT_NAME}-mc-ext ${PROJECT_NAME}-mc-ext.cpp)
 | 
				
			||||||
 | 
					target_compile_features (${PROJECT_NAME}-mc-ext PUBLIC cxx_std_17)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
include (GNUInstallDirs)
 | 
					include (GNUInstallDirs)
 | 
				
			||||||
install (TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})
 | 
					# sdn-mc-ext should be in libexec, but we prefer it in PATH.
 | 
				
			||||||
install (PROGRAMS ${PROJECT_NAME}-install DESTINATION ${CMAKE_INSTALL_BINDIR})
 | 
					install (TARGETS sdn sdn-mc-ext
 | 
				
			||||||
install (FILES sdn.1 sdn-install.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
 | 
						DESTINATION ${CMAKE_INSTALL_BINDIR})
 | 
				
			||||||
 | 
					install (PROGRAMS sdn-install sdn-view
 | 
				
			||||||
 | 
						DESTINATION ${CMAKE_INSTALL_BINDIR})
 | 
				
			||||||
 | 
					install (FILES sdn.1 sdn-install.1 sdn-view.1
 | 
				
			||||||
 | 
						DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
 | 
				
			||||||
install (FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR})
 | 
					install (FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "Directory navigator")
 | 
					set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "Directory navigator")
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								LICENSE
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
				
			|||||||
Copyright (c) 2017 - 2021, Přemysl Eric Janouch <p@janouch.name>
 | 
					Copyright (c) 2017 - 2024, Přemysl Eric Janouch <p@janouch.name>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Permission to use, copy, modify, and/or distribute this software for any
 | 
					Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
purpose with or without fee is hereby granted.
 | 
					purpose with or without fee is hereby granted.
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								Makefile
									
									
									
									
									
								
							@@ -1,19 +1,19 @@
 | 
				
			|||||||
.POSIX:
 | 
					.POSIX:
 | 
				
			||||||
SHELL = /bin/sh
 | 
					SHELL = /bin/sh
 | 
				
			||||||
CXXFLAGS = -g -std=c++14 -Wall -Wextra -pedantic
 | 
					CXXFLAGS = -g -std=c++14 -Wall -Wextra -Wno-misleading-indentation -pedantic
 | 
				
			||||||
CPPFLAGS = `sed -ne '/^project (\([^ )]*\) VERSION \([^ )]*\).*/ \
 | 
					CPPFLAGS = `sed -ne '/^project (\([^ )]*\) VERSION \([^ )]*\).*/ \
 | 
				
			||||||
	s//-DPROJECT_NAME="\1" -DPROJECT_VERSION="\2"/p' CMakeLists.txt`
 | 
						s//-DPROJECT_NAME="\1" -DPROJECT_VERSION="\2"/p' CMakeLists.txt`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sdn: sdn.cpp CMakeLists.txt
 | 
					sdn: sdn.cpp CMakeLists.txt
 | 
				
			||||||
	$(CXX) $(CXXFLAGS) $(CPPFLAGS) $< -o sdn \
 | 
						$(CXX) $(CXXFLAGS) $(CPPFLAGS) $< -o $@ \
 | 
				
			||||||
	-lacl `pkg-config --libs --cflags ncursesw`
 | 
						-lacl `pkg-config --libs --cflags ncursesw`
 | 
				
			||||||
static: sdn.cpp CMakeLists.txt
 | 
					sdn-static: sdn.cpp CMakeLists.txt
 | 
				
			||||||
	$(CXX) $(CXXFLAGS) $(CPPFLAGS) $< -o sdn \
 | 
						$(CXX) $(CXXFLAGS) $(CPPFLAGS) $< -o $@ \
 | 
				
			||||||
	-static-libstdc++ \
 | 
						-static-libstdc++ \
 | 
				
			||||||
	-Wl,--start-group,-Bstatic \
 | 
						-Wl,--start-group,-Bstatic \
 | 
				
			||||||
	-lacl `pkg-config --static --libs --cflags ncursesw` \
 | 
						-lacl `pkg-config --static --libs --cflags ncursesw` \
 | 
				
			||||||
	-Wl,--end-group,-Bdynamic
 | 
						-Wl,--end-group,-Bdynamic
 | 
				
			||||||
clean:
 | 
					clean:
 | 
				
			||||||
	rm -f sdn
 | 
						rm -f sdn sdn-static
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.PHONY: static clean
 | 
					.PHONY: clean
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										20
									
								
								NEWS
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								NEWS
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					Unreleased
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 * Added selection functionality, and adjusted key bindings:
 | 
				
			||||||
 | 
					    - C-t or Insert toggle whether the current item is selected;
 | 
				
			||||||
 | 
					    - + and - adjust the selection using shell globs;
 | 
				
			||||||
 | 
					    - t and T insert the selection into the external command line
 | 
				
			||||||
 | 
					      in relative or absolute form, respectively;
 | 
				
			||||||
 | 
						- Enter is like t but enters directories, and M-Enter is synonymous to t;
 | 
				
			||||||
 | 
					    - C-g or Escape clear the selection, similarly to the editor.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 * Added an sdn-view script that can process Midnight Commander mc.ext.ini files
 | 
				
			||||||
 | 
					   and apply matching filters; this script has been made the default F3 binding,
 | 
				
			||||||
 | 
					   while the original direct pager invocation has been moved to F13 (which also
 | 
				
			||||||
 | 
					   reflects Midnight Commander)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1.0.0 (2024-12-21)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 * Initial release
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										32
									
								
								README.adoc
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								README.adoc
									
									
									
									
									
								
							@@ -5,26 +5,29 @@ sdn
 | 
				
			|||||||
'sdn' is a simple directory navigator that you can invoke while editing shell
 | 
					'sdn' is a simple directory navigator that you can invoke while editing shell
 | 
				
			||||||
commands.  It enables you to:
 | 
					commands.  It enables you to:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 * take a quick peek at directory contents without running `ls`
 | 
					 * take a quick peek at directory contents without running `ls`;
 | 
				
			||||||
 | 
					 * select files to insert into the command line;
 | 
				
			||||||
 * browse the filesystem without all the mess that Midnight Commander does:
 | 
					 * browse the filesystem without all the mess that Midnight Commander does:
 | 
				
			||||||
   there's no need to create a subshell in a new pty.  The current command line
 | 
					   there's no need to create a subshell in a new pty.  The current command line
 | 
				
			||||||
   can be simply forwarded if it is to be edited.  What's more, it will always
 | 
					   can be simply forwarded if it is to be edited.  What's more, it will always
 | 
				
			||||||
   be obvious whether the navigator is running.
 | 
					   be obvious whether the navigator is running.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The only supported platform is Linux.  I wanted to try a different, simpler
 | 
					'sdn' runs on Linux and all BSD derivatives.  I wanted to try a different,
 | 
				
			||||||
approach here, and the end result is very friendly to tinkering.
 | 
					simpler approach here, and the end result is very friendly to tinkering.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
image::sdn.png[align="center"]
 | 
					image::sdn.png[align="center"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Packages
 | 
					Packages
 | 
				
			||||||
--------
 | 
					--------
 | 
				
			||||||
Regular releases are sporadic.  git master should be stable enough.  You can get
 | 
					Regular releases are sporadic.  git master should be stable enough.
 | 
				
			||||||
a package with the latest development version from Archlinux's AUR.
 | 
					You can get a package with the latest development version using Arch Linux's
 | 
				
			||||||
 | 
					https://aur.archlinux.org/packages/sdn-git[AUR],
 | 
				
			||||||
 | 
					or as a https://git.janouch.name/p/nixexprs[Nix derivation].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Building
 | 
					Building
 | 
				
			||||||
--------
 | 
					--------
 | 
				
			||||||
Build dependencies: CMake and/or make, a C++14 compiler, pkg-config +
 | 
					Build dependencies: CMake and/or make, a C++17 compiler, pkg-config +
 | 
				
			||||||
Runtime dependencies: ncursesw, libacl
 | 
					Runtime dependencies: ncursesw, libacl (on Linux)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Working around libasciidoc's missing support for escaping it like \++
 | 
					// Working around libasciidoc's missing support for escaping it like \++
 | 
				
			||||||
Unfortunately most LLVM libc{plus}{plus} versions have a bug that crashes 'sdn'
 | 
					Unfortunately most LLVM libc{plus}{plus} versions have a bug that crashes 'sdn'
 | 
				
			||||||
@@ -73,6 +76,7 @@ that of git, only named colours aren't supported:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
....
 | 
					....
 | 
				
			||||||
cursor 231 202
 | 
					cursor 231 202
 | 
				
			||||||
 | 
					select 202 bold
 | 
				
			||||||
bar 16 255 ul
 | 
					bar 16 255 ul
 | 
				
			||||||
cwd bold
 | 
					cwd bold
 | 
				
			||||||
input
 | 
					input
 | 
				
			||||||
@@ -89,15 +93,19 @@ To obtain more vifm-like controls, you may write the following to your
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
....
 | 
					....
 | 
				
			||||||
normal h parent
 | 
					normal h parent
 | 
				
			||||||
normal l choose
 | 
					normal l enter
 | 
				
			||||||
....
 | 
					....
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Helper programs
 | 
					Helper programs
 | 
				
			||||||
~~~~~~~~~~~~~~~
 | 
					~~~~~~~~~~~~~~~
 | 
				
			||||||
The F3 and F4 keys are normally bound to actions 'view' and 'edit', similarly to
 | 
					The F3, F13 and F4 keys are normally bound to actions 'view', 'view-raw',
 | 
				
			||||||
Norton Commander and other orthodox file managers.  The helper programs used
 | 
					and 'edit', similarly to Norton Commander and other orthodox file managers.
 | 
				
			||||||
here may be changed by setting the PAGER and VISUAL (or EDITOR) environment
 | 
					The helper programs used here may be changed by setting the PAGER and VISUAL
 | 
				
			||||||
variables.
 | 
					(or EDITOR) environment variables.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If 'view' finds Midnight Commander, it will make use of its configuration
 | 
				
			||||||
 | 
					to apply any matching filter, such as to produce archive listings,
 | 
				
			||||||
 | 
					or it will run the respective command.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
While it is mostly possible to get 'mcview' working using an invocation like
 | 
					While it is mostly possible to get 'mcview' working using an invocation like
 | 
				
			||||||
`PAGER='mcview -u' sdn`, beware that this helper cannot read files from its
 | 
					`PAGER='mcview -u' sdn`, beware that this helper cannot read files from its
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,9 @@ sdn-navigate () {
 | 
				
			|||||||
    # helpers after the terminal has been resized while running sdn
 | 
					    # helpers after the terminal has been resized while running sdn
 | 
				
			||||||
    command true
 | 
					    command true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Add to history, see https://www.zsh.org/mla/workers/2020/msg00633.html
 | 
				
			||||||
 | 
					    fc -R =(print -- "$helper")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /bin/sh -c "$helper" </dev/tty || break
 | 
					    /bin/sh -c "$helper" </dev/tty || break
 | 
				
			||||||
  done
 | 
					  done
 | 
				
			||||||
  # optionally: zle zle-line-init
 | 
					  # optionally: zle zle-line-init
 | 
				
			||||||
@@ -51,6 +54,7 @@ sdn-navigate () {
 | 
				
			|||||||
      ((SDN_P=SDN_P+${#insert}+1))
 | 
					      ((SDN_P=SDN_P+${#insert}+1))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    [[ -z $helper ]] && break
 | 
					    [[ -z $helper ]] && break
 | 
				
			||||||
 | 
					    history -s -- "$helper"
 | 
				
			||||||
    /bin/sh -c "$helper" || break
 | 
					    /bin/sh -c "$helper" || break
 | 
				
			||||||
  done
 | 
					  done
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -121,7 +125,7 @@ done
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# Figure out the shell to integrate with
 | 
					# Figure out the shell to integrate with
 | 
				
			||||||
login=$(basename "$SHELL")
 | 
					login=$(basename "$SHELL")
 | 
				
			||||||
actual=$(ps -p $$ -o ppid= | xargs ps -o comm= -p)
 | 
					actual=$(ps -p $$ -o ppid= | xargs ps -o comm= -p | sed 's/^-//')
 | 
				
			||||||
if [ -z "$shell" ]
 | 
					if [ -z "$shell" ]
 | 
				
			||||||
then
 | 
					then
 | 
				
			||||||
  if [ "$login" != "$actual" ]
 | 
					  if [ "$login" != "$actual" ]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
.Dd October 27, 2020
 | 
					.Dd October 27, 2020
 | 
				
			||||||
.Dt SDN-INSTALL 1
 | 
					.Dt SDN-INSTALL 1
 | 
				
			||||||
.Os Linux
 | 
					.Os
 | 
				
			||||||
.Sh NAME
 | 
					.Sh NAME
 | 
				
			||||||
.Nm sdn-install
 | 
					.Nm sdn-install
 | 
				
			||||||
.Nd integrate sdn with the shell
 | 
					.Nd integrate sdn with the shell
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										222
									
								
								sdn-mc-ext.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										222
									
								
								sdn-mc-ext.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,222 @@
 | 
				
			|||||||
 | 
					//
 | 
				
			||||||
 | 
					// sdn-mc-ext: Midnight Commander extension file processor
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Copyright (c) 2024, Přemysl Eric Janouch <p@janouch.name>
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 | 
					// purpose with or without fee is hereby granted.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 | 
				
			||||||
 | 
					// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 | 
				
			||||||
 | 
					// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 | 
				
			||||||
 | 
					// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstdlib>
 | 
				
			||||||
 | 
					#include <cctype>
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <regex>
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <unordered_map>
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Trailing return types make C++ syntax suck considerably less
 | 
				
			||||||
 | 
					#define fun static auto
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace std;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// It is completely fine if this only modifies ASCII letters.
 | 
				
			||||||
 | 
					fun tolower (const string &s) -> string {
 | 
				
			||||||
 | 
					    string result;
 | 
				
			||||||
 | 
						for (auto c : s) result += tolower (c);
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fun shell_escape (const string &v) -> string {
 | 
				
			||||||
 | 
					    return "'" + regex_replace (v, regex {"'"}, "'\\''") + "'";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					string arg_type, arg_path, arg_basename, arg_dirname, arg_verb;
 | 
				
			||||||
 | 
					unordered_map<string, unordered_map<string, string>> sections;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fun expand_command (string command) -> pair<string, string> {
 | 
				
			||||||
 | 
						regex re_sequence {R"(%(%|[[:alpha:]]*\{([^}]*)\}|[[:alpha:]]+))"};
 | 
				
			||||||
 | 
						regex re_name {R"([^{}]*)"};
 | 
				
			||||||
 | 
						regex re_parameter {R"([^,]+")"};
 | 
				
			||||||
 | 
						string kind, out, pipe; smatch m;
 | 
				
			||||||
 | 
						while (regex_search (command, m, re_sequence)) {
 | 
				
			||||||
 | 
							out.append (m.prefix ());
 | 
				
			||||||
 | 
							auto seq = m.str (1);
 | 
				
			||||||
 | 
							command = m.suffix ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							string argument = m.str (2);
 | 
				
			||||||
 | 
							if (regex_search (seq, m, re_name))
 | 
				
			||||||
 | 
								seq = m.str ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (seq == "%") {
 | 
				
			||||||
 | 
								out += "%";
 | 
				
			||||||
 | 
							} else if (seq == "p") {
 | 
				
			||||||
 | 
								out += shell_escape (arg_basename);
 | 
				
			||||||
 | 
							} else if (seq == "f") {
 | 
				
			||||||
 | 
								out += shell_escape (arg_path);
 | 
				
			||||||
 | 
							} else if (seq == "d") {
 | 
				
			||||||
 | 
								out += shell_escape (arg_dirname);
 | 
				
			||||||
 | 
							} else if (seq == "var") {
 | 
				
			||||||
 | 
								string value;
 | 
				
			||||||
 | 
								if (auto colon = argument.find (':'); colon == argument.npos) {
 | 
				
			||||||
 | 
									if (auto v = getenv (argument.c_str ()))
 | 
				
			||||||
 | 
										value = v;
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									value = argument.substr (colon + 1);
 | 
				
			||||||
 | 
									if (auto v = getenv (argument.substr (0, colon).c_str ()))
 | 
				
			||||||
 | 
										value = v;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								out += shell_escape (value);
 | 
				
			||||||
 | 
							} else if (seq == "cd") {
 | 
				
			||||||
 | 
								kind = seq;
 | 
				
			||||||
 | 
								command = regex_replace (command, regex {"^ +"}, "");
 | 
				
			||||||
 | 
							} else if (seq == "view") {
 | 
				
			||||||
 | 
								kind = seq;
 | 
				
			||||||
 | 
								command = regex_replace (command, regex {"^ +"}, "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								sregex_token_iterator it (argument.begin (), argument.end (),
 | 
				
			||||||
 | 
									re_parameter, 0), end;
 | 
				
			||||||
 | 
								for (; it != end; it++) {
 | 
				
			||||||
 | 
									if (*it == "hex")
 | 
				
			||||||
 | 
										pipe.append (" | od -t x1");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// more(1) and less(1) either ignore or display this:
 | 
				
			||||||
 | 
									//if (*it == "nroff")
 | 
				
			||||||
 | 
									//	pipe.append (" | col -b");
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else if (seq == "") {
 | 
				
			||||||
 | 
								cerr << "sdn-mc-ext: prompting not supported" << endl;
 | 
				
			||||||
 | 
								return {};
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								cerr << "sdn-mc-ext: unsupported: %" << seq << endl;
 | 
				
			||||||
 | 
								return {};
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return {kind,
 | 
				
			||||||
 | 
							pipe.empty () ? out.append (command) : "(" + out + ")" + pipe};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fun print_command (string cmd) {
 | 
				
			||||||
 | 
						auto command = expand_command (cmd);
 | 
				
			||||||
 | 
						cout << get<0> (command) << endl << get<1> (command) << endl;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fun section_matches (const unordered_map<string, string> §ion) -> bool {
 | 
				
			||||||
 | 
						if (section.count ("Directory"))
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// The configuration went through some funky changes;
 | 
				
			||||||
 | 
						// unescape \\ but leave other escapes alone.
 | 
				
			||||||
 | 
						auto filter_re = [](const string &s) {
 | 
				
			||||||
 | 
							string result;
 | 
				
			||||||
 | 
							for (size_t i = 0; i < s.length (); ) {
 | 
				
			||||||
 | 
								auto c = s[i++];
 | 
				
			||||||
 | 
								if (c == '\\' && i < s.length ())
 | 
				
			||||||
 | 
									if (c = s[i++]; c != '\\')
 | 
				
			||||||
 | 
										result += '\\';
 | 
				
			||||||
 | 
								result += c;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return result;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						auto is_true = [&](const string &name) {
 | 
				
			||||||
 | 
							auto value = section.find (name);
 | 
				
			||||||
 | 
							return value != section.end () && value->second == "true";
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						if (auto kv = section.find ("Type"); kv != section.end ()) {
 | 
				
			||||||
 | 
							auto flags = std::regex::ECMAScript;
 | 
				
			||||||
 | 
							if (is_true ("TypeIgnoreCase"))
 | 
				
			||||||
 | 
								flags |= regex_constants::icase;
 | 
				
			||||||
 | 
							if (!regex_search (arg_type, regex {filter_re (kv->second), flags}))
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						auto basename = arg_basename;
 | 
				
			||||||
 | 
						if (auto kv = section.find ("Regex"); kv != section.end ()) {
 | 
				
			||||||
 | 
							auto flags = std::regex::ECMAScript;
 | 
				
			||||||
 | 
							if (is_true ("RegexIgnoreCase"))
 | 
				
			||||||
 | 
								flags |= regex_constants::icase;
 | 
				
			||||||
 | 
							return regex_search (basename, regex {filter_re (kv->second), flags});
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (auto kv = section.find ("Shell"); kv != section.end ()) {
 | 
				
			||||||
 | 
							auto value = kv->second;
 | 
				
			||||||
 | 
							if (is_true ("ShellIgnoreCase")) {
 | 
				
			||||||
 | 
								value = tolower (value);
 | 
				
			||||||
 | 
								basename = tolower (arg_basename);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (value.empty () || value[0] != '.')
 | 
				
			||||||
 | 
								return value == basename;
 | 
				
			||||||
 | 
							return basename.length () >= value.length () &&
 | 
				
			||||||
 | 
								basename.substr (basename.length () - value.length ()) == value;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return !arg_type.empty ();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fun process (const string §ion) -> bool {
 | 
				
			||||||
 | 
						auto full = sections.at (section);
 | 
				
			||||||
 | 
						if (auto include = full.find ("Include"); include != full.end ()) {
 | 
				
			||||||
 | 
							full.erase ("Open");
 | 
				
			||||||
 | 
							full.erase ("View");
 | 
				
			||||||
 | 
							full.erase ("Edit");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (auto included = sections.find ("Include/" + include->second);
 | 
				
			||||||
 | 
								included != sections.end ()) {
 | 
				
			||||||
 | 
								for (const auto &kv : included->second)
 | 
				
			||||||
 | 
									full[kv.first] = kv.second;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (getenv ("SDN_MC_EXT_DEBUG")) {
 | 
				
			||||||
 | 
							cerr << "[" << section << "]" << endl;
 | 
				
			||||||
 | 
							for (const auto &kv : full)
 | 
				
			||||||
 | 
								cerr << "  " << kv.first << ": " << kv.second << endl;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (full.count (arg_verb) && section_matches (full)) {
 | 
				
			||||||
 | 
							print_command (full[arg_verb]);
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main (int argc, char *argv[]) {
 | 
				
			||||||
 | 
						if (argc != 6) {
 | 
				
			||||||
 | 
							cerr << "Usage: " << argv[0]
 | 
				
			||||||
 | 
								<< " TYPE PATH BASENAME DIRNAME VERB < mc.ext.ini" << endl;
 | 
				
			||||||
 | 
							return 2;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						arg_type = argv[1];
 | 
				
			||||||
 | 
						arg_path = argv[2], arg_basename = argv[3], arg_dirname = argv[4];
 | 
				
			||||||
 | 
						arg_verb = argv[5];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						string line, section;
 | 
				
			||||||
 | 
						vector<string> order;
 | 
				
			||||||
 | 
						regex re_entry {R"(^([-\w]+) *= *(.*)$)"};
 | 
				
			||||||
 | 
						smatch m;
 | 
				
			||||||
 | 
						while (getline (cin, line)) {
 | 
				
			||||||
 | 
							if (line.empty () || line[0] == '#') {
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							} else if (auto length = line.length();
 | 
				
			||||||
 | 
								line.find_last_of ('[') == 0 &&
 | 
				
			||||||
 | 
								line.find_first_of (']') == length - 1) {
 | 
				
			||||||
 | 
								order.push_back ((section = line.substr (1, length - 2)));
 | 
				
			||||||
 | 
							} else if (regex_match (line, m, re_entry)) {
 | 
				
			||||||
 | 
								sections[section][m[1]] = m[2];
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for (const auto §ion : order) {
 | 
				
			||||||
 | 
							if (section == "mc.ext.ini" ||
 | 
				
			||||||
 | 
								section == "Default" ||
 | 
				
			||||||
 | 
								section.substr (0, 8) == "Include/")
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							if (process (section))
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						print_command (sections["Default"][arg_verb]);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										54
									
								
								sdn-view
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										54
									
								
								sdn-view
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					#!/bin/sh -e
 | 
				
			||||||
 | 
					# sdn-view: a viewer for sdn that makes use of Midnight Commander configuration
 | 
				
			||||||
 | 
					# to make more kinds of files directly viewable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [ "$#" -ne 1 ]
 | 
				
			||||||
 | 
					then
 | 
				
			||||||
 | 
						echo "Usage: $0 FILE" >&2
 | 
				
			||||||
 | 
						exit 2
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This handles both MC_DATADIR and odd installation locations.
 | 
				
			||||||
 | 
					datadir=
 | 
				
			||||||
 | 
					if command -v mc >/dev/null
 | 
				
			||||||
 | 
					then datadir=$(mc --datadir | sed 's/ (.*)$//')
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config=
 | 
				
			||||||
 | 
					for dir in "$HOME"/.config/mc "$datadir" /etc/mc
 | 
				
			||||||
 | 
					do
 | 
				
			||||||
 | 
						if [ -n "$dir" -a -f "$dir/mc.ext.ini" ]
 | 
				
			||||||
 | 
						then
 | 
				
			||||||
 | 
							config=$dir/mc.ext.ini
 | 
				
			||||||
 | 
							break
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This is often used in %env{} expansion, so let's be on the same page.
 | 
				
			||||||
 | 
					export PAGER=${PAGER:-less}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export MC_EXT_FILENAME=$(realpath "$1")
 | 
				
			||||||
 | 
					export MC_EXT_BASENAME=$(basename "$1")
 | 
				
			||||||
 | 
					export MC_EXT_CURRENTDIR=$(dirname "$MC_EXT_FILENAME")
 | 
				
			||||||
 | 
					output=$(sdn-mc-ext <"$config" "$(file -Lbz "$1")" \
 | 
				
			||||||
 | 
						"$MC_EXT_FILENAME" "$MC_EXT_BASENAME" "$MC_EXT_CURRENTDIR" View || :)
 | 
				
			||||||
 | 
					kind=$(echo "$output" | sed -n 1p)
 | 
				
			||||||
 | 
					command=$(echo "$output" | sed -n 2p)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					case "$kind" in
 | 
				
			||||||
 | 
					view)
 | 
				
			||||||
 | 
						if [ -n "$command" ]
 | 
				
			||||||
 | 
						then eval "$command" | "$PAGER"
 | 
				
			||||||
 | 
						else "$PAGER" -- "$MC_EXT_FILENAME"
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
						;;
 | 
				
			||||||
 | 
					'')
 | 
				
			||||||
 | 
						if [ -n "$command" ]
 | 
				
			||||||
 | 
						then eval "$command"
 | 
				
			||||||
 | 
						else "$PAGER" -- "$MC_EXT_FILENAME"
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
						;;
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
						echo "Unsupported: $kind" >&2
 | 
				
			||||||
 | 
						exit 1
 | 
				
			||||||
 | 
					esac
 | 
				
			||||||
							
								
								
									
										24
									
								
								sdn-view.1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								sdn-view.1
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					.Dd December 30, 2024
 | 
				
			||||||
 | 
					.Dt SDN-VIEW 1
 | 
				
			||||||
 | 
					.Os
 | 
				
			||||||
 | 
					.Sh NAME
 | 
				
			||||||
 | 
					.Nm sdn-view
 | 
				
			||||||
 | 
					.Nd run Midnight Commander view configuration externally
 | 
				
			||||||
 | 
					.Sh SYNOPSIS
 | 
				
			||||||
 | 
					.Nm sdn-view
 | 
				
			||||||
 | 
					.Ar path
 | 
				
			||||||
 | 
					.Sh DESCRIPTION
 | 
				
			||||||
 | 
					.Nm
 | 
				
			||||||
 | 
					invokes
 | 
				
			||||||
 | 
					.Ev PAGER
 | 
				
			||||||
 | 
					or a fallback pager on the passed filename.
 | 
				
			||||||
 | 
					.Pp
 | 
				
			||||||
 | 
					If it succeeds in finding a
 | 
				
			||||||
 | 
					.Xr mc 1
 | 
				
			||||||
 | 
					.Pa mc.ext.ini
 | 
				
			||||||
 | 
					file, it will first process it, and apply any matching filter,
 | 
				
			||||||
 | 
					or run the respective command.
 | 
				
			||||||
 | 
					.Sh REPORTING BUGS
 | 
				
			||||||
 | 
					Use
 | 
				
			||||||
 | 
					.Lk https://git.janouch.name/p/sdn
 | 
				
			||||||
 | 
					to report bugs, request features, or submit pull requests.
 | 
				
			||||||
							
								
								
									
										13
									
								
								sdn.1
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								sdn.1
									
									
									
									
									
								
							@@ -1,7 +1,7 @@
 | 
				
			|||||||
\" https://mandoc.bsd.lv/man/roff.7.html#Sentence_Spacing
 | 
					\" https://mandoc.bsd.lv/man/roff.7.html#Sentence_Spacing
 | 
				
			||||||
.Dd October 27, 2020
 | 
					.Dd December 30, 2024
 | 
				
			||||||
.Dt SDN 1
 | 
					.Dt SDN 1
 | 
				
			||||||
.Os Linux
 | 
					.Os
 | 
				
			||||||
.Sh NAME
 | 
					.Sh NAME
 | 
				
			||||||
.Nm sdn
 | 
					.Nm sdn
 | 
				
			||||||
.Nd directory navigator
 | 
					.Nd directory navigator
 | 
				
			||||||
@@ -68,8 +68,8 @@ and you can use the
 | 
				
			|||||||
.Xr dircolors 1
 | 
					.Xr dircolors 1
 | 
				
			||||||
utility to initialize this variable.
 | 
					utility to initialize this variable.
 | 
				
			||||||
.It Ev PAGER
 | 
					.It Ev PAGER
 | 
				
			||||||
The viewer program to be launched by the F3 key binding as well as to show
 | 
					The viewer program to be launched by the F3 and F13 key bindings as well as
 | 
				
			||||||
the internal help message.
 | 
					to show the internal help message.
 | 
				
			||||||
If none is set, it defaults to
 | 
					If none is set, it defaults to
 | 
				
			||||||
.Xr less 1 .
 | 
					.Xr less 1 .
 | 
				
			||||||
.It Ev VISUAL , Ev EDITOR
 | 
					.It Ev VISUAL , Ev EDITOR
 | 
				
			||||||
@@ -95,7 +95,7 @@ names are used for special keys.
 | 
				
			|||||||
To obtain more vifm-like controls and Windows-like quit abilities:
 | 
					To obtain more vifm-like controls and Windows-like quit abilities:
 | 
				
			||||||
.Bd -literal -offset indent
 | 
					.Bd -literal -offset indent
 | 
				
			||||||
normal h parent
 | 
					normal h parent
 | 
				
			||||||
normal l choose
 | 
					normal l enter
 | 
				
			||||||
normal M-f4 quit
 | 
					normal M-f4 quit
 | 
				
			||||||
.Ed
 | 
					.Ed
 | 
				
			||||||
.Pp
 | 
					.Pp
 | 
				
			||||||
@@ -107,7 +107,7 @@ For rxvt, that would be:
 | 
				
			|||||||
define C-ppage ^[[5^
 | 
					define C-ppage ^[[5^
 | 
				
			||||||
define C-npage ^[[6^
 | 
					define C-npage ^[[6^
 | 
				
			||||||
normal C-ppage parent
 | 
					normal C-ppage parent
 | 
				
			||||||
normal C-npage choose
 | 
					normal C-npage enter
 | 
				
			||||||
.Ed
 | 
					.Ed
 | 
				
			||||||
.Pp
 | 
					.Pp
 | 
				
			||||||
Escape characters must be inserted verbatim, e.g., by pressing C-v ESC in vi,
 | 
					Escape characters must be inserted verbatim, e.g., by pressing C-v ESC in vi,
 | 
				
			||||||
@@ -120,6 +120,7 @@ For a black-on-white terminal supporting 256 colours, a theme such as the
 | 
				
			|||||||
following may work:
 | 
					following may work:
 | 
				
			||||||
.Bd -literal -offset indent
 | 
					.Bd -literal -offset indent
 | 
				
			||||||
cursor 231 202
 | 
					cursor 231 202
 | 
				
			||||||
 | 
					select 202 bold
 | 
				
			||||||
bar 16 255 ul
 | 
					bar 16 255 ul
 | 
				
			||||||
cwd bold
 | 
					cwd bold
 | 
				
			||||||
input
 | 
					input
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user