Skip to content
Merged
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
3 changes: 3 additions & 0 deletions .lispwords
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
(match-define 1)
(with-read-doc 1)
(with-write-doc 1)
(with-read-safedoc 1)
(with-write-safedoc 1)
(syntax-parse 1)
(define-json-expander 1)
(for/fold/derived 2)
Expand All @@ -15,3 +17,4 @@
(call-with-write-lock 1)
(define-syntax-parse-rule 1)
(with-limits 2)
(and-let* 1)
69 changes: 49 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,55 @@ 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 from opened files within the workspace.
- **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)
## Language Support

The server recognizes language families and provides different levels of
support depending on whether the language uses s-expression syntax.

- Racket - The standard Racket language (`#lang racket`, `#lang racket/*`, etc.).
- Typed Racket - (`#lang typed/racket`, `#lang typed/racket/*`, etc.).
- Other sexp - Predefined s-expression language families beyond Racket and Typed Racket.
- Scribble - (`#lang scribble`, `#lang scribble/*`, etc.).
- Rhombus - (`#lang rhombus`, `#lang rhombus/*`, etc.).
- Unknown - Language declaration found and parsed, but not in the predefined list.
- Unrecognized - No language declaration found (missing `#lang`, `#reader`, or `(module ...)` form).

### Legend

| Mark | Meaning |
|---|---|
| ✅ | Feature works well and produces useful results. |
| ⚠️ | Partial support - the feature runs but may produce incomplete or imprecise results. |
| ❌ | Not implemented or intentionally filtered out for this language family. |

The matrix rates expected usefulness for each language family. Expansion-based features are marked supported when they only depend on successful expansion and `check-syntax` data. Features are marked partial when they have additional syntax-family limits, lexer limits, or intentionally noisy results.

### Support Matrix

| Feature | Racket | Typed Racket | Other sexp | Scribble | Rhombus | Unknown | Unrecognized |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| Completion | ✅ | ✅ | ✅ | ⚠️ | ⚠️ | ⚠️ | ⚠️ |
| Definition | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| Hover | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| Signature Help | ✅ | ✅ | ✅ | ❌ | ❌ | ⚠️ | ❌ |
| References | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| Document Highlight | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| Rename | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| Prepare Rename | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| Code Action | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| Diagnostics | ✅ | ✅ | ✅ | ✅ | ✅ | ⚠️ | ✅ |
| Document Symbols | ⚠️ | ⚠️ | ⚠️ | ⚠️ | ⚠️ | ⚠️ | ⚠️ |
| Semantic Tokens, Delta | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Semantic Tokens, Full | ✅ | ✅ | ✅ | ⚠️ | ⚠️ | ⚠️ | ⚠️ |
| Semantic Tokens, Range | ✅ | ✅ | ✅ | ⚠️ | ⚠️ | ⚠️ | ⚠️ |
| Formatting | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
| Range Formatting | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
| On-Type Formatting | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
| Inlay Hints | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |

### Features

See [features.md](features.md) for a detailed breakdown of each feature.

## Development

Expand Down
16 changes: 13 additions & 3 deletions common/interfaces.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
racket/match
"json-util.rkt")

(provide (json-type-out Pos)
(provide (struct-out CharRange)
(json-type-out Pos)
(json-type-out Range)
char-range-intersect?
(json-type-out TextEdit)
Expand Down Expand Up @@ -252,6 +253,13 @@
[trim-final-newlines (optional boolean?) #:json trimFinalNewlines]
[key (or/c false/c (optional/c hash?))])

;; Character-offset range. Distinct from the protocol-level `Range`
;; (which uses line/char positions); this one uses zero-based absolute
;; character offsets.
(struct CharRange
(start end)
#:transparent)

;; Public query result for cached lexer tokens. Positions are zero-based
;; absolute character offsets; callers still need to convert them to line /
;; character pairs for LSP positions.
Expand All @@ -267,7 +275,8 @@
[function "function"]
[string "string"]
[number "number"]
[regexp "regexp"])
[regexp "regexp"]
[comment "comment"])

(define-json-enum SemanticTokenModifier
[definition "definition"])
Expand All @@ -287,7 +296,8 @@
SemanticTokenType-function
SemanticTokenType-string
SemanticTokenType-number
SemanticTokenType-regexp))
SemanticTokenType-regexp
SemanticTokenType-comment))

;; The order of this list is irrelevant, similar to *semantic-token-types*.
(define *semantic-token-modifiers*
Expand Down
5 changes: 1 addition & 4 deletions common/path-util.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,12 @@
directory-contains?)

(require net/url
racket/string
racket/list
racket/path)

(define path->uri (compose url->string path->url))

(define (uri->path uri)
(cond [(string-prefix? uri "file:") (path->string (url->path (string->url uri)))]
[else (uri->path (regexp-replace #rx".*?:" uri "file:"))]))
(define uri->path (compose path->string url->path string->url))

(define (directory-contains? dir filepath)
(define dir-parts (explode-path (simple-form-path dir)))
Expand Down
33 changes: 7 additions & 26 deletions doclib/check-syntax.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,10 @@
racket/port
"editor.rkt"
"doc-trace.rkt"
"doc-lang.rkt"
"../common/path-util.rkt"
"internal-types.rkt")

(define (get-indenter text)
(define lang-info
(with-handlers ([exn:fail:read? (lambda (e) 'missing)]
[exn:missing-module? (lambda (e) #f)])
(read-language (open-input-string text) (lambda () 'missing))))
(cond
[(procedure? lang-info)
(lang-info 'drracket:indentation #f)]
[(eq? lang-info 'missing)
; check for a #reader directive at start of file, ignoring comments
; the ^ anchor here matches start-of-string, not start-of-line
(if (regexp-match #rx"^(;[^\n]*\n)*#reader" text)
#f ; most likely a drracket file, use default indentation
; (https://github.com/jeapostrophe/racket-langserver/issues/86)
'missing)]
[else #f]))

;; TODO: cache the namespace with some strategy
(define (expand-source path in collector #:expand? [expand? #t])
(define-values (src-dir _1 _2) (split-path path))
Expand Down Expand Up @@ -72,20 +56,18 @@
(define (check-syntax uri doc-text)
(define path (uri->path uri))
(define text (send doc-text get-text))
; rktd <-> rkt is just like JSON <-> js
(define data-file? (equal? (path-get-extension path) #".rktd"))
(define indenter (if data-file? #f (get-indenter text)))
(define new-trace (new build-trace% [src path] [doc-text doc-text] [indenter indenter]))
(define expand? (requires-expansion? path))
(define new-trace (new build-trace% [src path] [doc-text doc-text]))

(define in (open-input-string text))
(define er (expand-source path in new-trace #:expand? (not data-file?)))
(define er (expand-source path in new-trace #:expand? expand?))

(send new-trace walk-stx er)
(send new-trace walk-log (ExpandResult-logs er))
(CSResult new-trace text
(if data-file?
(and (ExpandResult-pre-syntax er) #t)
(ExpandResult-all-succeed? er))))
(if expand?
(ExpandResult-all-succeed? er)
(and (ExpandResult-pre-syntax er) #t))))

(provide
(struct-out CSResult)
Expand All @@ -94,4 +76,3 @@
(#:expand? boolean?)
ExpandResult?)]
[check-syntax (-> string? (is-a?/c lsp-editor%) CSResult?)]))

Loading
Loading