Giter Club home page Giter Club logo

languageserverprotocol's Introduction

Build Status Platforms Documentation Discord

LanguageServerProtocol

This is a Swift library for interacting with Language Server Protocol. It contains type definitions and utilities useful for both server- and client-side projects.

Need to interact with servers? You may want to take a look at LanguageClient. Want to build a server? Check out LanguageServer.

Typing Approach

Where possible, this library matches the LSP spec. However, there are some additional types present in this library that aren't in the spec. This is caused by the use of anonymous structures.

This library models these cases using nested structures and/or the TwoTypeOption and ThreeTypeOption types.

Integration

dependencies: [
    .package(url: "https://github.com/ChimeHQ/LanguageServerProtocol", from: "0.11.0")
]

Extra Features

For the most part, this library strives to be a straightforward version of the spec in Swift. There are a few places, however, where it just makes sense to pull in some extra functionality.

  • Snippet: makes it easier to interpret the contents of completion results
  • TokenRepresentation: maintains the state of a document's semantic tokens
  • DataChannel.withMessageFraming: wraps an existing JSONRPC DataChannel up with HTTP header-based message framing

If you need to support other communication channels, you'll have to work with the DataChannel type from the JSONRPC package. There are a few specialized ones already defined in LanguageClient.

Client Support

Right now, there are still some bits useful for client support in this library:

  • MockServer: a stand-in that is useful for mocking a real server
  • Server: a protocol that describes the essential server functionality

The intention is to migrate all of these out into LanguageClient, leaving this library purely focused on protocol-level support.

Usage

Responding to Events

You can respond to server events using eventSequence. Be careful here as some servers require responses to certain requests. It is also potentially possible that not all request types have been mapped in the ServerRequest type. The spec is big! If you find a problem, please open an issue!

Task {
    for await event in server.eventSequence {
        print("receieved event:", event)
        
        switch event {
        case let .request(id: id, request: request):
            request.relyWithError(MyError.unsupported)
        default:
            print("dropping notification/error")
        }
    }
}

Supported Features

The LSP specification is large, and this library currently does not implement it all. The intention is to support the 3.x specification, but be as backwards-compatible as possible with pre-3.0 servers.

Message Supported
$/cancelRequest
$/logTrace
$/progress
$/setTrace
callHierarchy/incomingCalls
callHierarchy/outgoingCalls
client/registerCapability
client/unregisterCapability
codeAction/resolve
codeLens/resolve
completionItem/resolve
documentLink/resolve
exit
initialize
initialized
inlayHint/resolve
notebookDocument/didChange -
notebookDocument/didClose -
notebookDocument/didOpen -
notebookDocument/didSave -
server-defined
shutdown
telemetry/event
textDocument/codeAction
textDocument/codeLens
textDocument/colorPresentation
textDocument/completion
textDocument/declaration
textDocument/definition
textDocument/diagnostic
textDocument/didChange
textDocument/didClose
textDocument/didOpen
textDocument/didSave
textDocument/documentColor
textDocument/documentHighlight
textDocument/documentLink
textDocument/documentSymbol
textDocument/foldingRange
textDocument/formatting
textDocument/hover
textDocument/implementation
textDocument/inlayHint
textDocument/inlineValue -
textDocument/linkedEditingRange
textDocument/moniker
textDocument/onTypeFormatting
textDocument/prepareCallHierarchy
textDocument/prepareRename
textDocument/prepareTypeHierarchy
textDocument/publishDiagnostics
textDocument/rangeFormatting
textDocument/references
textDocument/rename
textDocument/selectionRange
textDocument/semanticTokens/full
textDocument/semanticTokens/full/delta
textDocument/semanticTokens/range
textDocument/signatureHelp
textDocument/typeDefinition
textDocument/willSave
textDocument/willSaveWaitUntil
typeHierarchy/subtypes -
typeHierarchy/supertypes -
window/logMessage
window/showDocument
window/showMessage
window/showMessageRequest
window/workDoneProgress/cancel
window/workDoneProgress/create
workspace/applyEdit
workspace/codeLens/refresh
workspace/configuration
workspace/diagnostic -
workspace/diagnostic/refresh -
workspace/didChangeConfiguration
workspace/didChangeWatchedFiles
workspace/didChangeWorkspaceFolders
workspace/didCreateFiles
workspace/didDeleteFiles
workspace/didRenameFiles
workspace/executeCommand
workspace/inlayHint/refresh
workspace/inlineValue/refresh -
workspace/semanticTokens/refresh
workspace/symbol
workspace/willCreateFiles
workspace/willDeleteFiles
workspace/willRenameFiles
workspace/workspaceFolders
workspaceSymbol/resolve

Contributing and Collaboration

I would love to hear from you! Issues or pull requests work great. A Discord server is also available for live help, but I have a strong bias towards answering in the form of documentation.

I prefer collaboration, and would love to find ways to work together if you have a similar project.

I prefer indentation with tabs for improved accessibility. But, I'd rather you use the system you want and make a PR than hesitate because of whitespace.

By participating in this project you agree to abide by the Contributor Code of Conduct.

languageserverprotocol's People

Contributors

fastestmolasses avatar koliyo avatar lukas-stuehrk avatar mattmassicotte avatar mchakravarty avatar mingyoung avatar qmoya avatar rex4539 avatar wouter01 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

Watchers

 avatar  avatar  avatar  avatar

languageserverprotocol's Issues

Expand method testing

To start, a test that exercises a specific feature, including parameter serialization and result deserialization.

Serverside LSP development: Proof-of-concept and discussion

Hi!

I am trying to implement a LSP server backend using this library, and I would like to discuss some potential changes to support this goal.

First of all, thank you for your work on this library! There is a lot of great functionality here for LSP work in Swift.

Secondly, this is my first swift project, so I may be doing somethings that are not considered idiomatic Swift coding.

Ok, to summarize, I am building a LSP server with Swift, and this library looked like the perfect foundation to use.

The main problem, which I did not immediately realize, is that this project only seems to have been used for client-side LSP development, and this makes sense given your connection with the Chime editor, which i noticed you are building.

There are definitely lots of common LSP functionality that is useful for both clientside and serverside development, as the readme says. But I was a little confused that the Server protocol is not used for server development, but rather on the client side. It does makes sense from the client context, as the Server instances represent the RPC-backend.

I have implemented the corresponding protocols and dispatch mechanisms for the other side of the protocol, the actual LSP backend. And from your current naming, this new addition should then be called Client ?

That kind of makes sense, but it is a bit confusing at the same time.

I would like some discussion on what possible alternatives are available. For example in gRPC, they use FooServicer and FooStub, where Servicer is the server implementation side, and Stub is the client. Not sure if this is the best approach though.

Anyway what I have done at this point is to fork this library, and split the library into three parts:

  • LanguageServerProtocol
    • Common protocol code
  • LanguageServerProtocol-Client
    • Client side functionality to communicate with existing LSP servers
  • LanguageServerProtocol-Server
    • Functionality to build LSP server backends

And currently, I use the exact same names on the serverside, to me it made more sense to use Server terminology on the server side. So now there are two Server protocols, but in different packages/namespaces. Not completely satisfied with my current approach either :)

Here is an overview of what I have done:

  • Add server backend building blocks
  • Split the libarary into client and server parts
  • Implemented a few new data channels that are useful for me, in separate repositories
  • And as part of the above, I have refactored message framing to a generalized wrapper
    • This will work with any DataChannel, so the interfacing data channels does not need to bother with framing semantics
    • This is added to both client and server side: self.session = JSONRPCSession(channel: dataChannel.withMessageFraming())
  • I have added propagation of the RPC response handlers to the serverside LSP protocols. These where not used by the client side code, but are needed for serverside development.
    • Currently I am using a ClientRequest.NullHandler on the client side, where the handler is not used, but enum definitions are common.
    • An alternative would be to split server and client enums, but this would also be a lot of duplication. But I am open for suggestions!
  • On the serverside I made the request response a return value instead of using the handler.
    • I think this makes the API safer, as a missing return value will give compiler errors, while the handler callback can not be checked until runtime, and even then somewhat difficult to trace problems.
  • There are a lot of missing public initializers to create respons messages from an external library
    • I have added the initilaizers I currently need, but this should be more exhaustive to support general LSP backend development.
  • Made some naming refactorings to be more consistent with the protocol specifications
    • Eg DidCloseTextDocumentParams -> TextDocumentDidCloseParams
    • One potential problem with this is breaking backward compability
    • The existing code was however a bit inconsistent, both internally and also wrt the spec
  • Introduce logging dependency
    • Since common use case is to use stdio pipe as a transport mechanism it is important to not print non-protocol message to stdout in that context
  • This work with LSP is also the reason for the previous issue regarding RPC ordering of requests and notifications

This is certainly a lot at once. Currently I have forks to support my needs, but my hope is that we together can come up with a plan on how we can bring server side LSP development into this library, which definitely could be useful to other people?

The current state of my things is a kind of WIP.

My LanguageServerProtocol fork is here: https://github.com/koliyo/LanguageServerProtocol
And I have also some corresponding changes in LanguageClient: https://github.com/koliyo/LanguageClient

I would appreciate if you could a look at the overall changes, and give some thoughts on this.

To reiterate, the goal here for me is that LanguageServerProtocol should support building LSP server backends with the same kind of abstractions as the client side.

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.