├── README.md ├── doc └── textobj-key-value.txt └── plugin └── textobj └── keyvalue.vim /README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /doc/textobj-key-value.txt: -------------------------------------------------------------------------------- 1 | textobj-keyvalue is a Vim plugin to provide text objects to select general key and value of map. 2 | 3 | Version: 0.1.0 4 | Author : vimtaku 5 | License: Creative Commons Attribution 2.1 Japan License 6 | 7 | 8 | ============================================================================== 9 | INTRODUCTION |textobj-keyvalue-introduction| 10 | INTERFACE |textobj-keyvalue-interface| 11 | KEY MAPPINGS |textobj-keyvalue-key-mappings| 12 | CUSTOMIZING |textobj-keyvalue-customizing| 13 | CHANGELOG |textobj-keyvalue-changelog| 14 | 15 | ============================================================================== 16 | INTRODUCTION *textobj-keyvalue-introduction* 17 | 18 | *textobj-keyvalue* is a Vim plugin to provide text objects to select a string 19 | that general key and value of map. 20 | For example, in javascript, you can define map easily as following. 21 | 22 | var map = { 23 | 'somekey' : 'somevalue', 24 | }; 25 | 26 | If you use this plugin, you can select 'somekey' and 'somevalue' very easily. 27 | 28 | Requirements: 29 | - Vim 7.2 or later 30 | - |textobj-user| 0.3.8 or later 31 | 32 | 33 | Latest version: 34 | https://vimtaku@github.com/vimtaku/vim-textobj-keyvalue.git 35 | 36 | ============================================================================== 37 | INTERFACE *textobj-keyvalue-interface* 38 | 39 | ------------------------------------------------------------------------------ 40 | KEY MAPPINGS *textobj-keyvalue-key-mappings* 41 | 42 | These key mappings are defined in Visual mode and Operator-pending mode. 43 | 44 | (textobj-key-a){char} *(textobj-key-a)* 45 | This mappings select key include quotes or double quotes. 46 | Examples: 47 | var map = { 48 | 'somekey' : 'somevalue', 49 | ^ here is cursor 50 | }; 51 | then 52 | var map = { 53 | 'somekey' : 'somevalue', 54 | ~~~~~~~~~~ 55 | ^ this range is selected. 56 | }; 57 | 58 | (textobj-key-i){char} *(textobj-key-i)* 59 | This mappings select inner text of the key surrounded by quotes or double quote. 60 | Examples: 61 | var map = { 62 | 'somekey' : 'somevalue', 63 | ^ here is cursor 64 | }; 65 | then 66 | var map = { 67 | 'somekey' : 'somevalue', 68 | ~~~~~~~~ 69 | ^ this inner range is selected. 70 | }; 71 | 72 | 73 | ============================================================================== 74 | CUSTOMIZING *textobj-keyvalue-customizing* 75 | *g:textobj_key_no_default_key_mappings* 76 | *g:textobj_value_no_default_key_mappings* 77 | *:TextobjKeyDefaultKeyMappings* 78 | *:TextobjValueDefaultKeyMappings* 79 | This plugin will define the following key mappings in Visual mode and 80 | Operator-pending mode automatically. If you don't want these key mappings, 81 | define |g:textobj_key_no_default_key_mappings| 82 | or |g:textobj_key_no_default_key_mappings| before this plugin is loaded 83 | (e.g. in your |vimrc|). You can also use |:TextobjKeyDefaultKeyMappings| 84 | or |:TextobjValueDefaultKeyMappings| 85 | to redefine these key mappings. This command doesn't override existing {lhs}s 86 | unless [!] is given. 87 | 88 | {lhs} {rhs} ~ 89 | ----- ---------------------- ~ 90 | ak (textobj-key-a) 91 | ik (textobj-key-i) 92 | av (textobj-value-a) 93 | iv (textobj-value-i) 94 | 95 | 96 | ============================================================================== 97 | CHANGELOG *textobj-keyvalue-changelog* 98 | 99 | 0.1.0 2012-04-14 100 | - Initial version. 101 | 102 | ============================================================================== 103 | vim:tw=78:fo=tcq2mM:ts=8:ft=help:norl 104 | 105 | -------------------------------------------------------------------------------- /plugin/textobj/keyvalue.vim: -------------------------------------------------------------------------------- 1 | if exists('g:loaded_textobj_keyvalue') 2 | finish 3 | endif 4 | 5 | let g:loaded_textobj_keyvalue = 1 6 | 7 | call textobj#user#plugin('key', { 8 | \ '-': { 9 | \ '*sfile*': expand(':p'), 10 | \ 'select-i': 'ik', 11 | \ 'select-a': 'ak', 12 | \ '*select-i-function*': 's:select_key_i', 13 | \ '*select-a-function*': 's:select_key_a', 14 | \ } 15 | \}) 16 | 17 | function! s:select_key_i() "{{{2 18 | let save_pos = getpos(".") 19 | normal! 0 20 | let splitter = s:get_splitter() 21 | call search('["' . "'][^'" .'"'."]\\+" . '["' . "']" . "\\s*" . splitter) 22 | normal! l 23 | let c = getpos('.') 24 | if abs(c[1] - save_pos[1]) > 2 25 | call setpos('.', save_pos) 26 | normal! l 27 | return 28 | endif 29 | let [b, e] = [c, c] 30 | call search('["' . "']" . "\\s*" . splitter) 31 | normal! h 32 | let e = getpos('.') 33 | return ['v', b, e] 34 | endfunction 35 | 36 | function! s:select_key_a() "{{{2 37 | let save_pos = getpos(".") 38 | normal! 0 39 | let splitter = s:get_splitter() 40 | call search('\S\+\s*' . splitter) 41 | let c = getpos('.') 42 | if abs(c[1] - save_pos[1]) > 2 43 | call setpos('.', save_pos) 44 | normal! l 45 | return 46 | endif 47 | let [b, e] = [c, c] 48 | call search('\S\s*' . splitter, '', line('.')) 49 | let e = getpos('.') 50 | return ['v', b, e] 51 | endfunction 52 | 53 | 54 | 55 | call textobj#user#plugin('value', { 56 | \ '-': { 57 | \ '*sfile*': expand(':p'), 58 | \ 'select-i': 'iv', 59 | \ 'select-a': 'av', 60 | \ '*select-i-function*': 's:select_value_i', 61 | \ '*select-a-function*': 's:select_value_a', 62 | \ } 63 | \}) 64 | 65 | 66 | function! s:select_value_i() "{{{2 67 | let save_pos = getpos(".") 68 | normal! 0 69 | let splitter = s:get_splitter() 70 | call search(splitter . "\\s*" . '["' . "'][^'" .'"'."]\\+" . '["' . "']", 'c') 71 | call search('["' . "']") 72 | normal! l 73 | let c = getpos('.') 74 | if abs(c[1] - save_pos[1]) > 2 75 | call setpos('.', save_pos) 76 | normal! l 77 | return 78 | endif 79 | let [b, e] = [c, c] 80 | normal! $ 81 | call search('["' . "']", 'bc', line('.')) 82 | normal! h 83 | let e = getpos('.') 84 | return ['v', b, e] 85 | endfunction 86 | 87 | function! s:select_value_a() "{{{2 88 | let save_pos = getpos(".") 89 | normal! 0 90 | let splitter = s:get_splitter() 91 | call search(splitter . "\s*", 'c') 92 | execute('normal! ' . len(splitter) . 'l') 93 | call search("\\S", '') 94 | let c = getpos('.') 95 | if abs(c[1] - save_pos[1]) > 2 96 | call setpos('.', save_pos) 97 | normal! l 98 | return 99 | endif 100 | let [b, e] = [c, c] 101 | normal! $ 102 | call search("\S", 'bc', line('.')) 103 | let cursorchar = getline('.')[col('.') - 1] 104 | if (cursorchar =~ ',') 105 | normal! h 106 | endif 107 | 108 | let e = getpos('.') 109 | return ['v', b, e] 110 | endfunction 111 | 112 | let s:splitter_map = { 113 | \ 'vim' : ':', 114 | \ 'javascript' : ':', 115 | \ 'javascript.jsx' : ':', 116 | \ 'json' : ':', 117 | \ 'coffee' : ':', 118 | \ 'python' : ':', 119 | \ 'perl' : '=>', 120 | \ 'default' : '=' 121 | \} 122 | 123 | function! s:get_splitter() 124 | let ft = &filetype 125 | if has_key(s:splitter_map, ft) 126 | return s:splitter_map[ft] 127 | endif 128 | return s:splitter_map['default'] 129 | endfunction 130 | 131 | --------------------------------------------------------------------------------