Skip to content

Commit

Permalink
cmd/govim: minor fixes
Browse files Browse the repository at this point in the history
* Log to a specific gopls logfile
* Only do ftplugin-based configuration once govim has loaded
* Prevent race condition on autocmd events possibly being handled before
govim is initcomplete
* Use Vim's execute() function instead of our own terrible function
* Put in a hacky fix for local-aware version parsing; add a test for a
non-English version string
  • Loading branch information
myitcv committed Jun 13, 2019
1 parent 6c99797 commit 24030b4
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 39 deletions.
50 changes: 32 additions & 18 deletions cmd/govim/main.go
Expand Up @@ -93,24 +93,9 @@ func launch(goplspath string, in io.ReadCloser, out io.WriteCloser) error {

d := newplugin(goplspath)

var tf *os.File
var err error
logfiletmpl := os.Getenv(testsetup.EnvLogfileTmpl)
if logfiletmpl == "" {
logfiletmpl = "%v_%v_%v"
}
logfiletmpl = strings.Replace(logfiletmpl, "%v", "govim_log", 1)
logfiletmpl = strings.Replace(logfiletmpl, "%v", time.Now().Format("20060102_1504_05.000000000"), 1)
if strings.Contains(logfiletmpl, "%v") {
logfiletmpl = strings.Replace(logfiletmpl, "%v", "*", 1)
tf, err = ioutil.TempFile("", logfiletmpl)

} else {
// append to existing file
tf, err = os.OpenFile(filepath.Join(os.TempDir(), logfiletmpl), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
}
tf, err := createLogFile("govim_log")
if err != nil {
return fmt.Errorf("failed to create log file: %v", err)
return err
}
defer tf.Close()

Expand All @@ -132,6 +117,28 @@ func launch(goplspath string, in io.ReadCloser, out io.WriteCloser) error {
return d.tomb.Wait()
}

func createLogFile(prefix string) (*os.File, error) {
var tf *os.File
var err error
logfiletmpl := os.Getenv(testsetup.EnvLogfileTmpl)
if logfiletmpl == "" {
logfiletmpl = "%v_%v_%v"
}
logfiletmpl = strings.Replace(logfiletmpl, "%v", prefix, 1)
logfiletmpl = strings.Replace(logfiletmpl, "%v", time.Now().Format("20060102_1504_05.000000000"), 1)
if strings.Contains(logfiletmpl, "%v") {
logfiletmpl = strings.Replace(logfiletmpl, "%v", "*", 1)
tf, err = ioutil.TempFile("", logfiletmpl)
} else {
// append to existing file
tf, err = os.OpenFile(filepath.Join(os.TempDir(), logfiletmpl), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
}
if err != nil {
err = fmt.Errorf("failed to create log file: %v", err)
}
return tf, err
}

type govimplugin struct {
plugin.Driver
*vimstate
Expand Down Expand Up @@ -199,7 +206,14 @@ func (g *govimplugin) Init(gg govim.Govim, errCh chan error) error {

g.isGui = g.ParseInt(g.ChannelExpr(`has("gui_running")`)) == 1

gopls := exec.Command(g.goplspath, "-rpc.trace")
logfile, err := createLogFile("gopls_log")
if err != nil {
return err
}
logfile.Close()
g.Logf("gopls log file: %v", logfile.Name())

gopls := exec.Command(g.goplspath, "-rpc.trace", "-logfile", logfile.Name())
stderr, err := gopls.StderrPipe()
if err != nil {
return fmt.Errorf("failed to create stderr pipe for gopls: %v", err)
Expand Down
20 changes: 11 additions & 9 deletions ftplugin/go.vim
@@ -1,9 +1,11 @@
setlocal balloonexpr=GOVIM_internal_BalloonExpr()
setlocal omnifunc=GOVIM_internal_Complete
nnoremap <buffer> <silent> gd :GOVIMGoToDef<cr>
nnoremap <buffer> <silent> <C-]> :GOVIMGoToDef<cr>
nnoremap <buffer> <silent> <C-LeftMouse> <LeftMouse>:GOVIMGoToDef<cr>
nnoremap <buffer> <silent> g<LeftMouse> <LeftMouse>:GOVIMGoToDef<cr>
nnoremap <buffer> <silent> <C-t> :GOVIMGoToPrevDef<cr>
nnoremap <buffer> <silent> <C-RightMouse> :GOVIMGoToPrevDef<cr>
nnoremap <buffer> <silent> g<RightMouse> :GOVIMGoToPrevDef<cr>
if GOVIMPluginStatus() == "initcomplete"
setlocal balloonexpr=GOVIM_internal_BalloonExpr()
setlocal omnifunc=GOVIM_internal_Complete
nnoremap <buffer> <silent> gd :GOVIMGoToDef<cr>
nnoremap <buffer> <silent> <C-]> :GOVIMGoToDef<cr>
nnoremap <buffer> <silent> <C-LeftMouse> <LeftMouse>:GOVIMGoToDef<cr>
nnoremap <buffer> <silent> g<LeftMouse> <LeftMouse>:GOVIMGoToDef<cr>
nnoremap <buffer> <silent> <C-t> :GOVIMGoToPrevDef<cr>
nnoremap <buffer> <silent> <C-RightMouse> :GOVIMGoToPrevDef<cr>
nnoremap <buffer> <silent> g<RightMouse> :GOVIMGoToPrevDef<cr>
endif
5 changes: 3 additions & 2 deletions govim.go
Expand Up @@ -262,7 +262,7 @@ func (g *govimImpl) load() error {
GuiRunning int
}

v, err := g.ChannelExpr(`{"Version": GOVIMEvalRedir("version"), "GuiRunning": has("gui_running")}`)
v, err := g.ChannelExpr(`{"Version": execute("version"), "GuiRunning": has("gui_running")}`)
if err != nil {
return err
}
Expand Down Expand Up @@ -901,13 +901,14 @@ func ParseVimVersion(b []byte) (string, error) {
// Depending on OS/build, the patch versions are printed on different lines
var patch string
for _, line := range lines {
if strings.HasPrefix(line, "Included patches:") {
if strings.Contains(line, ": ") {
patch = strings.Fields(line)[2]
patchI := strings.Index(patch, "-")
if patchI == -1 {
return "", fmt.Errorf("failed to parse patch version from %v", patch)
}
patch = patch[patchI+1:]
break
}
}
av += "." + patch
Expand Down
23 changes: 13 additions & 10 deletions plugin/govim.vim
Expand Up @@ -39,9 +39,6 @@ let s:userBusy = 0
set ballooneval
set balloonevalterm

" TODO these probably doesn't belong here?
let g:govim_format_on_save = "goimports"

function s:callbackFunction(name, args)
let l:args = ["function", "function:".a:name, a:args]
let l:resp = ch_evalexpr(s:channel, l:args)
Expand Down Expand Up @@ -71,6 +68,18 @@ function s:callbackCommand(name, flags, ...)
endfunction

function s:callbackAutoCommand(name, exprs)
" When govim is the process of loading, i.e. its Init(Govim) method is
" called, we make a number of calls to Vim to register functions, commands
" autocommands etc. In parallel to this, Vim is busily loading itself.
" Therefore (and this has been observed), it's entirely possible that before
" govim finishes its Init(Govim) that we receive callbacks for autocmd
" events. We _have_ to ignore these, and rely on the fact that the doautoall
" which is called once we are initcomplete will put everything in order.
" It's conceivable that calls to functions/commands _are_ valid during this
" phase, so we allow those (for now)
if s:govim_status != "initcomplete"
return
endif
let l:exprVals = []
for e in a:exprs
call add(l:exprVals, eval(e))
Expand Down Expand Up @@ -139,6 +148,7 @@ function s:define(channel, msg)
let s:govim_status = "initcomplete"
" doautoall BufRead also triggers ftplugin stuff
doautoall BufRead
doautoall FileType
au CursorMoved,CursorMovedI *.go :call s:userBusy(1)
au CursorHold,CursorHoldI *.go :call s:userBusy(0)
for F in s:loadStatusCallbacks
Expand Down Expand Up @@ -330,13 +340,6 @@ endif

au VimLeave * call s:doShutdown()

function GOVIMEvalRedir(expr)
redir => l:output
silent! execute a:expr
redir END
return l:output
endfunction

function GOVIM_internal_EnrichDelta(bufnr, start, end, added, changes)
for l:change in a:changes
let l:change.lines = getbufline(a:bufnr, l:change.lnum, l:change.end-1+l:change.added)
Expand Down
16 changes: 16 additions & 0 deletions version_test.go
@@ -0,0 +1,16 @@
package govim

import "testing"

func TestParseVersion(t *testing.T) {
input := "\n\nVIM - Vi IMproved 8.1 (2018 May 18, compiled Jun 12 2019 11:38:35)\nPoužité záplaty: 1-1518\npřeložil jnml@e5-1650\nmaximální verzewith GTK2 GUI. Vlastnosti zahrnuté (+) a nezahrnuté (-):\n+acl +clipboard +dnd +gettext +localmap +mouse_urxvt +profile +statusline +timers +windows\n+arabic +cmdline_compl -ebcdic -hangul_input -lua +mouse_xterm -python -sun_workshop +title +writebackup\n+autocmd +cmdline_hist +emacs_tags +iconv +menu +multi_byte -python3 +syntax +toolbar +X11\n+autochdir +cmdline_info +eval +insert_expand +mksession +multi_lang +quickfix +tag_binary +user_commands -xfontset\n-autoservername +comments +ex_extra +job +modify_fname -mzscheme +reltime -tag_old_static +vartabs +xim\n+balloon_eval +conceal +extra_search +jumplist +mouse +netbeans_intg +rightleft -tag_any_white +vertsplit +xpm\n+balloon_eval_term +cryptv -farsi +keymap +mouseshape +num64 -ruby -tcl +virtualedit +xsmp_interact\n+browse +cscope +file_in_path +lambda +mouse_dec +packages +scrollbind +termguicolors +visual +xterm_clipboard\n++builtin_terms +cursorbind +find_in_path +langmap -mouse_gpm +path_extra +signs +terminal +visualextra -xterm_save\n+byte_offset +cursorshape +float +libcall -mouse_jsbterm -perl +smartindent +terminfo +viminfo \n+channel +dialog_con_gui +folding +linebreak +mouse_netterm +persistent_undo -sound +termresponse +vreplace \n+cindent +diff -footer +lispindent +mouse_sgr +postscript +spell +textobjects +wildignore \n+clientserver +digraphs +fork() +listcmds -mouse_sysmouse +printer +startuptime +textprop +wildmenu \n systémový vimrc soubor: \"$VIM/vimrc\"\n uživatelský vimrc soubor: \"$HOME/.vimrc\"\n druhý uživatelský vimrc soubor: \"~/.vim/vimrc\"\n uživatelský exrc soubor: \"$HOME/.exrc\"\n systémový gvimrc soubor: \"$VIM/gvimrc\"\n uživatelský gvimrc soubor: \"$HOME/.gvimrc\"\ndruhý uživatelský gvimrc soubor: \"~/.vim/gvimrc\"\n defaults file: \"$VIMRUNTIME/defaults.vim\"\n systémový soubor s menu: \"$VIMRUNTIME/menu.vim\"\n implicitní hodnota $VIM:\"/home/jnml/share/vim\"\nPřeklad: gcc -c -I. -Iproto -DHAVE_CONFIG_H -DFEAT_GUI_GTK -pthread -I/usr/local/include -I/usr/include/gtk-2.0 -I/usr/lib64/gtk-2.0/include -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/libdrm -I/usr/include/libpng16 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/freetype2 -g -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 \nLinkuji: gcc -L/usr/local/lib -Wl,--as-needed -o vim -lgtk-x11-2.0 -lgdk-x11-2.0 -lpangocairo-1.0 -latk-1.0 -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lpangoft2-1.0 -lpango-1.0 -lgobject-2.0 -lglib-2.0 -lfontconfig -lfreetype -lSM -lICE -lXpm -lXt -lX11 -lXdmcp -lSM -lICE -lm -ltinfo -lelf -ldl "

got, err := ParseVimVersion([]byte(input))
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
want := "v8.1.1518"
if got != want {
t.Fatalf("unexpected version: want %v, got %v", want, got)
}
}

0 comments on commit 24030b4

Please sign in to comment.