├── LICENSE ├── README.md └── plugin ├── changing_text.vim ├── default_maps.vim ├── killing_yanking.vim ├── macros.vim.disabled ├── misc.vim ├── movement.vim └── type_for_you.vim.disabled /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Jon Higgs 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 10 | Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the 13 | distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vim & Readline 2 | 3 | Why am I always exiting from insert mode? Because I don't know the [insert modes special keys](http://vimdoc.sourceforge.net/htmldoc/insert.html). 4 | 5 | Why are those special keys so different from Readline? I don't know. 6 | 7 | Some might say that I should be using Emacs, or Spacemacs or something. But, nah. I like Vim. 8 | 9 | 10 | ## Installation 11 | 12 | Install with your favourite plugin manager (I use [Vundle](https://github.com/VundleVim/Vundle.vim)). 13 | 14 | 15 | ## Usage 16 | 17 | On start-up, the [default key bindings](./plugin/default_maps.vim) will be loaded. I will endeavour to keep these defaults sane and avoid clashing with Vim's native key bindings. 18 | 19 | You may of course extend or modify the defaults within your own personal configuration. Perhaps you'll append it to `~/.vimrc` or `~/.vim/plugins/vim-readline.vim`. How you go about it is up to you. 20 | 21 | A complete list of functionality can be seen within [./plugin/default_maps.vim](./plugin/default_maps.vim). 22 | 23 | 24 | ## Development 25 | 26 | The functions are spread across the files in `./plugins` with each file corresponding to a chapter of the [Readline manual](http://www.delorie.com/gnu/docs/readline/rlman_13.html). 27 | 28 | - [Movement](./plugin/movement.vim) 29 | - [Killing & Yanking](./plugin/killing_yanking.vim) 30 | - [Changing Text](./plugin/changing_text.vim) 31 | - [Miscellaneous](./plugin/misc.vim) 32 | 33 | Not all of the functions have been written yet, but the intention is to make Vim functions with 100% identical behaviour as each of the Readline functions. The user may then use the default bindings offered, or customise the bindings to their own liking. 34 | 35 | The Vim functions are namespaced as `Readline` and each of the functions is available as [user defined commands](http://vimdoc.sourceforge.net/htmldoc/map.html#:command). 36 | 37 | For example for the Readline function of `end-of-line`, it can be ran with `:ReadlineEndOfLine` and bound with `imap :ReadlineEndOfLine`. 38 | 39 | Described is a universal pattern for all functionality, regardless of how trivial the problem. The example of `end-of-line` could have been simply solved with `imap $` but being consistent is beneficial to the user. If they understand one function, they understand them all. There are no exceptions and the burden of complexity is shifted from the user to the developer where it belongs. 40 | -------------------------------------------------------------------------------- /plugin/changing_text.vim: -------------------------------------------------------------------------------- 1 | " COMMANDS FOR CHANGING TEXT 2 | " http://www.delorie.com/gnu/docs/readline/rlman_16.html 3 | 4 | " delete-char (C-d) 5 | " Delete the character at point. If point is at the beginning of the line, 6 | " there are no characters in the line, and the last character typed was not 7 | " bound to delete-char, then return EOF. 8 | function! ReadlineDeleteChar() 9 | if col(".") == col("$")-1 10 | call feedkeys("\lr i") 11 | else 12 | call feedkeys("\x") 13 | endif 14 | endfunction 15 | command! ReadlineDeleteChar call ReadlineDeleteChar() 16 | 17 | " backward-delete-char (Rubout) 18 | " Delete the character behind the cursor. A numeric argument means to kill the 19 | " characters instead of deleting them. 20 | " 21 | 22 | " forward-backward-delete-char () 23 | " Delete the character under the cursor, unless the cursor is at the end of 24 | " the line, in which case the character behind the cursor is deleted. By 25 | " default, this is not bound to a key. 26 | 27 | " quoted-insert (C-q or C-v) 28 | " Add the next character typed to the line verbatim. This is how to insert key 29 | " sequences like C-q, for example. 30 | " 31 | 32 | " tab-insert (M-TAB) 33 | " Insert a tab character. 34 | 35 | " self-insert (a, b, A, 1, !, ...) 36 | " Insert yourself. 37 | " 38 | 39 | " transpose-chars (C-t) 40 | " Drag the character before the cursor forward over the character at the 41 | " cursor, moving the cursor forward as well. If the insertion point is at the 42 | " end of the line, then this transposes the last two characters of the line. 43 | " Negative arguments have no effect. 44 | function! ReadlineTransposeChars() 45 | if col(".") == col("$")-1 " When we are at the end of the line 46 | call feedkeys("\") 47 | endif 48 | call feedkeys("\xpa") 49 | endfunction 50 | command! ReadlineTransposeChars call ReadlineTransposeChars() 51 | 52 | " transpose-words (M-t) 53 | " Drag the word before point past the word after point, moving point past that 54 | " word as well. If the insertion point is at the end of the line, this 55 | " transposes the last two words on the line. 56 | function! ReadlineTransposeWords() 57 | call feedkeys("\b\"adE\"bxb\"bP\"aPEa") 58 | endfunction 59 | command! ReadlineTransposeWords call ReadlineTransposeWords() 60 | 61 | " upcase-word (M-u) 62 | " Uppercase the current (or following) word. With a negative argument, 63 | " uppercase the previous word, but do not move the cursor. 64 | function! ReadlineUpcaseWord() 65 | call feedkeys("\\eUea") 66 | endfunction 67 | command! ReadlineUpcaseWord call ReadlineUpcaseWord() 68 | 69 | " downcase-word (M-l) 70 | " Lowercase the current (or following) word. With a negative argument, 71 | " lowercase the previous word, but do not move the cursor. 72 | function! ReadlineDowncaseWord() 73 | call feedkeys("\\euea") 74 | endfunction 75 | command! ReadlineDowncaseWord call ReadlineDowncaseWord() 76 | 77 | " capitalize-word (M-c) 78 | " Capitalize the current (or following) word. With a negative argument, 79 | " capitalize the previous word, but do not move the cursor. 80 | function! ReadlineCapitalizeWord() 81 | call feedkeys("\l~ea") 82 | endfunction 83 | command! ReadlineCapitalizeWord call ReadlineCapitalizeWord() 84 | 85 | -------------------------------------------------------------------------------- /plugin/default_maps.vim: -------------------------------------------------------------------------------- 1 | " VIM MAP " VIM-READLINE FUNCTION 2 | """""""""" :ReadlineKillWholeLine 3 | inoremap :ReadlineCharacterSearchBackward 4 | inoremap :ReadlineViEditingMode 5 | inoremap :ReadlineCharacterSearch 6 | inoremap :ReadlineBeginningOfLine 7 | inoremap :ReadlineBackwardChar 8 | inoremap :ReadlineDeleteChar 9 | inoremap :ReadlineEndOfLine 10 | inoremap :ReadlineForwardChar 11 | inoremap :ReadlineKillLine 12 | inoremap :ReadlineTransposeChars 13 | inoremap :ReadlineUnixLineDiscard 14 | inoremap :ReadlineUnixWordRubout 15 | inoremap :ReadlineBackwardKillLine 16 | inoremap :ReadlineBackwardKillWord 17 | inoremap :ReadlineBackwardWord 18 | inoremap :ReadlineCapitalizeWord 19 | inoremap :ReadlineKillWord 20 | inoremap :ReadlineForwardWord 21 | inoremap :ReadlineDowncaseWord 22 | inoremap :ReadlineRevertLine 23 | inoremap :ReadlineTransposeWords 24 | inoremap :ReadlineUpcaseWord 25 | inoremap :ReadlineInsertComment 26 | 27 | cmap 28 | cmap 29 | cmap 30 | cmap 31 | -------------------------------------------------------------------------------- /plugin/killing_yanking.vim: -------------------------------------------------------------------------------- 1 | " KILLING AND YANKING 2 | " http://www.delorie.com/gnu/docs/readline/rlman_17.html 3 | 4 | " kill-line (C-k) 5 | " Kill the text from point to the end of the line. 6 | function! ReadlineKillLine() 7 | call feedkeys("\C") 8 | endfunction 9 | command! ReadlineKillLine call ReadlineKillLine() 10 | 11 | " backward-kill-line (C-x Rubout) 12 | " Kill backward to the beginning of the line. 13 | command! ReadlineBackwardKillLine call ReadlineUnixLineDiscard() 14 | 15 | " unix-line-discard (C-u) 16 | " Kill backward from the cursor to the beginning of the current line. 17 | function! ReadlineUnixLineDiscard() 18 | if col(".") == col("$")-1 " When we are at the end of the line 19 | call feedkeys("\^d$") 20 | else 21 | call feedkeys("\d0xi") 22 | endif 23 | endfunction 24 | command! ReadlineUnixLineDiscard call ReadlineUnixLineDiscard() 25 | 26 | " kill-whole-line () 27 | " Kill all characters on the current line, no matter where point is. By 28 | " default, this is unbound. 29 | function! ReadlineKillWholeLine() 30 | call feedkeys("\ddO") 31 | endfunction 32 | 33 | " kill-word (M-d) 34 | " Kill from point to the end of the current word, or if between words, to the 35 | " end of the next word. Word boundaries are the same as forward-word. 36 | function! ReadlineKillWord() 37 | if col(".") != col("$")-1 " When we are not at the end of the line 38 | call feedkeys("\de") 39 | endif 40 | endfunction 41 | command! ReadlineKillWord call ReadlineKillWord() 42 | 43 | " backward-kill-word (M-DEL) 44 | " Kill the word behind point. Word boundaries are the same as backward-word. 45 | function! ReadlineBackwardKillWord() 46 | if &iskeyword =~ '_' 47 | let remove_keyword=0 48 | else 49 | let remove_keyword=1 50 | set iskeyword+=_ 51 | endif 52 | 53 | if col(".") == col("$")-1 " When we are at the end of the line 54 | call feedkeys("\dbxa") 55 | else 56 | call feedkeys("\ldbi") 57 | endif 58 | 59 | if remove_keyword 60 | set iskeyword-=_ 61 | unlet remove_keyword 62 | endif 63 | endfunction 64 | command! ReadlineBackwardKillWord call ReadlineBackwardKillWord() 65 | 66 | " unix-word-rubout (C-w) 67 | " Kill the word behind point, using white space as a word boundary. The killed 68 | " text is saved on the kill-ring. 69 | function! ReadlineUnixWordRubout() 70 | if col(".") == col("$")-1 " When we are at the end of the line 71 | call feedkeys("\dB\x") 72 | else 73 | call feedkeys("\dB") 74 | endif 75 | endfunction 76 | command! ReadlineUnixWordRubout call ReadlineUnixWordRubout() 77 | 78 | " delete-horizontal-space () 79 | " Delete all spaces and tabs around point. By default, this is unbound. 80 | 81 | " kill-region () 82 | " Kill the text in the current region. By default, this command is unbound. 83 | 84 | " copy-region-as-kill () 85 | " Copy the text in the region to the kill buffer, so it can be yanked right 86 | " away. By default, this command is unbound. 87 | 88 | " copy-backward-word () 89 | " Copy the word before point to the kill buffer. The word boundaries are the 90 | " same as backward-word. By default, this command is unbound. 91 | 92 | " copy-forward-word () 93 | " Copy the word following point to the kill buffer. The word boundaries are 94 | " the same as forward-word. By default, this command is unbound. 95 | 96 | " yank (C-y) 97 | " Yank the top of the kill ring into the buffer at point. 98 | "imap u 99 | 100 | " yank-pop (M-y) 101 | " Rotate the kill-ring, and yank the new top. You can only do this if the 102 | " prior command is yank or yank-pop. 103 | -------------------------------------------------------------------------------- /plugin/macros.vim.disabled: -------------------------------------------------------------------------------- 1 | " I can't think of any time when I'd be using macro's in insert mode so I'm 2 | " going to leve them out. If you have a strong argument to do so, create an 3 | " issue. 4 | 5 | " KEYBOARD MACROS 6 | " http://www.delorie.com/gnu/docs/readline/rlman_20.html 7 | 8 | " start-kbd-macro (C-x () 9 | " Begin saving the characters typed into the current keyboard macro. 10 | 11 | " end-kbd-macro (C-x )) 12 | " Stop saving the characters typed into the current keyboard macro and save the 13 | " definition. 14 | 15 | " call-last-kbd-macro (C-x e) 16 | " Re-execute the last keyboard macro defined, by making the characters in the 17 | " macro appear as if typed at the keyboard. 18 | 19 | -------------------------------------------------------------------------------- /plugin/misc.vim: -------------------------------------------------------------------------------- 1 | " SOME MISCELLANEOUS COMMANDS 2 | " http://www.delorie.com/gnu/docs/readline/rlman_21.html 3 | 4 | " re-read-init-file (C-x C-r) 5 | " Read in the contents of the inputrc file, and incorporate any bindings or 6 | " variable assignments found there. 7 | " 8 | 9 | " abort (C-g) 10 | " Abort the current editing command and ring the terminal's bell (subject to 11 | " the setting of bell-style). 12 | 13 | " do-uppercase-version (M-a, M-b, M-x, ...) 14 | " If the metafied character x is lowercase, run the command that is bound to 15 | " the corresponding uppercase character. 16 | 17 | " prefix-meta (ESC) 18 | " Metafy the next character typed. This is for keyboards without a meta key. 19 | " Typing `ESC f' is equivalent to typing M-f. 20 | 21 | " undo (C-_ or C-x C-u) 22 | " Incremental undo, separately remembered for each line. 23 | 24 | " revert-line (M-r) 25 | " Undo all changes made to this line. This is like executing the undo command 26 | " enough times to get back to the beginning. 27 | command! ReadlineRevertLine call ReadlineUnixLineDiscard() 28 | 29 | " tilde-expand (M-~) 30 | " Perform tilde expansion on the current word. 31 | 32 | " set-mark (C-@) 33 | " Set the mark to the point. If a numeric argument is supplied, the mark is set 34 | " to that position. 35 | 36 | " exchange-point-and-mark (C-x C-x) 37 | " Swap the point with the mark. The current cursor position is set to the saved 38 | " position, and the old cursor position is saved as the mark. 39 | 40 | " character-search (C-]) 41 | " A character is read and point is moved to the next occurrence of that 42 | " character. A negative count searches for previous occurrences. 43 | function! ReadlineCharacterSearch() 44 | let c = getchar() 45 | let v = nr2char(c) 46 | call feedkeys("\lf".v."i") 47 | endfunction 48 | command! ReadlineCharacterSearch call ReadlineCharacterSearch() 49 | 50 | " character-search-backward (M-C-]) 51 | " A character is read and point is moved to the previous occurrence of that 52 | " character. A negative count searches for subsequent occurrences. 53 | function! ReadlineCharacterSearchBackward() 54 | let c = getchar() 55 | let v = nr2char(c) 56 | call feedkeys("\F".v."i") 57 | endfunction 58 | command! ReadlineCharacterSearchBackward call ReadlineCharacterSearchBackward() 59 | 60 | " insert-comment (M-#) 61 | " Without a numeric argument, the value of the comment-begin variable is 62 | " inserted at the beginning of the current line. If a numeric argument is 63 | " supplied, this command acts as a toggle: if the characters at the beginning 64 | " of the line do not match the value of comment-begin, the value is inserted, 65 | " otherwise the characters in comment-begin are deleted from the beginning of 66 | " the line. In either case, the line is accepted as if a newline had been 67 | " typed. 68 | function! ReadlineInsertComment() 69 | if &filetype == "c" 70 | let comment='//' 71 | elseif &filetype == "ruby" 72 | let comment='#' 73 | elseif &filetype == "sh" 74 | let comment='#' 75 | elseif &filetype == "dosini" 76 | let comment=';' 77 | elseif &filetype == "python" 78 | let comment='#' 79 | elseif &filetype == "vim" 80 | let comment='"' 81 | endif 82 | 83 | p = getcol() 84 | call feedkeys("\ma0i".comment."\`ai") 85 | endfunction 86 | command! ReadlineInsertComment call ReadlineInsertComment() 87 | 88 | " dump-functions () 89 | " Print all of the functions and their key bindings to the Readline output 90 | " stream. If a numeric argument is supplied, the output is formatted in such a 91 | " way that it can be made part of an inputrc file. This command is unbound by 92 | " default. 93 | " 94 | 95 | " dump-variables () 96 | " Print all of the settable variables and their values to the Readline output 97 | " stream. If a numeric argument is supplied, the output is formatted in such a 98 | " way that it can be made part of an inputrc file. This command is unbound by 99 | " default. 100 | " 101 | 102 | " dump-macros () 103 | " Print all of the Readline key sequences bound to macros and the strings they 104 | " output. If a numeric argument is supplied, the output is formatted in such a 105 | " way that it can be made part of an inputrc file. This command is unbound by 106 | " default. 107 | " 108 | 109 | " emacs-editing-mode (C-e) 110 | " When in vi command mode, this causes a switch to emacs editing mode. 111 | " 112 | 113 | " vi-editing-mode (M-C-j) 114 | " When in emacs editing mode, this causes a switch to vi editing mode. 115 | function! ReadlineViEditingMode() 116 | call feedkeys("\") 117 | endfunction 118 | command! ReadlineViEditingMode call ReadlineViEditingMode() 119 | -------------------------------------------------------------------------------- /plugin/movement.vim: -------------------------------------------------------------------------------- 1 | " COMMANDS FOR MOVING 2 | " http://www.delorie.com/gnu/docs/readline/rlman_14.html 3 | 4 | "beginning-of-line (C-a) 5 | "Move to the start of the current line. 6 | function! ReadlineBeginningOfLine() 7 | call feedkeys("\0") 8 | endfunction 9 | command! ReadlineBeginningOfLine call ReadlineBeginningOfLine() 10 | 11 | "end-of-line (C-e) 12 | "Move to the end of the line. 13 | imap $ 14 | 15 | function! ReadlineEndOfLine() 16 | call feedkeys("\$") 17 | endfunction 18 | command! ReadlineEndOfLine call ReadlineEndOfLine() 19 | 20 | "forward-char (C-f) 21 | "Move forward a character. 22 | function! ReadlineForwardChar() 23 | call feedkeys("\") 24 | endfunction 25 | command! ReadlineForwardChar call ReadlineForwardChar() 26 | 27 | "backward-char (C-b) 28 | "Move back a character. 29 | function! ReadlineBackwardChar() 30 | call feedkeys("\") 31 | endfunction 32 | command! ReadlineBackwardChar call ReadlineBackwardChar() 33 | 34 | "forward-word (M-f) 35 | "Move forward to the end of the next word. Words are composed of letters and 36 | "digits. 37 | function! ReadlineForwardWord() 38 | call feedkeys("\ea") 39 | endfunction 40 | command! ReadlineForwardWord call ReadlineForwardWord() 41 | 42 | "backward-word (M-b) 43 | "Move back to the start of the current or previous word. Words are composed of 44 | "letters and digits. 45 | function! ReadlineBackwardWord() 46 | if getline(".")[col(".")-2] =~ '[^a-zA-Z0-9]' " if we stopped at punctuation 47 | call feedkeys("\") 48 | endif 49 | call feedkeys("\b") 50 | endfunction 51 | command! ReadlineBackwardWord call ReadlineBackwardWord() 52 | 53 | "clear-screen (C-l) 54 | "Clear the screen and redraw the current line, leaving the current line at the 55 | "top of the screen. 56 | " 57 | 58 | "redraw-current-line () 59 | "Refresh the current line. By default, this is unbound. 60 | " 61 | " 62 | -------------------------------------------------------------------------------- /plugin/type_for_you.vim.disabled: -------------------------------------------------------------------------------- 1 | " Vim's default and work fine as a replacement for this. If you 2 | " have a strong argument to the contrary, raise an issue. 3 | 4 | " LETTING READLINE TYPE FOR YOU 5 | " http://www.delorie.com/gnu/docs/readline/rlman_19.html 6 | 7 | " complete (TAB) 8 | " Attempt to perform completion on the text before point. The actual completion 9 | " performed is application-specific. The default is filename completion. 10 | 11 | " possible-completions (M-?) 12 | " List the possible completions of the text before point. 13 | 14 | " insert-completions (M-*) 15 | " Insert all completions of the text before point that would have been 16 | " generated by possible-completions. 17 | 18 | " menu-complete () 19 | " Similar to complete, but replaces the word to be completed with a single 20 | " match from the list of possible completions. Repeated execution of 21 | " menu-complete steps through the list of possible completions, inserting each 22 | " match in turn. At the end of the list of completions, the bell is rung 23 | " (subject to the setting of bell-style) and the original text is restored. An 24 | " argument of n moves n positions forward in the list of matches; a negative 25 | " argument may be used to move backward through the list. This command is 26 | " intended to be bound to TAB, but is unbound by default. 27 | 28 | " delete-char-or-list () Deletes the character under the cursor if not at the 29 | " beginning or end of the line (like delete-char). If at the end of the line, 30 | " behaves identically to possible-completions. This command is unbound by 31 | " default. 32 | --------------------------------------------------------------------------------