Skip to content

Commit

Permalink
cmd/govim: remove internal buffer on BufWipeout (#1037)
Browse files Browse the repository at this point in the history
There are cases where we might get a BufWipeout autocmd without the
BufDelete (most notably when running :vimgrep). When that happen we kept
the internal buffer in govim even if we had no use of it anymore.

When using :bwipe we do get both BufDelete and BufWipeout, but as far as
we know BufDelete will always appear before BufWipeout. Trying to remove
an internal buffer due to BufWipeout will not cause an error.

Fixes #1033
  • Loading branch information
leitzler committed Feb 9, 2021
1 parent 2d95013 commit cec2a53
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 7 deletions.
25 changes: 19 additions & 6 deletions cmd/govim/buffer_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,35 +214,48 @@ func (v *vimstate) handleBufferEvent(b *types.Buffer) error {
return err
}

func (v *vimstate) deleteCurrentBuffer(args ...json.RawMessage) error {
func (v *vimstate) bufDelete(args ...json.RawMessage) error {
currBufNr := v.ParseInt(args[0])
cb, ok := v.buffers[currBufNr]
if !ok {
return fmt.Errorf("tried to remove buffer %v; but we have no record of it", currBufNr)
}

return v.deleteBuffer(cb)
}

func (v *vimstate) bufWipeout(args ...json.RawMessage) error {
currBufNr := v.ParseInt(args[0])

if v.vimgrepPendingBufs != nil {
delete(v.vimgrepPendingBufs, currBufNr)
}

if cb, ok := v.buffers[currBufNr]; ok {
return v.deleteBuffer(cb)
}
return nil
}

func (v *vimstate) deleteBuffer(b *types.Buffer) error {
// The diagnosticsCache is updated with -1 (unknown buffer) as bufnr.
// We don't want to remove the entries completely here since we want to show them in
// the quickfix window. And we don't need to remove existing signs or text properties
// either here since they are removed by vim automatically when a buffer is deleted.
diags := *v.diagnosticsCache
for i, d := range diags {
if d.Buf == currBufNr {
if d.Buf == b.Num {
diags[i].Buf = -1
}
}

v.ChannelCall("listener_remove", cb.Listener)
delete(v.buffers, cb.Num)
v.ChannelCall("listener_remove", b.Listener)
delete(v.buffers, b.Num)
params := &protocol.DidCloseTextDocumentParams{
TextDocument: cb.ToTextDocumentIdentifier(),
TextDocument: b.ToTextDocumentIdentifier(),
}
if err := v.server.DidClose(context.Background(), params); err != nil {
return fmt.Errorf("failed to call gopls.DidClose on %v: %v", cb.Name, err)
return fmt.Errorf("failed to call gopls.DidClose on %v: %v", b.Name, err)
}
return nil
}
Expand Down
3 changes: 2 additions & 1 deletion cmd/govim/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,8 @@ func (g *govimplugin) Init(gg govim.Govim, errCh chan error) error {
g.DefineCommand(string(config.CommandSuggestedFixes), g.vimstate.suggestFixes, govim.NArgsZeroOrOne)
g.DefineCommand(string(config.CommandGoToPrevDef), g.vimstate.gotoPrevDef, govim.NArgsZeroOrOne, govim.CountN(1))
g.DefineFunction(string(config.FunctionHover), []string{}, g.vimstate.hover)
g.DefineAutoCommand("", govim.Events{govim.EventBufDelete}, govim.Patterns{"*.go", "go.mod", "go.sum"}, false, g.vimstate.deleteCurrentBuffer, "eval(expand('<abuf>'))")
g.DefineAutoCommand("", govim.Events{govim.EventBufDelete}, govim.Patterns{"*.go", "go.mod", "go.sum"}, false, g.vimstate.bufDelete, "eval(expand('<abuf>'))")
g.DefineAutoCommand("", govim.Events{govim.EventBufWipeout}, govim.Patterns{"*.go", "go.mod", "go.sum"}, false, g.vimstate.bufWipeout, "eval(expand('<abuf>'))")
g.DefineCommand(string(config.CommandGoFmt), g.vimstate.gofmtCurrentBufferRange)
g.DefineCommand(string(config.CommandGoImports), g.vimstate.goimportsCurrentBufferRange)
g.DefineCommand(string(config.CommandQuickfixDiagnostics), g.vimstate.quickfixDiagnostics)
Expand Down

0 comments on commit cec2a53

Please sign in to comment.