forked from jeapostrophe/racket-langserver
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmethods.rkt
154 lines (141 loc) · 5.28 KB
/
methods.rkt
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#lang racket/base
(require json
racket/contract/base
racket/exn
racket/match
"error-codes.rkt"
"msg-io.rkt"
"responses.rkt"
(prefix-in text-document/ "text-document.rkt"))
;; TextDocumentSynKind enumeration
(define TextDocSync-None 0)
(define TextDocSync-Full 1)
(define TextDocSync-Incremental 2)
;; Mutable variables
(define already-initialized? #f)
(define already-shutdown? #f)
;;
;; Dispatch
;;;;;;;;;;;;;
;; Processes a message. This displays any repsonse it generates
;; and should always return void.
(define (process-message msg)
(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)]
;; Notification
[(hash-table ['method (? string? method)])
(define params (hash-ref msg 'params hasheq))
(process-notification method params)]
;; Batch Request
[(? (non-empty-listof (and/c hash? jsexpr?)))
(for-each process-message msg)]
;; Invalid Message
[_
(define id-ref (hash-ref msg 'id void))
(define id (if ((or/c number? string?) id-ref) id-ref (json-null)))
(define err "The JSON sent is not a valid request object.")
(display-message/flush (error-response id INVALID-REQUEST err))]))
(define ((report-request-error id method) exn)
(eprintf "Caught exn in request ~v\n~a\n" method (exn->string exn))
(define err (format "internal error in method ~v" method))
(error-response id INTERNAL-ERROR err))
;; Processes a request. This procedure should always return a jsexpr
;; which is a suitable response object.
(define (process-request id method params)
(with-handlers ([exn:fail? (report-request-error id method)])
(match method
["initialize"
(initialize id params)]
["shutdown"
(shutdown id)]
["textDocument/hover"
(text-document/hover id params)]
["textDocument/completion"
(text-document/completion id params)]
["textDocument/signatureHelp"
(text-document/signatureHelp id params)]
["textDocument/definition"
(text-document/definition id params)]
["textDocument/documentHighlight"
(text-document/document-highlight id params)]
["textDocument/references"
(text-document/references id params)]
["textDocument/documentSymbol"
(text-document/document-symbol id params)]
["textDocument/rename"
(text-document/rename id params)]
["textDocument/prepareRename"
(text-document/prepareRename id params)]
["textDocument/formatting"
(text-document/formatting! id params)]
["textDocument/rangeFormatting"
(text-document/range-formatting! id params)]
["textDocument/onTypeFormatting"
(text-document/on-type-formatting! id params)]
[_
(eprintf "invalid request for method ~v\n" method)
(define err (format "The method ~v was not found" method))
(error-response id METHOD-NOT-FOUND err)])))
;; Processes a notification. Because notifications do not require
;; a response, this procedure always returns void.
(define (process-notification method params)
(match method
["exit"
(exit (if already-shutdown? 0 1))]
["textDocument/didOpen"
(text-document/did-open! params)]
["textDocument/didClose"
(text-document/did-close! params)]
["textDocument/didChange"
(text-document/did-change! params)]
[_ (void)]))
;;
;; Requests
;;;;;;;;;;;;;
(define (initialize id params)
(match params
[(hash-table ['processId (? (or/c number? (json-null)) process-id)]
['capabilities (? jsexpr? capabilities)])
(define sync-options
(hasheq 'openClose #t
'change TextDocSync-Incremental
'willSave #f
'willSaveWaitUntil #f))
(define renameProvider
(match capabilities
[(hash-table ['textDocument
(hash-table ['rename
(hash-table ['prepareSupport #t])])])
(hasheq 'prepareProvider #t)]
[_ #t]))
(define server-capabilities
(hasheq 'textDocumentSync sync-options
'hoverProvider #t
'definitionProvider #t
'referencesProvider #t
'completionProvider (hasheq 'triggerCharacters (list "("))
'signatureHelpProvider (hasheq 'triggerCharacters (list " " ")" "]"))
'renameProvider renameProvider
'documentHighlightProvider #t
'documentSymbolProvider #t
'documentFormattingProvider #t
'documentRangeFormattingProvider #t
'documentOnTypeFormattingProvider (hasheq 'firstTriggerCharacter ")" 'moreTriggerCharacter (list "\n" "]"))))
(define resp (success-response id (hasheq 'capabilities server-capabilities)))
(set! already-initialized? #t)
resp]
[_
(error-response id INVALID-PARAMS "initialize failed")]))
(define (shutdown id)
(set! already-shutdown? #t)
(success-response id (json-null)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(provide
(contract-out
[process-message
(jsexpr? . -> . void?)]))