-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Use new `gomodifytags` tool to manipulate and modify tags * Adds new `:GoRenameTags` * `:GoAddTags` is able to add options * `:GoRemoveTags` is able to remove options Usage: Following command add multiple tags. Does not modify if the key already exist. If `,optionaname` is given, it adds the given option to that key. If called without arguments, it adds by default tags with `json` key. ``` :GoAddTags :GoAddTags json :GoAddTags json,omitempty :GoAddTags json hcl bson :GoAddTags json,omitempty hcl bson ``` Following command removes multiple tags and options. If `,optionname` is given, it removes the option belonging to that key instead of removing the key. If called without arguments, it removes all tags belonging to a struct. ``` :GoRemoveTags :GoRemoveTags json :GoRemoveTags json,omitempty :GoRemoveTags json hcl bson :GoRemoveTags json,omitempty hcl bson ``` Fixes following issues: #984 #985 #990 #1064 #1091
- Loading branch information
Showing
8 changed files
with
305 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
function! go#tags#Add(start, end, count, ...) abort | ||
let fname = fnamemodify(expand("%"), ':p:gs?\\?/?') | ||
if &modified | ||
" Write current unsaved buffer to a temp file and use the modified content | ||
let l:tmpname = tempname() | ||
call writefile(getline(1, '$'), l:tmpname) | ||
let fname = l:tmpname | ||
endif | ||
|
||
let offset = 0 | ||
if a:count == -1 | ||
let offset = go#util#OffsetCursor() | ||
endif | ||
|
||
let test_mode = 0 | ||
call call("go#tags#run", [a:start, a:end, offset, "add", fname, test_mode] + a:000) | ||
|
||
" if exists, delete it as we don't need it anymore | ||
if exists("l:tmpname") | ||
call delete(l:tmpname) | ||
endif | ||
endfunction | ||
|
||
function! go#tags#Remove(start, end, count, ...) abort | ||
let fname = fnamemodify(expand("%"), ':p:gs?\\?/?') | ||
if &modified | ||
" Write current unsaved buffer to a temp file and use the modified content | ||
let l:tmpname = tempname() | ||
call writefile(getline(1, '$'), l:tmpname) | ||
let fname = l:tmpname | ||
endif | ||
|
||
let offset = 0 | ||
if a:count == -1 | ||
let offset = go#util#OffsetCursor() | ||
endif | ||
|
||
let test_mode = 0 | ||
call call("go#tags#run", [a:start, a:end, offset, "remove", fname, test_mode] + a:000) | ||
|
||
" if exists, delete it as we don't need it anymore | ||
if exists("l:tmpname") | ||
call delete(l:tmpname) | ||
endif | ||
endfunction | ||
|
||
" run runs gomodifytag. This is an internal test so we can test it | ||
function! go#tags#run(start, end, offset, mode, fname, test_mode, ...) abort | ||
" do not split this into multiple lines, somehow tests fail in that case | ||
let args = {'mode': a:mode,'start': a:start,'end': a:end,'offset': a:offset,'fname': a:fname,'cmd_args': a:000} | ||
|
||
let result = s:create_cmd(args) | ||
if has_key(result, 'err') | ||
call go#util#EchoError(result.err) | ||
return -1 | ||
endif | ||
|
||
let command = join(result.cmd, " ") | ||
|
||
call go#cmd#autowrite() | ||
let out = go#util#System(command) | ||
if go#util#ShellError() != 0 | ||
call go#util#EchoError(out) | ||
return | ||
endif | ||
|
||
if a:test_mode | ||
exe 'edit ' . a:fname | ||
endif | ||
|
||
call s:write_out(out) | ||
|
||
if a:test_mode | ||
exe 'write! ' . a:fname | ||
endif | ||
endfunc | ||
|
||
|
||
" write_out writes back the given output to the current buffer | ||
func s:write_out(out) abort | ||
" not a json output | ||
if a:out[0] !=# '{' | ||
return | ||
endif | ||
|
||
" nothing to do | ||
if empty(a:out) || type(a:out) != type("") | ||
return | ||
endif | ||
|
||
let result = json_decode(a:out) | ||
if type(result) != type({}) | ||
call go#util#EchoError(printf("malformed output from gomodifytags: %s", a:out)) | ||
return | ||
endif | ||
|
||
let lines = result['lines'] | ||
let start_line = result['start'] | ||
let end_line = result['end'] | ||
|
||
let index = 0 | ||
for line in range(start_line, end_line) | ||
call setline(line, lines[index]) | ||
let index += 1 | ||
endfor | ||
endfunc | ||
|
||
|
||
" create_cmd returns a dict that contains the command to execute gomodifytags | ||
func s:create_cmd(args) abort | ||
if !exists("*json_decode") | ||
return {'err': "requires 'json_decode'. Update your Vim/Neovim version."} | ||
endif | ||
|
||
let bin_path = go#path#CheckBinPath('gomodifytags') | ||
if empty(bin_path) | ||
return {'err': "gomodifytags does not exist"} | ||
endif | ||
|
||
let l:start = a:args.start | ||
let l:end = a:args.end | ||
let l:offset = a:args.offset | ||
let l:mode = a:args.mode | ||
let l:cmd_args = a:args.cmd_args | ||
|
||
" start constructing the command | ||
let cmd = [bin_path] | ||
call extend(cmd, ["-format", "json"]) | ||
call extend(cmd, ["-file", a:args.fname]) | ||
|
||
if l:offset != 0 | ||
call extend(cmd, ["-offset", l:offset]) | ||
else | ||
let range = printf("%d,%d", l:start, l:end) | ||
call extend(cmd, ["-line", range]) | ||
endif | ||
|
||
if l:mode == "add" | ||
let l:tags = [] | ||
let l:options = [] | ||
|
||
if !empty(l:cmd_args) | ||
for item in l:cmd_args | ||
let splitted = split(item, ",") | ||
|
||
" tag only | ||
if len(splitted) == 1 | ||
call add(l:tags, splitted[0]) | ||
endif | ||
|
||
" options only | ||
if len(splitted) == 2 | ||
call add(l:tags, splitted[0]) | ||
call add(l:options, printf("%s=%s", splitted[0], splitted[1])) | ||
endif | ||
endfor | ||
endif | ||
|
||
" default value | ||
if empty(l:tags) | ||
let l:tags = ["json"] | ||
endif | ||
|
||
" construct tags | ||
call extend(cmd, ["-add-tags", join(l:tags, ",")]) | ||
|
||
" construct options | ||
if !empty(l:options) | ||
call extend(cmd, ["-add-options", join(l:options, ",")]) | ||
endif | ||
elseif l:mode == "remove" | ||
if empty(l:cmd_args) | ||
call add(cmd, "-clear-tags") | ||
else | ||
let l:tags = [] | ||
let l:options = [] | ||
for item in l:cmd_args | ||
let splitted = split(item, ",") | ||
|
||
" tag only | ||
if len(splitted) == 1 | ||
call add(l:tags, splitted[0]) | ||
endif | ||
|
||
" options only | ||
if len(splitted) == 2 | ||
call add(l:options, printf("%s=%s", splitted[0], splitted[1])) | ||
endif | ||
endfor | ||
|
||
" construct tags | ||
if !empty(l:tags) | ||
call extend(cmd, ["-remove-tags", join(l:tags, ",")]) | ||
endif | ||
|
||
" construct options | ||
if !empty(l:options) | ||
call extend(cmd, ["-remove-options", join(l:options, ",")]) | ||
endif | ||
endif | ||
else | ||
return {'err': printf("unknown mode: %s", l:mode)} | ||
endif | ||
|
||
return {'cmd': cmd} | ||
endfunc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
func Test_add_tags() | ||
let input_file = tempname() | ||
call writefile(readfile("test-fixtures/tags/add_all_input.go"), input_file) | ||
|
||
let expected = join(readfile("test-fixtures/tags/add_all_golden.go"), "\n") | ||
|
||
" run for offset 40, which is inside the struct | ||
call go#tags#run(0, 0, 40, "add", input_file, 1) | ||
|
||
let actual = join(readfile(input_file), "\n") | ||
|
||
call assert_equal(expected, actual) | ||
endfunc | ||
|
||
|
||
func Test_remove_tags() | ||
let input_file = tempname() | ||
call writefile(readfile("test-fixtures/tags/remove_all_input.go"), input_file) | ||
|
||
let expected = join(readfile("test-fixtures/tags/remove_all_golden.go"), "\n") | ||
|
||
" run for offset 40, which is inside the struct | ||
call go#tags#run(0, 0, 40, "remove", input_file, 1) | ||
|
||
let actual = join(readfile(input_file), "\n") | ||
|
||
call assert_equal(expected, actual) | ||
endfunc | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package main | ||
|
||
type Server struct { | ||
Name string `json:"name"` | ||
ID int `json:"id"` | ||
MyHomeAddress string `json:"my_home_address"` | ||
SubDomains []string `json:"sub_domains"` | ||
Empty string `json:"empty"` | ||
Example int64 `json:"example"` | ||
Example2 string `json:"example_2"` | ||
Bar struct { | ||
Four string `json:"four"` | ||
Five string `json:"five"` | ||
} `json:"bar"` | ||
Lala interface{} `json:"lala"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package main | ||
|
||
type Server struct { | ||
Name string | ||
ID int | ||
MyHomeAddress string | ||
SubDomains []string | ||
Empty string | ||
Example int64 | ||
Example2 string | ||
Bar struct { | ||
Four string | ||
Five string | ||
} | ||
Lala interface{} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package main | ||
|
||
type Server struct { | ||
Name string | ||
ID int | ||
MyHomeAddress string | ||
SubDomains []string | ||
Empty string | ||
Example int64 | ||
Example2 string | ||
Bar struct { | ||
Four string | ||
Five string | ||
} | ||
Lala interface{} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package main | ||
|
||
type Server struct { | ||
Name string `json:"name"` | ||
ID int `json:"id"` | ||
MyHomeAddress string `json:"my_home_address"` | ||
SubDomains []string `json:"sub_domains"` | ||
Empty string `json:"empty"` | ||
Example int64 `json:"example"` | ||
Example2 string `json:"example_2"` | ||
Bar struct { | ||
Four string `json:"four"` | ||
Five string `json:"five"` | ||
} `json:"bar"` | ||
Lala interface{} `json:"lala"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters