language-server: multiple files and ford

Handle multiple files by keeping a map of text buffers.  Also use the
Ford parser so we can parse ford runes.  At some point we should load in
libraries when that happens so we have the appropriate types.

This corresponds to hoon-language-server 0.1.1
This commit is contained in:
Philip Monk 2019-11-04 18:12:23 -08:00
parent 8fe859ad49
commit 0713d3d38c
No known key found for this signature in database
GPG Key ID: B66E1F02604E44EC
3 changed files with 233 additions and 23 deletions

View File

@ -15,8 +15,10 @@
==
::
+$ lsp-req
$% [%sync changes=(list change)]
[%completion position]
$: uri=@t
$% [%sync changes=(list change)]
[%completion position]
==
==
::
+$ change
@ -33,15 +35,12 @@
+$ position
[row=@ud col=@ud]
::
+$ state buf=wall
+$ state bufs=(map uri=@t buf=wall)
--
::
|_ [bow=bowl:gall state]
::
++ this .
++ tall
(ifix [gay gay] tall:vast)
::
++ prep
|= old=(unit state)
^- (quip move _this)
@ -49,7 +48,7 @@
?~ old
:_ this
[ost.bow %connect / [~ /'~language-server-protocol'] %language-server]~
[~ this(buf u.old)]
[~ this(bufs u.old)]
::
:: alerts us that we were bound.
::
@ -63,9 +62,14 @@
++ parser
=, dejs:format
|^
%- of
:~ sync+sync
completion+position
%: ot
uri+so
:- %data
%- of
:~ sync+sync
completion+position
==
~
==
::
++ sync
@ -99,15 +103,18 @@
=/ =lsp-req
%- parser
(need (de-json:html q.u.body.request.inbound-request))
=/ buf (~(gut by bufs) uri.lsp-req *wall)
=^ out-jon buf
?- -.lsp-req
%sync (handle-sync +.lsp-req)
%completion (handle-completion +.lsp-req)
?- +<.lsp-req
%sync (handle-sync buf +>.lsp-req)
%completion (handle-completion buf +>.lsp-req)
==
=. bufs
(~(put by bufs) uri.lsp-req buf)
[[ost.bow %http-response (json-response:app (json-to-octs out-jon))]~ this]
::
++ handle-sync
|= changes=(list change)
|= [buf=wall changes=(list change)]
:- *json
|- ^- wall
?~ changes
@ -117,8 +124,8 @@
=. buf (turn wain trip)
$(changes t.changes)
=/ =tape (zing (join "\0a" buf))
=/ start-pos (get-pos start.u.range.i.changes)
=/ end-pos (get-pos end.u.range.i.changes)
=/ start-pos (get-pos buf start.u.range.i.changes)
=/ end-pos (get-pos buf end.u.range.i.changes)
=. tape
;: weld
(scag start-pos tape)
@ -140,7 +147,7 @@
[[char i.wall] t.wall]
::
++ get-pos
|= position
|= [buf=wall position]
^- @ud
?~ buf
0
@ -156,10 +163,10 @@
(sub a b)
::
++ handle-completion
|= [row=@ud col=@ud]
|= [buf=wall row=@ud col=@ud]
^- [json wall]
=/ =tape (zing (join "\0a" buf))
=/ pos (get-pos row col)
=/ pos (get-pos buf row col)
:_ buf
:: Check if we're on a rune
::

View File

@ -1,3 +1,4 @@
/+ language-server-parser
:: Autocomplete for hoon.
::
=/ debug |
@ -316,13 +317,11 @@
~? > debug %start-magick
=/ magicked txt:(insert-magic pos code)
~? > debug %start-parsing
=/ parser
(ifix [gay gay] tall:vast)
=/ res (lily magicked parser)
=/ res (lily magicked (language-server-parser *beam))
?: ?=(%| -.res)
~? > debug [%parsing-error p.res]
[%| p.res]
:- %&
~? > debug %parsed-good
((cury tab-list-hoon sut) p.res)
((cury tab-list-hoon sut) tssg+sources.p.res)
--

View File

@ -0,0 +1,204 @@
:: lifted directly from ford, should probably be in zuse
=< parse-scaffold
=, ford
|%
++ parse-scaffold
|= src-beam=beam
::
=/ hoon-parser (vang & (en-beam:format src-beam))
|^ ::
%+ cook
|= a=[@ud (list ^cable) (list ^cable) (list ^crane) (list hoon)]
^- scaffold
[[[p q] s]:src-beam a]
::
%+ ifix [gay gay]
;~ plug
:: parses the zuse version, eg "/? 309"
::
;~ pose
(ifix [;~(plug net wut gap) gap] dem)
(easy zuse)
==
:: pareses the structures, eg "/- types"
::
;~ pose
(ifix [;~(plug net hep gap) gap] (most ;~(plug com gaw) cable))
(easy ~)
==
:: parses the libraries, eg "/+ lib1, lib2"
::
;~ pose
(ifix [;~(plug net lus gap) gap] (most ;~(plug com gaw) cable))
(easy ~)
==
::
(star ;~(sfix crane gap))
::
(most gap tall:hoon-parser)
==
:: +beam: parses a hood path and converts it to a beam
::
++ beam
%+ sear de-beam:format
;~ pfix
net
(sear plex (stag %clsg poor)):hoon-parser
==
:: +cable: parses a +^cable, a reference to something on the filesystem
::
:: This parses:
::
:: `library` -> wraps `library` around the library `library`
:: `face=library` -> wraps `face` around the library `library`
:: `*library` -> exposes `library` directly to the subject
::
++ cable
%+ cook |=(a=^cable a)
;~ pose
(stag ~ ;~(pfix tar sym))
(cook |=([face=term tis=@ file=term] [`face file]) ;~(plug sym tis sym))
(cook |=(a=term [`a a]) sym)
==
:: +crane: all runes that start with / which aren't /?, /-, /+ or //.
::
++ crane
=< apex
:: whether we allow tall form
=| allow-tall-form=?
::
|%
++ apex
%+ knee *^crane |. ~+
;~ pfix net
;~ pose
:: `/~` hoon literal
::
(stag %fssg ;~(pfix sig hoon))
:: `/$` process query string
::
(stag %fsbc ;~(pfix bus hoon))
:: `/|` first of many options that succeeds
::
(stag %fsbr ;~(pfix bar parse-alts))
:: `/=` wrap a face around a crane
::
(stag %fsts ;~(pfix tis parse-face))
:: `/.` null terminated list
::
(stag %fsdt ;~(pfix dot parse-list))
:: `/,` switch by path
::
(stag %fscm ;~(pfix com parse-switch))
:: `/&` pass through a series of mark
::
(stag %fspm ;~(pfix pad parse-pipe))
:: `/_` run a crane on each file in the current directory
::
(stag %fscb ;~(pfix cab subcrane))
:: `/;` passes date through a gate
::
(stag %fssm ;~(pfix mic parse-gate))
:: `/:` evaluate at path
::
(stag %fscl ;~(pfix col parse-at-path))
:: `/^` cast
::
(stag %fskt ;~(pfix ket parse-cast))
:: `/*` run a crane on each file with current path as prefix
::
(stag %fstr ;~(pfix tar subcrane))
:: `/!mark/ evaluate as hoon, then pass through mark
::
(stag %fszp ;~(pfix zap ;~(sfix sym net)))
:: `/mark/` passes current path through :mark
::
(stag %fszy ;~(sfix sym net))
==
==
:: +parse-alts: parse a set of alternatives
::
++ parse-alts
%+ wide-or-tall
(ifix [lit rit] (most ace subcrane))
;~(sfix (star subcrane) gap duz)
:: +parse-face: parse a face around a subcrane
::
++ parse-face
%+ wide-or-tall
;~(plug sym ;~(pfix tis subcrane))
;~(pfix gap ;~(plug sym subcrane))
:: +parse-list: parse a null terminated list of cranes
::
++ parse-list
%+ wide-or-tall
fail
;~(sfix (star subcrane) gap duz)
:: +parse-switch: parses a list of [path crane]
::
++ parse-switch
%+ wide-or-tall
fail
=- ;~(sfix (star -) gap duz)
;~(pfix gap net ;~(plug static-path subcrane))
:: +parse-pipe: parses a pipe of mark conversions
::
++ parse-pipe
%+ wide-or-tall
;~(plug (plus ;~(sfix sym pad)) subcrane)
=+ (cook |=(a=term [a ~]) sym)
;~(pfix gap ;~(plug - subcrane))
:: +parse-gate: parses a gate applied to a crane
::
++ parse-gate
%+ wide-or-tall
;~(plug ;~(sfix wide:hoon-parser mic) subcrane)
;~(pfix gap ;~(plug tall:hoon-parser subcrane))
:: +parse-at-path: parses a late bound bath
::
++ parse-at-path
%+ wide-or-tall
;~(plug ;~(sfix late-bound-path col) subcrane)
;~(pfix gap ;~(plug late-bound-path subcrane))
:: +parse-cast: parses a mold and then the subcrane to apply that mold to
::
++ parse-cast
%+ wide-or-tall
;~(plug ;~(sfix wyde:hoon-parser ket) subcrane)
;~(pfix gap ;~(plug till:hoon-parser subcrane))
:: +subcrane: parses a subcrane
::
++ subcrane
%+ wide-or-tall
apex(allow-tall-form |)
;~(pfix gap apex)
:: +wide-or-tall: parses tall form hoon if :allow-tall-form is %.y
::
++ wide-or-tall
|* [wide=rule tall=rule]
?. allow-tall-form wide
;~(pose wide tall)
:: +hoon: parses hoon as an argument to a crane
::
++ hoon
%+ wide-or-tall
(ifix [lac rac] (stag %cltr (most ace wide:hoon-parser)))
;~(pfix gap tall:hoon-parser)
--
:: +static-path: parses a path
::
++ static-path
(sear plex (stag %clsg (more net hasp))):hoon-parser
:: +late-bound-path: a path whose time varies
::
++ late-bound-path
;~ pfix net
%+ cook |=(a=truss a)
=> hoon-parser
;~ plug
(stag ~ gash)
;~(pose (stag ~ ;~(pfix cen porc)) (easy ~))
==
==
--
--