Giter VIP home page Giter VIP logo

vim-lsc's Introduction

Vim Language Server Client

Adds language-aware tooling to vim by communicating with a language server following the language server protocol. For more information see langserver.org.

Installation

Install with your plugin management method of choice. If you don't have a preference check out vim-plug. Install a language server and ensure it is executable from your $PATH.

vim-lsc is compatible with vim 8, and neovim.

Note: When using neovim be sure to use set shortmess-=F to avoid suppressing error messages from this plugin.

Configuration

Map a filetype to the command that starts the language server for that filetype in your vimrc.

let g:lsc_server_commands = {'dart': 'dart_language_server'}

To disable autocomplete in favor of manual completion also add

let g:lsc_enable_autocomplete = v:false

Most interactive features are triggered by commands. You can use g:lsc_auto_map to have them automatically mapped for the buffers which have a language server enabled. You can use the default mappings by setting it to v:true, or specify your own mappings in a dict.

Most keys take strings or lists of strings which are the keys bound to that command in normal mode. The 'ShowHover' key can also be v:true in which case it sets keywordprg instead of a keybind (keywordprg maps K). The 'Completion' key sets a completion function for manual invocation, and should be either 'completefunc' or 'omnifunc' (see :help complete-functions).

" Use all the defaults (recommended):
let g:lsc_auto_map = v:true

" Apply the defaults with a few overrides:
let g:lsc_auto_map = {'defaults': v:true, 'FindReferences': '<leader>r'}

" Setting a value to a blank string leaves that command unmapped:
let g:lsc_auto_map = {'defaults': v:true, 'FindImplementations': ''}

" ... or set only the commands you want mapped without defaults.
" Complete default mappings are:
let g:lsc_auto_map = {
    \ 'GoToDefinition': '<C-]>',
    \ 'GoToDefinitionSplit': ['<C-W>]', '<C-W><C-]>'],
    \ 'FindReferences': 'gr',
    \ 'NextReference': '<C-n>',
    \ 'PreviousReference': '<C-p>',
    \ 'FindImplementations': 'gI',
    \ 'FindCodeActions': 'ga',
    \ 'Rename': 'gR',
    \ 'ShowHover': v:true,
    \ 'DocumentSymbol': 'go',
    \ 'WorkspaceSymbol': 'gS',
    \ 'SignatureHelp': 'gm',
    \ 'Completion': 'completefunc',
    \}

During the initialization call LSP supports a trace argument which configures logging on the server. Set this with g:lsc_trace_level. Valid values are 'off', 'messages', or 'verbose'. Defaults to 'off'.

Features

The protocol does not require that every language server supports every feature so support may vary.

All communication with the server is asynchronous and will not block the editor. For requests that trigger an action the response might be silently ignored if it can no longer be used - you can abort most operations that are too slow by moving the cursor.

The client can be temporarily disabled for a session with LSClientDisable and re-enabled with LSClientEnable. At any time the server can be exited and restarted with LSClientRestartServer - this sends a request for the server to exit rather than kill it's process so a completely unresponsive server should be killed manually instead.

Diagnostics

Errors, warnings, and hints reported by the server are highlighted in the buffer. When the cursor is on a line with a diagnostic the message will be displayed. If there are multiple diagnostics on a line the one closest to the cursor will be displayed.

Diagnostics are also reported in the location list for each window which has the buffer open. Tip: Use :lbefore or :lafter to jump to the next diagnostic before or after the cursor position. If the location list was overwritten it can be restored with :LSCLientWindowDiagnostics.

Run :LSClientAllDiagnostics to populate, and maintain, a list of all diagnostics across the project in the quickfix list.

Autocomplete

When more than 3 word characters or a trigger character are typed a request for autocomplete suggestions is sent to the server. If the server responds before the cursor moves again the options will be provided using vim's built in completion.

Note: By default completeopt includes preview and completion items include documentation in the preview window. Close the window after completion with <c-w><c-z> or disable with set completeopt-=preview. To automatically close the documentation window use the following:

autocmd CompleteDone * silent! pclose

Disable autocomplete with let g:lsc_enable_autocomplete = v:false. A completion function is available at lsc#complete#complete (set to completefunc if applying the default keymap). This is synchronous and has a cap of 5 seconds to wait for the server to respond. It can be used whether autocomplete is enabled or not.

Reference Highlights

If the server supports the textDocument/documentHighlight call references to the element under the cursor throughout the document will be highlighted. Disable with let g:lsc_reference_highlights = v:false or customize the highlighting with the group lscReference. Use <c-n> (:LSClientNextReference) or <c-p> (:LSClientPReviousReference) to jump to other reference to the currently highlighted element.

Jump to definition

While the cursor is on any identifier call LSClientGoToDefinition (<C-]> if using the default mappings) to jump to the location of the definition. If the cursor moves before the server responds the response will be ignored.

Find references

While the cursor is on any identifier call LSClientFindReferences (gr if using the default mappings) to populate the quickfix list with usage locations.

Find implementations

While the cursor is on any identifier call LSClientFindImplementations (gI if using the default mappings) to populate the quickfix list with implementation locations.

Document Symbols

Call LSClientDocumentSymbol (go if using the default mappings) to populate the quickfix list with the locations of all symbols in that document.

Workspace Symbol Search

Call LSClientWorkspaceSymbol with a no arguments, or with a single String argument. (gS if using the default mappings) to query the server for symbols matching a search string. Results will populate the quickfix list.

Hover

While the cursor is on any identifier call LSClientShowHover (K if using the default mappings, bound through keywordprg) to request hover text and show it in a popup or preview window. Override the direction of the split by setting g:lsc_preview_split_direction to either 'below' or 'above'. Quickly close the preview without switching buffers with <c-w><c-z>. See :help preview-window.

Code Actions

Call LSClientFindCodeActions (ga if using the default mappings) to look for code actions available at the cursor location and run one by entering the number of the chosen action.

Signature help

Call LSClientSignatureHelp (gm if using the default mappings) to get help while writing a function call. The currently active parameter is highlighted with the group lscCurrentParameter.

Integrations with other plugins

vim-lsc's People

Contributors

alindeman avatar andymass avatar arp242 avatar bluz71 avatar chaoren avatar ckipp01 avatar dohq avatar duhemm avatar fenuks avatar gokcehan avatar habamax avatar hia3 avatar hrsh7th avatar jinyius avatar jtmcdole avatar leighmcculloch avatar luocm-git avatar madbrain avatar martint17r avatar mvanderkamp avatar natebosch avatar nkanaev avatar olafurpg avatar pawel-slowik avatar reinerh avatar rexroni avatar rganardi avatar rliang avatar thchha avatar xuanduc987 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vim-lsc's Issues

Add LSClientDiagnostics

At a first run should include:

  • What server(s) do we think are running.
  • What was the last ID sent for each server
  • Maybe store sent/received messages? Maybe just requests with no response?

dedup identical diagnostics

This seems to happen especially when the a file repeatedly get's an empty list of diagnostics. The location list is overwritten which makes :lolder harder to use.
It's not clear whether this should be a responsibility of the language server, or if it's OK to keep sending the same list of diagnostics. It may as well be handled in the client anyway.

Should be easy with a deep equality check on the list of diagnostics.

Clear state when restarting language server

If the server crashes (or we exit intentionally?) it will be restarted on the next opened file, but all the state we expect the server to have, such as already opened files, will likely be missing. When starting the server again we need to resend all open files, or somehow know to send them when that file becomes visible.

Support manual omnicomplete completion

It would be awesome to be able to have a setting to allow disabling autocomplete on . and instead support wiring up to manual omni-complete on C-x, C-o.

Poor interaction with Ultisnips

When expanding a snippet the file gets sent to the server and then something causes the tabstop to no longer be selected.

Some possibilities:

  • Highlighting the diagnostic could poke ultisnips in a weird way
  • Could be trying to do autocompletion in the middle of expansion

Error on close

Error detected while processing function <SNR>159_OnVimQuit[2]..lsc#server#kill:
line 3:
E716: Key not present in Dictionary: vim

Support additional per-server configuration

One thing I want to be able to do is specify that a server should start out disabled and only enable it when I need it. I'm finding myself repeatedly commenting and uncommenting a config instead.

Send responses to requests

It's required. Notifications say they "must not send a response back" but it seems that some servers might expect one anyway... Can probably check for the presence of the 'id' field and use that to determine whether to send back an empty response even if the 'method' should be a 'notification' rather than 'request' according to the spec.

While I'm at it may as well change calls and messages to outgoing_requests, responses, and incoming_requests or similar. Not sure if it's worth separating out 'notifications' from 'requests'.

Add some diffing for changes

Sending the entire file on every change is annoying even if the only downside is ugly wirelogs.

There is some low hanging fruit to improve this - if we keep a separate copy of the buffer in memory we should be able to do a straightforward linewise diff:

Find the equal suffix and postfix of the file, consider every line in between changed.

LSC does not encode/decode characters which are not allowed in File URIs

Hello @natebosch ,

Thank you for your plugin!

It would appear that current version of LSC does not encode characters which are not allowed in File URIs.

According to FILE URI requirements:

Characters which are not allowed in URIs, but which are allowed in filenames, must also be percent-encoded. For example, any of "{}`^ " and all control characters. In the example above, the space in the filename is encoded as %20.

For instance, here is a Go To Definition message from VS Code (which does appropriate encoding):

{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"file:///Users/tester/projects/Sforce%20-%20SFDC%20Experiments/SForce%20%28lcs-test%29/src/classes/CompletionTester.cls"},"position":{"line":14,"character":10}}}

and here is the same message from vim LSC:

{"method":"textDocument/definition","jsonrpc":"2.0","id":2,"params":{"textDocument":{"uri":"file:///Users/tester/projects/Sforce - SFDC Experiments/SForce (lcs-test)/src/classes/CompletionTester.cls"},"position":{"character":10,"line":14}}}

In the opposite direction - if server does appropriate URI encoding and returns URI same way as in above VS Code example - vim LSC does not understand returned path.

e.g. example below is understood by VS Code but not understood by vim LSC

{"id":1,"result":[{"uri":"file:///Users/tester/projects/Sforce%20-%20SFDC%20Experiments/SForce%20(lsc-test)/src/classes/CompletionTester.cls","range":{"start":{"line":10,"character":8},"end":{"line":10,"character":18},"offset":{"line":0,"character":0}}}],"jsonrpc":"2.0"}

Add a way to see workspace diagnostics

Currently only can see diagnostics per file, and ignore those for files which aren't open.

Would be nice to populate the quickfix list with all diagnostics.

Highlights get lost when leaving the window to a non-tracked filetype

Highlights are cleared in case the window will be showing an untracked filetype. Without this line it leaves a highlight in some file where it doesn't belong. However this also means if there are multiple windows and we leave by changing windows rather than changing the buffer in a window we lose the highlights when we shouldn't.

Is there a way to tell the difference between changing window (leave highlights) or changing buffer within a window (clear highlights)?

Should highlights always be checked for untracked filetypes?

Investigate allowing TCP connections in as an alternative to pipes

ch_open might let us get a channel without starting a process. If this doesn't cause too much brittleness could make the config a dict and allow specifying servers by host:port. The bit I'm not too sure about is losing out on the info we have about the process lifespan.

Alternatively it might also be possible to avoid changing the viml if we write a thin process to translate in between the server and client.

Show a message if a server call fails

This is related to #41, but in addition to giving feedback when a server crashes, it would be helpful to see if a command failed to execute.

lsc#server#call already returns boolean indicating if a call was successful or not. Yet, none of the call sites propagate this information to the user.

Add utility to set up mappings for tracked filetypes

Would be nice to use <C-]> for jump to definition and K for hover but shouldn't clobber these for other filetypes.

Shouldn't have this on by default but would be easy to opt-in. Could also opt-in to setting completefunc if not using autocomplete.

Will need to find a reasonable default for find references.

Error when changing git branches

Started seeing this.

E121: Undefined variable: b:lsc_flush_timer
E116: Invalid arguments for function timer_stop

I wonder if the act of reloading changed files on disk has started blowing away buffer local variables? In any case should be easy enough to through in a check for undefined.

consider truncating reported errors

I've noticed that my editor slows down dramatically on some scenarios. I believe this is because of the volume of errors I am getting, but I'm not 100% sure.

Sample scenario: open pkg/compiler/lib/src/deferred_load.dart, jump to _mapDependencies, add a function right above it, but do not close the parenthesis of the argument list:

void _newMethod(

This causes a bunch of cascade errors (about 400 errors?) and the editor slows down dramatically.

Possible stack overflow

I've run into some stack overflow errors at times, not sure yet on the possible cause.

I can repro easily in the dart sdk repo, standing on the root, and opening some files under the tests folder.

For example, if I open tests/language/issue4295001_test.dart, I then see this error:

Error detected while processing function lsc#server#channelCallback[3]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMe
ssage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#cons
umeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol
#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#pro
tocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..ls
c#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24
]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessa
ge[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consume
Message[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#co
nsumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protoc
ol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#p
rotocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..
lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[
24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMes
sage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consu
meMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#
consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#prot
ocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc#protocol#consumeMessage[24]..lsc
#protocol#co

Followed by this error:

E132: Function call depth is higher than 'maxfuncdepth'

Don't change highlights while in visual mode

I think this behavior varies depending on the version of vim or some other config. I was not able to repro before, but I can now reliably see it happen.

If the diagnostics get updated while in visual mode you get punted back to normal mode. I think this is due to changing the highlights. I saw the same thing with select mode when using UltiSnips.

cc @sigmundch - I think this explains the issue you were seeing.

Add ability to customize params per request

Some language servers can take advantage of additional metadata on certain calls. Add a hook so that users can customize/override parameters sent on each request.

See discussion at #50

wrong view when doing jump to definition on an already opened file

How to repro:

  • open b.dart
  • put cursor under A
  • jump to definition -> works great!
  • go back (C-O)
  • jump to definition -> cursor is in the right position of the window, but the text is not scrolled to the right place

b.dart:

import 'a.dart';
class B extends A {}

a.dart:

// Note: all these empty lines are on purpose to cause the definition to be further out from the window size














































































class A {}

Doesn't work with rls (Rust Language Server)

Hello

When I try to use vim-lsc with rls (rust language server), I get this error:

Error detected while processing function lsc#server#channelCallback[3]..lsc#protocol#consumeMessage[20]..lsc#dispatch#message:
line    1:
E715: Dictionary required

I think the rls is installed correctly, because it works in neovim with autozimu/LanguageClient-neovim, but I'd actually prefer to use the original vim over neovim. I don't have any other language server installed right now, so I can't check if it is broken with some other one.

How should I debug this further?

Reuse preview window if it's already open

#24 implements hover with a preview window - but it closes and re-splits every time. If the preview window is left open it would be better to reuse it. This is how completion preview windows behave.

Autocomplete is kind of annoying

  1. Tries to complete from normal mode after typing a quick character an then hitting escape. When the results come in the cursor is in the same spot so it does the autocomplete dance and leaves in extra stuff.
  2. Fires way too often. The quick jump to a suggestion and back can eat some typed characters and generally gets in the way.

For 1 should be enough to check the mode before trying to do completion.

For 2 might need some kind of caching or similar.

Edits before initialization can get lost

I think this is something to do with the buffered commands. If an edit is made too quickly during server startup it can get lost and diagnostics won't show up correctly until further changes are made.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.