├── LICENSE ├── README.md └── plugin └── cursormode.vim /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2014 Andrea Cedraro 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the "Software"), 5 | to deal in the Software without restriction, including without limitation 6 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | and/or sell copies of the Software, and to permit persons to whom the 8 | Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included 11 | in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 15 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 16 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 18 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 19 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | 21 | 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cursor Mode 2 | Change the color of the cursor based on the mode we're in for terminal vim. 3 | At the moment it is tested for iTerm2 only (because is the only thing that I use) but basic implementation for xterm/urxvt is there and should work. 4 | 5 | # Why would I want this? 6 | 7 | Vim already has `:h 'showmode'` but I like colors to distinguish things. 8 | Other plugin offer something colored like [vim-airline][] or [powerline][]/[vim-powerline][] that let you color part of the statusline based on the mode we are in but specially if we have big screen it is not so easy to see the color in the bottom left corner of the statusline, 9 | so I prefer coloring what I'm looking at that usually is where my cursor is. 10 | 11 | # How to use it 12 | 13 | Install it as any plugin, using your plugin manager of choice: 14 | 15 | [vim-plug][] 16 | 17 | ```viml 18 | Plug 'vheon/vim-cursormode' 19 | ``` 20 | 21 | [Vundle.vim][] 22 | 23 | ```viml 24 | Plugin 'vheon/vim-cursormode' 25 | ``` 26 | 27 | [NeoBundle.vim][] 28 | 29 | ```viml 30 | NeoBundle 'vheon/vim-cursormode' 31 | ``` 32 | 33 | Or using [vim-pathogen][] 34 | 35 | # Cursor colors 36 | For setting the color to be used in the different mode you have a couple of options: 37 | 38 | * define a variable `g:cursormode_color_map` 39 | * define a variable with a name like `g:cursormode#{colorscheme}#color_map` 40 | i.e. `let cursormode#solarized#color_map = {...}` 41 | This kind of maps are reloaded if you change the colorscheme. 42 | As you may have noticed this are autoload variable, so you could define them in a 43 | `autoload/cursormode/{colorscheme}.vim` file. So for example you could ship this file with a colorscheme. 44 | 45 | If none of the above are defined we use a default color map using the colors in the default colorscheme in iTerm2 46 | 47 | ## Color map format 48 | 49 | Every color map is in the form: 50 | 51 | ```viml 52 | let cursormode_color_map = { 53 | \ "mode": "#rrggbb", 54 | ... 55 | \ } 56 | ``` 57 | 58 | The mode string are the ones returned by `:h mode()` and the colors are in the form of `#rrggbb`. 59 | 60 | For example this is a possible map: 61 | 62 | ```viml 63 | let cursormode_color_map = { 64 | \ "n": "#FFFFFF", 65 | \ "i": "#0000FF", 66 | \ "v": "#00FF00", 67 | \ "V": "#FF0000", 68 | \ "\": "#FFFF00", 69 | \ } 70 | ``` 71 | 72 | If you want to specify a color for a mode based on the `background` you can do it appending the background string to the mode 73 | 74 | For example here is my solarized map with the normal mode color based on the background: 75 | 76 | ```viml 77 | let cursormode_solarized_color_map = { 78 | \ "nlight": "#657b83", 79 | \ "ndark": "#839496", 80 | \ "i": "#268bd2", 81 | \ "v": "#cb4b16", 82 | \ "V": "#b58900", 83 | \ "\": "#6c71c4", 84 | \ } 85 | ``` 86 | 87 | # Known Issues 88 | 89 | * At the moment only tested in iTerm2. 90 | * Sporadically the view is moved, so for example I enter Insert mode and the current line is moved at the top as if I typed `zt`. I didn't find a way of debug this thing, so any input on this is welcome. 91 | * Do not work when ssh into a remote machine 92 | 93 | # TODO 94 | 95 | * fallback to coloring the entire statusline when using vim on remote machine through ssh 96 | * Make a compatibility layer with `guicursor` 97 | 98 | # Credits 99 | 100 | Idea stolen from [http://www.blaenkdenum.com/posts/a-simpler-vim-statusline/][] 101 | He uses the `guicursor` option which it's for GUI, MSDOW and Win32 console only 102 | but I use terminal vim on iTerm2 only at the moment so I thoght about sending escape codes to 103 | iTerm2 to change the cursor color. 104 | 105 | [vim-airline]: https://github.com/bling/vim-airline 106 | [powerline]: https://github.com/Lokaltog/powerline 107 | [vim-powerline]: https://github.com/Lokaltog/vim-powerline 108 | [vim-plug]: https://github.com/junegunn/vim-plug 109 | [Vundle.vim]: https://github.com/gmarik/Vundle.vim 110 | [NeoBundle.vim]: https://github.com/Shougo/neobundle.vim 111 | [vim-pathogen]: https://github.com/tpope/vim-pathogen 112 | [http://www.blaenkdenum.com/posts/a-simpler-vim-statusline/]: http://www.blaenkdenum.com/posts/a-simpler-vim-statusline/ 113 | -------------------------------------------------------------------------------- /plugin/cursormode.vim: -------------------------------------------------------------------------------- 1 | " Copyright (C) 2014 Andrea Cedraro 2 | " 3 | " Permission is hereby granted, free of charge, to any person obtaining 4 | " a copy of this software and associated documentation files (the "Software"), 5 | " to deal in the Software without restriction, including without limitation 6 | " the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | " and/or sell copies of the Software, and to permit persons to whom the 8 | " Software is furnished to do so, subject to the following conditions: 9 | " 10 | " The above copyright notice and this permission notice shall be included 11 | " in all copies or substantial portions of the Software. 12 | " 13 | " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 | " EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 15 | " OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 16 | " IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 17 | " DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 18 | " TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 19 | " OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | 21 | let s:is_win = has('win32') || has('win64') 22 | let s:is_iTerm = exists('$TERM_PROGRAM') && $TERM_PROGRAM =~# 'iTerm.app' 23 | let s:is_AppleTerminal = exists('$TERM_PROGRAM') && $TERM_PROGRAM =~# 'Apple_Terminal' 24 | 25 | let s:is_good = !has('gui_running') && !s:is_win && !s:is_AppleTerminal 26 | 27 | if exists('g:loaded_cursormode') || !s:is_good 28 | finish 29 | endif 30 | let g:loaded_cursormode = 1 31 | 32 | let s:cpo_save = &cpo 33 | set cpo&vim 34 | 35 | let s:last_mode = '' 36 | 37 | function! cursormode#tmux_escape(escape) 38 | return '\033Ptmux;'.substitute(a:escape, '\\033', '\\033\\033', 'g').'\033\\' 39 | endfunction 40 | 41 | let s:iTerm_escape_template = '\033]Pl%s\033\\' 42 | let s:xterm_escape_template = '\033]12;%s\007' 43 | 44 | function! cursormode#CursorMode() 45 | let mode = mode() 46 | if mode !=# s:last_mode 47 | let s:last_mode = mode 48 | call s:set_cursor_color_for(mode) 49 | endif 50 | return '' 51 | endfunction 52 | 53 | function! s:set_cursor_color_for(mode) 54 | let mode = a:mode 55 | for mode in [a:mode, a:mode.&background] 56 | if has_key(s:color_map, mode) 57 | try 58 | let save_eventignore = &eventignore 59 | set eventignore=all 60 | let save_shelltemp = &shelltemp 61 | set noshelltemp 62 | 63 | silent call system(s:build_command(s:color_map[mode])) 64 | return 65 | finally 66 | let &shelltemp = save_shelltemp 67 | let &eventignore = save_eventignore 68 | endtry 69 | endif 70 | endfor 71 | endfunction 72 | 73 | function! s:build_command(color) 74 | if s:is_iTerm 75 | let color = substitute(a:color, '^#', '', '') 76 | let escape_template = s:iTerm_escape_template 77 | else 78 | let color = a:color 79 | let escape_template = s:xterm_escape_template 80 | endif 81 | 82 | let escape = printf(escape_template, color) 83 | if exists('$TMUX') 84 | let escape = cursormode#tmux_escape(escape) 85 | endif 86 | return "printf '".escape."' > /dev/tty" 87 | endfunction 88 | 89 | function! s:get_color_map() 90 | if exists('g:cursormode_color_map') 91 | return g:cursormode_color_map 92 | endif 93 | 94 | try 95 | let map = g:cursormode#{g:colors_name}#color_map 96 | return map 97 | catch 98 | return { 99 | \ "nlight": "#000000", 100 | \ "ndark": "#BBBBBB", 101 | \ "i": "#0000BB", 102 | \ "v": "#FF5555", 103 | \ "V": "#BBBB00", 104 | \ "\": "#BB00BB", 105 | \ } 106 | endtry 107 | endfunction 108 | 109 | function! cursormode#Activate() 110 | let s:color_map = s:get_color_map() 111 | call s:activate('&statusline') 112 | endfunction 113 | 114 | function! cursormode#LocalActivate() 115 | call s:activate('&l:statusline') 116 | endfunction 117 | 118 | function! s:activate(on) 119 | call s:deactivate(a:on) 120 | execute 'let' a:on ".= '%{cursormode#CursorMode()}'" 121 | endfunction 122 | 123 | function! s:deactivate(on) 124 | execute "let" a:on "= substitute(".a:on.", '%{cursormode#CursorMode()}', '', 'g')" 125 | endfunction 126 | 127 | augroup cursormode 128 | autocmd! 129 | autocmd VimLeave * call s:set_cursor_color_for("n") 130 | autocmd VimEnter * call cursormode#Activate() 131 | autocmd Colorscheme * call cursormode#Activate() 132 | augroup END 133 | 134 | let &cpo = s:cpo_save 135 | unlet s:cpo_save 136 | --------------------------------------------------------------------------------