And remove it from the "similar software" section. Our relationship has progressed. Other unusual shells I've checked before I gave up: - nushell lacks the ability to bind keys to user functions - yash can but is otherwise way too basic
sdn
sdn is a simple directory navigator that you can invoke while editing shell commands. It enables you to:
- 
take a quick peek at directory contents without running ls
- 
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 can be simply forwarded if it is to be edited. What’s more, it will always be obvious whether the navigator is running. 
The only supported platform is Linux. I wanted to try a different, simpler approach here, and the end result is very friendly to tinkering.
 
Building
Build dependencies: CMake and/or make, a C++14 compiler, pkg-config
Runtime dependencies: ncursesw, libacl
Unfortunately most LLVM libc++ versions have a bug that crashes sdn on start. Use GNU libstdc++ if you’re affected.
$ git clone https://git.janouch.name/p/sdn.git $ mkdir sdn/build $ cd sdn/build $ cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug $ make
To install the application, you can do either the usual:
# make install
Or you can try telling CMake to make a package for you. For Debian it is:
$ cpack -G DEB # dpkg -i sdn-*.deb
There is also a Makefile you can use to quickly build a binary to be copied into the PATH of any machine you want to have sdn on.
Integration
zsh
To start using this navigator, put the following in your .zshrc:
sdn-navigate () {
  # ... possibly zle-line-finish
  while eval "`sdn "$BUFFER" "$CURSOR"`"; do
    [ -z "$cd" ] || cd "$cd"
    [ -z "$insert" ] || LBUFFER="$LBUFFER$insert "
    [ -z "$helper" ] && break
    # Workaround for "zsh: suspended (tty output)" when invoking
    # helpers after the terminal has been resized while running sdn
    command true
    eval "exec </dev/tty; $helper" || break
  done
  # ... possibly zle-line-init
  zle reset-prompt
}
zle -N sdn-navigate
bindkey '\eo' sdn-navigate
fish
To start using this navigator, put the following in your config.fish:
function sdn-navigate
  set --local IFS
  set --local buffer (commandline)
  set --local cursor (commandline --cursor)
  while eval (sdn $buffer $cursor | string replace -ar '^(.*?)=' 'set --$1 ')
    test -z "$cd" || cd "$cd"
    test -z "$insert" || commandline --insert "$insert "
    test -z "$helper" && break
    eval $helper || break
  end
  commandline --function repaint
end
bind \eo sdn-navigate
bash
Here we can’t make the shell update the prompt on directory changes since
there’s no way to invoke prompt_again() from a bind -x handler but we can
work around it by submitting a blank line:
sdn-navigate () {
  SDN_L=$READLINE_LINE SDN_P=$READLINE_POINT
  READLINE_LINE=
  while eval "`sdn "$SDN_L" "$SDN_P"`"; do
    [[ -z "$cd" ]] || cd "$cd"
    [[ -z "$insert" ]] || {
      SDN_L="${SDN_L:0:$SDN_P}$insert ${SDN_L:$SDN_P}"
      ((SDN_P=SDN_P+${#insert}+1))
    }
    [[ -z "$helper" ]] && break
    eval "$helper" || break
  done
}
sdn-restore () {
  READLINE_LINE=$SDN_L READLINE_POINT=$SDN_P
  unset SDN_L SDN_P
}
bind -x '"\200": sdn-navigate'
bind -x '"\201": sdn-restore'
bind '"\eo":"\200\C-m\201"'
elvish
To start using this navigator, put the following in your rc.elv:
use str
edit:insert:binding[Alt-o] = {
  local:reesc = [posix]{ str:replace "'\\''"  "''" $posix }
  local:posix = [cmd]{ eval ($reesc $cmd)" </dev/tty >/dev/tty 2>&1" }
  # XXX: the -dot is not a stable API, and may hence break soon
  local:buffer = $edit:current-command
  local:cursor = (str:to-codepoints $buffer[0..$edit:-dot] | count)
  local:ns = (ns [&])
  while ?(eval ($reesc (sdn $buffer $cursor |
    sed 's/^local //' | slurp)) &ns=$ns) {
    if (not-eq $ns[cd] "") { cd $ns[cd] }
    if (not-eq $ns[insert] "") { edit:insert-at-dot $ns[insert]" " }
    if (or (eq $ns[helper] "") (not ?($posix $ns[helper]))) { break }
  }
  edit:redraw &full=$true
}
This shell is absolutely perverse. And so is integrating sdn into it because it already includes a custom file manager, bound to Ctrl-N (though I find the ranger-like interface confusing and resource-demanding). Version 0.14.1 or newer is required.
Configuration
Colours
Here is an example of a ~/.config/sdn/look file; the format is similar to that of git, only named colours aren’t supported:
cursor 231 202 bar 16 255 ul cwd bold input cmdline 145
Filename colours are taken from the LS_COLORS environment variable.
Run dircolors to get some defaults.
Bindings
To obtain more vifm-like controls, you may write the following to your ~/.config/sdn/bindings file:
normal h parent normal l choose normal ? help
Helper programs
The F3 and F4 keys are normally bound to actions view and edit, similarly to Norton Commander and other orthodox file managers. The helper programs used here may be changed by setting the PAGER and VISUAL (or EDITOR) environment variables.
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
standard input, nor does it enable overstrike processing by default (F9, could
be hacked around in mc.ext by turning on the nroff switch for a custom file
extension, just without actually invoking nroff), and thus it can’t show the
program help.  sdn is currently optimised for less as the pager.
Contributing and Support
Use https://git.janouch.name/p/sdn to report any bugs, request features,
or submit pull requests.  git send-email is tolerated.  If you want to discuss
the project, feel free to join me at ircs://irc.janouch.name, channel #dev.
Bitcoin donations are accepted at: 12r5uEWEgcHC46xd64tt3hHt9EUvYYDHe9
License
This software is released under the terms of the 0BSD license, the text of which is included within the package along with the list of authors.