Skip to content

Commit

Permalink
Implement :GoFillStruct (#1443)
Browse files Browse the repository at this point in the history
Fixes #1425.
  • Loading branch information
arp242 authored Sep 18, 2017
1 parent 0371da6 commit 40bdb6a
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 13 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
## unplanned

FEATURES:

* Add `:GoFillStruct` to fill a struct with all fields; uses
[`fillstruct`](https://github.com/davidrjenni/reftools/tree/master/cmd/fillstruct)
[[GH-1443]](https://github.com/fatih/vim-go/pull/1443).

IMPROVEMENTS:

* `:GoAddTags` and `:GoRemoveTags` now continue to process if there are
Expand Down
12 changes: 1 addition & 11 deletions autoload/go/doc.vim
Original file line number Diff line number Diff line change
Expand Up @@ -150,18 +150,8 @@ function! s:gogetdoc(json) abort
let command = join(cmd, " ")

if &modified
" gogetdoc supports the same archive format as guru for dealing with
" modified buffers.
" use the -modified flag
" write each archive entry on stdin as:
" filename followed by newline
" file size followed by newline
" file contents
let in = ""
let content = join(go#util#GetLines(), "\n")
let in = fname . "\n" . strlen(content) . "\n" . content
let command .= " -modified"
let out = go#util#System(command, in)
let out = go#util#System(command, go#util#archive())
else
let out = go#util#System(command)
endif
Expand Down
57 changes: 57 additions & 0 deletions autoload/go/fillstruct.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
function! go#fillstruct#FillStruct() abort
let binpath = go#path#CheckBinPath('fillstruct')
if empty(binpath)
return
endif

let l:cmd = [binpath,
\ '-file', bufname(''),
\ '-offset', go#util#OffsetCursor()]

" Read from stdin if modified.
if &modified
call add(l:cmd, '-modified')
let l:out = go#util#System(go#util#Shelljoin(l:cmd), go#util#archive())
else
let l:out = go#util#System(go#util#Shelljoin(l:cmd))
endif

if go#util#ShellError() != 0
call go#util#EchoError(l:out)
return
endif

try
let l:json = json_decode(l:out)
catch
call go#util#EchoError(l:out)
return
endtry

let l:code = split(l:json['code'], "\n")
let l:pos = getpos('.')

try
" Add any code before/after the struct.
exe l:json['start'] . 'go'
let l:code[0] = getline('.')[:col('.')-1] . l:code[0]
exe l:json['end'] . 'go'
let l:code[len(l:code)-1] .= getline('.')[col('.'):]

" Indent every line except the first one; makes it look nice.
let l:indent = repeat("\t", indent('.') / &ts)
for i in range(1, len(l:code)-1)
let l:code[l:i] = l:indent . l:code[i]
endfor

" Out with the old ...
exe 'normal! ' . l:json['start'] . 'gov' . l:json['end'] . 'gox'
" ... in with the new.
call setline('.', l:code[0])
call append('.', l:code[1:])
finally
call setpos('.', l:pos)
endtry
endfunction

" vim: sw=2 ts=2 et
3 changes: 1 addition & 2 deletions autoload/go/guru.vim
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ function! s:guru_cmd(args) range abort

let filename = fnamemodify(expand("%"), ':p:gs?\\?/?')
if &modified
let content = join(go#util#GetLines(), "\n")
let result.stdin_content = filename . "\n" . strlen(content) . "\n" . content
let result.stdin_content = go#util#archive()
call add(cmd, "-modified")
endif

Expand Down
13 changes: 13 additions & 0 deletions autoload/go/util.vim
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ function! go#util#EchoInfo(msg)
call s:echo(a:msg, 'Debug')
endfunction

" Get all lines in the buffer as a a list.
function! go#util#GetLines()
let buf = getline(1, '$')
if &encoding != 'utf-8'
Expand All @@ -309,4 +310,16 @@ function! go#util#GetLines()
return buf
endfunction

" Convert the current buffer to the "archive" format of
" golang.org/x/tools/go/buildutil:
" https://godoc.org/golang.org/x/tools/go/buildutil#ParseOverlayArchive
"
" > The archive consists of a series of files. Each file consists of a name, a
" > decimal file size and the file contents, separated by newlinews. No newline
" > follows after the file contents.
function! go#util#archive()
let l:buffer = join(go#util#GetLines(), "\n")
return expand("%:p:gs!\\!/!") . "\n" . strlen(l:buffer) . "\n" . l:buffer
endfunction

" vim: sw=2 ts=2 et
19 changes: 19 additions & 0 deletions doc/vim-go.txt
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,25 @@ CTRL-t
Surname: "Smith",
}
<
*:GoFillStruct*
:GoFillStruct

Use `fillstruct` to fill a struct literal with default values. Existing
values (if any) are preserved. The cursor must be on the struct you wish
to fill.

For example:
>
addr := net.Address{Name: "Ford Prefect"}
<
Becomes:
>
addr := net.Address{
Name: "Ford Prefect",
Email: "",
}
<

==============================================================================
MAPPINGS *go-mappings*

Expand Down
3 changes: 3 additions & 0 deletions ftplugin/go/commands.vim
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,7 @@ command! -nargs=0 GoTemplateAutoCreateToggle call go#template#ToggleAutoCreate()
" -- keyify
command! -nargs=0 GoKeyify call go#keyify#Keyify()

" -- fillstruct
command! -nargs=0 GoFillStruct call go#fillstruct#FillStruct()

" vim: sw=2 ts=2 et
1 change: 1 addition & 0 deletions plugin/go.vim
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ let s:packages = [
\ "github.com/zmb3/gogetdoc",
\ "github.com/josharian/impl",
\ "github.com/dominikh/go-tools/cmd/keyify",
\ "github.com/davidrjenni/reftools/cmd/fillstruct",
\ ]

" These commands are available on any filetypes
Expand Down

0 comments on commit 40bdb6a

Please sign in to comment.