Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions cmd/langserver-vim/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package main

import (
"context"
"log"
"os"

"github.com/haya14busa/go-vimlparser/langserver"
"github.com/sourcegraph/jsonrpc2"
)

func main() {
log.Println("langserver-vim: reading on stdin, writing on stdout")
var connOpt []jsonrpc2.ConnOpt
<-jsonrpc2.NewConn(context.Background(), jsonrpc2.NewBufferedStream(stdrwc{}, jsonrpc2.VSCodeObjectCodec{}), langserver.NewHandler(), connOpt...).DisconnectNotify()
log.Println("langserver-vim: connections closed")
}

type stdrwc struct{}

func (stdrwc) Read(p []byte) (int, error) {
return os.Stdin.Read(p)
}

func (stdrwc) Write(p []byte) (int, error) {
return os.Stdout.Write(p)
}

func (stdrwc) Close() error {
if err := os.Stdin.Close(); err != nil {
return err
}
return os.Stdout.Close()
}
26 changes: 26 additions & 0 deletions langserver/handle_initialize.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package langserver

import (
"context"
"encoding/json"

"github.com/sourcegraph/jsonrpc2"
)

func (h *LangHandler) handleInitialize(ctx context.Context, conn *jsonrpc2.Conn, req *jsonrpc2.Request) (result interface{}, err error) {
if req.Params == nil {
return nil, &jsonrpc2.Error{Code: jsonrpc2.CodeInvalidParams}
}

var params InitializeParams
if err := json.Unmarshal(*req.Params, &params); err != nil {
return nil, err
}

return InitializeResult{
Capabilities: ServerCapabilities{
TextDocumentSync: TDSKFull,
DocumentSymbolProvider: true,
},
}, nil
}
26 changes: 26 additions & 0 deletions langserver/handle_text_document_did_open.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package langserver

import (
"context"
"encoding/json"

"github.com/sourcegraph/jsonrpc2"
)

func (h *LangHandler) handleTextDocumentDidOpen(ctx context.Context, conn *jsonrpc2.Conn, req *jsonrpc2.Request) (result interface{}, err error) {
if req.Params == nil {
return nil, &jsonrpc2.Error{Code: jsonrpc2.CodeInvalidParams}
}

var params DidOpenTextDocumentParams
if err := json.Unmarshal(*req.Params, &params); err != nil {
return nil, err
}

f, err := newVimFile(params.TextDocument)
if err != nil {
return nil, err
}
h.files[params.TextDocument.URI] = f
return nil, nil
}
72 changes: 72 additions & 0 deletions langserver/handle_text_document_symbol.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package langserver

import (
"context"
"encoding/json"
"fmt"

"github.com/haya14busa/go-vimlparser/ast"

"github.com/sourcegraph/jsonrpc2"
)

func (h *LangHandler) handleTextDocumentSymbols(ctx context.Context, conn *jsonrpc2.Conn, req *jsonrpc2.Request) (result interface{}, err error) {
if req.Params == nil {
return nil, &jsonrpc2.Error{Code: jsonrpc2.CodeInvalidParams}
}

var params DocumentSymbolParams
if err := json.Unmarshal(*req.Params, &params); err != nil {
return nil, err
}

if f, ok := h.files[params.TextDocument.URI]; ok {
node, err := f.GetAst()
if err != nil {
return nil, err
}
return getDocumentSymbols(params, node), nil
}
return nil, fmt.Errorf("%s not open", params.TextDocument.URI)
}

func getDocumentSymbols(params DocumentSymbolParams, node ast.Node) []SymbolInformation {
var symbols []SymbolInformation
ast.Inspect(node, func(n ast.Node) bool {
var name string
var kind SymbolKind
var pos ast.Pos
switch x := n.(type) {
case *ast.Function:
switch y := x.Name.(type) {
case *ast.Ident:
kind = SKFunction
name = y.Name
pos = y.NamePos
}

if name != "" {
symbols = append(symbols, SymbolInformation{
Name: name,
Kind: kind,
Location: Location{
URI: params.TextDocument.URI,
Range: Range{
Start: Position{
Line: pos.Line - 1,
Character: pos.Column - 1,
},
End: Position{
Line: pos.Line - 1,
Character: pos.Column + len(name) - 1,
},
},
},
})
return false
}
}
return true
})
return symbols
}
65 changes: 65 additions & 0 deletions langserver/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package langserver

import (
"bytes"
"context"
"fmt"

"github.com/haya14busa/go-vimlparser"
"github.com/haya14busa/go-vimlparser/ast"

"github.com/sourcegraph/jsonrpc2"
)

func NewHandler() jsonrpc2.Handler {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported function NewHandler should have comment or be unexported

var langHandler = &LangHandler{
files: make(map[string]*vimfile),
}
return jsonrpc2.HandlerWithError(langHandler.handle)
}

type LangHandler struct {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported type LangHandler should have comment or be unexported

files map[string]*vimfile
}

type vimfile struct {
TextDocumentItem
Ast *ast.File
AstError error
}

func newVimFile(textDocumentItem TextDocumentItem) (result *vimfile, error error) {
return &vimfile{
TextDocumentItem: textDocumentItem,
Ast: nil,
AstError: nil,
}, nil
}

func (f *vimfile) GetAst() (result *ast.File, error error) {
if f.AstError != nil {
return nil, f.AstError
} else if f.Ast != nil {
return f.Ast, nil
} else {
opt := &vimlparser.ParseOption{Neovim: false}
r := bytes.NewBufferString(f.Text)
ast, err := vimlparser.ParseFile(r, f.URI, opt)
f.Ast = ast
f.AstError = err
return ast, err
}
}

func (h *LangHandler) handle(ctx context.Context, conn *jsonrpc2.Conn, req *jsonrpc2.Request) (result interface{}, err error) {
switch req.Method {
case "initialize":
return h.handleInitialize(ctx, conn, req)
case "textDocument/didOpen":
return h.handleTextDocumentDidOpen(ctx, conn, req)
case "textDocument/documentSymbol":
return h.handleTextDocumentSymbols(ctx, conn, req)
}

return nil, &jsonrpc2.Error{Code: jsonrpc2.CodeMethodNotFound, Message: fmt.Sprintf("method not supported: %s", req.Method)}
}
95 changes: 95 additions & 0 deletions langserver/lsp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package langserver

type InitializeParams struct {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported type InitializeParams should have comment or be unexported

ProcessID int `json:"processId,omitempty"`
RootPath string `json:"rootPath,omitempty"`
InitializationOptions InitializeOptions `json:"initializationOptions,omitempty"`
Capabilities ClientCapabilities `json:"capabilities,omitempty"`
Trace string `json:"trace,omitempty"`
}

type InitializeOptions struct {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported type InitializeOptions should have comment or be unexported

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported type InitializeOptions should have comment or be unexported

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported type InitializeOptions should have comment or be unexported

}

type ClientCapabilities struct {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported type ClientCapabilities should have comment or be unexported

}

type InitializeResult struct {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported type InitializeResult should have comment or be unexported

Capabilities ServerCapabilities `json:"capabilities,omitempty"`
}

type TextDocumentSyncKind int
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported type TextDocumentSyncKind should have comment or be unexported


const (
TDSKNone TextDocumentSyncKind = 0
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported const TDSKNone should have comment (or a comment on this block) or be unexported

TDSKFull = 1
TDSKIncremental = 2
)

type ServerCapabilities struct {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported type ServerCapabilities should have comment or be unexported

TextDocumentSync TextDocumentSyncKind `json:"textDocumentSync,omitempty"`
DocumentSymbolProvider bool `json:"documentSymbolProvider,omitempty"`
}

type TextDocumentItem struct {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported type TextDocumentItem should have comment or be unexported

URI string `json:"uri"`
LanguageID string `json:"languageId"`
Version int `json:"version"`
Text string `json:"text"`
}

type TextDocumentIdentifier struct {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported type TextDocumentIdentifier should have comment or be unexported

URI string `json:"uri"`
}

type DidOpenTextDocumentParams struct {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported type DidOpenTextDocumentParams should have comment or be unexported

TextDocument TextDocumentItem `json:"textDocument"`
}

type DocumentSymbolParams struct {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported type DocumentSymbolParams should have comment or be unexported

TextDocument TextDocumentIdentifier
}

type SymbolKind int
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported type SymbolKind should have comment or be unexported


const (
SKFile SymbolKind = 1
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported const SKFile should have comment (or a comment on this block) or be unexported

SKModule SymbolKind = 2
SKNamespace SymbolKind = 3
SKPackage SymbolKind = 4
SKClass SymbolKind = 5
SKMethod SymbolKind = 6
SKProperty SymbolKind = 7
SKField SymbolKind = 8
SKConstructor SymbolKind = 9
SKEnum SymbolKind = 10
SKInterface SymbolKind = 11
SKFunction SymbolKind = 12
SKVariable SymbolKind = 13
SKConstant SymbolKind = 14
SKString SymbolKind = 15
SKNumber SymbolKind = 16
SKBoolean SymbolKind = 17
SKArray SymbolKind = 18
)

type SymbolInformation struct {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported type SymbolInformation should have comment or be unexported

Name string `json:"name"`
Kind SymbolKind `json:"kind"`
Location Location `json:"location"`
}

type Location struct {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported type Location should have comment or be unexported

URI string `json:"uri"`
Range Range `json:"range"`
}

type Range struct {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported type Range should have comment or be unexported

Start Position `json:"start"`
End Position `json:"end"`
}

type Position struct {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[golint] reported by reviewdog 🐶
exported type Position should have comment or be unexported

Line int `json:"line"`
Character int `json:"character"`
}