├── README.md └── ftplugin └── go └── goaddtags.vim /README.md: -------------------------------------------------------------------------------- 1 | # vim-goaddtags 2 | 3 | `:GoAddTags` command for Go 4 | 5 | ## Usage 6 | 7 | When you have struct 8 | 9 | ```go 10 | type Foo struct { 11 | Name string 12 | Value int 13 | } 14 | ``` 15 | 16 | Add json/db tags to the struct under the cursor 17 | 18 | ``` 19 | :GoAddTags json db 20 | ``` 21 | 22 | ```go 23 | type Foo struct { 24 | Name string `json:"name" db:"name"` 25 | Age int `json:"age" db:"age"` 26 | } 27 | 28 | ``` 29 | 30 | If you prefer to use `camelCase` instead of `snake_case` for the values, you can use the `g:go_addtags_transform` variable to define a different transformation rule. The following example uses the `camelCase` transformation rule. 31 | 32 | ```vim 33 | let g:go_addtags_transform = 'camelcase' 34 | ``` 35 | 36 | ## Installation 37 | 38 | 39 | For [vim-plug](https://github.com/junegunn/vim-plug) plugin manager: 40 | 41 | ```viml 42 | Plug 'mattn/vim-goaddtags' 43 | ``` 44 | 45 | ## License 46 | 47 | MIT 48 | 49 | ## Author 50 | 51 | Yasuhiro Matsumoto (a.k.a. mattn) 52 | -------------------------------------------------------------------------------- /ftplugin/go/goaddtags.vim: -------------------------------------------------------------------------------- 1 | function! s:bytes_offset(line, col) abort 2 | if &encoding !=# 'utf-8' 3 | let l:sep = "\n" 4 | if &fileformat ==# 'dos' 5 | let l:sep = "\r\n" 6 | elseif &fileformat ==# 'mac' 7 | let l:sep = "\r" 8 | endif 9 | let l:buf = a:line ==# 1 ? '' : (join(getline(1, a:line-1), l:sep) . l:sep) 10 | let l:buf .= a:col ==# 1 ? '' : getline('.')[:a:col-2] 11 | return len(iconv(l:buf, &encoding, 'utf-8')) 12 | endif 13 | return line2byte(a:line) + (a:col-2) 14 | endfunction 15 | 16 | function! s:goremovetags(...) abort 17 | noau update 18 | let l:fname = expand('%:p') 19 | let l:cmd = printf('gomodifytags -file %s -offset %d --clear-tags', shellescape(l:fname), s:bytes_offset(line('.'), col('.'))) 20 | let l:out = system(l:cmd) 21 | let l:lines = split(substitute(l:out, "\n$", '', ''), '\n') 22 | if v:shell_error != 0 23 | echomsg join(l:lines, "\n") 24 | return 25 | endif 26 | let l:view = winsaveview() 27 | silent! %d _ 28 | call setline(1, l:lines) 29 | call winrestview(l:view) 30 | endfunction 31 | 32 | function! s:goaddtags(...) abort 33 | noau update 34 | let l:tags = [] 35 | let l:options = [] 36 | for l:tag in split(a:000[0], '\s\+') 37 | let l:token = split(l:tag, ',') 38 | call add(l:tags, l:token[0]) 39 | if len(l:token) == 2 40 | call add(l:options, l:token[0] . '=' . l:token[1]) 41 | endif 42 | endfor 43 | let l:args = ['--add-tags', join(l:tags, ',')] 44 | if !empty(l:options) 45 | let l:args += ['--add-options', join(l:options, ' ')] 46 | endif 47 | let l:fname = expand('%:p') 48 | let l:transform = get(g:, 'go_addtags_transform', 'snakecase') 49 | let l:cmd = printf('gomodifytags -file %s -offset %d -transform %s %s', shellescape(l:fname), s:bytes_offset(line('.'), col('.')), l:transform, join(map(l:args, 'shellescape(v:val)'), ' ')) 50 | let l:out = system(l:cmd) 51 | let l:lines = split(substitute(l:out, "\n$", '', ''), '\n') 52 | if v:shell_error != 0 53 | echomsg join(l:lines, "\n") 54 | return 55 | endif 56 | let l:view = winsaveview() 57 | silent! %d _ 58 | call setline(1, l:lines) 59 | call winrestview(l:view) 60 | endfunction 61 | 62 | command! -nargs=1 -buffer GoAddTags call s:goaddtags() 63 | command! -nargs=0 -buffer GoRemoveTags call s:goremovetags() 64 | --------------------------------------------------------------------------------