Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

commands: add :GoAddTags #971

Merged
merged 1 commit into from
Jul 31, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions autoload/go/util.vim
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,50 @@ function! go#util#camelcase(word)
endif
endfunction

function! go#util#AddTags(line1, line2, ...)
" default is json
let l:keys = ["json"]
if a:0
let l:keys = a:000
endif

let l:line1 = a:line1
let l:line2 = a:line2

" If we're inside a struct and just call this function let us add the tags
" to all fields
" TODO(arslan): I don't like using patterns. Check if we can move it to
" `motion` and do it via AST based position
let ln1 = searchpair('struct {', '', '}', 'bcnW')
if ln1 == 0
echon "vim-go: " | echohl ErrorMsg | echon "cursor is outside the struct" | echohl None
return
endif

" searchpair only returns a single position
let ln2 = search('}', "cnW")

" if no range is given we apply for the whole struct
if l:line1 == l:line2
let l:line1 = ln1 + 1
let l:line2 = ln2 - 1
endif

for line in range(l:line1, l:line2)
" get the field name (word) that are not part of a commented line
let l:matched = matchstr(getline(line), '\(\/\/.*\)\@<!\w\+')
if empty(l:matched)
continue
endif

let word = go#util#snippetcase(l:matched)
let tags = map(copy(l:keys), 'printf("%s:%s", v:val,"\"'. word .'\"")')
let updated_line = printf("%s `%s`", getline(line), join(tags, " "))

" finally, update the line inplace
call setline(line, updated_line)
endfor
endfunction

" TODO(arslan): I couldn't parameterize the highlight types. Check if we can
" simplify the following functions
Expand Down
14 changes: 14 additions & 0 deletions doc/vim-go.txt
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,21 @@ CTRL-t
:GoImpl f *Foo io.Writer
:GoImpl T io.ReadWriteCloser
<
*:GoAddTags*
:[range]GoAddTags [key] [key1] ...

Adds field tags for the fields of a struct. If called inside a struct it
automatically add field tags with the `json` key and the value
automatically generated based on the field name. An error message is given
if it's called outside a struct definition.

If [range] is given, only the selected fields will be changed.

The default `json` can be changed by providing one or more [key]
arguments. An example of adding `xml` and `db` would be:
>
:GoAddTags xml db
<
*:GoAutoTypeInfoToggle*
:GoAutoTypeInfoToggle

Expand Down
2 changes: 2 additions & 0 deletions ftplugin/go/commands.vim
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ command! -range=% GoReferrers call go#guru#Referrers(<count>)
command! -nargs=? GoGuruTags call go#guru#Tags(<f-args>)


command! -nargs=* -range GoAddTags call go#util#AddTags(<line1>, <line2>, <f-args>)

command! -range=% GoSameIds call go#guru#SameIds(<count>)
command! -range=0 GoSameIdsClear call go#guru#ClearSameIds()
command! -range=% GoSameIdsToggle call go#guru#ToggleSameIds(<count>)
Expand Down