Skip to content

Commit da5a386

Browse files
committed
add boilerplate for fennel plugin with nfnl
1 parent 8478c3a commit da5a386

28 files changed

Lines changed: 8624 additions & 50 deletions

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
lua/**/*.lua linguist-generated
2+
lua/example/nfnl/**/*.lua linguist-vendored

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
deps/

.ignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
lua/**/*.lua

.nfnl.fnl

Lines changed: 9 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,9 @@
1-
{;; Enables verbose notifications from nfnl, including notifications about
2-
;; when it starts up and when it compiles successfully. Useful for debugging
3-
;; the plugin itself and checking that it's running when you expect it to.
4-
:verbose false
5-
6-
;; When false, will not write the protective `-- [nfnl] ...` header to the resulting .lua files.
7-
;; It will also prevent nfnl from checking for this header before overwriting .lua files.
8-
;; Intended for users who wish to write shebang comments at the top of their .lua for easier execution.
9-
:header-comment true
10-
11-
:orphan-detection
12-
{;; Automatically invoke :NfnlFindOrphans whenever you write to a .fnl file. This acts as a passive
13-
;; garbage collection check and will warn you about dangling .lua files left over from .fnl deletions or renames.
14-
;; If an orphan is found, you can use :NfnlDeleteOrphans to delete all of the files listed
15-
;; automatically. The deletion command will NOT prompt you, so make sure you check the list first!
16-
:auto? true
17-
18-
;; If you embed nfnl, for example, in your Lua directory then nfnl will detect those files as orphans.
19-
;; You can add Lua patterns here to tell nfnl which Lua paths are okay and should not be counted as orphans.
20-
;; Example: ["lua/nfnl/"]
21-
:ignore-patterns []}
22-
23-
;; Passed to fennel.compileString when your code is compiled.
24-
;; See https://fennel-lang.org/api for more information.
25-
:compiler-options {;; Disables ansi escape sequences in compiler output.
26-
:error-pinpoint false}
27-
28-
;; Warning! In reality these paths are absolute and set to the root directory
29-
;; of your project (where your .nfnl.fnl file is). This means even if you
30-
;; open a .fnl file from outside your project's cwd the compiler will still
31-
;; find your macro files. If you use relative paths like I'm demonstrating here
32-
;; then macros will only work if your cwd is in the project you're working on.
33-
34-
;; They also use OS specific path separators, what you see below is just an example really.
35-
;; I'm not including nfnl's directory from your runtimepath, but it would be there by default.
36-
;; See :rtp-patterns below for more information on including other plugins in your path.
37-
38-
;; String to set the compiler's fennel.path to before compilation.
39-
:fennel-path "/home/.../?.fnlm;/home/.../?/init.fnlm;/home/.../fnl/?.fnlm;/home/.../fnl/?/init.fnlm;/home/.../?.fnl;/home/.../?/init.fnl;/home/.../?/init-macros.fnl;/home/.../fnl/?.fnl;/home/.../fnl/?/init.fnl;/home/.../fnl/?/init-macros.fnl"
40-
41-
;; String to set the compiler's fennel.macro-path to before compilation.
42-
:fennel-macro-path "/home/.../?.fnlm;/home/.../?/init.fnlm;/home/.../fnl/?.fnlm;/home/.../fnl/?/init.fnlm;/home/.../?.fnl;/home/.../?/init.fnl;/home/.../?/init-macros.fnl;/home/.../fnl/?.fnl;/home/.../fnl/?/init.fnl;/home/.../fnl/?/init-macros.fnl"
43-
44-
;; A list of glob patterns (autocmd pattern syntax) of files that
45-
;; should be compiled. This is used as configuration for the BufWritePost
46-
;; autocmd, so it'll only apply to buffers you're interested in.
47-
;; Will use backslashes on Windows.
48-
;; Defaults to compiling all .fnl files, you may want to limit it to your fnl/ directory.
49-
:source-file-patterns ["fnl/**/*.fnl"]
50-
}
1+
(local core (require :eca.nfnl.core))
2+
(local config (require :eca.nfnl.config))
3+
(local defaults (config.default))
4+
5+
{:compiler-options (core.merge
6+
defaults.compiler-options
7+
{:compilerEnv _G})
8+
:source-file-patterns [".nvim.fnl" "plugin/*.fnl" "fnl/**/*.fnl"]
9+
:orphan-detection {:ignore-patterns ["lua/eca/nfnl/"]}}

Makefile

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Makefile for ECA Neovim plugin testing
2+
3+
.PHONY: test deps clean
4+
5+
# Download dependencies for testing
6+
deps: deps/plenary
7+
8+
deps/plenary:
9+
mkdir -p deps
10+
git clone --filter=blob:none https://github.com/nvim-lua/plenary.nvim.git
11+
12+
# Run all tests
13+
test: deps
14+
./script/test
15+
16+
# Clean up dependencies
17+
clean:
18+
rm -rf deps/

fnl/eca/init.fnl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
(local {: autoload} (require :eca.nfnl.module))
2+
(local notify (autoload :eca.nfnl.notify))
3+
4+
(fn setup []
5+
(notify.info "Hello, World!"))
6+
7+
{: setup}

fnl/eca/nfnl/macros.fnlm

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
(fn time [...]
2+
`(let [start# (vim.loop.hrtime)
3+
result# (do ,...)
4+
end# (vim.loop.hrtime)]
5+
(print (.. "Elapsed time: " (/ (- end# start#) 1000000) " msecs"))
6+
result#))
7+
8+
(fn conditional-let [branch bindings ...]
9+
(assert (= 2 (length bindings)) "expected a single binding pair")
10+
11+
(let [[bind-expr value-expr] bindings]
12+
(if
13+
;; Simple symbols
14+
;; [foo bar]
15+
(sym? bind-expr)
16+
`(let [,bind-expr ,value-expr]
17+
(,branch ,bind-expr ,...))
18+
19+
;; List / values destructure
20+
;; [(a b) c]
21+
(list? bind-expr)
22+
(do
23+
;; Even if the user isn't using the first slot, we will.
24+
;; [(_ val) (pcall #:foo)]
25+
;; => [(bindGENSYM12345 val) (pcall #:foo)]
26+
(when (= `_ (. bind-expr 1))
27+
(tset bind-expr 1 (gensym "bind")))
28+
29+
`(let [,bind-expr ,value-expr]
30+
(,branch ,(. bind-expr 1) ,...)))
31+
32+
;; Sequential and associative table destructure
33+
;; [[a b] c]
34+
;; [{: a : b} c]
35+
(table? bind-expr)
36+
`(let [value# ,value-expr
37+
,bind-expr (or value# {})]
38+
(,branch value# ,...))
39+
40+
;; We should never get here, but just in case.
41+
(assert (.. "unknown bind-expr type: " (type bind-expr))))))
42+
43+
(fn if-let [bindings ...]
44+
(assert (<= (length [...]) 2) (.. "if-let does not support more than two branches"))
45+
(conditional-let `if bindings ...))
46+
47+
(fn when-let [bindings ...]
48+
(conditional-let `when bindings ...))
49+
50+
{: time
51+
: if-let
52+
: when-let}

fnl/eca/nfnl/macros/aniseed.fnlm

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
;; Copied over from Aniseed. Contains all of the def* module macro systems.
2+
;; https://github.com/Olical/aniseed
3+
4+
;; This has been heavily slimmed down from the original implementation, the
5+
;; `(module ...) macro can now ONLY define your module, it can not be used
6+
;; to require dependencies.
7+
8+
;; We had to slim things down because the Fennel compiler no longer supports
9+
;; the weird tricks we were using.
10+
11+
;; In nfnl they are not automatically required, you must use import-macros to
12+
;; require them explicitly when migrating your Aniseed based projects.
13+
14+
;; Avoids the compiler complaining that we're introducing locals without gensym.
15+
(local mod-str :*module*)
16+
(local mod-sym (sym mod-str))
17+
18+
;; Upserts the existence of the module for subsequent def forms.
19+
;;
20+
;; (module foo
21+
;; {:some-optional-base :table-of-things
22+
;; :to-base :the-module-off-of})
23+
(fn module [mod-name mod-base]
24+
`(local
25+
,mod-sym
26+
(let [pkg# (require :package)]
27+
(tset pkg#.loaded ,(tostring mod-name) ,(or mod-base {}))
28+
(. pkg#.loaded ,(tostring mod-name)))))
29+
30+
(fn def- [name value]
31+
`(local ,name ,value))
32+
33+
(fn def [name value]
34+
`(local ,name (do (tset ,mod-sym ,(tostring name) ,value) (. ,mod-sym ,(tostring name)))))
35+
36+
(fn defn- [name ...]
37+
`(fn ,name ,...))
38+
39+
(fn defn [name ...]
40+
`(def ,name (fn ,name ,...)))
41+
42+
(fn defonce- [name value]
43+
`(def- ,name (or ,name ,value)))
44+
45+
(fn defonce [name value]
46+
`(def ,name (or (. ,mod-sym ,(tostring name)) ,value)))
47+
48+
{:module module
49+
:def- def- :def def
50+
:defn- defn- :defn defn
51+
:defonce- defonce- :defonce defonce}

fnl/spec/nfnl/example_spec.fnl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
(local {: describe : it} (require :plenary.busted))
2+
(local assert (require :luassert.assert))
3+
(local core (require :eca.nfnl.core))
4+
5+
(describe
6+
"first"
7+
(fn []
8+
(it "gets the first value"
9+
(fn []
10+
(assert.equals 1 (core.first [1 2 3 4 5]))))
11+
12+
(it "returns nil for empty lists or nil"
13+
(fn []
14+
(assert.is_nil (core.first nil))
15+
(assert.is_nil (core.first []))))))

lua/eca/init.lua

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)