├── ftplugin ├── c │ └── textobj_clang.vim └── cpp │ └── textobj_clang.vim ├── autoload └── textobj │ └── clang.vim └── README.md /ftplugin/c/textobj_clang.vim: -------------------------------------------------------------------------------- 1 | if exists('g:loaded_textobj_clang') 2 | finish 3 | endif 4 | 5 | let s:save_cpo = &cpo 6 | set cpo&vim 7 | 8 | let g:textobj_clang_more_mappings = get(g:, 'textobj_clang_more_mappings', 0) 9 | let g:textobj_clang_include_headers = get(g:, 'textobj_clang_include_headers', 0) 10 | let s:spec = {} 11 | 12 | if g:textobj_clang_more_mappings 13 | let g:textobj_clang_mapping_kinds = get(g:, 'textobj_clang_kinds', ['any', 'class', 'function', 'expression', 'statement', 'parameter', 'namespace', 'under_cursor', 'most_inner']) 14 | for s:name in g:textobj_clang_mapping_kinds 15 | let s:spec[s:name] = { 16 | \ 'select-i' : 'i;'.s:name[0], 17 | \ '*select-i-function*' : 'textobj#clang#' . s:name . '_select_i', 18 | \ } 19 | endfor 20 | else 21 | let s:spec['-'] = { 22 | \ 'select-i' : 'i;', '*select-i-function*' : 'textobj#clang#under_cursor_select_i', 23 | \ 'select-a' : 'a;', '*select-a-function*' : 'textobj#clang#any_select_i', 24 | \ } 25 | endif 26 | 27 | call textobj#user#plugin('clang', s:spec) 28 | 29 | let &cpo = s:save_cpo 30 | unlet s:save_cpo 31 | 32 | let g:loaded_textobj_clang = 1 33 | -------------------------------------------------------------------------------- /ftplugin/cpp/textobj_clang.vim: -------------------------------------------------------------------------------- 1 | if exists('g:loaded_textobj_clang') 2 | finish 3 | endif 4 | 5 | let s:save_cpo = &cpo 6 | set cpo&vim 7 | 8 | let g:textobj_clang_more_mappings = get(g:, 'textobj_clang_more_mappings', 0) 9 | let g:textobj_clang_include_headers = get(g:, 'textobj_clang_include_headers', 0) 10 | let s:spec = {} 11 | 12 | if g:textobj_clang_more_mappings 13 | let g:textobj_clang_mapping_kinds = get(g:, 'textobj_clang_kinds', ['any', 'class', 'function', 'expression', 'statement', 'parameter', 'namespace', 'under_cursor', 'most_inner']) 14 | for s:name in g:textobj_clang_mapping_kinds 15 | let s:spec[s:name] = { 16 | \ 'select-i' : 'i;'.s:name[0], 17 | \ '*select-i-function*' : 'textobj#clang#' . s:name . '_select_i', 18 | \ } 19 | endfor 20 | else 21 | let s:spec['-'] = { 22 | \ 'select-i' : 'i;', '*select-i-function*' : 'textobj#clang#under_cursor_select_i', 23 | \ 'select-a' : 'a;', '*select-a-function*' : 'textobj#clang#any_select_i', 24 | \ } 25 | endif 26 | 27 | call textobj#user#plugin('clang', s:spec) 28 | 29 | let &cpo = s:save_cpo 30 | unlet s:save_cpo 31 | 32 | let g:loaded_textobj_clang = 1 33 | -------------------------------------------------------------------------------- /autoload/textobj/clang.vim: -------------------------------------------------------------------------------- 1 | function! s:prepare_temp_file() 2 | if g:textobj_clang_include_headers 3 | let temp_name = expand('%:p:h') . substitute(tempname(), '\W', '_', 'g') . (&filetype ==# 'c' ? '.c' : '.cpp') 4 | call writefile(getline(1, '$'), temp_name) 5 | else 6 | let temp_name = tempname() . (&filetype ==# 'c' ? '.c' : '.cpp') 7 | call writefile(map(getline(1, '$'), 'v:val =~# "^\\s*#include\\s*\\(<[^>]\\+>\\|\"[^\"]\\+\"\\)" ? "" : v:val'), temp_name) 8 | endif 9 | 10 | return temp_name 11 | endfunction 12 | 13 | function! s:select_extent(func) 14 | let temp_name = s:prepare_temp_file() 15 | try 16 | let extent = call(a:func, [temp_name, line('.'), col('.')]) 17 | finally 18 | call delete(temp_name) 19 | endtry 20 | if empty(extent) || extent.start.file !=# extent.end.file 21 | return 0 22 | endif 23 | let pos = getpos('.') 24 | let start = [pos[0], extent.start.line, extent.start.column, pos[3]] 25 | let end = [pos[0], extent.end.line, extent.end.column, pos[3]] 26 | return ['v', start, end] 27 | endfunction 28 | 29 | function! textobj#clang#any_select_i() 30 | return s:select_extent('libclang#location#inner_definition_extent') 31 | endfunction 32 | 33 | function! textobj#clang#function_select_i() 34 | return s:select_extent('libclang#location#function_extent') 35 | endfunction 36 | 37 | function! textobj#clang#statement_select_i() 38 | return s:select_extent('libclang#location#statement_extent') 39 | endfunction 40 | 41 | function! textobj#clang#expression_select_i() 42 | return s:select_extent('libclang#location#expression_extent') 43 | endfunction 44 | 45 | function! textobj#clang#parameter_select_i() 46 | return s:select_extent('libclang#location#parameter_extent') 47 | endfunction 48 | 49 | function! textobj#clang#namespace_select_i() 50 | return s:select_extent('libclang#location#namespace_extent') 51 | endfunction 52 | 53 | function! textobj#clang#under_cursor_select_i() 54 | return s:select_extent('libclang#location#extent') 55 | endfunction 56 | 57 | function! textobj#clang#most_inner_select_i() 58 | return s:select_extent('libclang#location#class_extent') 59 | endfunction 60 | 61 | function! textobj#clang#any_select_i() 62 | let temp_name = s:prepare_temp_file() 63 | try 64 | let extents = filter(libclang#location#all_extents(temp_name, line('.'), col('.')), '!empty(v:val)') 65 | finally 66 | call delete(temp_name) 67 | endtry 68 | let len = len(extents) 69 | if len == 0 70 | return 0 71 | elseif len == 1 72 | let extent = extents[0] 73 | else 74 | let idx = 1 75 | while extents[idx] == extents[0] 76 | if idx == len - 1 | break | endif 77 | let idx += 1 78 | endwhile 79 | let extent = extents[idx] 80 | endif 81 | 82 | let pos = getpos('.') 83 | let start = [pos[0], extent.start.line, extent.start.column, pos[3]] 84 | let end = [pos[0], extent.end.line, extent.end.column, pos[3]] 85 | return ['v', start, end] 86 | endfunction 87 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Make text objects for various C and C++ blocks with power of clang 2 | ================================================================== 3 | 4 | This vim plugin makes text objects for various C and C++ blocks, function, class, namespace, expression, statement and so on. 5 | 6 | ## Dependencies 7 | 8 | - [vim-textobj-user](https://github.com/kana/vim-textobj-user) 9 | - [libclang-vim](https://github.com/rhysd/libclang-vim) 10 | 11 | If you use [neobundle.vim](https://github.com/Shougo/neobundle.vim), you can install this plugin easily as below. 12 | 13 | ```vim 14 | NeoBundleLazy 'rhysd/libclang-vim', { 15 | \ 'build' : { 16 | \ 'windows' : 'echo "Please build manually"', 17 | \ 'mac' : 'make', 18 | \ 'unix' : 'make', 19 | \ } 20 | \ } 21 | 22 | NeoBundleLazy 'rhysd/vim-textobj-clang', { 23 | \ 'depends' : ['kana/vim-textobj-user', 'rhysd/libclang-vim'], 24 | \ 'autoload' : { 25 | \ 'mappings' : [['xo', 'a;'], ['xo', 'i;']] 26 | \ } 27 | \ } 28 | ``` 29 | 30 | ## Simple operator-pending mappings `i;` and `a;` 31 | 32 | Operator-pending mappings `i;` and `a;` are available. `i;` selects the element under cursor. `a;` selects the most inner definition under cursor. 33 | 34 | For example, see below code. 35 | 36 | ```cpp 37 | int main() 38 | { 39 | return 0; 40 | } 41 | ``` 42 | 43 | When the cursor is placed at `return`, `i;` selects `return 0;` and `a;` selects whole `main()` function. 44 | This is very simple example. Clang can parse more complicated source files like Boost libraries. 45 | 46 | Screenshot: 47 | 48 |  49 | 50 | ## More complicated operator-pending mappings 51 | 52 | If you set `g:textobj_clang_more_mappings` to `1`, many operator-pending mappings are defined. As a default, mappings in a below table are defined. You can control the number of the mappings with `g:textobj_clang_mapping_kinds`. 53 | 54 |
| Mapping | 57 |Block | 58 |
|---|---|
| i;m | 61 |select the most inner definition | 62 |
| i;c | 65 |select class blocks | 66 |
| i;f | 69 |select function blocks | 70 |
| i;e | 73 |select an expression | 74 |
| i;s | 77 |select an statement | 78 |
| i;p | 81 |select an parameter and a template parameter | 82 |
| i;n | 85 |select a namespace | 86 |
| i;u | 89 |select an element under cursor | 90 |
| i;a | 93 |select expression, statement, function, class or namespace | 94 |