mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-29 06:12:35 +09:00
Hover support
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/zyedidia/micro/v2/internal/buffer"
|
||||
"github.com/zyedidia/micro/v2/internal/clipboard"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/lsp"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/shell"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
@@ -1814,6 +1815,20 @@ func (h *BufPane) RemoveAllMultiCursors() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (h *BufPane) SemanticInfo() bool {
|
||||
info, err := h.Buf.Server.Hover(h.Buf.AbsPath, lsp.Position(h.Cursor.X, h.Cursor.Y))
|
||||
|
||||
if err != nil {
|
||||
InfoBar.Error(err)
|
||||
return false
|
||||
}
|
||||
|
||||
info = strings.Split(info, "\n")[0]
|
||||
|
||||
InfoBar.Message(info)
|
||||
return true
|
||||
}
|
||||
|
||||
// None is an action that does nothing
|
||||
func (h *BufPane) None() bool {
|
||||
return true
|
||||
|
||||
@@ -688,6 +688,7 @@ var BufKeyActions = map[string]BufKeyAction{
|
||||
"JumpLine": (*BufPane).JumpLine,
|
||||
"Deselect": (*BufPane).Deselect,
|
||||
"ClearInfo": (*BufPane).ClearInfo,
|
||||
"SemanticInfo": (*BufPane).SemanticInfo,
|
||||
"None": (*BufPane).None,
|
||||
|
||||
// This was changed to InsertNewline but I don't want to break backwards compatibility
|
||||
|
||||
@@ -72,6 +72,7 @@ var bufdefaults = map[string]string{
|
||||
"Ctrl-w": "NextSplit",
|
||||
"Ctrl-u": "ToggleMacro",
|
||||
"Ctrl-j": "PlayMacro",
|
||||
"Alt-i": "SemanticInfo",
|
||||
"Insert": "ToggleOverwriteMode",
|
||||
|
||||
// Emacs-style keybindings
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
lspt "github.com/sourcegraph/go-lsp"
|
||||
"github.com/zyedidia/micro/v2/internal/lsp"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
)
|
||||
|
||||
@@ -213,11 +213,8 @@ func LSPComplete(b *Buffer) ([]string, []string) {
|
||||
return []string{}, []string{}
|
||||
}
|
||||
|
||||
pos := lspt.Position{
|
||||
Line: c.Y,
|
||||
Character: c.X,
|
||||
}
|
||||
items, err := b.server.Completion(b.AbsPath, pos)
|
||||
pos := lsp.Position(c.X, c.Y)
|
||||
items, err := b.Server.Completion(b.AbsPath, pos)
|
||||
if err != nil {
|
||||
return []string{}, []string{}
|
||||
}
|
||||
|
||||
@@ -18,13 +18,13 @@ import (
|
||||
"time"
|
||||
|
||||
dmp "github.com/sergi/go-diff/diffmatchpatch"
|
||||
lspt "github.com/sourcegraph/go-lsp"
|
||||
"github.com/zyedidia/micro/v2/internal/config"
|
||||
"github.com/zyedidia/micro/v2/internal/lsp"
|
||||
ulua "github.com/zyedidia/micro/v2/internal/lua"
|
||||
"github.com/zyedidia/micro/v2/internal/screen"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
"github.com/zyedidia/micro/v2/pkg/highlight"
|
||||
lspt "go.lsp.dev/protocol"
|
||||
"golang.org/x/text/encoding/htmlindex"
|
||||
"golang.org/x/text/encoding/unicode"
|
||||
"golang.org/x/text/transform"
|
||||
@@ -126,8 +126,8 @@ type SharedBuffer struct {
|
||||
// Hash of the original buffer -- empty if fastdirty is on
|
||||
origHash [md5.Size]byte
|
||||
|
||||
server *lsp.Server
|
||||
version int
|
||||
Server *lsp.Server
|
||||
version uint64
|
||||
}
|
||||
|
||||
func (b *SharedBuffer) insert(pos Loc, value []byte) {
|
||||
@@ -154,26 +154,20 @@ func (b *SharedBuffer) lspDidChange(start, end Loc, text string) {
|
||||
// TODO: convert to UTF16 codepoints
|
||||
change := lspt.TextDocumentContentChangeEvent{
|
||||
Range: &lspt.Range{
|
||||
Start: lspt.Position{
|
||||
Line: start.Y,
|
||||
Character: start.X,
|
||||
},
|
||||
End: lspt.Position{
|
||||
Line: end.Y,
|
||||
Character: end.X,
|
||||
},
|
||||
Start: lsp.Position(start.X, start.Y),
|
||||
End: lsp.Position(end.X, end.Y),
|
||||
},
|
||||
Text: text,
|
||||
}
|
||||
|
||||
if b.HasLSP() {
|
||||
b.server.DidChange(b.AbsPath, b.version, []lspt.TextDocumentContentChangeEvent{change})
|
||||
b.Server.DidChange(b.AbsPath, &b.version, []lspt.TextDocumentContentChangeEvent{change})
|
||||
}
|
||||
}
|
||||
|
||||
// HasLSP returns whether this buffer is communicating with an LSP server
|
||||
func (b *SharedBuffer) HasLSP() bool {
|
||||
return b.server != nil && b.server.Active
|
||||
return b.Server != nil && b.Server.Active
|
||||
}
|
||||
|
||||
// MarkModified marks the buffer as modified for this frame
|
||||
@@ -420,12 +414,12 @@ func (b *Buffer) lspInit() {
|
||||
ft := b.Settings["filetype"].(string)
|
||||
l, ok := lsp.GetLanguage(ft)
|
||||
if ok && l.Installed() {
|
||||
b.server = lsp.GetServer(l, gopath.Dir(b.AbsPath))
|
||||
if b.server == nil {
|
||||
b.Server = lsp.GetServer(l, gopath.Dir(b.AbsPath))
|
||||
if b.Server == nil {
|
||||
var err error
|
||||
b.server, err = lsp.StartServer(l)
|
||||
b.Server, err = lsp.StartServer(l)
|
||||
if err == nil {
|
||||
b.server.Initialize(gopath.Dir(b.AbsPath))
|
||||
b.Server.Initialize(gopath.Dir(b.AbsPath))
|
||||
}
|
||||
}
|
||||
if b.HasLSP() {
|
||||
@@ -433,7 +427,7 @@ func (b *Buffer) lspInit() {
|
||||
if len(bytes) == 0 {
|
||||
bytes = []byte{'\n'}
|
||||
}
|
||||
b.server.DidOpen(b.AbsPath, ft, string(bytes), b.version)
|
||||
b.Server.DidOpen(b.AbsPath, ft, string(bytes), &b.version)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -464,7 +458,7 @@ func (b *Buffer) Fini() {
|
||||
}
|
||||
|
||||
if b.HasLSP() {
|
||||
b.server.DidClose(b.AbsPath)
|
||||
b.Server.DidClose(b.AbsPath)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -197,7 +197,7 @@ func (b *Buffer) saveToFile(filename string, withSudo bool) error {
|
||||
b.UpdateRules()
|
||||
|
||||
if b.HasLSP() {
|
||||
b.server.DidSave(b.AbsPath)
|
||||
b.Server.DidSave(b.AbsPath)
|
||||
}
|
||||
|
||||
return err
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
package lsp
|
||||
|
||||
import "github.com/sourcegraph/go-lsp"
|
||||
import (
|
||||
lsp "go.lsp.dev/protocol"
|
||||
"go.lsp.dev/uri"
|
||||
)
|
||||
|
||||
func (s *Server) DidOpen(filename, language, text string, version int) {
|
||||
func (s *Server) DidOpen(filename, language, text string, version *uint64) {
|
||||
doc := lsp.TextDocumentItem{
|
||||
URI: lsp.DocumentURI("file://" + filename),
|
||||
LanguageID: language,
|
||||
Version: version,
|
||||
URI: uri.File(filename),
|
||||
LanguageID: lsp.LanguageIdentifier(language),
|
||||
Version: float64(*version), // not sure why this is a float on go.lsp.dev
|
||||
Text: text,
|
||||
}
|
||||
|
||||
@@ -19,7 +22,7 @@ func (s *Server) DidOpen(filename, language, text string, version int) {
|
||||
|
||||
func (s *Server) DidSave(filename string) {
|
||||
doc := lsp.TextDocumentIdentifier{
|
||||
URI: lsp.DocumentURI("file://" + filename),
|
||||
URI: uri.File(filename),
|
||||
}
|
||||
|
||||
params := lsp.DidSaveTextDocumentParams{
|
||||
@@ -28,10 +31,10 @@ func (s *Server) DidSave(filename string) {
|
||||
go s.sendNotification("textDocument/didSave", params)
|
||||
}
|
||||
|
||||
func (s *Server) DidChange(filename string, version int, changes []lsp.TextDocumentContentChangeEvent) {
|
||||
func (s *Server) DidChange(filename string, version *uint64, changes []lsp.TextDocumentContentChangeEvent) {
|
||||
doc := lsp.VersionedTextDocumentIdentifier{
|
||||
TextDocumentIdentifier: lsp.TextDocumentIdentifier{
|
||||
URI: lsp.DocumentURI("file://" + filename),
|
||||
URI: uri.File(filename),
|
||||
},
|
||||
Version: version,
|
||||
}
|
||||
@@ -45,7 +48,7 @@ func (s *Server) DidChange(filename string, version int, changes []lsp.TextDocum
|
||||
|
||||
func (s *Server) DidClose(filename string) {
|
||||
doc := lsp.TextDocumentIdentifier{
|
||||
URI: lsp.DocumentURI("file://" + filename),
|
||||
URI: uri.File(filename),
|
||||
}
|
||||
|
||||
params := lsp.DidCloseTextDocumentParams{
|
||||
|
||||
@@ -3,7 +3,8 @@ package lsp
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/sourcegraph/go-lsp"
|
||||
lsp "go.lsp.dev/protocol"
|
||||
"go.lsp.dev/uri"
|
||||
)
|
||||
|
||||
type RPCCompletion struct {
|
||||
@@ -12,6 +13,19 @@ type RPCCompletion struct {
|
||||
Result lsp.CompletionList `json:"result"`
|
||||
}
|
||||
|
||||
type RPCHover struct {
|
||||
RPCVersion string `json:"jsonrpc"`
|
||||
ID int `json:"id"`
|
||||
Result lsp.Hover `json:"result"`
|
||||
}
|
||||
|
||||
func Position(x, y int) lsp.Position {
|
||||
return lsp.Position{
|
||||
Line: float64(y),
|
||||
Character: float64(x),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) DocumentFormat() {
|
||||
|
||||
}
|
||||
@@ -22,19 +36,19 @@ func (s *Server) DocumentRangeFormat() {
|
||||
|
||||
func (s *Server) Completion(filename string, pos lsp.Position) ([]lsp.CompletionItem, error) {
|
||||
cc := lsp.CompletionContext{
|
||||
TriggerKind: lsp.CTKInvoked,
|
||||
TriggerKind: lsp.Invoked,
|
||||
}
|
||||
|
||||
docpos := lsp.TextDocumentPositionParams{
|
||||
TextDocument: lsp.TextDocumentIdentifier{
|
||||
URI: lsp.DocumentURI("file://" + filename),
|
||||
URI: uri.File(filename),
|
||||
},
|
||||
Position: pos,
|
||||
}
|
||||
|
||||
params := lsp.CompletionParams{
|
||||
TextDocumentPositionParams: docpos,
|
||||
Context: cc,
|
||||
Context: &cc,
|
||||
}
|
||||
resp, err := s.sendRequest("textDocument/completion", params)
|
||||
if err != nil {
|
||||
@@ -53,3 +67,25 @@ func (s *Server) Completion(filename string, pos lsp.Position) ([]lsp.Completion
|
||||
func (s *Server) CompletionResolve() {
|
||||
|
||||
}
|
||||
|
||||
func (s *Server) Hover(filename string, pos lsp.Position) (string, error) {
|
||||
params := lsp.TextDocumentPositionParams{
|
||||
TextDocument: lsp.TextDocumentIdentifier{
|
||||
URI: uri.File(filename),
|
||||
},
|
||||
Position: pos,
|
||||
}
|
||||
|
||||
resp, err := s.sendRequest("textDocument/hover", params)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var r RPCHover
|
||||
err = json.Unmarshal(resp, &r)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return r.Result.Contents.Value, nil
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/sourcegraph/go-lsp"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
lsp "go.lsp.dev/protocol"
|
||||
"go.lsp.dev/uri"
|
||||
)
|
||||
|
||||
var activeServers map[string]*Server
|
||||
@@ -102,56 +102,36 @@ func StartServer(l Language) (*Server, error) {
|
||||
// The directory must be an absolute path
|
||||
func (s *Server) Initialize(directory string) {
|
||||
params := lsp.InitializeParams{
|
||||
ProcessID: os.Getpid(),
|
||||
RootURI: lsp.DocumentURI("file://" + directory),
|
||||
ClientInfo: lsp.ClientInfo{
|
||||
Name: "micro",
|
||||
Version: util.Version,
|
||||
},
|
||||
Trace: "off",
|
||||
ProcessID: float64(os.Getpid()),
|
||||
RootURI: uri.File(directory),
|
||||
Capabilities: lsp.ClientCapabilities{
|
||||
Workspace: lsp.WorkspaceClientCapabilities{
|
||||
WorkspaceEdit: struct {
|
||||
DocumentChanges bool `json:"documentChanges,omitempty"`
|
||||
ResourceOperations []string `json:"resourceOperations,omitempty"`
|
||||
}{
|
||||
Workspace: &lsp.WorkspaceClientCapabilities{
|
||||
WorkspaceEdit: &lsp.WorkspaceClientCapabilitiesWorkspaceEdit{
|
||||
DocumentChanges: true,
|
||||
ResourceOperations: []string{"create", "rename", "delete"},
|
||||
},
|
||||
ApplyEdit: true,
|
||||
},
|
||||
TextDocument: lsp.TextDocumentClientCapabilities{
|
||||
Formatting: &struct {
|
||||
DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
|
||||
}{
|
||||
DynamicRegistration: true,
|
||||
TextDocument: &lsp.TextDocumentClientCapabilities{
|
||||
Formatting: &lsp.TextDocumentClientCapabilitiesFormatting{
|
||||
DynamicRegistration: false,
|
||||
},
|
||||
Completion: struct {
|
||||
CompletionItem struct {
|
||||
DocumentationFormat []lsp.DocumentationFormat `json:"documentationFormat,omitempty"`
|
||||
SnippetSupport bool `json:"snippetSupport,omitempty"`
|
||||
} `json:"completionItem,omitempty"`
|
||||
|
||||
CompletionItemKind struct {
|
||||
ValueSet []lsp.CompletionItemKind `json:"valueSet,omitempty"`
|
||||
} `json:"completionItemKind,omitempty"`
|
||||
|
||||
ContextSupport bool `json:"contextSupport,omitempty"`
|
||||
}{
|
||||
CompletionItem: struct {
|
||||
DocumentationFormat []lsp.DocumentationFormat `json:"documentationFormat,omitempty"`
|
||||
SnippetSupport bool `json:"snippetSupport,omitempty"`
|
||||
}{
|
||||
DocumentationFormat: []lsp.DocumentationFormat{lsp.DFPlainText},
|
||||
SnippetSupport: false,
|
||||
Completion: &lsp.TextDocumentClientCapabilitiesCompletion{
|
||||
DynamicRegistration: false,
|
||||
CompletionItem: &lsp.TextDocumentClientCapabilitiesCompletionItem{
|
||||
SnippetSupport: false,
|
||||
CommitCharactersSupport: false,
|
||||
DocumentationFormat: []lsp.MarkupKind{lsp.PlainText},
|
||||
DeprecatedSupport: false,
|
||||
PreselectSupport: false,
|
||||
},
|
||||
ContextSupport: false,
|
||||
},
|
||||
Hover: &lsp.TextDocumentClientCapabilitiesHover{
|
||||
DynamicRegistration: false,
|
||||
ContentFormat: []lsp.MarkupKind{lsp.PlainText},
|
||||
},
|
||||
},
|
||||
Window: lsp.WindowClientCapabilities{
|
||||
WorkDoneProgress: false,
|
||||
},
|
||||
Experimental: nil,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user