1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
|
sdn
===
:compact-option:
'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.
image::sdn.png[align="center"]
Building
--------
Build dependencies: CMake and/or make, a C++14 compiler, pkg-config +
Runtime dependencies: ncursesw, libacl
// Working around libasciidoc's missing support for escaping it like \++
:doubleplus: ++
Unfortunately most LLVM libc++ versions have a bug that crashes 'sdn' on start.
Use GNU libstdc{doubleplus} 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
/bin/sh -c "$helper" </dev/tty || break
done
# ... possibly zle-line-init
zle reset-prompt
}
zle -N sdn-navigate
bindkey '\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-cursor () {
if [[ $BASH_VERSINFO -lt 5 ]]
then echo -n "$SDN_L" | wc -m
else echo "$SDN_P"
fi
}
sdn-navigate () {
SDN_L=$READLINE_LINE SDN_P=$READLINE_POINT
READLINE_LINE=
while eval "`sdn "$SDN_L" "$(sdn-cursor)"`"; 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
/bin/sh -c "$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"'
----
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
/bin/sh -c "$helper" || break
end
commandline --function repaint
end
bind \eo sdn-navigate
----
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]{ /bin/sh -c $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.
|