├── .gitignore ├── .github └── FUNDING.yml ├── README.markdown ├── doc └── capslock.txt └── plugin └── capslock.vim /.gitignore: -------------------------------------------------------------------------------- 1 | /doc/tags 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: tpope 2 | custom: ["https://www.paypal.me/vimpope"] 3 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # capslock.vim 2 | 3 | Press `c` in insert mode to toggle a temporary software caps lock, or 4 | `gC` in normal mode to toggle a slightly more permanent one. 5 | 6 | ## Installation 7 | 8 | If you don't have a preferred installation method, I recommend 9 | installing [pathogen.vim](https://github.com/tpope/vim-pathogen), and 10 | then simply copy and paste: 11 | 12 | cd ~/.vim/bundle 13 | git clone https://github.com/tpope/vim-capslock.git 14 | vim -u NONE -c "helptags vim-capslock/doc" -c q 15 | 16 | Once help tags have been generated, you can view the manual with 17 | `:help capslock`. 18 | 19 | ## Contributing 20 | 21 | See the contribution guidelines for 22 | [pathogen.vim](https://github.com/tpope/vim-pathogen#readme). 23 | 24 | ## Self-Promotion 25 | 26 | Like capslock.vim? Follow the repository on 27 | [GitHub](https://github.com/tpope/vim-capslock) and vote for it on 28 | [vim.org](http://www.vim.org/scripts/script.php?script_id=1725). And if 29 | you're feeling especially charitable, follow [tpope](http://tpo.pe/) on 30 | [Twitter](http://twitter.com/tpope) and 31 | [GitHub](https://github.com/tpope). 32 | 33 | ## License 34 | 35 | Copyright (c) Tim Pope. Distributed under the same terms as Vim itself. 36 | See `:help license`. 37 | -------------------------------------------------------------------------------- /doc/capslock.txt: -------------------------------------------------------------------------------- 1 | *capslock.txt* Software caps lock 2 | 3 | Author: Tim Pope 4 | License: Same terms as Vim itself (see |license|) 5 | 6 | This plugin is only available if 'compatible' is not set. 7 | 8 | SUMMARY *capslock* 9 | 10 | This plugin enables a software caps lock. This is advantageous over a regular 11 | caps lock in that normal mode commands, other buffers, and other applications 12 | are unaffected. 13 | 14 | *capslock-i_CTRL-G_c* *capslock-gC* 15 | The default insert mode mapping is c, and the default normal mode map is 16 | gC. Additionally, is mapped in insert mode if it is otherwise unused. 17 | CapsLockToggle, CapsLockEnable, and CapsLockDisable are 18 | provided in normal, insert, and command line mode if you would prefer to 19 | define your own maps. 20 | 21 | By default, caps lock is automatically disabled after leaving insert mode for 22 | the insert mode mappings, but must be explicitly disabled for the normal mode 23 | mappings. If you always want to use the latter method, make your insert mode 24 | mapping call the normal mode one. 25 | > 26 | imap CapsLockToggle 27 | < 28 | CapsLockStatusline() is provided to use inside %{} in 'statusline'. This 29 | returns "[Caps]" (or the optional first argument) if software caps lock is 30 | enabled. Here's an example usage that won't cause problems if capslock.vim is 31 | missing: 32 | > 33 | set statusline^=%{exists('*CapsLockStatusline')?CapsLockStatusline():''} 34 | < 35 | vim:tw=78:et:ft=help:norl: 36 | -------------------------------------------------------------------------------- /plugin/capslock.vim: -------------------------------------------------------------------------------- 1 | " capslock.vim - Software caps lock 2 | " Maintainer: Tim Pope 3 | " Version: 1.1 4 | " GetLatestVimScripts: 1725 1 :AutoInstall: capslock.vim 5 | 6 | if exists("g:loaded_capslock") || v:version < 704 || &cp 7 | finish 8 | endif 9 | let g:loaded_capslock = 1 10 | 11 | let s:cpo_save = &cpo 12 | set cpo&vim 13 | 14 | " Code {{{1 15 | 16 | function! s:enable(mode, ...) abort 17 | if a:mode ==# 'i' 18 | let b:capslock = 1 + a:0 19 | endif 20 | if a:mode ==# 'c' 21 | let i = char2nr('A') 22 | while i <= char2nr('Z') 23 | exe a:mode."noremap " nr2char(i) nr2char(i+32) 24 | exe a:mode."noremap " nr2char(i+32) nr2char(i) 25 | let i = i + 1 26 | endwhile 27 | endif 28 | let &l:readonly = &l:readonly 29 | return '' 30 | endfunction 31 | 32 | function! s:disable(mode) abort 33 | if a:mode ==# 'i' 34 | unlet! b:capslock 35 | endif 36 | if a:mode ==# 'c' 37 | let i = char2nr('A') 38 | while i <= char2nr('Z') 39 | silent! exe a:mode."unmap " nr2char(i) 40 | silent! exe a:mode."unmap " nr2char(i+32) 41 | let i += 1 42 | endwhile 43 | endif 44 | let &l:readonly = &l:readonly 45 | return '' 46 | endfunction 47 | 48 | function! s:toggle(mode, ...) abort 49 | if s:enabled(a:mode) 50 | return s:disable(a:mode) 51 | elseif a:0 52 | return s:enable(a:mode,a:1) 53 | else 54 | return s:enable(a:mode) 55 | endif 56 | endfunction 57 | 58 | function! s:enabled(mode) abort 59 | if a:mode ==# 'i' 60 | return get(b:, 'capslock', 0) 61 | else 62 | return maparg('a', a:mode) ==# 'A' 63 | endif 64 | endfunction 65 | 66 | function! s:exitcallback() abort 67 | if s:enabled('i') == 1 68 | call s:disable('i') 69 | endif 70 | endfunction 71 | 72 | function! CapsLockStatusline(...) abort 73 | return s:enabled('i') ? (a:0 == 1 ? a:1 : '[Caps]') : '' 74 | endfunction 75 | 76 | augroup capslock 77 | autocmd! 78 | autocmd User Flags call Hoist('window', 'CapsLockStatusline') 79 | 80 | autocmd InsertLeave * call s:exitcallback() 81 | autocmd InsertCharPre * 82 | \ if s:enabled('i') | 83 | \ let v:char = v:char ==# tolower(v:char) ? toupper(v:char) : tolower(v:char) | 84 | \ endif 85 | augroup END 86 | 87 | " }}}1 88 | " Maps {{{1 89 | 90 | nnoremap CapsLockToggle :call toggle('i',1) 91 | nnoremap CapsLockEnable :call enable('i',1) 92 | nnoremap CapsLockDisable :call disable('i') 93 | inoremap CapsLockToggle =toggle('i') 94 | inoremap CapsLockEnable =enable('i') 95 | inoremap CapsLockDisable =disable('i') 96 | cnoremap CapsLockToggle =toggle('c') 97 | cnoremap CapsLockEnable =enable('c') 98 | cnoremap CapsLockDisable =disable('c') 99 | 100 | if empty(mapcheck("", "i")) && exists("*complete_info") && !&insertmode 101 | function! s:ctrl_l() abort 102 | let l:compl_mode = complete_info(['mode']).mode 103 | return l:compl_mode ==# 'ctrl_x' || l:compl_mode ==# 'whole_line' || 104 | \ (pumvisible() && complete_info(['selected']).selected !=# -1) || 105 | \ &insertmode 106 | \ ? "\" : "\CapsLockToggle" 107 | endfunction 108 | imap ctrl_l() 109 | endif 110 | if empty(mapcheck("c", "i")) 111 | imap c CapsLockToggle 112 | endif 113 | if empty(mapcheck("gC", "n")) 114 | nmap gC CapsLockToggle 115 | endif 116 | 117 | " }}}1 118 | 119 | let &cpo = s:cpo_save 120 | 121 | " vim:set sw=2 et: 122 | --------------------------------------------------------------------------------