... | ... |
@@ -1,41 +1,59 @@ |
1 | 1 |
# [`readline-vim`][] |
2 | 2 |
|
3 |
-Upgrade [Readline][] from [`vi`][] to [Vim][]. |
|
3 |
+Upgrade [Readline][] from [vi][] to [Vim][]. |
|
4 | 4 |
|
5 |
-[`readline-vim`][] is a Python program that generates [Readline][] macros that |
|
6 |
-provide [Vim][] [motions][], [operators][] and [text objects][] (that are |
|
7 |
-useful on a single line). |
|
5 |
+[`readline-vim`][] is a [Python][] script that generates [Readline][] macros |
|
6 |
+(4658 of them) that provide [Vim][] [motions][], [operators][] and [text |
|
7 |
+objects][] (the ones that are useful on a single line) as well as functionality |
|
8 |
+from the popular [`vim-surround`][]. |
|
8 | 9 |
|
9 | 10 |
[`readline-vim`]: https://git.rcrnstn.net/rcrnstn/readline-vim |
10 |
-[Python]: https://www.python.org |
|
11 | 11 |
[Readline]: https://en.wikipedia.org/wiki/Readline |
12 |
-[`vi`]: https://en.wikipedia.org/wiki/vi |
|
13 |
-[Vim]: https://en.wikipedia.org/wiki/Vim |
|
12 |
+[vi]: https://en.wikipedia.org/wiki/vi |
|
13 |
+[Vim]: https://en.wikipedia.org/wiki/Vim_(text_editor) |
|
14 |
+[Python]: https://www.python.org |
|
14 | 15 |
[motions]: https://vimhelp.org/motion.txt.html |
15 | 16 |
[operators]: https://vimhelp.org/motion.txt.html#operator |
16 | 17 |
[text objects]: https://vimhelp.org/motion.txt.html#text-objects |
18 |
+[`vim-surround`]: https://github.com/tpope/vim-surround |
|
17 | 19 |
|
18 | 20 |
## Background |
19 | 21 |
|
20 | 22 |
[Readline][] is a library that provides line-editing for interactive |
21 | 23 |
command-line programs. It is used in a great many places, including shells such |
22 |
-as [Bash][] (where it originated) and [REPL][]s such as [Python][] or |
|
23 |
-[Octave][]. Using [`rlwrap`][], Readline can even be used with programs that |
|
24 |
-doesn't have built in support for it, such as Matlab (as in `lrwrap -a matlab |
|
25 |
--nodesktop -nosplash`). These factors make it fairly ubiquitous. |
|
24 |
+as [Bash][] (where it originated) and [REPL][]s such as [Python][]'s or |
|
25 |
+[Octave][]'s. Using [`rlwrap`][], Readline can even be used with programs that |
|
26 |
+don't have built-in support for it, such as [MATLAB][] (as in `rlwrap -a matlab |
|
27 |
+-nodesktop -nosplash`). There are bindings in many languages, so if you're a |
|
28 |
+developer you can easily use it in your own projects. These factors make it |
|
29 |
+fairly ubiquitous. |
|
26 | 30 |
|
27 |
-Readline can be configured with an `inputrc` file, usually placed at |
|
28 |
-`~/.inputrc`. |
|
31 |
+Readline can be configured with an [`inputrc`][] file, usually placed at |
|
32 |
+[`~/.inputrc`][], which supports an [`$include`][] directive useful for |
|
33 |
+including other files, e.g. from `~/.inputrc.d/`. |
|
29 | 34 |
|
30 | 35 |
Readline uses [Emacs][]-like key bindings by default. If you're a Vim fan |
31 |
-though, you probably use its `vi` mode, activated by `set editing-mode vi` in |
|
32 |
-the configuration or through some mechanism in the containing program, such as |
|
36 |
+though, you probably use its vi mode, activated by `set editing-mode vi` in the |
|
37 |
+configuration or through some mechanism in the containing program, such as |
|
33 | 38 |
Bash's `set -o vi`. |
34 | 39 |
|
35 | 40 |
If you *are* a Vim fan though, this has the potential of landing you in a sort |
36 |
-of [uncanny valley][] since (Readline's) `vi` (mode) does not include the many |
|
41 |
+of [uncanny valley][] since (Readline's) vi (mode) does not include the many |
|
37 | 42 |
improvements contained in Vim that you have come to rely on, mainly [text |
38 |
-objects][]. |
|
43 |
+objects][] and the related plugins. This is especially bad if you're using |
|
44 |
+Readline inside Vim's own [`:terminal`][]. [`readline-vim`][] aims to fix this. |
|
45 |
+ |
|
46 |
+[Bash]: https://en.wikipedia.org/wiki/Bash_(Unix_shell) |
|
47 |
+[REPL]: https://en.wikipedia.org/wiki/Read-eval-print_loop |
|
48 |
+[Octave]: https://en.wikipedia.org/wiki/GNU_Octave |
|
49 |
+[`rlwrap`]: https://manpages.debian.org/rlwrap/rlwrap.1.html |
|
50 |
+[MATLAB]: https://en.wikipedia.org/wiki/MATLAB |
|
51 |
+[`inputrc`]: https://www.mankier.com/3/readline#Initialization_File |
|
52 |
+[`~/.inputrc`]: https://www.mankier.com/3/readline#Files-~/.inputrc |
|
53 |
+[`$include`]: https://www.mankier.com/3/readline#Initialization_File-Conditional_Constructs |
|
54 |
+[Emacs]: https://en.wikipedia.org/wiki/Emacs |
|
55 |
+[uncanny valley]: https://en.wikipedia.org/wiki/Uncanny_valley |
|
56 |
+[`:terminal`]: https://vimhelp.org/terminal.txt.html#:terminal |
|
39 | 57 |
|
40 | 58 |
## Usage |
41 | 59 |
|
... | ... |
@@ -46,15 +64,151 @@ git clone https://git.rcrnstn.net/rcrnstn/readline-vim |
46 | 64 |
cd readline-vim |
47 | 65 |
``` |
48 | 66 |
|
49 |
-and append the output to your `~/.inputrc` |
|
67 |
+and either append the output to your `~/.inputrc` |
|
50 | 68 |
|
51 | 69 |
```sh |
52 | 70 |
./readline-vim >> ~/.inputrc |
53 | 71 |
``` |
54 | 72 |
|
55 |
-## Similar projects |
|
73 |
+or use a separate file and include it (recommended) |
|
74 |
+ |
|
75 |
+```sh |
|
76 |
+mkdir -p ~/.inputrc.d |
|
77 |
+./readline-vim >| ~/.inputrc.d/readline-vim.inputrc |
|
78 |
+``` |
|
79 |
+ |
|
80 |
+```sh |
|
81 |
+cat >> ~/.inputrc << 'EOF' |
|
82 |
+ |
|
83 |
+## `readline-vim` |
|
84 |
+$include ~/.inputrc.d/readline-vim.inputrc |
|
85 |
+EOF |
|
86 |
+``` |
|
87 |
+ |
|
88 |
+### Use vi mode by default |
|
89 |
+ |
|
90 |
+```sh |
|
91 |
+cat >> ~/.inputrc << 'EOF' |
|
92 |
+ |
|
93 |
+## Use vi editing mode |
|
94 |
+set editing-mode vi |
|
95 |
+EOF |
|
96 |
+``` |
|
97 |
+ |
|
98 |
+### Indicate mode with cursor shape |
|
99 |
+ |
|
100 |
+```sh |
|
101 |
+cat >> ~/.inputrc << 'EOF' |
|
102 |
+ |
|
103 |
+## Indicate mode with cursor shape |
|
104 |
+set show-mode-in-prompt On |
|
105 |
+$if term=linux |
|
106 |
+ # https://www.kernel.org/doc/Documentation/admin-guide/vga-softcursor.rst |
|
107 |
+ set vi-cmd-mode-string \1\e[?8c\2 |
|
108 |
+ set vi-ins-mode-string \1\e[?0c\2 |
|
109 |
+ set emacs-mode-string \1\e[?0c\2 |
|
110 |
+$else |
|
111 |
+ # https://vt100.net/docs/vt510-rm/DECSCUSR |
|
112 |
+ # http://invisible-island.net/xterm/ctlseqs/ctlseqs.html |
|
113 |
+ set vi-cmd-mode-string \1\e[1 q\2 |
|
114 |
+ set vi-ins-mode-string \1\e[5 q\2 |
|
115 |
+ set emacs-mode-string \1\e[5 q\2 |
|
116 |
+$endif |
|
117 |
+EOF |
|
118 |
+``` |
|
119 |
+ |
|
120 |
+## Features |
|
121 |
+ |
|
122 |
+- Motions |
|
123 |
+ - vi (built-in) |
|
124 |
+ - Word (upper and lower case versions) |
|
125 |
+ - `w` *word beginning, forwards* |
|
126 |
+ - `e` *word end, forwards* |
|
127 |
+ - `b` *word beginning, backwards* |
|
128 |
+ - Other |
|
129 |
+ - `h`, `l` *left, right* |
|
130 |
+ - `0`, `^`, `$` *line beginning, first non-whitespace character, |
|
131 |
+ end*. |
|
132 |
+ - `|` *(first) column* |
|
133 |
+ - `;`, `,` *next, previous searched character* |
|
134 |
+ - `%` *matching pair character* |
|
135 |
+ - Vim |
|
136 |
+ - Word (upper and lower case versions) |
|
137 |
+ - `ge` *word end, backwards* |
|
138 |
+ - Other |
|
139 |
+ - `g_` *last non-whitespace character* |
|
140 |
+ - `)`, `(` *sentence, forwards, backwards* (only works with |
|
141 |
+ sentences after ".") |
|
142 |
+- Operators |
|
143 |
+ - vi |
|
144 |
+ - `d` *delete* |
|
145 |
+ - `c` *change* |
|
146 |
+ - `y` *[yank][]* |
|
147 |
+ - [`vim-surround`][] |
|
148 |
+ - `ds` *delete surroundings* |
|
149 |
+ - `cs` *change surroundings* |
|
150 |
+ - `ys` *add surroundings ("you surround")* |
|
151 |
+- Text objects |
|
152 |
+ - Motions (vi and Vim) |
|
153 |
+ - Implicit line (repeat last character of operator) |
|
154 |
+ - Vim words (`a` *an* and `i` *inner*, upper and lower case versions) |
|
155 |
+ - `w` *word* |
|
156 |
+ - Vim pairs (`a` *an* and `i` *inner* versions) |
|
157 |
+ - Distinct |
|
158 |
+ - Matching |
|
159 |
+ - `(`, `)`, `b` |
|
160 |
+ - `{`, `}`, `B` |
|
161 |
+ - `[`, `]` |
|
162 |
+ - Other |
|
163 |
+ - `<`, `>` |
|
164 |
+ - Nondistinct |
|
165 |
+ - Quotes |
|
166 |
+ - `"`, `'`, `` ` `` |
|
167 |
+ - Punctuation |
|
168 |
+ - `#`, `$`, `%`, `&`, `@`, `\\`, `^` `_`, `|`, `~` |
|
169 |
+ - `.`, `,`, `:`, `;`, `!`, `?` |
|
170 |
+ - `+`, `-`, `*`, `/`, `=` |
|
171 |
+ |
|
172 |
+[yank]: https://en.wiktionary.org/wiki/yank |
|
173 |
+ |
|
174 |
+## Bugs |
|
175 |
+ |
|
176 |
+Some macros clobber the `a`, `b` and/or `c` marks. |
|
177 |
+ |
|
178 |
+Only forward motions work as expected with the surround operators. |
|
179 |
+ |
|
180 |
+Most known bugs exhibit themselves at the end, and sometimes the beginning, of |
|
181 |
+line. This is sometimes unavoidable, sometimes a trade-off to produce correct |
|
182 |
+behavior elsewhere, mostly single-character words and/or whitespace: |
|
183 |
+ |
|
184 |
+- `ge`/`gE` motions: Jumps past last word on line, does not jump past first |
|
185 |
+ word on line. |
|
186 |
+- word/WORD text objects: Always excludes the last character on line. |
|
187 |
+- Implicit line text object (as used in e.g. `yss)`): Includes whitespace at |
|
188 |
+ the beginning and end of line. |
|
189 |
+ |
|
190 |
+## Implementation notes |
|
191 |
+ |
|
192 |
+This is an honest attempt to solve this problem "optimally". However, Readline |
|
193 |
+macros are not [Turing complete][Turing completeness] (in contrast to e.g. |
|
194 |
+VimScript) which makes this kind of hard (and more fun :smile:). |
|
56 | 195 |
|
57 |
-- [`bash-surround`](https://github.com/liloman/bash-surround) |
|
196 |
+Testing suggests that marks are not supported by all applications when combined |
|
197 |
+with operators in macros. No workaround has been found. |
|
198 |
+ |
|
199 |
+Counts used in macros have to come before the operator. That is, `2cl` works |
|
200 |
+but `c2l` does not. |
|
201 |
+ |
|
202 |
+Macros are what Vim calls recursive, i.e. they can make use of other macros in |
|
203 |
+their expansion. To use Readline commands (such as `upcase-word`) they need to |
|
204 |
+be bound to a key sequence (if no binding exists already) before being used in |
|
205 |
+macros. |
|
206 |
+ |
|
207 |
+[Turing completeness]: https://en.wikipedia.org/wiki/Turing_completeness |
|
208 |
+ |
|
209 |
+## Related projects |
|
210 |
+ |
|
211 |
+- [`bash-surround`][] |
|
58 | 212 |
|
59 | 213 |
Defines the macros manually and therefore "only" provides 234 of them, |
60 | 214 |
missing some functionality. |
... | ... |
@@ -62,7 +216,7 @@ and append the output to your `~/.inputrc` |
62 | 216 |
The instructions are Bash centric, although it uses general Readline |
63 | 217 |
macros. |
64 | 218 |
|
65 |
-- [Athame](https://github.com/ardagnir/athame) |
|
219 |
+- [Athame][] |
|
66 | 220 |
|
67 | 221 |
Patches Readline to route keystrokes through an actual Vim process. Also |
68 | 222 |
provides patches for [Zsh][]. This means that whatever your local Vim |
... | ... |
@@ -71,14 +225,35 @@ and append the output to your `~/.inputrc` |
71 | 225 |
Can be a little unreliable if your local Vim has a ton of plugins, |
72 | 226 |
especially if they interact with the terminal in non-obvious ways. |
73 | 227 |
|
74 |
-- [`readline-vim`](https://github.com/thlorenz/readline-vim) |
|
228 |
+- [Zsh][] |
|
229 |
+ |
|
230 |
+ Has built-in [text objects][Zsh text objects] and [surround][Zsh surround] |
|
231 |
+ support. It even has a Vim-like [Visual mode][Zsh Visual mode]. The popular |
|
232 |
+ [Oh My Zsh][] Zsh configuration framework extends this with its |
|
233 |
+ [`vi-mode`][Oh My Zsh `vi-mode`] plugin. There are also several other |
|
234 |
+ plugins: |
|
235 |
+ |
|
236 |
+ - [`softmoth/zsh-vim-mode`][] |
|
237 |
+ - [`jeffreytse/zsh-vi-mode`][] |
|
238 |
+ |
|
239 |
+- [`thlorenz/readline-vim`][] |
|
75 | 240 |
|
76 | 241 |
Exclusive to [Node.js][] [`readline`][Node.js `readline`] and only defines |
77 |
- `vi` bindings, not Vim. |
|
242 |
+ vi bindings, not Vim bindings. |
|
78 | 243 |
|
244 |
+[`bash-surround`]: https://github.com/liloman/bash-surround |
|
245 |
+[Athame]: https://github.com/ardagnir/athame |
|
246 |
+[Zsh]: https://en.wikipedia.org/wiki/Zsh |
|
247 |
+[Zsh text objects]: http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#Text-Objects |
|
248 |
+[Zsh surround]: https://sourceforge.net/p/zsh/code/ci/master/tree/Functions/Zle/surround |
|
249 |
+[Zsh Visual mode]: http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#index-visual_002dmode |
|
250 |
+[Oh My Zsh]: https://ohmyz.sh |
|
251 |
+[Oh My Zsh `vi-mode`]: https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/vi-mode |
|
252 |
+[`softmoth/zsh-vim-mode`]: https://github.com/softmoth/zsh-vim-mode |
|
253 |
+[`jeffreytse/zsh-vi-mode`]: https://github.com/jeffreytse/zsh-vi-mode |
|
254 |
+[`thlorenz/readline-vim`]: https://github.com/thlorenz/readline-vim |
|
79 | 255 |
[Node.js]: https://nodejs.org |
80 | 256 |
[Node.js `readline`]: https://nodejs.org/api/readline.html#readline_readline |
81 |
-[Zsh]: https://en.wikipedia.org/wiki/Zsh |
|
82 | 257 |
|
83 | 258 |
## License |
84 | 259 |
|
... | ... |
@@ -2,11 +2,12 @@ |
2 | 2 |
|
3 | 3 |
Upgrade [Readline][] from [`vi`][] to [Vim][]. |
4 | 4 |
|
5 |
-[`readline-vim`][] generates [Readline][] macros that provide [Vim][] |
|
6 |
-[motions][], [operators][] and [text objects][] (that are useful on a single |
|
7 |
-line). |
|
5 |
+[`readline-vim`][] is a Python program that generates [Readline][] macros that |
|
6 |
+provide [Vim][] [motions][], [operators][] and [text objects][] (that are |
|
7 |
+useful on a single line). |
|
8 | 8 |
|
9 | 9 |
[`readline-vim`]: https://git.rcrnstn.net/rcrnstn/readline-vim |
10 |
+[Python]: https://www.python.org |
|
10 | 11 |
[Readline]: https://en.wikipedia.org/wiki/Readline |
11 | 12 |
[`vi`]: https://en.wikipedia.org/wiki/vi |
12 | 13 |
[Vim]: https://en.wikipedia.org/wiki/Vim |
... | ... |
@@ -36,6 +36,21 @@ of [uncanny valley][] since (Readline's) `vi` (mode) does not include the many |
36 | 36 |
improvements contained in Vim that you have come to rely on, mainly [text |
37 | 37 |
objects][]. |
38 | 38 |
|
39 |
+## Usage |
|
40 |
+ |
|
41 |
+Clone the repository |
|
42 |
+ |
|
43 |
+```sh |
|
44 |
+git clone https://git.rcrnstn.net/rcrnstn/readline-vim |
|
45 |
+cd readline-vim |
|
46 |
+``` |
|
47 |
+ |
|
48 |
+and append the output to your `~/.inputrc` |
|
49 |
+ |
|
50 |
+```sh |
|
51 |
+./readline-vim >> ~/.inputrc |
|
52 |
+``` |
|
53 |
+ |
|
39 | 54 |
## Similar projects |
40 | 55 |
|
41 | 56 |
- [`bash-surround`](https://github.com/liloman/bash-surround) |
... | ... |
@@ -36,6 +36,34 @@ of [uncanny valley][] since (Readline's) `vi` (mode) does not include the many |
36 | 36 |
improvements contained in Vim that you have come to rely on, mainly [text |
37 | 37 |
objects][]. |
38 | 38 |
|
39 |
+## Similar projects |
|
40 |
+ |
|
41 |
+- [`bash-surround`](https://github.com/liloman/bash-surround) |
|
42 |
+ |
|
43 |
+ Defines the macros manually and therefore "only" provides 234 of them, |
|
44 |
+ missing some functionality. |
|
45 |
+ |
|
46 |
+ The instructions are Bash centric, although it uses general Readline |
|
47 |
+ macros. |
|
48 |
+ |
|
49 |
+- [Athame](https://github.com/ardagnir/athame) |
|
50 |
+ |
|
51 |
+ Patches Readline to route keystrokes through an actual Vim process. Also |
|
52 |
+ provides patches for [Zsh][]. This means that whatever your local Vim |
|
53 |
+ supports, Athame supports (including plugins)! |
|
54 |
+ |
|
55 |
+ Can be a little unreliable if your local Vim has a ton of plugins, |
|
56 |
+ especially if they interact with the terminal in non-obvious ways. |
|
57 |
+ |
|
58 |
+- [`readline-vim`](https://github.com/thlorenz/readline-vim) |
|
59 |
+ |
|
60 |
+ Exclusive to [Node.js][] [`readline`][Node.js `readline`] and only defines |
|
61 |
+ `vi` bindings, not Vim. |
|
62 |
+ |
|
63 |
+[Node.js]: https://nodejs.org |
|
64 |
+[Node.js `readline`]: https://nodejs.org/api/readline.html#readline_readline |
|
65 |
+[Zsh]: https://en.wikipedia.org/wiki/Zsh |
|
66 |
+ |
|
39 | 67 |
## License |
40 | 68 |
|
41 | 69 |
Licensed under the [ISC License][], see the [`LICENSE`](LICENSE) file. |
... | ... |
@@ -14,6 +14,28 @@ line). |
14 | 14 |
[operators]: https://vimhelp.org/motion.txt.html#operator |
15 | 15 |
[text objects]: https://vimhelp.org/motion.txt.html#text-objects |
16 | 16 |
|
17 |
+## Background |
|
18 |
+ |
|
19 |
+[Readline][] is a library that provides line-editing for interactive |
|
20 |
+command-line programs. It is used in a great many places, including shells such |
|
21 |
+as [Bash][] (where it originated) and [REPL][]s such as [Python][] or |
|
22 |
+[Octave][]. Using [`rlwrap`][], Readline can even be used with programs that |
|
23 |
+doesn't have built in support for it, such as Matlab (as in `lrwrap -a matlab |
|
24 |
+-nodesktop -nosplash`). These factors make it fairly ubiquitous. |
|
25 |
+ |
|
26 |
+Readline can be configured with an `inputrc` file, usually placed at |
|
27 |
+`~/.inputrc`. |
|
28 |
+ |
|
29 |
+Readline uses [Emacs][]-like key bindings by default. If you're a Vim fan |
|
30 |
+though, you probably use its `vi` mode, activated by `set editing-mode vi` in |
|
31 |
+the configuration or through some mechanism in the containing program, such as |
|
32 |
+Bash's `set -o vi`. |
|
33 |
+ |
|
34 |
+If you *are* a Vim fan though, this has the potential of landing you in a sort |
|
35 |
+of [uncanny valley][] since (Readline's) `vi` (mode) does not include the many |
|
36 |
+improvements contained in Vim that you have come to rely on, mainly [text |
|
37 |
+objects][]. |
|
38 |
+ |
|
17 | 39 |
## License |
18 | 40 |
|
19 | 41 |
Licensed under the [ISC License][], see the [`LICENSE`](LICENSE) file. |
... | ... |
@@ -13,3 +13,9 @@ line). |
13 | 13 |
[motions]: https://vimhelp.org/motion.txt.html |
14 | 14 |
[operators]: https://vimhelp.org/motion.txt.html#operator |
15 | 15 |
[text objects]: https://vimhelp.org/motion.txt.html#text-objects |
16 |
+ |
|
17 |
+## License |
|
18 |
+ |
|
19 |
+Licensed under the [ISC License][], see the [`LICENSE`](LICENSE) file. |
|
20 |
+ |
|
21 |
+[ISC License]: https://choosealicense.com/licenses/isc/ |
1 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,15 @@ |
1 |
+# [`readline-vim`][] |
|
2 |
+ |
|
3 |
+Upgrade [Readline][] from [`vi`][] to [Vim][]. |
|
4 |
+ |
|
5 |
+[`readline-vim`][] generates [Readline][] macros that provide [Vim][] |
|
6 |
+[motions][], [operators][] and [text objects][] (that are useful on a single |
|
7 |
+line). |
|
8 |
+ |
|
9 |
+[`readline-vim`]: https://git.rcrnstn.net/rcrnstn/readline-vim |
|
10 |
+[Readline]: https://en.wikipedia.org/wiki/Readline |
|
11 |
+[`vi`]: https://en.wikipedia.org/wiki/vi |
|
12 |
+[Vim]: https://en.wikipedia.org/wiki/Vim |
|
13 |
+[motions]: https://vimhelp.org/motion.txt.html |
|
14 |
+[operators]: https://vimhelp.org/motion.txt.html#operator |
|
15 |
+[text objects]: https://vimhelp.org/motion.txt.html#text-objects |