mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-19 23:37:13 +09:00
Autoformatting
This commit is contained in:
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/zyedidia/micro/v2/internal/shell"
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
"github.com/zyedidia/tcell"
|
||||
"go.lsp.dev/protocol"
|
||||
)
|
||||
|
||||
// ScrollUp is not an action
|
||||
@@ -1815,6 +1816,9 @@ func (h *BufPane) RemoveAllMultiCursors() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// SemanticInfo returns information about the identifier the cursor is on and
|
||||
// displays the information in the infobar
|
||||
// The information is fetched using the LSP server (must be enabled)
|
||||
func (h *BufPane) SemanticInfo() bool {
|
||||
info, err := h.Buf.Server.Hover(h.Buf.AbsPath, lsp.Position(h.Cursor.X, h.Cursor.Y))
|
||||
|
||||
@@ -1829,6 +1833,24 @@ func (h *BufPane) SemanticInfo() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// AutoFormat automatically formats the document using LSP
|
||||
func (h *BufPane) AutoFormat() bool {
|
||||
edits, err := h.Buf.Server.DocumentFormat(h.Buf.AbsPath, protocol.FormattingOptions{
|
||||
InsertSpaces: h.Buf.Settings["tabstospaces"].(bool),
|
||||
TabSize: h.Buf.Settings["tabsize"].(float64),
|
||||
})
|
||||
if err != nil {
|
||||
InfoBar.Error(err)
|
||||
return false
|
||||
}
|
||||
|
||||
for _, e := range edits {
|
||||
h.Buf.ApplyEdit(e)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// None is an action that does nothing
|
||||
func (h *BufPane) None() bool {
|
||||
return true
|
||||
|
||||
@@ -689,6 +689,7 @@ var BufKeyActions = map[string]BufKeyAction{
|
||||
"Deselect": (*BufPane).Deselect,
|
||||
"ClearInfo": (*BufPane).ClearInfo,
|
||||
"SemanticInfo": (*BufPane).SemanticInfo,
|
||||
"AutoFormat": (*BufPane).AutoFormat,
|
||||
"None": (*BufPane).None,
|
||||
|
||||
// This was changed to InsertNewline but I don't want to break backwards compatibility
|
||||
|
||||
@@ -419,7 +419,8 @@ func (b *Buffer) lspInit() {
|
||||
var err error
|
||||
b.Server, err = lsp.StartServer(l)
|
||||
if err == nil {
|
||||
b.Server.Initialize(gopath.Dir(b.AbsPath))
|
||||
d, _ := os.Getwd()
|
||||
b.Server.Initialize(d)
|
||||
}
|
||||
}
|
||||
if b.HasLSP() {
|
||||
@@ -505,6 +506,17 @@ func (b *Buffer) Remove(start, end Loc) {
|
||||
}
|
||||
}
|
||||
|
||||
// ApplyEdit performs a LSP text edit on the buffer
|
||||
func (b *Buffer) ApplyEdit(e lspt.TextEdit) {
|
||||
if len(e.NewText) == 0 {
|
||||
// deletion
|
||||
b.Remove(toLoc(e.Range.Start), toLoc(e.Range.End))
|
||||
} else {
|
||||
// insertion
|
||||
b.Insert(toLoc(e.Range.Start), e.NewText)
|
||||
}
|
||||
}
|
||||
|
||||
// FileType returns the buffer's filetype
|
||||
func (b *Buffer) FileType() string {
|
||||
return b.Settings["filetype"].(string)
|
||||
|
||||
@@ -2,6 +2,7 @@ package buffer
|
||||
|
||||
import (
|
||||
"github.com/zyedidia/micro/v2/internal/util"
|
||||
"go.lsp.dev/protocol"
|
||||
)
|
||||
|
||||
// Loc stores a location
|
||||
@@ -146,3 +147,10 @@ func clamp(pos Loc, la *LineArray) Loc {
|
||||
}
|
||||
return pos
|
||||
}
|
||||
|
||||
func toLoc(r protocol.Position) Loc {
|
||||
return Loc{
|
||||
X: int(r.Character),
|
||||
Y: int(r.Line),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,12 +13,24 @@ type RPCCompletion struct {
|
||||
Result lsp.CompletionList `json:"result"`
|
||||
}
|
||||
|
||||
type RPCCompletionAlternate struct {
|
||||
RPCVersion string `json:"jsonrpc"`
|
||||
ID int `json:"id"`
|
||||
Result []lsp.CompletionItem `json:"result"`
|
||||
}
|
||||
|
||||
type RPCHover struct {
|
||||
RPCVersion string `json:"jsonrpc"`
|
||||
ID int `json:"id"`
|
||||
Result lsp.Hover `json:"result"`
|
||||
}
|
||||
|
||||
type RPCFormat struct {
|
||||
RPCVersion string `json:"jsonrpc"`
|
||||
ID int `json:"id"`
|
||||
Result []lsp.TextEdit `json:"result"`
|
||||
}
|
||||
|
||||
type hoverAlternate struct {
|
||||
// Contents is the hover's content
|
||||
Contents []interface{} `json:"contents"`
|
||||
@@ -41,8 +53,28 @@ func Position(x, y int) lsp.Position {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) DocumentFormat() {
|
||||
func (s *Server) DocumentFormat(filename string, options lsp.FormattingOptions) ([]lsp.TextEdit, error) {
|
||||
doc := lsp.TextDocumentIdentifier{
|
||||
URI: uri.File(filename),
|
||||
}
|
||||
|
||||
params := lsp.DocumentFormattingParams{
|
||||
Options: options,
|
||||
TextDocument: doc,
|
||||
}
|
||||
|
||||
resp, err := s.sendRequest(lsp.MethodTextDocumentFormatting, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var r RPCFormat
|
||||
err = json.Unmarshal(resp, &r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r.Result, nil
|
||||
}
|
||||
|
||||
func (s *Server) DocumentRangeFormat() {
|
||||
@@ -65,18 +97,22 @@ func (s *Server) Completion(filename string, pos lsp.Position) ([]lsp.Completion
|
||||
TextDocumentPositionParams: docpos,
|
||||
Context: &cc,
|
||||
}
|
||||
resp, err := s.sendRequest("textDocument/completion", params)
|
||||
resp, err := s.sendRequest(lsp.MethodTextDocumentCompletion, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var r RPCCompletion
|
||||
err = json.Unmarshal(resp, &r)
|
||||
if err == nil {
|
||||
return r.Result.Items, nil
|
||||
}
|
||||
var ra RPCCompletionAlternate
|
||||
err = json.Unmarshal(resp, &ra)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r.Result.Items, nil
|
||||
return ra.Result, nil
|
||||
}
|
||||
|
||||
func (s *Server) CompletionResolve() {
|
||||
@@ -91,7 +127,7 @@ func (s *Server) Hover(filename string, pos lsp.Position) (string, error) {
|
||||
Position: pos,
|
||||
}
|
||||
|
||||
resp, err := s.sendRequest("textDocument/hover", params)
|
||||
resp, err := s.sendRequest(lsp.MethodTextDocumentHover, params)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package lsp
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
@@ -10,6 +11,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
lsp "go.lsp.dev/protocol"
|
||||
"go.lsp.dev/uri"
|
||||
@@ -263,10 +265,15 @@ func (s *Server) sendRequest(method string, params interface{}) ([]byte, error)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bytes := <-r
|
||||
var bytes []byte
|
||||
select {
|
||||
case bytes = <-r:
|
||||
case <-time.After(5 * time.Second):
|
||||
err = errors.New("Request timed out")
|
||||
}
|
||||
delete(s.responses, id)
|
||||
|
||||
return bytes, nil
|
||||
return bytes, err
|
||||
}
|
||||
|
||||
func (s *Server) sendMessage(m interface{}) error {
|
||||
|
||||
@@ -32,11 +32,11 @@ command = "pyls"
|
||||
install = [["pip", "install", "python-language-server"]]
|
||||
|
||||
[language.c]
|
||||
command = "ccls"
|
||||
command = "clangd"
|
||||
args = []
|
||||
|
||||
[language.cpp]
|
||||
command = "ccls"
|
||||
command = "clangd"
|
||||
args = []
|
||||
|
||||
[language.haskell]
|
||||
|
||||
Reference in New Issue
Block a user