Refactor :?definition to :definition

This commit is contained in:
XeroOl 2022-09-02 18:20:09 -05:00
parent 3f92a293b5
commit 6b642f1d9b
No known key found for this signature in database
GPG Key ID: 9DD4B4B4DAED0322
7 changed files with 113 additions and 75 deletions

View File

@ -67,10 +67,10 @@ later by fennel-ls.language to answer requests from the client."
(if (sym? binding)
(let [definition
{: binding
: ?definition
:?keys (if (not= 0 (length keys))
(fcollect [i 1 (length keys)]
(. keys i)))}]
:definition ?definition
:keys (if (< 0 (length keys))
(fcollect [i 1 (length keys)]
(. keys i)))}]
(tset (. definitions-by-scope scope) (tostring binding) definition)
(tset definitions binding definition))
(= :table (type binding))
@ -90,7 +90,7 @@ later by fennel-ls.language to answer requests from the client."
(tset (. definitions-by-scope scope) ;; !!! TODO somehow insert into child scope
(tostring name)
{:binding name
:?definition ast})))
:definition ast})))
(λ define-function-args [ast scope]
;; add the definitions of function arguments to the definitions
@ -99,18 +99,18 @@ later by fennel-ls.language to answer requests from the client."
(where [_fn args] (fennel.sequence? args)) args
(where [_fn _name args] (fennel.sequence? args)) args))
(each [_ argument (ipairs args)]
(define nil argument scope))) ;; we say function arguments are set to nil ;; !!! parent or child?
(define nil argument scope))) ;; we say function arguments are set to nil
(λ define-function [ast scope]
;; handle the definitions of a function
(define-function-name ast scope))
(λ compile-fn [ast scope]
(tset scopes ast scope) ;; update scope
(tset scopes ast scope)
(define-function-args ast scope))
(λ compile-do [ast scope]
(tset scopes ast scope)) ;; update scope
(tset scopes ast scope))
(λ call [ast scope]
(tset scopes ast scope)
@ -129,7 +129,8 @@ later by fennel-ls.language to answer requests from the client."
(msg:find "expected closing delimiter")
(msg:find "expected body expression")
(msg:find "expected whitespace before opening delimiter")
(msg:find "malformed multisym")))
(msg:find "malformed multisym")
(msg:find "expected at least one pattern/body pair")))
(λ on-compile-error [_ msg ast call-me-to-reset-the-compiler]
(let [range (or (message.ast->range ast file)
@ -168,7 +169,7 @@ later by fennel-ls.language to answer requests from the client."
{:name "fennel-ls"
:versions ["1.3.0"]
:symbol-to-expression reference
:call call
: call
:destructure define
:assert-compile on-compile-error
:parse-error on-parse-error

View File

@ -17,40 +17,57 @@ user code."
(.. "```fnl\n" str "\n```"))
(local width 80)
(fn fn-format [name args docstring]
(.. "(fn"
(if name (.. " " (tostring name)) "")
(.. " " (view args {:one-line? true :prefer-colon? true}))
" ...)"
(fn fn-format [special name args docstring]
(.. (code-block (.. "(fn"
(if name (.. " " (tostring name)) "")
(.. " " (view args
{:one-line? true
:prefer-colon? true}))
" ...)"))
(if docstring (.. "\n" docstring) "")))
(λ fn? [sym]
(if (sym? sym)
(let [sym (tostring sym)]
(or (= sym "fn")
(= sym "λ")
(= sym "lambda")))))
(λ hover-format [result]
"Format code that will appear when the user hovers over a symbol"
(code-block
(match result.?definition
;; name + docstring
(where [-fn- name args docstring body]
(and (sym? name)
(type= args :table)
(type= docstring :string)))
(fn-format name args docstring)
;; docstring
(where [-fn- args docstring body]
(and (type= args :table)
(type= docstring :string)))
(fn-format nil args docstring)
;; name
(where [-fn- name args]
(and (sym? name)
(type= args :table)))
(fn-format name args nil)
;; none
(where [-fn- args]
(and (type= args :table)))
(fn-format nil args nil)
?anything-else
(if result.?keys
(view result.?keys)
(view ?anything-else {:prefer-colon? true})))))
(match result.definition
;; name + docstring
(where [special name args docstring body]
(fn? special)
(sym? name)
(type= args :table)
(type= docstring :string))
(fn-format special name args docstring)
;; docstring
(where [special args docstring body]
(fn? special)
(type= args :table)
(type= docstring :string))
(fn-format special nil args docstring)
;; name
(where [special name args]
(fn? special)
(sym? name)
(type= args :table))
(fn-format special name args nil)
;; none
(where [special args]
(fn? special)
(type= args :table))
(fn-format special nil args nil)
?anything-else
(code-block
(if (-?>> result.keys length (< 0))
(.. "ERROR, I don't know how to show this "
"(. "
(view ?anything-else {:prefer-colon? true}) " "
(view result.keys {:prefer-colon? true}) ")")
(view ?anything-else {:prefer-colon? true})))))
{: hover-format}

View File

@ -79,7 +79,7 @@ Every time the client sends a message, it gets handled by a function in the corr
(language.search-main self file symbol))
(result result-file)
(message.range-and-uri
(or result.binding result.?definition)
(or result.binding result.definition)
result-file)
(catch _ nil))))
@ -108,15 +108,36 @@ Every time the client sends a message, it gets handled by a function in the corr
file.scope)]
(collect-scope scope typ callback ?target)))
(λ requests.textDocument/completion [self send {: position :textDocument {: uri}}]
(let [file (state.get-by-uri self uri)
byte (pos->byte file.text position.line position.character)
(?symbol parents) (language.find-symbol file.ast byte)]
(λ scope-completion [file byte ?symbol parents]
(let [result []]
(find-things-in-scope file parents :manglings #{:label $} result)
(find-things-in-scope file parents :macros #{:label $} result)
(find-things-in-scope file parents :specials #{:label $} result)
(icollect [_ k (ipairs file.allowed-globals) &into result] {:label k}))))
(icollect [_ k (ipairs file.allowed-globals) &into result]
{:label k})))
(λ field-completion [self file symbol split]
(match (. file.references symbol)
ref
(let [stack (fcollect [i (- (length split) 1) 2 -1]
(. split i))]
(match-try (language.search-assignment self file ref stack)
{: definition}
(match (values definition (type definition))
(str :string) (icollect [k v (pairs string)]
{:label k})
(tbl :table) (icollect [k v (pairs tbl)]
(if (= (type k) :string)
{:label k})))
(catch _ nil)))))
(λ requests.textDocument/completion [self send {: position :textDocument {: uri}}]
(let [file (state.get-by-uri self uri)
byte (pos->byte file.text position.line position.character)
(?symbol parents) (language.find-symbol file.ast byte)]
(match (-?> ?symbol utils.multi-sym-split)
(where (or nil [_ nil])) (scope-completion file byte ?symbol parents)
[a b &as split] (field-completion self file ?symbol split))))
(λ notifications.textDocument/didChange [self send {: contentChanges :textDocument {: uri}}]
(local file (state.get-by-uri self uri))

View File

@ -16,7 +16,8 @@ the data provided by compiler.fnl."
(var search nil) ;; all of the search functions are mutually recursive
(λ search-assignment [self file {: binding : ?definition : ?keys &as assignment} stack]
(λ search-assignment [self file {: binding :definition ?definition :keys ?keys &as assignment}
stack]
(if (= 0 (length stack))
(values assignment file) ;; BASE CASE!!
(do
@ -36,7 +37,7 @@ the data provided by compiler.fnl."
(if (. tbl (. stack (length stack)))
(search self file (. tbl (table.remove stack)) stack)
(= 0 (length stack))
(values {:?definition tbl} file) ;; BASE CASE !!
(values {:definition tbl} file) ;; BASE CASE !!
nil)) ;; BASE CASE Give up
(λ search-list [self file call stack]
@ -64,7 +65,7 @@ the data provided by compiler.fnl."
(sym? item) (search-symbol self file item stack)
(list? item) (search-list self file item stack)
(= :table (type item)) (search-table self file item stack)
(= 0 (length stack)) {:?definition item} ;; BASE CASE !!
(= 0 (length stack)) {:definition item} ;; BASE CASE !!
(error (.. "I don't know what to do with " (view item))))))
(λ search-main [self file symbol]
@ -82,11 +83,11 @@ the data provided by compiler.fnl."
(search-assignment self file ref stack)
(_ def)
(do
(if def.?keys
(fcollect [i (length def.?keys) 1 -1 &into stack]
(. def.?keys i)))
(search self file def.?definition stack))))
;; (search self file def.?definition stack))))
(if def.keys
(fcollect [i (length def.keys) 1 -1 &into stack]
(. def.keys i)))
(search self file def.definition stack))))
;; (search self file def.definition stack))))
(λ past? [?ast byte]
;; check if a byte is past an ast object
@ -148,4 +149,5 @@ the data provided by compiler.fnl."
{: find-symbol
: search-main
: search-assignment
: search}

View File

@ -69,7 +69,7 @@
(check-completion "(fn foo [arg1 arg2 arg3]\n )" 1 2 [:arg1 :arg2 :arg3]))
(it "suggests function arguments at the top scope of the function"
(check-completion "(fn foo [arg1 arg2 arg3]\n (do (do (do ))))" 1 14 [:arg1 :arg2 :arg3])))
(check-completion "(fn foo [arg1 arg2 arg3]\n (do (do (do ))))" 1 14 [:arg1 :arg2 :arg3]))
;; ;; Scope Ordering Rules
;; (it "does not suggest locals past the suggestion location when a symbol is partially typed")
@ -88,7 +88,14 @@
;; (it "doesn't suggest macros in the middle of a list (open paren required)")
;; (it "doesn't suggest macros at the very top level")
;; (it "suggests fields of tables")
(it "suggests fields of tables"
(check-completion
"(let [my-table {:foo 10 :bar 20}]\n my-table.)))"
1 11
[:foo :bar]
[:_G :local :doto :1]))) ;; no globals, specials, macros, or others
;; (it "suggests fields of strings"))
;; (it "suggests known fn fields of tables when using a method call multisym")
;; (it "suggests known fn keys when using the `:` special")
;; (it "suggests known keys when using the `.` special")

View File

@ -41,4 +41,7 @@
(check "hover.fnl" 9 30 "```fnl\n:colon-string\n```"))
(it "hovers over a literal nil"
(check "hover.fnl" 12 9 "```fnl\nnil\n```")))
(check "hover.fnl" 12 9 "```fnl\nnil\n```"))
(it "hovers over λ function"
(check "hover.fnl" 18 6 "```fnl\n(fn lambda-fn [arg1 arg2] ...)\n```\ndocstring")))

View File

@ -12,22 +12,9 @@
(local empty nil)
(print empty)
(fn sd [] "short docstring"
(λ lambda-fn [arg1 arg2]
"docstring"
(print "body")
nil)
(fn ld [arg1]
"long docstring
This function has a long docstring, and returns nil.
The docstring has newlines and markdown and stuff in it.
```fnl
(ld 100 100) ;; ==> nil
```
@arg arg1 is ignored
@arg arg2 is ignored.
@returns nil"
(let [result nil]
result))
(ld (sd))
(lambda-fn 1 2)