From 6604557f687159415b088e370caeccc1c316ef25 Mon Sep 17 00:00:00 2001 From: lilei Date: Mon, 2 Dec 2019 21:53:23 +0800 Subject: [PATCH] plugin: add vim-gocode plugin vim-gocode:9c8a27a130932c801037129016d6afa73a04156a Signed-off-by: lilei --- vim/bundle/vim-gocode/README.md | 53 ++++ vim/bundle/vim-gocode/addon-info.json | 7 + .../vim-gocode/autoload/go/complete.vim | 89 ++++++ vim/bundle/vim-gocode/autoload/go/package.vim | 145 ++++++++++ vim/bundle/vim-gocode/compiler/go.vim | 35 +++ vim/bundle/vim-gocode/doc/vim-gocode.txt | 65 +++++ vim/bundle/vim-gocode/ftdetect/gofiletype.vim | 25 ++ vim/bundle/vim-gocode/ftplugin/go.vim | 28 ++ vim/bundle/vim-gocode/ftplugin/go/fmt.vim | 80 ++++++ vim/bundle/vim-gocode/ftplugin/go/import.vim | 267 ++++++++++++++++++ vim/bundle/vim-gocode/ftplugin/go/install.vim | 67 +++++ vim/bundle/vim-gocode/ftplugin/go/pkg.vim | 46 +++ vim/bundle/vim-gocode/ftplugin/go/test.sh | 78 +++++ vim/bundle/vim-gocode/indent/go.vim | 67 +++++ vim/bundle/vim-gocode/plugin/godoc.vim | 130 +++++++++ vim/bundle/vim-gocode/syntax/go.vim | 209 ++++++++++++++ vim/bundle/vim-gocode/syntax/godoc.vim | 20 ++ vim/bundles.vim | 1 + 18 files changed, 1412 insertions(+) create mode 100644 vim/bundle/vim-gocode/README.md create mode 100644 vim/bundle/vim-gocode/addon-info.json create mode 100644 vim/bundle/vim-gocode/autoload/go/complete.vim create mode 100644 vim/bundle/vim-gocode/autoload/go/package.vim create mode 100644 vim/bundle/vim-gocode/compiler/go.vim create mode 100644 vim/bundle/vim-gocode/doc/vim-gocode.txt create mode 100644 vim/bundle/vim-gocode/ftdetect/gofiletype.vim create mode 100644 vim/bundle/vim-gocode/ftplugin/go.vim create mode 100644 vim/bundle/vim-gocode/ftplugin/go/fmt.vim create mode 100644 vim/bundle/vim-gocode/ftplugin/go/import.vim create mode 100644 vim/bundle/vim-gocode/ftplugin/go/install.vim create mode 100644 vim/bundle/vim-gocode/ftplugin/go/pkg.vim create mode 100755 vim/bundle/vim-gocode/ftplugin/go/test.sh create mode 100644 vim/bundle/vim-gocode/indent/go.vim create mode 100644 vim/bundle/vim-gocode/plugin/godoc.vim create mode 100644 vim/bundle/vim-gocode/syntax/go.vim create mode 100644 vim/bundle/vim-gocode/syntax/godoc.vim diff --git a/vim/bundle/vim-gocode/README.md b/vim/bundle/vim-gocode/README.md new file mode 100644 index 0000000..ec1ef02 --- /dev/null +++ b/vim/bundle/vim-gocode/README.md @@ -0,0 +1,53 @@ +vim-gocode +========== + +All credit goes to [nsf/code](http://github.com/nsf/gocode) and Go authors. +All Vim plugins from Go 1.2 are also included. + +You should *not* install this plugin with either [fsouza/go.vim](https://github.com/fsouza/go.vim) or [jnwhiteh/vim-golang](https://github.com/jnwhiteh/vim-golang)! It could take unknown effect on your setup. +## Commands + + +* **:RelPkg** takes no or one argument, a relative package path, and prints it as a full package path. If no argument is given, default to current package. + +*Example* `:RelPkg ../pkg/child` in the `$GOPATH/src/github.com/Blackrush/gofus/main.go` file will print `github.com/Blackrush/pkg/child` + +* **:GoInstall** takes no or one argument, a relative package path, installs it or prints compilation errors otherwise. If no argument is given, default to current package. + +*Example* `:GoInstall ../pkg/child` with current working directory `$GOPATH/src/github.com/Blackrush/gofus` +will try to install the `github.com/Blackrush/pkg/child` package + +* **:GoTest** takes no or one argument, a relative package path, tests it and prints its output. If no argument is given, default to current package. + +*Example* `:GoTest ../pkg/child` with current working directory `$GOPATH/src/github.com/Blackrush/gofus` +will try to test the `github.com/Blackrush/pkg/child` package + +* **:GoImport**, **:GoImportAs** and **:GoDrop** are equivalent of original **:Import**, **:ImportAs** and **:Drop** +but takes all a relative package path to the current working directory + +* **:make** — you can use QuickFix to iterate through build errors if any; if file is in subdirectory of $GOPATH/src/, the whole package is build, else — only current file + +See [#1](https://github.com/Blackrush/vim-gocode/issues/1) to see future commands implementation. + +## Installation + +Make sure you have installed [gocode](https://github.com/nsf/gocode) before installing this plugin : + +```bash +go get github.com/nsf/gocode +``` + +### Vundle + +Add this line to your ~/.vimrc configuration file : + + Bundle 'Blackrush/vim-gocode' + +And then run vim : + + vim +BundleInstall + +### Pathogen + + cd ~/.vim/bundle + git clone https://github.com/Blackrush/vim-gocode.git diff --git a/vim/bundle/vim-gocode/addon-info.json b/vim/bundle/vim-gocode/addon-info.json new file mode 100644 index 0000000..bad323d --- /dev/null +++ b/vim/bundle/vim-gocode/addon-info.json @@ -0,0 +1,7 @@ +{ + "name": "vim-gocode", + "repository": { + "type": "git", + "url": "https://github.com/Blackrush/vim-gocode.git" + } +} diff --git a/vim/bundle/vim-gocode/autoload/go/complete.vim b/vim/bundle/vim-gocode/autoload/go/complete.vim new file mode 100644 index 0000000..7c6dea9 --- /dev/null +++ b/vim/bundle/vim-gocode/autoload/go/complete.vim @@ -0,0 +1,89 @@ +if exists('g:loaded_gocode') + finish +endif +let g:loaded_gocode = 1 + +fu! s:gocodeCurrentBuffer() + let buf = getline(1, '$') + if &encoding != 'utf-8' + let buf = map(buf, 'iconv(v:val, &encoding, "utf-8")') + endif + if &l:fileformat == 'dos' + " XXX: line2byte() depend on 'fileformat' option. + " so if fileformat is 'dos', 'buf' must include '\r'. + let buf = map(buf, 'v:val."\r"') + endif + let file = tempname() + call writefile(buf, file) + return file +endf + +let s:vim_system = get(g:, 'gocomplete#system_function', 'system') + +fu! s:system(str, ...) + return call(s:vim_system, [a:str] + a:000) +endf + +fu! s:gocodeShellescape(arg) + try + let ssl_save = &shellslash + set noshellslash + return shellescape(a:arg) + finally + let &shellslash = ssl_save + endtry +endf + +fu! s:gocodeCommand(cmd, preargs, args) + for i in range(0, len(a:args) - 1) + let a:args[i] = s:gocodeShellescape(a:args[i]) + endfor + for i in range(0, len(a:preargs) - 1) + let a:preargs[i] = s:gocodeShellescape(a:preargs[i]) + endfor + let result = s:system(printf('gocode %s %s %s', join(a:preargs), a:cmd, join(a:args))) + if v:shell_error != 0 + return "[\"0\", []]" + else + if &encoding != 'utf-8' + let result = iconv(result, 'utf-8', &encoding) + endif + return result + endif +endf + +fu! s:gocodeCurrentBufferOpt(filename) + return '-in=' . a:filename +endf + +fu! s:gocodeCursor() + if &encoding != 'utf-8' + let c = col('.') + let buf = line('.') == 1 ? "" : (join(getline(1, line('.')-1), "\n") . "\n") + let buf .= c == 1 ? "" : getline('.')[:c-2] + return printf('%d', len(iconv(buf, &encoding, "utf-8"))) + endif + return printf('%d', line2byte(line('.')) + (col('.')-2)) +endf + +fu! s:gocodeAutocomplete() + let filename = s:gocodeCurrentBuffer() + let result = s:gocodeCommand('autocomplete', + \ [s:gocodeCurrentBufferOpt(filename), '-f=vim'], + \ [expand('%:p'), s:gocodeCursor()]) + call delete(filename) + return result +endf + +fu! go#complete#Complete(findstart, base) + "findstart = 1 when we need to get the text length + if a:findstart == 1 + execute "silent let g:gocomplete_completions = " . s:gocodeAutocomplete() + return col('.') - g:gocomplete_completions[0] - 1 + "findstart = 0 when we need to return the list of completions + else + return g:gocomplete_completions[1] + endif +endf + +" vim:sw=4:et diff --git a/vim/bundle/vim-gocode/autoload/go/package.vim b/vim/bundle/vim-gocode/autoload/go/package.vim new file mode 100644 index 0000000..cadf549 --- /dev/null +++ b/vim/bundle/vim-gocode/autoload/go/package.vim @@ -0,0 +1,145 @@ +" Copyright 2011 The Go Authors. All rights reserved. +" Use of this source code is governed by a BSD-style +" license that can be found in the LICENSE file. +" +" This file provides a utility function that performs auto-completion of +" package names, for use by other commands. + +let s:goos = $GOOS +let s:goarch = $GOARCH + +if len(s:goos) == 0 + if exists('g:golang_goos') + let s:goos = g:golang_goos + elseif has('win32') || has('win64') + let s:goos = 'windows' + elseif has('macunix') + let s:goos = 'darwin' + else + let s:goos = '*' + endif +endif + +if len(s:goarch) == 0 + if exists('g:golang_goarch') + let s:goarch = g:golang_goarch + else + let s:goarch = '*' + endif +endif + +function! go#package#Paths() + let dirs = [] + + if exists('$GOROOT') + let goroot = $GOROOT + else + if executable('go') + let goroot = substitute(system('go env GOROOT'), '\n', '', 'g') + if v:shell_error + echomsg '''go env GOROOT'' failed' + endif + endif + endif + + if len(goroot) != 0 && isdirectory(goroot) + let dirs += [goroot] + endif + + let pathsep = ':' + if s:goos == 'windows' + let pathsep = ';' + endif + let workspaces = split($GOPATH, pathsep) + if workspaces != [] + let dirs += workspaces + endif + + return dirs +endfunction + +function! go#package#FromPath(arg) + let path = fnamemodify(resolve(a:arg), ':p:h') + let dirs = go#package#Paths() + + if s:goos == 'windows' + let path = substitute(tolower(path), "\\", "/", 'g') + for dir in dirs + if len(dir) + let dir = substitute(tolower(dir), "\\", "/", 'g') + if stridx(path, dir) == 0 + let workspace = dir + endif + endif + endfor + else + for dir in dirs + if len(dir) && stridx(path, dir) == 0 + let workspace = dir + endif + endfor + endif + + if !exists('workspace') + return -1 + endif + + let workspace = substitute(workspace, '/$', '', '') + return substitute(path, workspace . '/src/', '', '') +endfunction + +function! go#package#CompleteMembers(package, member) + silent! let content = system('godoc ' . a:package) + if v:shell_error || !len(content) + return [] + endif + let lines = filter(split(content, "\n"),"v:val !~ '^\\s\\+$'") + try + let mx1 = '^\s\+\(\S+\)\s\+=\s\+.*' + let mx2 = '^\%(const\|var\|type\|func\) \([A-Z][^ (]\+\).*' + let candidates = map(filter(copy(lines), 'v:val =~ mx1'), + \ 'substitute(v:val, mx1, "\\1", "")') + \ + map(filter(copy(lines), 'v:val =~ mx2'), + \ 'substitute(v:val, mx2, "\\1", "")') + return filter(candidates, '!stridx(v:val, a:member)') + catch + return [] + endtry +endfunction + +function! go#package#Complete(ArgLead, CmdLine, CursorPos) + let words = split(a:CmdLine, '\s\+', 1) + if len(words) > 2 + " Complete package members + return go#package#CompleteMembers(words[1], words[2]) + endif + + let dirs = go#package#Paths() + + if len(dirs) == 0 + " should not happen + return [] + endif + + let ret = {} + for dir in dirs + " this may expand to multiple lines + let root = split(expand(dir . '/pkg/' . s:goos . '_' . s:goarch), "\n") + call add(root, expand(dir . '/src')) + for r in root + for i in split(globpath(r, a:ArgLead.'*'), "\n") + if isdirectory(i) + let i .= '/' + elseif i !~ '\.a$' + continue + endif + let i = substitute(substitute(i[len(r)+1:], '[\\]', '/', 'g'), + \ '\.a$', '', 'g') + let ret[i] = i + endfor + endfor + endfor + return sort(keys(ret)) +endfunction + +" vim:sw=4:et diff --git a/vim/bundle/vim-gocode/compiler/go.vim b/vim/bundle/vim-gocode/compiler/go.vim new file mode 100644 index 0000000..f1f96a7 --- /dev/null +++ b/vim/bundle/vim-gocode/compiler/go.vim @@ -0,0 +1,35 @@ +" Copyright 2013 The Go Authors. All rights reserved. +" Use of this source code is governed by a BSD-style +" license that can be found in the LICENSE file. +" +" compiler/go.vim: Vim compiler file for Go. + +if exists('current_compiler') + finish +endif +let current_compiler = 'go' + +if exists(':CompilerSet') != 2 " older Vim always used :setlocal + command -nargs=* CompilerSet setlocal +endif + +if exists('b:gopackage') + execute 'CompilerSet makeprg=go\ build\ $*\ ' . escape(b:gopackage, ' \') +else + CompilerSet makeprg=go\ build\ $*\ % +endif + +let s:save_cpo = &cpo +set cpo-=C + +CompilerSet errorformat= + \%-G#\ %.%#, + \%E%f:%l:%c:\ %m, + \%E%f:%l:\ %m, + \%C%*\\s%m, + \%-G%.%# + +let &cpo = s:save_cpo +unlet s:save_cpo + +" vim:ts=4:sw=4:et diff --git a/vim/bundle/vim-gocode/doc/vim-gocode.txt b/vim/bundle/vim-gocode/doc/vim-gocode.txt new file mode 100644 index 0000000..e7cbf51 --- /dev/null +++ b/vim/bundle/vim-gocode/doc/vim-gocode.txt @@ -0,0 +1,65 @@ +*vim-gocode.txt* Tools for Golang + + Compiler plugin, syntax highlight, omni completion (with gocode) + and other stuff for Go programming language + +============================================================================== +CONTENTS *vim-gocode-contents* + + 1. Usage...........................|vim-gocode-usage| + +============================================================================== +1. Usage *vim-gocode-usage* + + *:Import* +:Import Add to import section of file. + + *:ImportAs* +:ImportAs Add to import section of file with + name . + + *:Drop* +:Drop Remove from import section of file. + + *:Fmt* +:Fmt Format file with gofmt. + + *:Godoc* +:Godoc [] Open Godoc for . If no arguments given + open Godoc for word under the cursor. + + *:RelPkg* +:RelPkg [] Print full package path of . If no + argument is given, default to current package. + + + *:GoInstall* +:GoInstall [] Install the package at or current + package if no argument is given. + + *:GoTest* +:GoTest [] Test the package at or current + package if no argument is given. + + + *:GoTestVerbose* +:GoTestVerbse [] Verbosely test the pacakge at or + current package if no argument is given. + + + *:GoImport* +:GoImport Same as |:Import| but take a relative package + path to the current working directory. + + *:GoImportAs* +:GoImportAs Same as |:ImportAs| but take a relative + package path to the current working directory. + + + *:GoDrop* +:GoDrop Same as |:Drop| but take a relative package + path to the current working directory. + +============================================================================== + + vim:tw=78:ts=8:ft=help:norl: diff --git a/vim/bundle/vim-gocode/ftdetect/gofiletype.vim b/vim/bundle/vim-gocode/ftdetect/gofiletype.vim new file mode 100644 index 0000000..3a3b840 --- /dev/null +++ b/vim/bundle/vim-gocode/ftdetect/gofiletype.vim @@ -0,0 +1,25 @@ +" We take care to preserve the user's fileencodings and fileformats, +" because those settings are global (not buffer local), yet we want +" to override them for loading Go files, which are defined to be UTF-8. +let s:current_fileformats = '' +let s:current_fileencodings = '' + +" define fileencodings to open as utf-8 encoding even if it's ascii. +function! s:gofiletype_pre() + let s:current_fileformats = &g:fileformats + let s:current_fileencodings = &g:fileencodings + set fileencodings=utf-8 fileformats=unix + setlocal filetype=go +endfunction + +" restore fileencodings as others +function! s:gofiletype_post() + let &g:fileformats = s:current_fileformats + let &g:fileencodings = s:current_fileencodings +endfunction + +au BufNewFile *.go setlocal filetype=go fileencoding=utf-8 fileformat=unix +au BufRead *.go call s:gofiletype_pre() +au BufReadPost *.go call s:gofiletype_post() + +" vim:sw=4:et diff --git a/vim/bundle/vim-gocode/ftplugin/go.vim b/vim/bundle/vim-gocode/ftplugin/go.vim new file mode 100644 index 0000000..6405700 --- /dev/null +++ b/vim/bundle/vim-gocode/ftplugin/go.vim @@ -0,0 +1,28 @@ +" Copyright 2013 The Go Authors. All rights reserved. +" Use of this source code is governed by a BSD-style +" license that can be found in the LICENSE file. +" +" go.vim: Vim filetype plugin for Go. + +if exists("b:did_ftplugin") + finish +endif +let b:did_ftplugin = 1 + +setlocal comments=s1:/*,mb:*,ex:*/,:// +setlocal commentstring=//\ %s + +let b:undo_ftplugin = "setl com< cms<" + +" Set gocode completion +setlocal omnifunc=go#complete#Complete + +" Set b:gopackage if any +if type(go#package#FromPath(@%)) == type('') + let b:gopackage = go#package#FromPath(@%) +endif + +" Set compiler for :make command +compiler go + +" vim:sw=4:et diff --git a/vim/bundle/vim-gocode/ftplugin/go/fmt.vim b/vim/bundle/vim-gocode/ftplugin/go/fmt.vim new file mode 100644 index 0000000..ba2dbd5 --- /dev/null +++ b/vim/bundle/vim-gocode/ftplugin/go/fmt.vim @@ -0,0 +1,80 @@ +" Copyright 2011 The Go Authors. All rights reserved. +" Use of this source code is governed by a BSD-style +" license that can be found in the LICENSE file. +" +" fmt.vim: Vim command to format Go files with gofmt. +" +" This filetype plugin add a new commands for go buffers: +" +" :Fmt +" +" Filter the current Go buffer through gofmt. +" It tries to preserve cursor position and avoids +" replacing the buffer with stderr output. +" +" Options: +" +" g:go_fmt_commands [default=1] +" +" Flag to indicate whether to enable the commands listed above. +" +" g:gofmt_command [default="gofmt"] +" +" Flag naming the gofmt executable to use. +" +if exists("b:did_ftplugin_go_fmt") + finish +endif + +if !exists("g:go_fmt_commands") + let g:go_fmt_commands = 1 +endif + +if g:go_fmt_commands + command! -buffer Fmt call s:GoFormat() +endif + +if !exists('g:go_fmt_autofmt') + let g:go_fmt_autofmt = 1 +endif + +if g:go_fmt_autofmt + " Run gofmt before saving file + autocmd BufWritePre :keepjumps Fmt " thanks @justinmk +endif + +if !exists("g:gofmt_command") + let g:gofmt_command = "gofmt" +endif + +function! s:GoFormat() + let view = winsaveview() + + silent execute "%!" . g:gofmt_command + + if v:shell_error + let errors = [] + for line in getline(1, line('$')) + let tokens = matchlist(line, '^\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)') + if !empty(tokens) + call add(errors, {"filename": @%, + \"lnum": tokens[2], + \"col": tokens[3], + \"text": tokens[4]}) + endif + endfor + if empty(errors) + % | " Couldn't detect gofmt error format, output errors + endif + undo + if !empty(errors) + call setloclist(0, errors, 'r') + endif + echohl Error | echomsg "Gofmt returned error" | echohl None + endif + call winrestview(view) +endfunction + +let b:did_ftplugin_go_fmt = 1 + +" vim:sw=4:et diff --git a/vim/bundle/vim-gocode/ftplugin/go/import.vim b/vim/bundle/vim-gocode/ftplugin/go/import.vim new file mode 100644 index 0000000..4d8a076 --- /dev/null +++ b/vim/bundle/vim-gocode/ftplugin/go/import.vim @@ -0,0 +1,267 @@ +" Copyright 2011 The Go Authors. All rights reserved. +" Use of this source code is governed by a BSD-style +" license that can be found in the LICENSE file. +" +" import.vim: Vim commands to import/drop Go packages. +" +" This filetype plugin adds three new commands for go buffers: +" +" :Import {path} +" +" Import ensures that the provided package {path} is imported +" in the current Go buffer, using proper style and ordering. +" If {path} is already being imported, an error will be +" displayed and the buffer will be untouched. +" +" :ImportAs {localname} {path} +" +" Same as Import, but uses a custom local name for the package. +" +" :Drop {path} +" +" Remove the import line for the provided package {path}, if +" present in the current Go buffer. If {path} is not being +" imported, an error will be displayed and the buffer will be +" untouched. +" +" If you would like to add shortcuts, you can do so by doing the following: +" +" Import fmt +" au Filetype go nnoremap f :Import fmt +" +" Drop fmt +" au Filetype go nnoremap F :Drop fmt +" +" Import the word under your cursor +" au Filetype go nnoremap k +" \ :exe 'Import ' . expand('') +" +" The backslash '\' is the default maplocalleader, so it is possible that +" your vim is set to use a different character (:help maplocalleader). +" +" Options: +" +" g:go_import_commands [default=1] +" +" Flag to indicate whether to enable the commands listed above. +" +if exists("b:did_ftplugin_go_import") + finish +endif + +if !exists("g:go_import_commands") + let g:go_import_commands = 1 +endif + +if g:go_import_commands + command! -buffer -nargs=? -complete=customlist,go#package#Complete Drop call s:SwitchImport(0, '', ) + command! -buffer -nargs=1 -complete=customlist,go#package#Complete Import call s:SwitchImport(1, '', ) + command! -buffer -nargs=* -complete=customlist,go#package#Complete ImportAs call s:SwitchImport(1, ) + + command! -buffer -nargs=? -complete=dir GoDrop call s:RelSwitchImport(0, getcwd(), '', ) + command! -buffer -nargs=1 -complete=dir GoImport call s:RelSwitchImport(1, getcwd(), '', ) + command! -buffer -nargs=* -complete=dir GoImportAs call s:RelSwitchImport(1, getcwd(), ) +endif + +if !exists("g:go_import_maps") + let g:go_import_maps = 1 +endif + +if g:go_import_maps + map f :Import fmt + map F :Drop fmt +endif + +function! s:RelSwitchImport(enabled, basefile, localname, path) + call s:SwitchImport(a:enabled, a:localname, GoRelPkg(a:basefile, a:path)) +endfunction + +function! s:SwitchImport(enabled, localname, path) + let view = winsaveview() + let path = a:path + + " Quotes are not necessary, so remove them if provided. + if path[0] == '"' + let path = strpart(path, 1) + endif + if path[len(path)-1] == '"' + let path = strpart(path, 0, len(path) - 1) + endif + if path == '' + call s:Error('Import path not provided') + return + endif + + " Extract any site prefix (e.g. github.com/). + " If other imports with the same prefix are grouped separately, + " we will add this new import with them. + " Only up to and including the first slash is used. + let siteprefix = matchstr(path, "^[^/]*/") + + let qpath = '"' . path . '"' + if a:localname != '' + let qlocalpath = a:localname . ' ' . qpath + else + let qlocalpath = qpath + endif + let indentstr = 0 + let packageline = -1 " Position of package name statement + let appendline = -1 " Position to introduce new import + let deleteline = -1 " Position of line with existing import + let linesdelta = 0 " Lines added/removed + + " Find proper place to add/remove import. + let line = 0 + while line <= line('$') + let linestr = getline(line) + + if linestr =~# '^package\s' + let packageline = line + let appendline = line + + elseif linestr =~# '^import\s\+(' + let appendstr = qlocalpath + let indentstr = 1 + let appendline = line + let firstblank = -1 + let lastprefix = "" + while line <= line("$") + let line = line + 1 + let linestr = getline(line) + let m = matchlist(getline(line), '^\()\|\(\s\+\)\(\S*\s*\)"\(.\+\)"\)') + if empty(m) + if siteprefix == "" && a:enabled + " must be in the first group + break + endif + " record this position, but keep looking + if firstblank < 0 + let firstblank = line + endif + continue + endif + if m[1] == ')' + " if there's no match, add it to the first group + if appendline < 0 && firstblank >= 0 + let appendline = firstblank + endif + break + endif + let lastprefix = matchstr(m[4], "^[^/]*/") + if a:localname != '' && m[3] != '' + let qlocalpath = printf('%-' . (len(m[3])-1) . 's %s', a:localname, qpath) + endif + let appendstr = m[2] . qlocalpath + let indentstr = 0 + if m[4] == path + let appendline = -1 + let deleteline = line + break + elseif m[4] < path + " don't set candidate position if we have a site prefix, + " we've passed a blank line, and this doesn't share the same + " site prefix. + if siteprefix == "" || firstblank < 0 || match(m[4], "^" . siteprefix) >= 0 + let appendline = line + endif + elseif siteprefix != "" && match(m[4], "^" . siteprefix) >= 0 + " first entry of site group + let appendline = line - 1 + break + endif + endwhile + break + + elseif linestr =~# '^import ' + if appendline == packageline + let appendstr = 'import ' . qlocalpath + let appendline = line - 1 + endif + let m = matchlist(linestr, '^import\(\s\+\)\(\S*\s*\)"\(.\+\)"') + if !empty(m) + if m[3] == path + let appendline = -1 + let deleteline = line + break + endif + if m[3] < path + let appendline = line + endif + if a:localname != '' && m[2] != '' + let qlocalpath = printf("%s %" . len(m[2])-1 . "s", a:localname, qpath) + endif + let appendstr = 'import' . m[1] . qlocalpath + endif + + elseif linestr =~# '^\(var\|const\|type\|func\)\>' + break + + endif + let line = line + 1 + endwhile + + " Append or remove the package import, as requested. + if a:enabled + if deleteline != -1 + call s:Error(qpath . ' already being imported') + elseif appendline == -1 + call s:Error('No package line found') + else + if appendline == packageline + call append(appendline + 0, '') + call append(appendline + 1, 'import (') + call append(appendline + 2, ')') + let appendline += 2 + let linesdelta += 3 + let appendstr = qlocalpath + let indentstr = 1 + endif + call append(appendline, appendstr) + execute appendline + 1 + if indentstr + execute 'normal >>' + endif + let linesdelta += 1 + endif + else + if deleteline == -1 + call s:Error(qpath . ' not being imported') + else + execute deleteline . 'd' + let linesdelta -= 1 + + if getline(deleteline-1) =~# '^import\s\+(' && getline(deleteline) =~# '^)' + " Delete empty import block + let deleteline -= 1 + execute deleteline . "d" + execute deleteline . "d" + let linesdelta -= 2 + endif + + if getline(deleteline) == '' && getline(deleteline - 1) == '' + " Delete spacing for removed line too. + execute deleteline . "d" + let linesdelta -= 1 + endif + endif + endif + + " Adjust view for any changes. + let view.lnum += linesdelta + let view.topline += linesdelta + if view.topline < 0 + let view.topline = 0 + endif + + " Put buffer back where it was. + call winrestview(view) + +endfunction + +function! s:Error(s) + echohl Error | echo a:s | echohl None +endfunction + +let b:did_ftplugin_go_import = 1 + +" vim:sw=4:et diff --git a/vim/bundle/vim-gocode/ftplugin/go/install.vim b/vim/bundle/vim-gocode/ftplugin/go/install.vim new file mode 100644 index 0000000..db1247b --- /dev/null +++ b/vim/bundle/vim-gocode/ftplugin/go/install.vim @@ -0,0 +1,67 @@ +if exists("b:did_ftplugin_go_install") + finish +endif + +if !exists('g:go_install_commands') + let g:go_install_commands = 1 +endif + +if g:go_install_commands + command! -buffer -nargs=? -complete=dir GoInstall call s:GoInstall(getcwd(), ) + command! -buffer -nargs=? -complete=dir GoTest call s:GoTest(getcwd(), ) + command! -buffer -nargs=? -complete=dir GoTestVerbose call s:GoTestVerbose(getcwd(), ) +endif + +function! s:GoInstall(file, ...) + if a:0 == 0 + " no arguments + let relpkg = '.' + else + let relpkg = a:1 + endif + let pkg=GoRelPkg(a:file, relpkg) + if pkg != -1 + let output=system('go install '.pkg) + if !v:shell_error + echo 'Package '.pkg.' installed' + else + echo output + endif + else + echohl Error | echo 'You are not in a go package' | echohl None + endif +endfunction + +function! s:GoTest(file, ...) + if a:0 == 0 + " no arguments + let relpkg = '.' + else + let relpkg = a:1 + endif + let pkg=GoRelPkg(a:file, relpkg) + if pkg != -1 + echo system('go test '.pkg) + else + echohl Error | echo 'You are not in a go package' | echohl None + endif +endfunction + +function! s:GoTestVerbose(file, ...) + if a:0 == 0 + " no arguments + let relpkg = '.' + else + let relpkg = a:1 + endif + let pkg=GoRelPkg(a:file, relpkg) + if pkg != -1 + echo system('go test -v '.pkg) + else + echohl Error | echo 'You are not in a go package' | echohl None + endif +endfunction + +let b:did_ftplugin_go_install=1 + +" vim:sw=4:et diff --git a/vim/bundle/vim-gocode/ftplugin/go/pkg.vim b/vim/bundle/vim-gocode/ftplugin/go/pkg.vim new file mode 100644 index 0000000..6ba169e --- /dev/null +++ b/vim/bundle/vim-gocode/ftplugin/go/pkg.vim @@ -0,0 +1,46 @@ +if exists('b:did_ftplugin_go_pkg') + finish +endif + +if !exists('g:go_package_commands') + let g:go_package_commands = 1 +endif + +if g:go_package_commands + command! -buffer -nargs=? RelPkg call s:GoRelPkg() +endif + +function! GoRelPkg(file, relpkg) + if isdirectory(a:file) + return go#package#FromPath(a:file.'/'.a:relpkg) + else + return go#package#FromPath(fnamemodify(a:file, ':p:h').'/'.a:relpkg) + end +endfunction + +function! s:GoCurPkg() + let pkg=go#package#FromPath(@%) + if pkg != -1 + echo pkg + else + echohl Error | echo 'You are not in a go package' | echohl None + endif +endfunction + +function! s:GoRelPkg(...) + if a:0 == 0 + let relpkg = '.' + else + let relpkg = a:1 + endif + let pkg=GoRelPkg(@%, relpkg) + if pkg != -1 + echo pkg + else + echohl Error | echo 'You are not in a go package' | echohl None + end +endfunction + +let b:did_ft_plugin_go_pkg=1 + +" vim:sw=4:et diff --git a/vim/bundle/vim-gocode/ftplugin/go/test.sh b/vim/bundle/vim-gocode/ftplugin/go/test.sh new file mode 100755 index 0000000..d8a5b89 --- /dev/null +++ b/vim/bundle/vim-gocode/ftplugin/go/test.sh @@ -0,0 +1,78 @@ +#!/bin/bash -e +# +# Copyright 2012 The Go Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. +# +# Tests for import.vim. + +cd $(dirname $0) + +cat > base.go <&1 -n "$1: " + vim -e -s -u /dev/null -U /dev/null --noplugin -c "source import.vim" \ + -c "$1" -c 'wq! test.go' base.go + # ensure blank lines are treated correctly + if ! gofmt test.go | cmp test.go -; then + echo 2>&1 "gofmt conflict" + gofmt test.go | diff -u test.go - | sed "s/^/ /" 2>&1 + fail=1 + return + fi + if ! [[ $(cat test.go) =~ $2 ]]; then + echo 2>&1 "$2 did not match" + cat test.go | sed "s/^/ /" 2>&1 + fail=1 + return + fi + echo 2>&1 "ok" +} + +# Tests for Import + +test_one "Import baz" '"baz".*"bytes"' +test_one "Import io/ioutil" '"io".*"io/ioutil".*"net"' +test_one "Import myc" '"io".*"myc".*"net"' # prefix of a site prefix +test_one "Import nat" '"io".*"nat".*"net"' +test_one "Import net/http" '"net".*"net/http".*"mycorp/foo"' +test_one "Import zoo" '"net".*"zoo".*"mycorp/foo"' +test_one "Import mycorp/bar" '"net".*"mycorp/bar".*"mycorp/foo"' +test_one "Import mycorp/goo" '"net".*"mycorp/foo".*"mycorp/goo"' + +# Tests for Drop + +cat > base.go <&1 "FAIL" + exit 1 +fi +echo 2>&1 "PASS" diff --git a/vim/bundle/vim-gocode/indent/go.vim b/vim/bundle/vim-gocode/indent/go.vim new file mode 100644 index 0000000..63dc21a --- /dev/null +++ b/vim/bundle/vim-gocode/indent/go.vim @@ -0,0 +1,67 @@ +" Copyright 2011 The Go Authors. All rights reserved. +" Use of this source code is governed by a BSD-style +" license that can be found in the LICENSE file. +" +" indent/go.vim: Vim indent file for Go. +" +" TODO: +" - function invocations split across lines +" - general line splits (line ends in an operator) + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +" C indentation is too far off useful, mainly due to Go's := operator. +" Let's just define our own. +setlocal nolisp +setlocal autoindent +setlocal indentexpr=GoIndent(v:lnum) +setlocal indentkeys+=<:>,0=},0=) + +if exists("*GoIndent") + finish +endif + +function! GoIndent(lnum) + let prevlnum = prevnonblank(a:lnum-1) + if prevlnum == 0 + " top of file + return 0 + endif + + " grab the previous and current line, stripping comments. + let prevl = substitute(getline(prevlnum), '//.*$', '', '') + let thisl = substitute(getline(a:lnum), '//.*$', '', '') + let previ = indent(prevlnum) + + let ind = previ + + if prevl =~ '[({]\s*$' + " previous line opened a block + let ind += &sw + endif + if prevl =~# '^\s*\(case .*\|default\):$' + " previous line is part of a switch statement + let ind += &sw + endif + " TODO: handle if the previous line is a label. + + if thisl =~ '^\s*[)}]' + " this line closed a block + let ind -= &sw + endif + + " Colons are tricky. + " We want to outdent if it's part of a switch ("case foo:" or "default:"). + " We ignore trying to deal with jump labels because (a) they're rare, and + " (b) they're hard to disambiguate from a composite literal key. + if thisl =~# '^\s*\(case .*\|default\):$' + let ind -= &sw + endif + + return ind +endfunction + +" vim:sw=4:et diff --git a/vim/bundle/vim-gocode/plugin/godoc.vim b/vim/bundle/vim-gocode/plugin/godoc.vim new file mode 100644 index 0000000..050d8bc --- /dev/null +++ b/vim/bundle/vim-gocode/plugin/godoc.vim @@ -0,0 +1,130 @@ +" Copyright 2011 The Go Authors. All rights reserved. +" Use of this source code is governed by a BSD-style +" license that can be found in the LICENSE file. +" +" godoc.vim: Vim command to see godoc. +" +" +" Commands: +" +" :Godoc +" +" Open the relevant Godoc for either the word[s] passed to the command or +" the, by default, the word under the cursor. +" +" Options: +" +" g:go_godoc_commands [default=1] +" +" Flag to indicate whether to enable the commands listed above. + +if exists("g:loaded_godoc") + finish +endif +let g:loaded_godoc = 1 + +let s:buf_nr = -1 +let s:last_word = '' + +if !exists('g:go_godoc_commands') + let g:go_godoc_commands = 1 +endif + +if g:go_godoc_commands + command! -nargs=* -range -complete=customlist,go#package#Complete Godoc :call s:Godoc() +endif + +nnoremap (godoc-keyword) :call Godoc('') + +function! s:GodocView() + if !bufexists(s:buf_nr) + leftabove new + file `="[Godoc]"` + let s:buf_nr = bufnr('%') + elseif bufwinnr(s:buf_nr) == -1 + leftabove split + execute s:buf_nr . 'buffer' + delete _ + elseif bufwinnr(s:buf_nr) != bufwinnr('%') + execute bufwinnr(s:buf_nr) . 'wincmd w' + endif + + setlocal filetype=godoc + setlocal bufhidden=delete + setlocal buftype=nofile + setlocal noswapfile + setlocal nobuflisted + setlocal modifiable + setlocal nocursorline + setlocal nocursorcolumn + setlocal iskeyword+=: + setlocal iskeyword-=- + + nnoremap K :Godoc + + au BufHidden call let buf_nr = -1 +endfunction + +function! s:GodocWord(word) + if !executable('godoc') + echohl WarningMsg + echo "godoc command not found." + echo " install with: go get code.google.com/p/go.tools/cmd/godoc" + echohl None + return 0 + endif + let word = a:word + silent! let content = system('godoc ' . word) + if v:shell_error || !len(content) + if len(s:last_word) + silent! let content = system('godoc ' . s:last_word.'/'.word) + if v:shell_error || !len(content) + echo 'No documentation found for "' . word . '".' + return 0 + endif + let word = s:last_word.'/'.word + else + echo 'No documentation found for "' . word . '".' + return 0 + endif + endif + let s:last_word = word + silent! call s:GodocView() + setlocal modifiable + silent! %d _ + silent! put! =content + silent! normal gg + setlocal nomodifiable + setfiletype godoc + return 1 +endfunction + +function! s:Godoc(...) + if !len(a:000) + let oldiskeyword = &iskeyword + setlocal iskeyword+=. + let word = expand('') + let &iskeyword = oldiskeyword + let word = substitute(word, '[^a-zA-Z0-9\\/._~-]', '', 'g') + let words = split(word, '\.\ze[^./]\+$') + else + let words = a:000 + endif + if !len(words) + return + endif + if s:GodocWord(words[0]) + if len(words) > 1 + if search('^\%(const\|var\|type\|\s\+\) ' . words[1] . '\s\+=\s') + return + endif + if search('^func ' . words[1] . '(') + silent! normal zt + return + endif + echo 'No documentation found for "' . words[1] . '".' + endif + endif +endfunction + +" vim:sw=4:et diff --git a/vim/bundle/vim-gocode/syntax/go.vim b/vim/bundle/vim-gocode/syntax/go.vim new file mode 100644 index 0000000..8e2087a --- /dev/null +++ b/vim/bundle/vim-gocode/syntax/go.vim @@ -0,0 +1,209 @@ +" Copyright 2009 The Go Authors. All rights reserved. +" Use of this source code is governed by a BSD-style +" license that can be found in the LICENSE file. +" +" go.vim: Vim syntax file for Go. +" +" Options: +" There are some options for customizing the highlighting; the recommended +" settings are the default values, but you can write: +" let OPTION_NAME = 0 +" in your ~/.vimrc file to disable particular options. You can also write: +" let OPTION_NAME = 1 +" to enable particular options. At present, all options default to on. +" +" - go_highlight_array_whitespace_error +" Highlights white space after "[]". +" - go_highlight_chan_whitespace_error +" Highlights white space around the communications operator that don't follow +" the standard style. +" - go_highlight_extra_types +" Highlights commonly used library types (io.Reader, etc.). +" - go_highlight_space_tab_error +" Highlights instances of tabs following spaces. +" - go_highlight_trailing_whitespace_error +" Highlights trailing white space. + +" Quit when a (custom) syntax file was already loaded +if exists("b:current_syntax") + finish +endif + +if !exists("go_highlight_array_whitespace_error") + let go_highlight_array_whitespace_error = 1 +endif +if !exists("go_highlight_chan_whitespace_error") + let go_highlight_chan_whitespace_error = 1 +endif +if !exists("go_highlight_extra_types") + let go_highlight_extra_types = 1 +endif +if !exists("go_highlight_space_tab_error") + let go_highlight_space_tab_error = 1 +endif +if !exists("go_highlight_trailing_whitespace_error") + let go_highlight_trailing_whitespace_error = 1 +endif + +syn case match + +syn keyword goDirective package import +syn keyword goDeclaration var const type +syn keyword goDeclType struct interface + +hi def link goDirective Statement +hi def link goDeclaration Keyword +hi def link goDeclType Keyword + +" Keywords within functions +syn keyword goStatement defer go goto return break continue fallthrough +syn keyword goConditional if else switch select +syn keyword goLabel case default +syn keyword goRepeat for range + +hi def link goStatement Statement +hi def link goConditional Conditional +hi def link goLabel Label +hi def link goRepeat Repeat + +" Predefined types +syn keyword goType chan map bool string error +syn keyword goSignedInts int int8 int16 int32 int64 rune +syn keyword goUnsignedInts byte uint uint8 uint16 uint32 uint64 uintptr +syn keyword goFloats float32 float64 +syn keyword goComplexes complex64 complex128 + +hi def link goType Type +hi def link goSignedInts Type +hi def link goUnsignedInts Type +hi def link goFloats Type +hi def link goComplexes Type + +" Treat func specially: it's a declaration at the start of a line, but a type +" elsewhere. Order matters here. +syn match goType /\/ +syn match goDeclaration /^func\>/ + +" Predefined functions and values +syn keyword goBuiltins append cap close complex copy delete imag len +syn keyword goBuiltins make new panic print println real recover +syn keyword goConstants iota true false nil + +hi def link goBuiltins Keyword +hi def link goConstants Keyword + +" Comments; their contents +syn keyword goTodo contained TODO FIXME XXX BUG +syn cluster goCommentGroup contains=goTodo +syn region goComment start="/\*" end="\*/" contains=@goCommentGroup,@Spell +syn region goComment start="//" end="$" contains=@goCommentGroup,@Spell + +hi def link goComment Comment +hi def link goTodo Todo + +" Go escapes +syn match goEscapeOctal display contained "\\[0-7]\{3}" +syn match goEscapeC display contained +\\[abfnrtv\\'"]+ +syn match goEscapeX display contained "\\x\x\{2}" +syn match goEscapeU display contained "\\u\x\{4}" +syn match goEscapeBigU display contained "\\U\x\{8}" +syn match goEscapeError display contained +\\[^0-7xuUabfnrtv\\'"]+ + +hi def link goEscapeOctal goSpecialString +hi def link goEscapeC goSpecialString +hi def link goEscapeX goSpecialString +hi def link goEscapeU goSpecialString +hi def link goEscapeBigU goSpecialString +hi def link goSpecialString Special +hi def link goEscapeError Error + +" Strings and their contents +syn cluster goStringGroup contains=goEscapeOctal,goEscapeC,goEscapeX,goEscapeU,goEscapeBigU,goEscapeError +syn region goString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=@goStringGroup +syn region goRawString start=+`+ end=+`+ + +hi def link goString String +hi def link goRawString String + +" Characters; their contents +syn cluster goCharacterGroup contains=goEscapeOctal,goEscapeC,goEscapeX,goEscapeU,goEscapeBigU +syn region goCharacter start=+'+ skip=+\\\\\|\\'+ end=+'+ contains=@goCharacterGroup + +hi def link goCharacter Character + +" Regions +syn region goBlock start="{" end="}" transparent fold +syn region goParen start='(' end=')' transparent + +" Integers +syn match goDecimalInt "\<\d\+\([Ee]\d\+\)\?\>" +syn match goHexadecimalInt "\<0x\x\+\>" +syn match goOctalInt "\<0\o\+\>" +syn match goOctalError "\<0\o*[89]\d*\>" + +hi def link goDecimalInt Integer +hi def link goHexadecimalInt Integer +hi def link goOctalInt Integer +hi def link Integer Number + +" Floating point +syn match goFloat "\<\d\+\.\d*\([Ee][-+]\d\+\)\?\>" +syn match goFloat "\<\.\d\+\([Ee][-+]\d\+\)\?\>" +syn match goFloat "\<\d\+[Ee][-+]\d\+\>" + +hi def link goFloat Float + +" Imaginary literals +syn match goImaginary "\<\d\+i\>" +syn match goImaginary "\<\d\+\.\d*\([Ee][-+]\d\+\)\?i\>" +syn match goImaginary "\<\.\d\+\([Ee][-+]\d\+\)\?i\>" +syn match goImaginary "\<\d\+[Ee][-+]\d\+i\>" + +hi def link goImaginary Number + +" Spaces after "[]" +if go_highlight_array_whitespace_error != 0 + syn match goSpaceError display "\(\[\]\)\@<=\s\+" +endif + +" Spacing errors around the 'chan' keyword +if go_highlight_chan_whitespace_error != 0 + " receive-only annotation on chan type + syn match goSpaceError display "\(<-\)\@<=\s\+\(chan\>\)\@=" + " send-only annotation on chan type + syn match goSpaceError display "\(\/ + syn match goExtraType /\/ + syn match goExtraType /\/ + syn match goExtraType /\/ +endif + +" Space-tab error +if go_highlight_space_tab_error != 0 + syn match goSpaceError display " \+\t"me=e-1 +endif + +" Trailing white space error +if go_highlight_trailing_whitespace_error != 0 + syn match goSpaceError display excludenl "\s\+$" +endif + +hi def link goExtraType Type +hi def link goSpaceError Error + +" Search backwards for a global declaration to start processing the syntax. +"syn sync match goSync grouphere NONE /^\(const\|var\|type\|func\)\>/ + +" There's a bug in the implementation of grouphere. For now, use the +" following as a more expensive/less precise workaround. +syn sync minlines=500 + +let b:current_syntax = "go" + +" vim:sw=4:et diff --git a/vim/bundle/vim-gocode/syntax/godoc.vim b/vim/bundle/vim-gocode/syntax/godoc.vim new file mode 100644 index 0000000..e05ff63 --- /dev/null +++ b/vim/bundle/vim-gocode/syntax/godoc.vim @@ -0,0 +1,20 @@ +" Copyright 2011 The Go Authors. All rights reserved. +" Use of this source code is governed by a BSD-style +" license that can be found in the LICENSE file. + +if exists("b:current_syntax") + finish +endif + +syn case match +syn match godocTitle "^\([A-Z][A-Z ]*\)$" + +command -nargs=+ HiLink hi def link + +HiLink godocTitle Title + +delcommand HiLink + +let b:current_syntax = "godoc" + +" vim:sw=4:et diff --git a/vim/bundles.vim b/vim/bundles.vim index a2bf19d..14cee73 100644 --- a/vim/bundles.vim +++ b/vim/bundles.vim @@ -21,6 +21,7 @@ Bundle 'vim-scripts/DoxygenToolkit.vim' Bundle 'davidhalter/jedi-vim' Bundle 'fatih/vim-go' Bundle 'dgryski/vim-godef' +Bundle 'Blackrush/vim-gocode' filetype plugin indent on " required!