Code Monkey home page Code Monkey logo

racket-langserver's Introduction

racket-langserver

racket-langserver is a Language Server Protocol implementation for Racket. This project seeks to use DrRacket's public APIs to provide functionality that mimics DrRacket's code tools as closely as possible.

Installation and usage

A Racket runtime is a prerequisite, so before using racket-langserver, ensure that a Racket runtime is installed. You can install an from the official download page or install one from your package manager.

Atom

You can use the atom-ide-racket package. The language server will be automatically installed when atom-ide-racket installs.

VSCode

Use the Magic Racket extension.

Other editors and IDEs

First, install an LSP runtime for your editor.

Next, install the package via raco:

raco pkg install racket-langserver

Once it is installed, you can configure your editor to use a custom LSP client for Racket files (.rkt), and set the command for the custom client to

racket -l racket-langserver

You may need to restart your LSP runtime or your editor for racket-langserver to start.

Capabilities

Currently Supported:

  • Hover (textDocument/hover)
  • Jump to Definition (textDocument/definition)
  • Find References (textDocument/references)
    • Note: Currently only considers references within the current file.
  • Document Highlight (textDocument/documentHighlight)
  • Diagnostics (textDocument/publishDiagnostics)
  • Code Formatting (textDocument/formatting & textDocument/rangeFormatting & textDocument/onTypeFormatting)
  • Code Action (textDocument/codeAction)
  • Signature Help (textDocument/signatureHelp)
  • Rename (textDocument/rename & textDocument/prepareRename)
    • Note: Currently only allows renaming symbols defined within the current file.
  • Code completion (textDocument/completion)

Work in Progress:

  • Document Outline (textDocument/documentSymbol)

Notes for Contributers

It is useful to think of this project as a "headless mode" for DrRacket. Contributions to this project should seek to avoid re-implementing functionality that is already exposed through DrRacket's public API.

Currently, we do not support workspace-wide (or project-wide) methods because the underlying DrRacket code tools only operate on one file at a time. If multi-file code tools are a desirable feature, then they should be considered for inclusion into DrRacket proper before being implemented in this project.

jeapostrophe commented on Apr 29, 2020

I think that the right way to implement most features in Racket-LSP is to find the corresponding feature in DrRacket and then disentangle from DrR's GUI and then expose the feature through the LSP. In many cases, DrR has already been internally organized to do that, but we just haven't done enough spelunking yet.

racket-langserver's People

Contributors

6cdh avatar cfinegan avatar dalev avatar dannypsnl avatar dergemkr avatar jackfirth avatar jeapostrophe avatar jo-sm avatar jryans avatar mlavrent avatar rmculpepper avatar runi-c avatar shhyou avatar shih-liang avatar shocoman avatar spdegabrielle avatar stainlesspot 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

racket-langserver's Issues

Clashes with parinfer?

Hi there, thanks for a great project.

I've hit a situation where the LSP and what I think is parinfer are getting into fights, and this is confusing the LSP. Every few minutes, the LSP seems to lose track of matched parens, and I get errors like the following that won't go away until I restart the LSP:

lsp

As you can see, there are no actual mismatched parens in the buffer. If I attempt to save the buffer in this state, the code is often reformatted very strangely (as if there had been a missing paren) and I have to manually correct everything, restart the LSP, then continue.

Do you have an idea as to what might be happening here? Thank you kindly. 🙏

Error with coc.nvim on windows

I tried to use racket-langserver with coc.nvim, but it doesn't seem to work.
(I'm on windows with racket 8.0)
Log:

Caught exn:
current-load-relative-directory: contract violation
  expected: (or/c (and/c path-string? complete-path?) #f)
  given: #<path:g%3A/Programming/Racket/misc/>
  context...:
   C:\Users\Spore\AppData\Roaming\Racket\8.0\pkgs\racket-langserver\check-syntax.rkt:82:0: check-syntax
   D:\Racket\collects\racket\contract\private\arrow-val-first.rkt:486:18
   C:\Users\Spore\AppData\Roaming\Racket\8.0\pkgs\racket-langserver\text-document.rkt:86:0: did-open!
   D:\Racket\collects\racket\contract\private\arrow-val-first.rkt:486:18
   [repeats 1 more time]
   C:\Users\Spore\AppData\Roaming\Racket\8.0\pkgs\racket-langserver\main.rkt:53:2: consume

Caught exn:
hash-ref: no value found for key
  key: 'file:///g%3A/Programming/Racket/misc/test.rkt
  context...:
   C:\Users\Spore\AppData\Roaming\Racket\8.0\pkgs\racket-langserver\text-document.rkt:102:0: did-change!
   D:\Racket\collects\racket\contract\private\arrow-val-first.rkt:486:18
   [repeats 1 more time]
   C:\Users\Spore\AppData\Roaming\Racket\8.0\pkgs\racket-langserver\main.rkt:53:2: consume

The incorrectly encoded colon (%3A) is suspicious but I couldn't find where it is produced.

PS: Everything works fine for me with VSCode and Magic Racket.

No details for multiple errors in a file

If there are multiple errors with typed racket, the feedback is suboptimal. The current feedback says: "N errors encountered". Each particular diagnostics (In Problems view in VS Code or in Diagnostics window in Atom) is the same: "N errors encountered".

VS Code:
Screenshot 2021-02-14 at 20 11 13

Atom:
Screenshot 2021-02-14 at 20 11 52

DrRacket, however, in this situation is able to display additional controls for navigating between the errors. ("Jump to Error" controls at the bottom).

DrRacket:
Screenshot 2021-02-14 at 20 17 35

A minimal repro I have:

#lang typed/racket
(: list-set (-> (Listof Any) Integer Any (Listof Any)))
(define (list-set lst n x)
  (match lst
    ['() '()]
    [(cons h t) (if (eqv? n 0) (cons x t) (cons h (list-set t (- n 1) x)))]))

(: list-set-t (All (A) (-> (Listof A) Integer Any (Listof A))))
(define (list-set-t lst n x)
  (match lst
    ['() '()]
    [(cons h t) (if (eqv? n 0) (cons x t) (cons h (list-set t (- n 1) x)))]))

When type-checking from command line, it displays two errors:

repro.rkt:12:31: Type Checker: Polymorphic function `cons' could not be applied to arguments:
Types: a (Listof a)  -> (Listof a)
       a b  -> (Pairof a b)
Arguments: Any (Listof A)
Expected result: (Listof A)

  in: (cons x t)
  context...:
   /Applications/Racket_v8.0/share/pkgs/typed-racket-lib/typed-racket/utils/tc-utils.rkt:123:0: report-all-errors
   /Applications/Racket_v8.0/share/pkgs/typed-racket-lib/typed-racket/typecheck/tc-toplevel.rkt:376:0: type-check
   /Applications/Racket_v8.0/share/pkgs/typed-racket-lib/typed-racket/typecheck/tc-toplevel.rkt:619:0: tc-module
   /Applications/Racket_v8.0/share/pkgs/typed-racket-lib/typed-racket/tc-setup.rkt:96:12: temp34
   /Applications/Racket_v8.0/share/pkgs/typed-racket-lib/typed-racket/typed-racket.rkt:23:4
repro.rkt:12:42: Type Checker: Polymorphic function `cons' could not be applied to arguments:
Types: a (Listof a)  -> (Listof a)
       a b  -> (Pairof a b)
Arguments: A (Listof Any)
Expected result: (Listof A)

  in: (cons h (list-set t (- n 1) x))
  context...:
   /Applications/Racket_v8.0/share/pkgs/typed-racket-lib/typed-racket/utils/tc-utils.rkt:123:0: report-all-errors
   /Applications/Racket_v8.0/share/pkgs/typed-racket-lib/typed-racket/typecheck/tc-toplevel.rkt:376:0: type-check
   /Applications/Racket_v8.0/share/pkgs/typed-racket-lib/typed-racket/typecheck/tc-toplevel.rkt:619:0: tc-module
   /Applications/Racket_v8.0/share/pkgs/typed-racket-lib/typed-racket/tc-setup.rkt:96:12: temp34
   /Applications/Racket_v8.0/share/pkgs/typed-racket-lib/typed-racket/typed-racket.rkt:23:4
Type Checker: Summary: 2 errors encountered
  context...:
   /Applications/Racket_v8.0/share/pkgs/typed-racket-lib/typed-racket/typecheck/tc-toplevel.rkt:376:0: type-check
   /Applications/Racket_v8.0/share/pkgs/typed-racket-lib/typed-racket/typecheck/tc-toplevel.rkt:619:0: tc-module
   /Applications/Racket_v8.0/share/pkgs/typed-racket-lib/typed-racket/tc-setup.rkt:96:12: temp34
   /Applications/Racket_v8.0/share/pkgs/typed-racket-lib/typed-racket/typed-racket.rkt:23:4

Requires X11 display on Linux

When I ssh into my workstation and attempt to use nvim with racket-langserver I get the following error:

Unable to init server: Could not connect: Connection refused
Gtk initialization failed for display ":0"
  context...:
   body of "/usr/local/stow/racket-8.0/share/racket/pkgs/gui-lib/mred/private/wx/gtk/queue.rkt"
   body of "/usr/local/stow/racket-8.0/share/racket/pkgs/gui-lib/mred/private/wx/platform.rkt"

‘hash-ref: no value found for key’ for certain files

Steps to reproduce (using Magic Racket extension for VSCode):

Expected behavior: hovering shows a tooltip for the text (if applicable)

Actual behavior: the language server gives the following errors:

Caught exn:
standard-module-name-resolver: contract violation
  expected: module-path?
  given: '(just-space #f (rename scribble/manual racketmodlink racketmodlink))
  context...:
   /home/felirovas/.local/share/racket/8.7/pkgs/racket-langserver/autocomplete.rkt:106:0: walk-module
   /home/felirovas/.local/share/racket/8.7/pkgs/racket-langserver/check-syntax.rkt:111:10
   /usr/share/racket/collects/racket/logging.rkt:43:0: with-intercepted-logging
   /home/felirovas/.local/share/racket/8.7/pkgs/racket-langserver/check-syntax.rkt:77:0: check-syntax
   /usr/share/racket/collects/racket/contract/private/arrow-val-first.rkt:486:18
   /home/felirovas/.local/share/racket/8.7/pkgs/racket-langserver/text-document.rkt:68:0: did-open!
   /usr/share/racket/collects/racket/contract/private/arrow-val-first.rkt:486:18
   [repeats 1 more time]
   /home/felirovas/.local/share/racket/8.7/pkgs/racket-langserver/main.rkt:60:2: consume

Caught exn in request "textDocument/documentSymbol"
hash-ref: no value found for key
  key: 'file:///home/felirovas/conlang/ncv9/pollen/pollen/render.rkt
  context...:
   /home/felirovas/.local/share/racket/8.7/pkgs/racket-langserver/text-document.rkt:463:0: document-symbol
   /usr/share/racket/collects/racket/contract/private/arrow-val-first.rkt:486:18
   /home/felirovas/.local/share/racket/8.7/pkgs/racket-langserver/methods.rkt:26:0: process-message
   /usr/share/racket/collects/racket/contract/private/arrow-val-first.rkt:486:18
   /home/felirovas/.local/share/racket/8.7/pkgs/racket-langserver/main.rkt:60:2: consume

[Error - 3:09:20 AM] Request textDocument/documentSymbol failed.
  Message: internal error in method "textDocument/documentSymbol"
  Code: -32603 
Caught exn in request "textDocument/hover"
hash-ref: no value found for key
  key: 'file:///home/felirovas/conlang/ncv9/pollen/pollen/render.rkt
  context...:
   /home/felirovas/.local/share/racket/8.7/pkgs/racket-langserver/text-document.rkt:117:0: hover
   /usr/share/racket/collects/racket/contract/private/arrow-val-first.rkt:486:18
   /home/felirovas/.local/share/racket/8.7/pkgs/racket-langserver/methods.rkt:26:0: process-message
   /usr/share/racket/collects/racket/contract/private/arrow-val-first.rkt:486:18
   /home/felirovas/.local/share/racket/8.7/pkgs/racket-langserver/main.rkt:60:2: consume

Good first issue?

Hey, is the project alive? I'd love to get involved, but I don't have much experience with racket (nor LSPs, for that matter). Could you point me to some good issues/places to start reading the code or give me some tips on how to start?

Also, what is the difference between this and https://github.com/theia-ide/racket-language-server/ ?

Incorrect reporting of errors when deleting line breaks

Suppose I have a file containing the following dummy function:

#lang racket

(define (hello n) (cadr (list 6 3 6 2)))

If I insert a line break right before (cadr ...) (not including the space between n and cadr) to get the following:

#lang racket

(define (hello n) 
(cadr (list 6 3 6 2)))

and then delete the line break, I receive an error that does not disappear until I close and reopen the file.

After some testing, it seems that every time that I repeat the steps of adding a line break and then deleting it, the error is reported as being at a position one space to the left of where it was previously reported, and after enough repeats, the error type being reported changes. For instance, the example above is reported as the following (each new error message comes after inserting and then deleting the newline at the same position):

test.rkt:3:38: read-syntax: unexpected ')'
test.rkt:3:37: read-syntax: unexpected ')'
test.rkt:3:36: read-syntax: unexpected ')'
...
test.rkt:3:21: read-syntax: unexpected ')'
test.rkt:3:20: read-syntax: unexpected ')'
test.rkt:3:19: read-syntax: unexpected ')'
test.rkt:3:19: read-syntax: unexpected ')' (not a typo, it says 19 again)
test.rkt:3:0: define: bad syntax (no expressions for procedure body
test.rkt:3:0: read-syntax: expected a ')' to close '('
test.rkt:3:0: read-syntax: expected a ')' to close '('

Beyond this point it just repeats the last error about expected ')'.

Interestingly, when adding and deleting the line break BEFORE the space (i.e. right after (hello n) this error does not occur until the second time that the line break is deleted, or if the file is saved before deleting the line break the first time.

Server requires #lang line even though #reader is present.

By default, opening a file created in DrRacket in VSCode throws the error Missing or invalid #lang line from define lang-diag as seen in check-syntax.rkt. However this file compiles and runs just fine. Below is an example of the first three lines inserted by DrRacket.

;; The first three lines of this file were inserted by DrRacket. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-intermediate-lambda-reader.ss" "lang")((modname 1-family) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f () #f)))

Function Parameter/Field Name Virtual Text Inference

rust-analyzer provides a very neat feature in that it will print out virtual text of struct field names and function param names when you call said function.

This feature would be a huge productivity gain for racket as structs will be much easier to work with, along with functions. Currently I create a lot of keyword functions for structs that are very large because I don't want to keep guessing what they are by position. (I have looked into the rebellion packages and etc but ehh, I prefer to minimize dependencies)

image

pub struct Rect {
    pub x: u32,
    pub y: u32,
    pub w: u32,
    pub h: u32,
}
impl Rect {
    pub fn new(x: u32, y: u32, w: u32, h: u32) -> Self {
        Self { x, y, w, h }
    }
}
//so we can have a more ergonomic syntax for creating structs by position
let r = Rect::new(0, 5, 32, 32);

`get-bindings` returns `#f` -> language server crashes

Here's the log. I think the append call in question is on text-document.rkt:294:

                (or (append (get-bindings uri decl) (list (start/end->Range doc-text left right))))))

Log:

[Error - 5:26:52 PM] Request textDocument/documentHighlight failed.
  Message: internal error in method "textDocument/documentHighlight"
  Code: -32603 
Caught exn in request "textDocument/documentHighlight"
append: contract violation
  expected: list?
  given: #f
  context...:
   C:\Users\berry\AppData\Roaming\Racket\8.0\pkgs\racket-langserver\text-document.rkt:281:0: document-highlight
   C:\Program Files\Racket\collects\racket\contract\private\arrow-val-first.rkt:486:18
   C:\Users\berry\AppData\Roaming\Racket\8.0\pkgs\racket-langserver\methods.rkt:26:0: process-message
   C:\Program Files\Racket\collects\racket\contract\private\arrow-val-first.rkt:486:18
   C:\Users\berry\AppData\Roaming\Racket\8.0\pkgs\racket-langserver\main.rkt:53:2: consume

Version:

> racket --version
Welcome to Racket v8.0 [cs].

Wrong 'Content-Length' in response?

I am not entirely sure this problem really exists, but I have found that the response for textDocument/completion seems to give a wrong Content-Length. However, using racket-langserver with VSCode is all right, but I'm not sure whether VSCode uses the Content-Length field or just reads a complete JSON object for parsing responses.

The way to reproduce the issue:

  • Operating system: macOS 12.2.1
  • Racket: v8.3 [cs]
  • Put the following text into a file requests.txt (contains 4 requests: initialize, didOpen, didChange (inserts a character), completion (requests completion) ). Use CRLF.
Content-Length: 0

{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":7404,"clientInfo":{"name":"Visual Studio Code","version":"1.64.2"},"locale":"en-us","rootPath":"/","rootUri":"file:///","capabilities":{"workspace":{"applyEdit":true,"workspaceEdit":{"documentChanges":true,"resourceOperations":["create","rename","delete"],"failureHandling":"textOnlyTransactional","normalizesLineEndings":true,"changeAnnotationSupport":{"groupsOnLabel":true}},"didChangeConfiguration":{"dynamicRegistration":true},"didChangeWatchedFiles":{"dynamicRegistration":true},"symbol":{"dynamicRegistration":true,"symbolKind":{"valueSet":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]},"tagSupport":{"valueSet":[1]}},"codeLens":{"refreshSupport":true},"executeCommand":{"dynamicRegistration":true},"configuration":true,"workspaceFolders":true,"semanticTokens":{"refreshSupport":true},"fileOperations":{"dynamicRegistration":true,"didCreate":true,"didRename":true,"didDelete":true,"willCreate":true,"willRename":true,"willDelete":true}},"textDocument":{"publishDiagnostics":{"relatedInformation":true,"versionSupport":false,"tagSupport":{"valueSet":[1,2]},"codeDescriptionSupport":true,"dataSupport":true},"synchronization":{"dynamicRegistration":true,"willSave":true,"willSaveWaitUntil":true,"didSave":true},"completion":{"dynamicRegistration":true,"contextSupport":true,"completionItem":{"snippetSupport":true,"commitCharactersSupport":true,"documentationFormat":["markdown","plaintext"],"deprecatedSupport":true,"preselectSupport":true,"tagSupport":{"valueSet":[1]},"insertReplaceSupport":true,"resolveSupport":{"properties":["documentation","detail","additionalTextEdits"]},"insertTextModeSupport":{"valueSet":[1,2]}},"completionItemKind":{"valueSet":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]}},"hover":{"dynamicRegistration":true,"contentFormat":["markdown","plaintext"]},"signatureHelp":{"dynamicRegistration":true,"signatureInformation":{"documentationFormat":["markdown","plaintext"],"parameterInformation":{"labelOffsetSupport":true},"activeParameterSupport":true},"contextSupport":true},"definition":{"dynamicRegistration":true,"linkSupport":true},"references":{"dynamicRegistration":true},"documentHighlight":{"dynamicRegistration":true},"documentSymbol":{"dynamicRegistration":true,"symbolKind":{"valueSet":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]},"hierarchicalDocumentSymbolSupport":true,"tagSupport":{"valueSet":[1]},"labelSupport":true},"codeAction":{"dynamicRegistration":true,"isPreferredSupport":true,"disabledSupport":true,"dataSupport":true,"resolveSupport":{"properties":["edit"]},"codeActionLiteralSupport":{"codeActionKind":{"valueSet":["","quickfix","refactor","refactor.extract","refactor.inline","refactor.rewrite","source","source.organizeImports"]}},"honorsChangeAnnotations":false},"codeLens":{"dynamicRegistration":true},"formatting":{"dynamicRegistration":true},"rangeFormatting":{"dynamicRegistration":true},"onTypeFormatting":{"dynamicRegistration":true},"rename":{"dynamicRegistration":true,"prepareSupport":true,"prepareSupportDefaultBehavior":1,"honorsChangeAnnotations":true},"documentLink":{"dynamicRegistration":true,"tooltipSupport":true},"typeDefinition":{"dynamicRegistration":true,"linkSupport":true},"implementation":{"dynamicRegistration":true,"linkSupport":true},"colorProvider":{"dynamicRegistration":true},"foldingRange":{"dynamicRegistration":true,"rangeLimit":5000,"lineFoldingOnly":true},"declaration":{"dynamicRegistration":true,"linkSupport":true},"selectionRange":{"dynamicRegistration":true},"callHierarchy":{"dynamicRegistration":true},"semanticTokens":{"dynamicRegistration":true,"tokenTypes":["namespace","type","class","enum","interface","struct","typeParameter","parameter","variable","property","enumMember","event","function","method","macro","keyword","modifier","comment","string","number","regexp","operator"],"tokenModifiers":["declaration","definition","readonly","static","deprecated","abstract","async","modification","documentation","defaultLibrary"],"formats":["relative"],"requests":{"range":true,"full":{"delta":true}},"multilineTokenSupport":false,"overlappingTokenSupport":false},"linkedEditingRange":{"dynamicRegistration":true}},"window":{"showMessage":{"messageActionItem":{"additionalPropertiesSupport":true}},"showDocument":{"support":true},"workDoneProgress":true},"general":{"regularExpressions":{"engine":"ECMAScript","version":"ES2020"},"markdown":{"parser":"marked","version":"1.1.0"}}},"trace":"off","workspaceFolders":[{"uri":"file:///","name":"Demo"}]}
}Content-Length: 0

{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///a",
"text":"#lang racket\n\n(define i 0)\n(display )\n"}}
}Content-Length: 0

{"jsonrpc":"2.0","method":"textDocument/didChange","params":{
    "textDocument": {
        "uri": "file:///a"
    },
    "contentChanges": [
        {
            "range": {
                "start": {
                    "line": 3,
                    "character": 9
                },
                "end": {
                    "line": 3,
                    "character": 9
                }
            },
            "rangeLength": 0,
            "text": "i"
        }
    ]
}}Content-Length: 0

{"jsonrpc":"2.0","id":2,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///a"},
"position":{"line":3,"character":10},"context":{"triggerKind":1}}
}
  • Run command (cat requests.txt && cat) | racket -l racket-langserver. Wait for enough time that all four requests are processed, then Ctrl-C to terminate.

It's the fourth request that gives the wrong Content-Length (72071), but the actual length of the JSON object is 72066. I've looked into msg-io.rkt, where Content-Length is computed, but I cannot figure out what's going wrong in the code.

Exception when opening file: interval-map-set!: start is not strictly less than end

One Racket source file in my project is triggering the exception below.
It happens everytime I open the file, or another file that requires it, in an editor that uses the Racket language server.

Follow this link to download the problematic source file

I have tried to isolate what is causing the issue without success so far.
It seems that removing random parts of the code makes the exception disappear.
But when I try to create a minimal example, I cannot reproduce the error.

Here is my setup:

  • Racket 7.7 with a fresh install of racket-langserver (b283c2b)
  • Ubuntu 20.04, 64-bit
  • Atom 1.47.0 with atom-ide-racket 0.3.0
  • VS Code 1.46.0 with magic-racket 0.5.6

Please tell me what additional information I can provide to help fix the issue.

interval-map-set!: start is not strictly less than end
  im: (make-interval-map '(((6 . 12) . #<set: (3466 . 3468) (1990 ....
  start: 642
  end: 642
  value: (set '(670 . 674))
  context...:
   /usr/share/racket/pkgs/data-lib/data/interval-map.rkt:99:0: interval-map-set!
   /home/guillaume/.racket/7.7/pkgs/racket-langserver/check-syntax.rkt:36:4: syncheck:add-arrow method in build-trace%
   /usr/share/racket/pkgs/drracket-tool-lib/drracket/private/syncheck/traversals.rkt:844:0: connect-identifier
   /usr/share/racket/pkgs/drracket-tool-lib/drracket/private/syncheck/traversals.rkt:708:6: for-loop
   /usr/share/racket/pkgs/drracket-tool-lib/drracket/private/syncheck/traversals.rkt:707:4: for-loop
   /usr/share/racket/pkgs/drracket-tool-lib/drracket/private/syncheck/traversals.rkt:701:2: for-loop
   /usr/share/racket/pkgs/drracket-tool-lib/drracket/private/syncheck/traversals.rkt:669:0: annotate-variables
   /usr/share/racket/pkgs/drracket-tool-lib/drracket/private/syncheck/traversals.rkt:47:10: expanded-expression
   .../more-scheme.rkt:261:28
   /home/guillaume/.racket/7.7/pkgs/racket-langserver/check-syntax.rkt:75:0: check-syntax
   /usr/share/racket/collects/racket/contract/private/arrow-val-first.rkt:486:18
   /home/guillaume/.racket/7.7/pkgs/racket-langserver/text-document.rkt:86:0: did-open!
   /usr/share/racket/collects/racket/contract/private/arrow-val-first.rkt:486:18
   [repeats 1 more time]
   /home/guillaume/.racket/7.7/pkgs/racket-langserver/main.rkt:54:2: consume

General errors vs errors in current file

If one has a file, "A" and imports a file "B" and file "B" has an error on a specific line number (such as, say, an unbound identifier) that error shows up in the current file at the line number of that error.

I propose that errors that are not in the current file should be a general error.

Error get-lexer: 'before-lang-line

Error:

Caught exn in request "textDocument/documentSymbol"
get-lexer: 'before-lang-line
  context...:
   .../racket-langserver/text-document.rkt:233:0: document-symbol

The above error will throw when #lang .. is absent or when there are comments ahead of #lang ..

Missing or invalid #lang line error for custom #lang

When I open files written in #lang resyntax/testing/refactoring-test (example) I get the error "Missing or invalid #lang line" pointing at the #lang line. Based on this code it seems to be because my #lang implementation doesn't define an indenter. Yet DrRacket indents it using the default racket indenter just fine. Is this a bug in the langserver?

Debugger implementation

This is more driven by curiosity than anything practical but I was wondering would it would take to create a debugger API? I don't think a detailed answer is needed - I'm just trying to figure out the scope of this and some general starting points.

Typed Racket type annotations on hover

Would it be possible (and within the scope of this project) to display type annotations on hover when using Typed Racket? I think it would provide a lot of value if it were possible.

Implement formatting support

I started work on this. I thought it would be rather straight forward using the pretty printer. But that doesn't reindent at all.

textDocument/signatureHelp not working

I am not sure if the title of this issue is 'correct', but, because the README mentions 'Signature help' support, I am expecting to see signature help, while I can not discover it anywhere. I have tried using the server in vscode, and with lsp-mode and eglot on Emacs, but nowhere I could discover the signature help.
So now I am wondering if the feature is working correctly. Therefore, I am opening this issue, to ask you if you could confirm that it is working correctly. In that case, could you give a hint on how it should/I should get it to work?

If it is not working correctly, then it is probably nice for others to find this issue here (and for you to know about it). Of course, I am happy to provide any required info about the problem (e.g. server logs).

Sorry, for using this space as 'informal' support, but I figured it would make more sense to mention this here than e.g. on SO.

Anyway, thanks for the great work!

Exception thrown on empty racket files

This seems to be related to #12. I just installed Racket 8.0 and racket-langserver on Windows 10 for use with VSCode and the Magic Racket extension. The instant I opened an empty .rkt file, racket-langserver threw the following error:

Caught exn in request "textDocument/documentHighlight"
hash-ref: no value found for key
  key: 'file:///c:/Users/user/Documents/Programming/hello-racket/hello.rkt
  context...:
   C:\Users\user\AppData\Roaming\Racket\8.0\pkgs\racket-langserver\text-document.rkt:207:0: get-doc-refs
   C:\Users\user\AppData\Roaming\Racket\8.0\pkgs\racket-langserver\text-document.rkt:191:0: document-highlight
   C:\Program Files\Racket\collects\racket\contract\private\arrow-val-first.rkt:486:18
   C:\Users\user\AppData\Roaming\Racket\8.0\pkgs\racket-langserver\methods.rkt:26:0: process-message
   C:\Program Files\Racket\collects\racket\contract\private\arrow-val-first.rkt:486:18
   C:\Users\user\AppData\Roaming\Racket\8.0\pkgs\racket-langserver\main.rkt:54:2: consume

[Error - 7:45:07 PM] Request textDocument/documentHighlight failed.
  Message: internal error in method "textDocument/documentHighlight"
  Code: -32603

My best guess is that the key format 'file:///c:/...' is causing the problem, specifically the third slash following 'file.'

How to launch the server from CLI?

Sorry if this isn't relevant to this project, but how do I actually launch the server, without explicitly running racket path/to/main.rkt? I haven't use raco in a very long time, but I'd expect that after install it would link the executable and put it somewhere on my PATH.

Resyntax integration

In the long term, I would like to integrate Resyntax with this language server so that Racket users can get helpful suggestions for improving their code directly in the editor. I don't think Resyntax is stable enough for this yet, but it's a goal I'm working towards. Does this seem like a good idea to folks?

Exception thrown on format

While trying to use racket-langserver on VSCode with Magic Racket, trying to format the document I stumbled upon this issue:

Caught exn in request "textDocument/formatting"
=: contract violation
expected: number?
given: #f
context...:
/home/<user>/.local/share/racket/8.0/pkgs/racket-langserver/text-document.rkt:325:0: indent-line!
/home/<user>/.local/share/racket/8.0/pkgs/racket-langserver/text-document.rkt:313:7: loop
/home/<user>/.local/share/racket/8.0/pkgs/racket-langserver/text-document.rkt:294:0: range-formatting!
/usr/share/racket/collects/racket/contract/private/arrow-val-first.rkt:486:18
/home/<user>/.local/share/racket/8.0/pkgs/racket-langserver/methods.rkt:26:0: process-message
/usr/share/racket/collects/racket/contract/private/arrow-val-first.rkt:486:18
/home/<user>/.local/share/racket/8.0/pkgs/racket-langserver/main.rkt:54:2: consume

[Error - 11:37:25 AM] Request textDocument/formatting failed.
Message: internal error in method "textDocument/formatting"
Code: -32603

Server initialization failed: The JSON sent is not a valid request object. (racket/racket#4532)

A recent bug fix racket/racket#4532 going into Racket 8.8 changes the semantics of hash table patterns, so it breaks racket-langserver with the following error messages:

A request has failed. See the output for more information.

Server initialization failed.
  Message: The JSON sent is not a valid request object.
  Code: -32600 

Starting client failed
  Message: The JSON sent is not a valid request object.
  Code: -32600 

This piece of code now expects to match the full hash table instead of matching only the mentioned key-value pair:

;; Before: check the `id` field and the `method` field
;; After: asserts that `msg` only has the `id` field and the `match` field
(match msg
    ;; Request
    [(hash-table ['id (? (or/c number? string?) id)]
                 ['method (? string? method)])
     (define params (hash-ref msg 'params hasheq))
     (define response (process-request id method params))
     (display-message/flush response)]
    ...

I'm happy to send a PR but it'd take a while.

status on complete/WIP features?

I'm really excited to see that racket has LSP implementation! Questions:

  1. What features are completed and what are WIP? Particularly features listed on implementation list on official page:
  • Code completion
  • Hover
  • Jump to def
  • Workspace symbols
  • Find references
  • Diagnostics
  • Automatic dependency management
  • No arbitrary code execution
  • Files Extension
  • SymbolDescriptor Extension
  1. Talking about LSP's official page, is this project not listed on official list because it's still in early stage?

at-exp meta language breaks indentation

With a lang-line like #lang at-exp racket, read-language returns the lang-info of at-exp only, which defers to Scribble's indenter. It seems like there's absolutely no built-in support for querying a meta-language like at-exp for its "base" language, so I'm not entirely sure what the correct method is for determining which indenter is the correct one to use on a particular line.

Some preliminary ideas:

  • Just use the racket indenter when at-exp is used
  • Dig into DrRacket source more and figure out how they handle this (hasn't been successful so far)
  • Bug someone to properly implement at-exp's indenter... it's probably not correct for it to just fully defer to the scribble indenter
  • Manually re-implement the indenter... not sure how to determine if a given line is inside or outside of an @-exp

Unable to get document for symbols imported from `racket`

For example: if you hover over define and the langserver will redirect you to this link which is 404

https://docs.racket-lang.org/racket/reference/define.html#(form._((lib._racket/private/base..rkt)._define))

The working link now is:
https://docs.racket-lang.org/reference/define.html#(form._((lib._racket/private/base..rkt)._define))

There is no racket between docs.racket-lang.org and define.html#

Maybe some work can be done on the website side,

The hover-to-read-doc was added on: #33 by @Runi-c

Change `<>` replacements?

["<" ""] [">" ""]

These particular characters don't exist in the font I use in my terminal, so they appear as the empty block replacement character.

Perhaps « and » are viable? Though they may clash with some Rhombus work, they are at least far more likely to be supported by fonts.

I might prefer the escaped &lt; though in spite of the comment about editors and Markdown: I use vim, and even the "plain" version is relatively readable.

The last alternative I can think of is to "escape" all <> pairs by surrounding them with backticks, since `#<void>` doesn't give Markdown any trouble (though getting the representation into code, as I did, is non-trivial 😄 ).

check-syntax is slow

For now I'm disabling check-syntax, it solves the syntax coloring speed issue. Should probably run in a separate thread.

CRLF line endings handled incorrectly

This bug causes CRLF line endings to be double-counted, causing line positions to be reported incorrectly. The result is that generated symbols are entirely useless and the langserver is virtually unusable for editors configured to use CRLF.

It is caused by a bug in framework:
image
racket/gui#221

As I don't anticipate it to be fixed there any time soon a temporary fix could be considered here, such as manually replacing CRLF with LF before sending off to the racket:text instance.

Exception on stdout causing jsonrpc parse error

tldr: Is there a way to have the language server not put errors into stdout/avoid exception printing when invoking the language server?

Hi, I'm a Magic Racket user (without much racket background, so there might be an easy fix) who is trying to figure out where a bug is coming from. I posted an issue in Magic Racket (Eugleo/magic-racket#77 (comment)). It seems like stdout+stderr are getting mixed by the language server, and Magic Racket is unable to handle the error because of an uncatchable underlying exception in the jsonrpc parsing library (microsoft/vscode-languageserver-node#870).

I have a program that looks like this:

#lang racket

(require plot/no-gui)
(local-require (only-in plot/no-gui [plot-file plot-file*]))

This leads to a message from the language server with a mixture of racket error and jsonrpc data, which I caught in the VSCode extension debugger:

Caught exn:
standard-module-name-resolver: contract violation
  expected: module-path?
  given: '(just-space #f (rename plot/no-gui b plot-file))
  context...:
   /home/elm/.local/share/racket/8.6/pkgs/racket-langserver/autocomplete.rkt:106:0: walk-module
   /home/elm/.local/share/racket/8.6/pkgs/racket-langserver/check-syntax.rkt:111:10
   /usr/share/racket/collects/racket/logging.rkt:43:0: with-intercepted-logging
   /home/elm/.local/share/racket/8.6/pkgs/racket-langserver/check-syntax.rkt:77:0: check-syntax
   /usr/share/racket/collects/racket/contract/private/arrow-val-first.rkt:486:18
   /home/elm/.local/share/racket/8.6/pkgs/racket-langserver/text-document.rkt:65:0: did-open!
   /usr/share/racket/collects/racket/contract/private/arrow-val-first.rkt:486:18
   [repeats 1 more time]
   /home/elm/.local/share/racket/8.6/pkgs/racket-langserver/main.rkt:54:2: consume

Caught exn in request "textDocument/documentSymbol"
hash-ref: no value found for key
  key: 'file:///home/elm/temp/tst.rkt
  context...:
   /home/elm/.local/share/racket/8.6/pkgs/racket-langserver/text-document.rkt:405:0: document-symbol
   /usr/share/racket/collects/racket/contract/private/arrow-val-first.rkt:486:18
   /home/elm/.local/share/racket/8.6/pkgs/racket-langserver/methods.rkt:26:0: process-message
   /usr/share/racket/collects/racket/contract/private/arrow-val-first.rkt:486:18
   /home/elm/.local/share/racket/8.6/pkgs/racket-langserver/main.rkt:54:2: consume

Content-Length: 117

{"error":{"code":-32603,"message":"internal error in method \"textDocument/documentSymbol\""},"id":1,"jsonrpc":"2.0"}

jsonrpc fails to find the Content-Length header in this buffer due to the error text, and after the first such error, all subsequent requests result in the same problem since there's extra stuff in the buffer and it's never cleared. So it seems like this is a problem with stdout getting mixed with stderr.

I tried setting -W0 etc. in the langserver args to turn off stderr messages, but stuff still came through. I also tried redirection using a shell with 2>/dev/null and executing the langserver after loading an initial file that sets current-error-port to nowhere:

const executable = {  // VSCode language client config
      command: '/bin/bash',
      args: ['xvfb-run', '--auto-servernum', 'racket','-f', '/home/elm/nostderr.rkt', '--lib', 'racket-langserver', '2>/dev/null' ],
      // options: {
      //   shell: true
      // }
    };

with nostderr.rkt:

#lang racket
(require (only-in racket/port open-output-nowhere))
(current-error-port (open-output-nowhere))

Those didn't work either. My understanding of how the VSCode language server actually runs the process based on the executable configuration above and how to configure ports in racket are weak, so there's probably something here that I'm missing. I was able to solve the issue by commenting out the relevant eprintf lines in a racket-langserver fork.

So basically it seems like what's needed is an option to turn off the error printing to the extent that it's possible, since Magic Racket doesn't have a way to gracefully handle printed errors until the PR for the issue I linked goes through (no activity since December 2021).

Signature label should be a string, not array

Hello,
I'm coming from neoclide/coc.nvim#3385, where it was determined that racket-langserver for textDocument/signatureHelp returns label as an (singleton) array, instead of a string as the spec requires.

[Trace - 8:21:53 PM] Received response 'textDocument/signatureHelp - (2)' in 26ms.
Result: {
    "signatures": [
        {
            "documentation": "  char : char?",
            "label": [
                "(string char ...) -> string?"
            ]
        }
    ]
}

https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#signatureInformation

Exception thrown in textDocument/signatureHelp

I'm using VSCode with Magic Racket and occasionally seeing this error:

Caught exn in request "textDocument/signatureHelp"
drop: contract violation
expected: a (possibly improper) list with at least 1 pairs
given: #f
context...:
/Users/jackfirth/Library/Racket/8.0/pkgs/racket-langserver/docs-helpers.rkt:44:0: get-docs-for-tag
/Users/jackfirth/Library/Racket/8.0/pkgs/racket-langserver/text-document.rkt:161:0: signatureHelp
/Applications/Racket v8.0/collects/racket/contract/private/arrow-val-first.rkt:486:18
/Users/jackfirth/Library/Racket/8.0/pkgs/racket-langserver/methods.rkt:26:0: process-message
/Applications/Racket v8.0/collects/racket/contract/private/arrow-val-first.rkt:486:18
/Users/jackfirth/Library/Racket/8.0/pkgs/racket-langserver/main.rkt:54:2: consume

Haven't narrowed down the precise steps to trigger it yet, but it seems to happen pretty often.

empty line added when `format()`

I am not sure if this is an issue on the language server side or on the neovim side (https://github.com/neovim/nvim-lspconfig/blob/master/lua/lspconfig/server_configurations/racket_langserver.lua).

I am using this language server with neovim. Everytime the code is formatted with :lua vim.lsp.buf.format() via lsp, an empty line is added to the end of the file. So if autoformat is enable on save, lots of empty lines will be appended.

I tested it does not happen in VSCode.

I've no idea how to inspect/debug the problem.

Support for multi-language files in VSCode

Hello, I'm writing to mention that there is an issue being discussed at VSCode GitHub about supporting files with multiple embedded languages. The question is whether it would be useful to have an attribute defining the current active language at the cursor location.

I think the Racket community is especially sophisticated about language embedding, so you or "Magic Racket" VSCode extension maintainer @Eugleo might like to participate in that conversation. If nothing seems relevant, feel free to close and ignore this issue. 🙂

Why is libgdk required to run this language server?

libgdk is required by gui-lib. I'm trying to use this project with vim inside a headless linux box and the command complains 😕

~/dev/schemer$ racket --lib racket-langserver
ffi-lib: couldn't open "libgdk-x11-2.0.so.0" (libgdk-x11-2.0.so.0: cannot open shared object file: No such file or directory)
  context...:
   /usr/share/racket/collects/ffi/unsafe.rkt:131:0: get-ffi-lib
   "/usr/share/racket/pkgs/gui-lib/mred/private/wx/gtk/utils.rkt": [running body]
   temp35_0
   for-loop
   run-module-instance!
   for-loop
   [repeats 1 more time]
   run-module-instance!
   for-loop
   [repeats 1 more time]
   run-module-instance!
   do-dynamic-require
   "/usr/share/racket/pkgs/gui-lib/mred/private/wx/platform.rkt": [running body]
   temp35_0
   for-loop
   run-module-instance!
   ...

I just don't understand why libgdk is required. It seems I have to install gtk, is there a workaround?

Doesn't work with `code-server` (SSH w/o a display)

Unable to init server: Could not connect: Connection refused
Gtk initialization failed for display ":0"
  context...:
   body of "/home/jeff/racket/share/pkgs/gui-lib/mred/private/wx/gtk/queue.rkt"
   body of "/home/jeff/racket/share/pkgs/gui-lib/mred/private/wx/platform.rkt"

Additional context

This is running on a Digital Ocean droplet, which has no display. I connect to VS Code using code-server. I wouldn't think that a display is necessary to use the language server.

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.