Skip to content

Instantly share code, notes, and snippets.

@jaawerth
Last active June 11, 2021 14:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jaawerth/5306c267919721ba984884fc05669ac5 to your computer and use it in GitHub Desktop.
Save jaawerth/5306c267919721ba984884fc05669ac5 to your computer and use it in GitHub Desktop.
; lie to gist that this is clojure for syntax highlighting
; vim: ft=clojure
(require-macros :meta-macros)
(local (mpack Session Tcp Socket) (values (require :mpack)
(require :nvim.session)
(require :nvim.tcp_stream)
(require :nvim.socket_stream)))
(local (fmt join) (values string.format table.concat))
; an api.mpack file needs to be generated from /path/to/neovim/scripts/vim_gendoc.py
; which only exists in the neovim nightlies for 0.5.0
(fn get-api-doc [mpack-path]
(let [fh (io.open (or mpack-path (os.getenv :NVIM_APIDOC_MPACK) "./api.mpack"))
(r-ok raw) (when fh (pcall fh.read fh "*a"))
(ok docs) (when r-ok (pcall mpack.unpack raw))]
(when ok docs)))
(λ mk-api-func [sess fn-info ?api-doc]
(meta/with (partial sess:request fn-info.name)
(local meta {:fnl/arglist []
:fnl/docstring (if (not ?api-doc) ""
(join ?api-doc.doc "\n"))
:nvim/name fn-info.name
:nvim/method? fn-info.method
:nvim/return-type fn-info.return_type
})
(when fn-info.parameters
(local sig [])
(each [i [type-inf arg] (ipairs fn-info.parameters)]
(tset meta.fnl/arglist i arg)
(tset sig i (.. arg ":" type-inf)))
(tset meta :fnl/docstring
(fmt "%s\n\nnvim api call: %s%s" meta.fnl/docstring
fn-info.name
(match (join sig " ") "" ""
s (.. "\nSignature: [" s "]")))))
meta))
(fn mk-client [conn]
(local api-doc (get-api-doc))
(local conn
(match conn
{: host : port} (Tcp.open host port)
{: socket} (Socket.open socket)
_ (error "connection requires {: host : port} or {: socket}")))
(local session (Session.new conn))
(local (info-ok [api-info-n api-info])
(session:request "nvim_get_api_info"))
(local client {:session session :_conn conn :api {}})
(each [_ v (ipairs api-info.functions)]
(when (not v.deprecated_since)
(local f (mk-api-func session v (-?> api-doc (. v.name))))
(tset client.api (v.name:gsub "^nvim_" "") f)))
client)
{:connect mk-client}
; lie to gist that this is clojure for syntax highlighting
; vim: ft=clojure
; metadata manipulation macros
; used by metadata macros to tell whether metadata is enabled
(local meta-enabled (pcall _SCOPE.specials.doc
(list (sym :doc) (sym :doc)) _SCOPE _CHUNK))
(fn meta/when-enabled [...]
"Execute body in an implicit `do` when metadata is enabled. Otherwise,
contents are excluded from compiled output. Always returns nil."
(when meta-enabled `(do ,...)))
(λ meta/with [func ...]
"Accepts and always returns func. When metadata is enabled, evaluates body
in an implicit `let` with the global metadata table bound to `$metadata`. If
body returns a table, it's set as the metadata of func. The $metadata api is:
Get/set entire metadata for a function:
(. $metadata some-func) ; get func's metadata tbl
(tset $metadata func all-metadata-for-somefunc) ; set func's metadata tbl
($metadata:get func key) ; get meta field for func
($metadata:set func key value) ; set meta field for func
($metadata:setall func key1 val1 key2 val2 ...) ; set metadata k/v pairs
The built-in metadata keys are :fnl/docstring and :fnl/arglist."
(if (not meta-enabled) func
(let [meta-sym (sym :$metadata)]
`(let [func# ,func
,meta-sym (. (require :fennel) :metadata)]
(local fn-meta# (do ,...))
(when (= :table (type fn-meta#))
(each [k# v# (pairs fn-meta#)]
(: ,meta-sym :set func# k# v#)))
func#))))
{: meta/with : meta/when-enabled }
@jaawerth
Copy link
Author

client-screenshot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment