From c863f92442b13c4d928705addb3387ef190be01f Mon Sep 17 00:00:00 2001 From: michener Date: Wed, 4 May 2011 20:35:07 +0000 Subject: [PATCH] Add Go vim basics git-svn-id: http://photonzero.com/dotfiles/trunk@97 23f722f6-122a-0410-8cef-c75bd312dd78 --- .vim/colors/baraknew.vim | 2 +- .vim/ftdetect/gofiletype.vim | 1 + .vim/ftplugin/go/fmt.vim | 30 +++++++ .vim/ftplugin/go/import.vim | 201 +++++++++++++++++++++++++++++++++++++++++++ .vim/indent/go.vim | 30 +++++++ .vim/plugin/ShowFunc.vim | 2 +- .vim/syntax/go.vim | 32 +++++-- 7 files changed, 289 insertions(+), 9 deletions(-) create mode 100644 .vim/ftdetect/gofiletype.vim create mode 100644 .vim/ftplugin/go/fmt.vim create mode 100644 .vim/ftplugin/go/import.vim create mode 100644 .vim/indent/go.vim diff --git a/.vim/colors/baraknew.vim b/.vim/colors/baraknew.vim index 905eb39..006c32e 100644 --- a/.vim/colors/baraknew.vim +++ b/.vim/colors/baraknew.vim @@ -309,7 +309,7 @@ hi FoldColumn ctermfg=117 ctermbg=238 cterm=none hi IncSearch guifg=#66ffff gui=reverse hi IncSearch ctermfg=87 cterm=reverse " hlsearch (last search pattern), also used for quickfix -hi Search guibg=#ffaa33 gui=none +hi Search guibg=#e0e096 gui=none hi Search ctermbg=214 cterm=none diff --git a/.vim/ftdetect/gofiletype.vim b/.vim/ftdetect/gofiletype.vim new file mode 100644 index 0000000..8843121 --- /dev/null +++ b/.vim/ftdetect/gofiletype.vim @@ -0,0 +1 @@ +au BufRead,BufNewFile *.go set filetype=go diff --git a/.vim/ftplugin/go/fmt.vim b/.vim/ftplugin/go/fmt.vim new file mode 100644 index 0000000..18a2156 --- /dev/null +++ b/.vim/ftplugin/go/fmt.vim @@ -0,0 +1,30 @@ +" 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. +" + +command! Fmt call s:GoFormat() + +function! s:GoFormat() + let view = winsaveview() + %!gofmt + if v:shell_error + %| " output errors returned by gofmt + " TODO(dchest): perhaps, errors should go to quickfix + undo + echohl Error | echomsg "Gofmt returned error" | echohl None + endif + call winrestview(view) +endfunction + +" vim:ts=4:sw=4:et diff --git a/.vim/ftplugin/go/import.vim b/.vim/ftplugin/go/import.vim new file mode 100644 index 0000000..b5814ca --- /dev/null +++ b/.vim/ftplugin/go/import.vim @@ -0,0 +1,201 @@ +" 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. +" +" In addition to these commands, there are also two shortcuts mapped: +" +" \f - Runs :Import fmt +" \F - Runs :Drop fmt +" +" The backslash is the default maplocalleader, so it is possible that +" your vim is set to use a different character (:help maplocalleader). +" +if exists("b:did_ftplugin") + finish +endif + +command! -buffer -nargs=? Drop call s:SwitchImport(0, '', ) +command! -buffer -nargs=1 Import call s:SwitchImport(1, '', ) +command! -buffer -nargs=* ImportAs call s:SwitchImport(1, ) +map f :Import fmt +map F :Drop fmt + +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 + + 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 + while line <= line("$") + let line = line + 1 + let linestr = getline(line) + let m = matchlist(getline(line), '^\()\|\(\s\+\)\(\S*\s*\)"\(.\+\)"\)') + if empty(m) + continue + endif + if m[1] == ')' + break + endif + 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 + let appendline = line + 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 + +" vim:ts=4:sw=4:et diff --git a/.vim/indent/go.vim b/.vim/indent/go.vim new file mode 100644 index 0000000..2e9f191 --- /dev/null +++ b/.vim/indent/go.vim @@ -0,0 +1,30 @@ +" 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. +" + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +" C indentation is mostly correct +setlocal cindent + +" Options set: +" +0 -- Don't indent continuation lines (because Go doesn't use semicolons +" much) +" L0 -- Don't move jump labels (NOTE: this isn't correct when working with +" gofmt, but it does keep struct literals properly indented.) +" :0 -- Align case labels with switch statement +" l1 -- Always align case body relative to case labels +" J1 -- Indent JSON-style objects (properly indents struct-literals) +" (0, Ws -- Indent lines inside of unclosed parentheses by one shiftwidth +" m1 -- Align closing parenthesis line with first non-blank of matching +" parenthesis line +" +" Known issue: Trying to do a multi-line struct literal in a short variable +" declaration will not indent properly. +setlocal cinoptions+=+0,L0,:0,l1,J1,(0,Ws,m1 diff --git a/.vim/plugin/ShowFunc.vim b/.vim/plugin/ShowFunc.vim index a540892..2bc6dc8 100644 --- a/.vim/plugin/ShowFunc.vim +++ b/.vim/plugin/ShowFunc.vim @@ -143,7 +143,7 @@ function! s:CtagsTest(path) " if the location of the ctags executable is not already configured, then " attempt to find it.... if a:path == "unk" - let l:test_paths = "/usr/local/bin/ctags /usr/bin/ctags" . + let l:test_paths = "/usr/local/bin/ctags /opt/local/bin/ctags /usr/bin/ctags" . \ " C:\\gnu\\ctags\\ctags.exe " let l:rpath = "fail" while l:test_paths != '' diff --git a/.vim/syntax/go.vim b/.vim/syntax/go.vim index db3903a..26d7def 100644 --- a/.vim/syntax/go.vim +++ b/.vim/syntax/go.vim @@ -70,12 +70,14 @@ hi def link goRepeat Repeat syn keyword goType chan map bool string syn keyword goSignedInts int int8 int16 int32 int64 syn keyword goUnsignedInts byte uint uint8 uint16 uint32 uint64 uintptr -syn keyword goFloats float float32 float64 +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. @@ -83,7 +85,8 @@ syn match goType /\/ syn match goDeclaration /^func\>/ " Predefined functions and values -syn keyword goBuiltins cap close closed convert copy len make new panic panicln print println +syn keyword goBuiltins append cap close complex copy imag len +syn keyword goBuiltins make new panic print println real recover syn keyword goConstants iota true false nil hi def link goBuiltins Keyword @@ -92,8 +95,8 @@ 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 -syn region goComment start="//" end="$" contains=@goCommentGroup +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 @@ -133,7 +136,7 @@ syn region goBlock start="{" end="}" transparent fold syn region goParen start='(' end=')' transparent " Integers -syn match goDecimalInt "\<\d\+\>" +syn match goDecimalInt "\<\d\+\([Ee]\d\+\)\?\>" syn match goHexadecimalInt "\<0x\x\+\>" syn match goOctalInt "\<0\o\+\>" syn match goOctalError "\<0\o*[89]\d*\>" @@ -146,10 +149,18 @@ 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\+" +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\+" @@ -170,7 +181,7 @@ if go_highlight_extra_types != 0 syn match goExtraType /\/ syn match goExtraType /\/ syn match goExtraType /\<\(os\.Error\)\>/ - syn match goExtraType /\/ + syn match goExtraType /\/ syn match goExtraType /\/ endif @@ -187,4 +198,11 @@ 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"