├── .dockerignore ├── .fs.test ├── .gitattributes ├── .github ├── CODE_OF_CONDUCT.md ├── FUNDING.yml └── workflows │ ├── benchmark.yaml │ ├── luarocks.yml │ └── test.yaml ├── .gitignore ├── .ignore ├── .nfnl.fnl ├── .nvim.fnl ├── .nvim.lua ├── CONTRIBUTING.md ├── Dockerfile ├── README.adoc ├── UNLICENSE ├── deps.edn ├── dev ├── clojure │ ├── nrepl-babashka.sh │ ├── nrepl-base.sh │ ├── nrepl-cider.sh │ ├── nrepl-piggieback-cider.sh │ ├── nrepl-shadow.sh │ ├── public │ │ └── index.html │ └── src │ │ └── dev │ │ ├── append.clj │ │ ├── bar.clj │ │ ├── bb-sandbox.clj │ │ ├── foo.cljs │ │ └── sandbox.cljc ├── common-lisp │ ├── README.adoc │ ├── collider.lisp │ ├── install-quicklisp.sh │ ├── minimal.lisp │ ├── ros-swank-server.sh │ ├── sandbox.lisp │ └── swank-server.sh ├── fennel │ ├── .lnvim.fnl │ ├── append.fnl │ ├── deps.sh │ ├── nrepl-jeejah.sh │ └── sandbox.fnl ├── guile │ ├── .gitignore │ ├── .nvim.fnl │ ├── .nvim.lua │ ├── nrepl.sh │ ├── repl.sh │ └── sandbox.scm ├── hy │ ├── matplot-demo.hy │ └── sandbox.hy ├── janet │ ├── append.janet │ ├── netrepl.sh │ ├── other.janet │ └── sandbox.janet ├── julia │ └── sandbox.jl ├── lua │ ├── api-example.lua │ ├── other.lua │ └── sandbox.lua ├── python │ └── sandbox.py ├── racket │ ├── deps.sh │ ├── nrepl-client-spike.fnl │ ├── nrepl-ogion.sh │ ├── other.rkt │ ├── sandbox.rkt │ ├── stacker-test.rkt │ └── stacker.rkt ├── rust │ ├── readme.md │ └── sandbox.rs ├── scheme │ └── sandbox.scm ├── snd-s7 │ ├── one-tone.snd │ ├── sandbox.scm │ └── three-tone.snd └── sql │ ├── pg-docker.sh │ └── sandbox.sql ├── doc ├── conjure-client-clojure-nrepl.txt ├── conjure-client-common-lisp-swank.txt ├── conjure-client-fennel-aniseed.txt ├── conjure-client-fennel-nfnl.txt ├── conjure-client-fennel-stdio.txt ├── conjure-client-guile-socket.txt ├── conjure-client-hy-stdio.txt ├── conjure-client-janet-netrepl.txt ├── conjure-client-janet-stdio.txt ├── conjure-client-julia-stdio.txt ├── conjure-client-lua-neovim.txt ├── conjure-client-python-stdio.txt ├── conjure-client-racket-stdio.txt ├── conjure-client-rust-evcxr.txt ├── conjure-client-scheme-stdio.txt ├── conjure-client-snd-s7-stdio.txt ├── conjure-client-sql-stdio.txt └── conjure.txt ├── docs ├── CNAME ├── images │ ├── github.png │ └── lillian.png ├── index.html ├── school └── styles │ ├── main.css │ └── normalize.css ├── fnl ├── conjure-benchmark │ ├── bencode.fnl │ └── run.fnl ├── conjure-spec │ ├── .fs.test │ ├── bridge_spec.fnl │ ├── client │ │ ├── clojure │ │ │ └── nrepl │ │ │ │ ├── action_spec.fnl │ │ │ │ ├── auto-repl_spec.fnl │ │ │ │ └── init_spec.fnl │ │ ├── fennel │ │ │ ├── aniseed_spec.fnl │ │ │ └── nfnl_spec.fnl │ │ └── sql │ │ │ └── stdio_spec.fnl │ ├── client_spec.fnl │ ├── config_spec.fnl │ ├── dynamic_spec.fnl │ ├── extract_spec.fnl │ ├── fs_spec.fnl │ ├── linked-list_spec.fnl │ ├── process_spec.fnl │ ├── promise_spec.fnl │ ├── remote │ │ ├── stdio2_spec.fnl │ │ ├── stdio_spec.fnl │ │ └── transport │ │ │ ├── base64_spec.fnl │ │ │ ├── bencode_spec.fnl │ │ │ ├── elisp_spec.fnl │ │ │ └── netrepl_spec.fnl │ ├── school_spec.fnl │ ├── stack_spec.fnl │ ├── text_spec.fnl │ ├── util.fnl │ ├── util_spec.fnl │ └── uuid_spec.fnl └── conjure │ ├── bridge.fnl │ ├── buffer.fnl │ ├── client.fnl │ ├── client │ ├── clojure │ │ └── nrepl │ │ │ ├── action.fnl │ │ │ ├── auto-repl.fnl │ │ │ ├── debugger.fnl │ │ │ ├── init.fnl │ │ │ ├── parse.fnl │ │ │ ├── server.fnl │ │ │ ├── state.fnl │ │ │ └── ui.fnl │ ├── common-lisp │ │ └── swank.fnl │ ├── fennel │ │ ├── aniseed.fnl │ │ ├── nfnl.fnl │ │ └── stdio.fnl │ ├── guile │ │ └── socket.fnl │ ├── hy │ │ └── stdio.fnl │ ├── janet │ │ ├── netrepl.fnl │ │ └── stdio.fnl │ ├── julia │ │ └── stdio.fnl │ ├── lua │ │ └── neovim.fnl │ ├── python │ │ └── stdio.fnl │ ├── racket │ │ └── stdio.fnl │ ├── rust │ │ └── evcxr.fnl │ ├── scheme │ │ └── stdio.fnl │ ├── snd-s7 │ │ └── stdio.fnl │ └── sql │ │ └── stdio.fnl │ ├── config.fnl │ ├── dynamic.fnl │ ├── editor.fnl │ ├── eval.fnl │ ├── event.fnl │ ├── extract.fnl │ ├── extract │ └── searchpair.fnl │ ├── fs.fnl │ ├── hook.fnl │ ├── inline.fnl │ ├── linked-list.fnl │ ├── log.fnl │ ├── macros.fnl │ ├── main.fnl │ ├── mapping.fnl │ ├── net.fnl │ ├── nfnl │ ├── macros.fnl │ └── macros │ │ └── aniseed.fnl │ ├── process.fnl │ ├── promise.fnl │ ├── remote │ ├── netrepl.fnl │ ├── nrepl.fnl │ ├── socket.fnl │ ├── stdio-rt.fnl │ ├── stdio.fnl │ ├── stdio2.fnl │ ├── swank.fnl │ └── transport │ │ ├── base64.fnl │ │ ├── bencode.fnl │ │ ├── elisp.fnl │ │ ├── netrepl.fnl │ │ └── swank.fnl │ ├── school.fnl │ ├── sponsors.fnl │ ├── stack.fnl │ ├── text.fnl │ ├── timer.fnl │ ├── tree-sitter.fnl │ ├── util.fnl │ └── uuid.fnl ├── lua ├── conjure-benchmark │ ├── bencode.lua │ └── run.lua ├── conjure-spec │ ├── bridge_spec.lua │ ├── client │ │ ├── clojure │ │ │ └── nrepl │ │ │ │ ├── action_spec.lua │ │ │ │ ├── auto-repl_spec.lua │ │ │ │ └── init_spec.lua │ │ ├── fennel │ │ │ ├── aniseed_spec.lua │ │ │ └── nfnl_spec.lua │ │ └── sql │ │ │ └── stdio_spec.lua │ ├── client_spec.lua │ ├── config_spec.lua │ ├── dynamic_spec.lua │ ├── extract_spec.lua │ ├── fs_spec.lua │ ├── linked-list_spec.lua │ ├── process_spec.lua │ ├── promise_spec.lua │ ├── remote │ │ ├── stdio2_spec.lua │ │ ├── stdio_spec.lua │ │ └── transport │ │ │ ├── base64_spec.lua │ │ │ ├── bencode_spec.lua │ │ │ ├── elisp_spec.lua │ │ │ └── netrepl_spec.lua │ ├── school_spec.lua │ ├── stack_spec.lua │ ├── text_spec.lua │ ├── util.lua │ ├── util_spec.lua │ └── uuid_spec.lua └── conjure │ ├── aniseed │ ├── autoload.lua │ ├── compile.lua │ ├── core.lua │ ├── deps │ │ ├── fennel.lua │ │ ├── fun.lua │ │ └── nvim.lua │ ├── env.lua │ ├── eval.lua │ ├── fennel.lua │ ├── fs.lua │ ├── macros.fnl │ ├── macros │ │ └── autocmds.fnl │ ├── nvim.lua │ ├── nvim │ │ └── util.lua │ ├── setup.lua │ ├── string.lua │ ├── test.lua │ └── view.lua │ ├── bridge.lua │ ├── buffer.lua │ ├── client.lua │ ├── client │ ├── clojure │ │ └── nrepl │ │ │ ├── action.lua │ │ │ ├── auto-repl.lua │ │ │ ├── debugger.lua │ │ │ ├── init.lua │ │ │ ├── parse.lua │ │ │ ├── server.lua │ │ │ ├── state.lua │ │ │ └── ui.lua │ ├── common-lisp │ │ └── swank.lua │ ├── fennel │ │ ├── aniseed.lua │ │ ├── nfnl.lua │ │ └── stdio.lua │ ├── guile │ │ └── socket.lua │ ├── hy │ │ └── stdio.lua │ ├── janet │ │ ├── netrepl.lua │ │ └── stdio.lua │ ├── julia │ │ └── stdio.lua │ ├── lua │ │ └── neovim.lua │ ├── python │ │ └── stdio.lua │ ├── racket │ │ └── stdio.lua │ ├── rust │ │ └── evcxr.lua │ ├── scheme │ │ └── stdio.lua │ ├── snd-s7 │ │ └── stdio.lua │ └── sql │ │ └── stdio.lua │ ├── config.lua │ ├── dynamic.lua │ ├── editor.lua │ ├── eval.lua │ ├── event.lua │ ├── extract.lua │ ├── extract │ └── searchpair.lua │ ├── fs.lua │ ├── hook.lua │ ├── inline.lua │ ├── linked-list.lua │ ├── log.lua │ ├── main.lua │ ├── mapping.lua │ ├── net.lua │ ├── nfnl │ ├── api.lua │ ├── callback.lua │ ├── compile.lua │ ├── config.lua │ ├── core.lua │ ├── fennel.lua │ ├── fs.lua │ ├── init.lua │ ├── module.lua │ ├── notify.lua │ ├── nvim.lua │ ├── repl.lua │ └── string.lua │ ├── process.lua │ ├── promise.lua │ ├── remote │ ├── netrepl.lua │ ├── nrepl.lua │ ├── socket.lua │ ├── stdio-rt.lua │ ├── stdio.lua │ ├── stdio2.lua │ ├── swank.lua │ └── transport │ │ ├── base64.lua │ │ ├── bencode.lua │ │ ├── elisp.lua │ │ ├── netrepl.lua │ │ └── swank.lua │ ├── school.lua │ ├── sponsors.lua │ ├── stack.lua │ ├── text.lua │ ├── timer.lua │ ├── tree-sitter.lua │ ├── util.lua │ └── uuid.lua ├── mise.toml ├── notes ├── clojurists-together-update-1-may-2022.md └── clojurists-together-update-30-june-2022.md ├── package-lock.json ├── package.json ├── plugin ├── conjure.fnl └── conjure.lua ├── project.clj ├── rplugin └── python3 │ └── deoplete │ └── sources │ └── conjure.py ├── scripts ├── docker.sh ├── setup-test-deps ├── sponsors.sh └── test ├── shadow-cljs.edn └── tests.edn /.dockerignore: -------------------------------------------------------------------------------- 1 | .git/ 2 | .lsp/ 3 | .clj-kondo/ 4 | .cpcache/ 5 | -------------------------------------------------------------------------------- /.fs.test: -------------------------------------------------------------------------------- 1 | This is here to test some filesystem related things. 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | lua/**/*.lua linguist-generated 2 | lua/conjure/aniseed linguist-vendored 3 | dev/* -linguist-detectable 4 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: Olical 2 | ko_fi: olical 3 | -------------------------------------------------------------------------------- /.github/workflows/benchmark.yaml: -------------------------------------------------------------------------------- 1 | name: Benchmark 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | benchmark: 7 | strategy: 8 | matrix: 9 | os: [ubuntu-latest] 10 | neovim-version: ["stable"] 11 | 12 | runs-on: ${{ matrix.os }} 13 | 14 | steps: 15 | - uses: actions/checkout@v4 16 | 17 | - name: Mise 18 | uses: jdx/mise-action@v2 19 | 20 | - name: Benchmark 21 | env: 22 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 23 | run: | 24 | mise run -t neovim@${{ matrix.neovim-version }} benchmark 25 | -------------------------------------------------------------------------------- /.github/workflows/luarocks.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Push to Luarocks 3 | 4 | on: 5 | push: 6 | tags: 7 | - "*" 8 | release: 9 | types: 10 | - created 11 | pull_request: # Test the workflow on PR without publishing 12 | workflow_dispatch: 13 | 14 | jobs: 15 | luarocks-upload: 16 | runs-on: ubuntu-22.04 17 | steps: 18 | - uses: actions/checkout@v4 19 | with: 20 | fetch-depth: 0 # Required to count the commits 21 | - name: Get Version 22 | run: echo "LUAROCKS_VERSION=$(git describe --abbrev=0 --tags)" >> $GITHUB_ENV 23 | - name: LuaRocks Upload 24 | uses: nvim-neorocks/luarocks-tag-release@v7 25 | env: 26 | LUAROCKS_API_KEY: ${{ secrets.LUAROCKS_API_KEY }} 27 | with: 28 | version: ${{ env.LUAROCKS_VERSION }} 29 | -------------------------------------------------------------------------------- /.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | test: 7 | strategy: 8 | matrix: 9 | # TODO: Get windows-latest working. 10 | # Currently errors with: ln: failed to create symbolic link '.test/nvim/pack/main/start/conjure' -> '../../../../../': File name too long 11 | os: [ubuntu-latest, macOS-latest] 12 | neovim-version: ["0.9.5", "0.10.4", "stable", "nightly"] 13 | 14 | runs-on: ${{ matrix.os }} 15 | 16 | steps: 17 | - uses: actions/checkout@v4 18 | 19 | - name: Mise 20 | uses: jdx/mise-action@v2 21 | 22 | - name: Cache 23 | uses: actions/cache@v4 24 | with: 25 | path: | 26 | .test/nvim/pack 27 | key: conjure-${{ hashFiles('scripts/setup-test-deps') }} 28 | restore-keys: conjure- 29 | 30 | - name: Test 31 | env: 32 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 33 | run: | 34 | mise run -t neovim@${{ matrix.neovim-version }} test 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.clj-kondo/ 2 | /.lnvim.lua 3 | /test/lua/ 4 | /.cpcache/ 5 | /.cljs_node_repl/ 6 | /.nrepl-port 7 | /doc/tags 8 | /.shadow-cljs/ 9 | /node_modules/ 10 | /dev/clojure/public/ 11 | __pycache__/ 12 | /target/ 13 | /.lein-repl-history 14 | /.direnv 15 | .test/ 16 | -------------------------------------------------------------------------------- /.ignore: -------------------------------------------------------------------------------- 1 | lua/**/*.lua 2 | -------------------------------------------------------------------------------- /.nfnl.fnl: -------------------------------------------------------------------------------- 1 | (local core (require :nfnl.core)) 2 | (local config (require :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/conjure/nfnl/"]}} 10 | -------------------------------------------------------------------------------- /.nvim.fnl: -------------------------------------------------------------------------------- 1 | (local {: autoload} (require :nfnl.module)) 2 | (local reload (autoload :plenary.reload)) 3 | (local notify (autoload :nfnl.notify)) 4 | 5 | (vim.api.nvim_set_keymap 6 | :n "pt" "PlenaryTestFile" {:desc "Run the current test file with plenary."}) 7 | 8 | (vim.api.nvim_set_keymap 9 | :n "pT" "PlenaryBustedDirectory lua/conjure-spec/" {:desc "Run all tests with plenary."}) 10 | 11 | (vim.api.nvim_set_keymap 12 | :n "pr" "" 13 | {:desc "Reload the conjure modules." 14 | :callback (fn [] 15 | (notify.info "Reloading...") 16 | (reload.reload_module "conjure") 17 | (require :conjure.main) 18 | (notify.info "Done!"))}) 19 | 20 | ; (set vim.g.conjure#mapping#enable_defaults false) 21 | ; (set vim.g.conjure#extract#tree_sitter#enabled true) 22 | ; (set vim.g.conjure#client#racket#stdio#auto_enter false) 23 | ; (set vim.g.conjure#client#clojure#nrepl#test#runner "kaocha") 24 | ; (set vim.g.conjure#client#clojure#nrepl#test#pretty_print_test_failures false) 25 | (set vim.g.conjure#filetype#fennel "conjure.client.fennel.nfnl") 26 | ; (set vim.g.conjure#filetype#scheme "conjure.client.snd-s7.stdio") 27 | ; (set vim.g.conjure#debug true) 28 | 29 | ; (set vim.g.conjure#client#scheme#stdio#command "chicken-csi -quiet -:c") 30 | ; (set vim.g.conjure#client#scheme#stdio#prompt_pattern "\n-#;%d-> ") 31 | ; (set vim.g.conjure#client#scheme#stdio#value_prefix_pattern false) 32 | 33 | ; (set vim.g.conjure#filetype#scheme "conjure.client.guile.socket") 34 | ; (set vim.g.conjure#client#guile#socket#pipename "guile-repl.socket") 35 | 36 | ; (set vim.g.conjure#client#python#stdio#command "ipython --classic") 37 | 38 | (set vim.g.conjure#client#clojure#nrepl#refresh#backend "clj-reload") 39 | 40 | (set package.path (.. package.path ";test/lua/?.lua")) 41 | ; (set vim.g.conjure#eval#gsubs {:do-comment ["^%(comment[%s%c]" "(do "]}) 42 | 43 | (comment 44 | (nvim.ex.augroup :conjure_set_state_key_on_dir_changed) 45 | (nvim.ex.autocmd_) 46 | (nvim.ex.autocmd 47 | "DirChanged * call luaeval(\"require('conjure.client')['set-state-key!']('\" . getcwd() . \"')\")") 48 | (nvim.ex.augroup :END)) 49 | -------------------------------------------------------------------------------- /.nvim.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] .nvim.fnl 2 | local _local_1_ = require("nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local reload = autoload("plenary.reload") 5 | local notify = autoload("nfnl.notify") 6 | vim.api.nvim_set_keymap("n", "pt", "PlenaryTestFile", {desc = "Run the current test file with plenary."}) 7 | vim.api.nvim_set_keymap("n", "pT", "PlenaryBustedDirectory lua/conjure-spec/", {desc = "Run all tests with plenary."}) 8 | local function _2_() 9 | notify.info("Reloading...") 10 | reload.reload_module("conjure") 11 | require("conjure.main") 12 | return notify.info("Done!") 13 | end 14 | vim.api.nvim_set_keymap("n", "pr", "", {desc = "Reload the conjure modules.", callback = _2_}) 15 | vim.g["conjure#filetype#fennel"] = "conjure.client.fennel.nfnl" 16 | vim.g["conjure#client#clojure#nrepl#refresh#backend"] = "clj-reload" 17 | package.path = (package.path .. ";test/lua/?.lua") 18 | --[[ (nvim.ex.augroup "conjure_set_state_key_on_dir_changed") (nvim.ex.autocmd_) (nvim.ex.autocmd "DirChanged * call luaeval(\"require('conjure.client')['set-state-key!']('\" . getcwd() . \"')\")") (nvim.ex.augroup "END") ]] 19 | return nil 20 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Conjure 2 | 3 | Conjure is a [Neovim](https://neovim.io) specific Lua plugin written in [Fennel](https://fennel-lang.org/) and compiled to Lua by [nfnl](https://github.com/Olical/nfnl). You will need the nfnl plugin installed to work on Conjure. Don't fear, nfnl is designed to only load and operate on projects already configured to rely on it. So if there's no configuration file it's completely inert, it will only activate when you work on Conjure or other projects built with nfnl. 4 | 5 | It's developed using itself which leads to an extremely tight feedback loop. This makes it easier to move fast without breaking things. 6 | 7 | Now you can open up Conjure's source files (ending in `.fnl`) and evaluate them as you would any other language with Conjure, see `:help conjure`. 8 | 9 | Your changes and evaluations through Conjure only apply to the in memory copy of Conjure. When you write a `.fnl` file with nfnl installed however your Fennel will be compiled to a static `.lua` file automatically. Make sure you commit both your Fennel _and_ Lua file changes! 10 | 11 | Once you're happy with your changes, you can (maybe) write some tests and execute them with `make test`. CircleCI will also run them for you. 12 | 13 | You can run `scripts/docker.sh` to drop into a fresh Ubuntu based Neovim environment with Conjure pre-installed from your working directory. This can be used to verify your changes in a clean room environment. 14 | 15 | ## Branches 16 | 17 | Contrary to old versions of Conjure, we now simply work on branches that target the `main` branch, I no longer use the `develop` staging branch and we can consider that obsolete just like the `master` branch. 18 | 19 | ## Still unsure? 20 | 21 | If you'd like to contribute or are having issues please don't hesitate to get in touch with me through GitHub discussions and issues. You can also find some ways to contact me privately on my personal site, [oli.me.uk](https://oli.me.uk). 22 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:21.10 2 | 3 | RUN apt-get update 4 | RUN apt-get upgrade -y 5 | RUN apt-get install -y software-properties-common 6 | 7 | RUN add-apt-repository ppa:neovim-ppa/stable 8 | RUN apt-get update 9 | RUN apt-get install -y neovim 10 | 11 | CMD nvim 12 | -------------------------------------------------------------------------------- /UNLICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | 26 | -------------------------------------------------------------------------------- /deps.edn: -------------------------------------------------------------------------------- 1 | {:paths ["dev/clojure/src"] 2 | 3 | :deps 4 | {org.clojure/clojure {:mvn/version "1.11.3"} 5 | org.clojure/tools.logging {:mvn/version "1.1.0"} 6 | lambdaisland/kaocha {:mvn/version "1.66.1034"} 7 | nubank/matcher-combinators {:mvn/version "3.9.1"}} 8 | 9 | :aliases 10 | {:nrepl 11 | {:extra-deps 12 | {nrepl/nrepl {:mvn/version "1.1.1"}}} 13 | 14 | :cider 15 | {:extra-deps 16 | {cider/cider-nrepl {:mvn/version "0.47.1"}}} 17 | 18 | :cljs 19 | {:extra-deps 20 | {org.clojure/clojurescript {:mvn/version "1.11.4"}}} 21 | 22 | :piggieback 23 | {:extra-deps 24 | {cider/piggieback {:mvn/version "0.5.3"}}}}} 25 | -------------------------------------------------------------------------------- /dev/clojure/nrepl-babashka.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "5678" > .nrepl-port 4 | bb --nrepl-server 5678 5 | -------------------------------------------------------------------------------- /dev/clojure/nrepl-base.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | clj -A:nrepl \ 4 | -m nrepl.cmdline \ 5 | --interactive 6 | -------------------------------------------------------------------------------- /dev/clojure/nrepl-cider.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | clojure \ 4 | -A:nrepl:cider \ 5 | -m nrepl.cmdline \ 6 | --middleware "[cider.nrepl/cider-middleware]" \ 7 | --interactive 8 | -------------------------------------------------------------------------------- /dev/clojure/nrepl-piggieback-cider.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | clj -A:nrepl:cljs:cider:piggieback \ 4 | -m nrepl.cmdline \ 5 | --middleware "[cider.nrepl/cider-middleware cider.piggieback/wrap-cljs-repl]" \ 6 | --interactive 7 | -------------------------------------------------------------------------------- /dev/clojure/nrepl-shadow.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | npx shadow-cljs watch app 4 | -------------------------------------------------------------------------------- /dev/clojure/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | acme frontend 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /dev/clojure/src/dev/append.clj: -------------------------------------------------------------------------------- 1 | (ns dev.append) 2 | 3 | (comment 4 | (spit "triforce.txt" "Clojure!\n" :append true)) 5 | -------------------------------------------------------------------------------- /dev/clojure/src/dev/bar.clj: -------------------------------------------------------------------------------- 1 | (ns dev.bar) 2 | 3 | (defn xyz [] 4 | (println "This is a Clojure file!")) 5 | 6 | #_(xyz) 7 | -------------------------------------------------------------------------------- /dev/clojure/src/dev/bb-sandbox.clj: -------------------------------------------------------------------------------- 1 | (ns bb-sandbox) 2 | 3 | (def test-vector [1 2 3]) 4 | ;; This should obviously work 5 | (nth test-vector 2) 6 | ;; This should obviously not work 7 | (nth test-vector 3) 8 | -------------------------------------------------------------------------------- /dev/clojure/src/dev/foo.cljs: -------------------------------------------------------------------------------- 1 | (ns dev.foo) 2 | 3 | (defn xyz [] 4 | (println "This is a ClojureScript file!")) 5 | 6 | #_(xyz) 7 | -------------------------------------------------------------------------------- /dev/common-lisp/README.adoc: -------------------------------------------------------------------------------- 1 | = Using Common Lisp with Conjure 2 | 3 | Connecting Common Lisp to Conjure is an easy process if you have used swank, emacs, or quicklisp before. 4 | 5 | Firstly, set up Common Lisp and Quick Lisp as normal. 6 | 7 | Open up the CL REPL in another terminal, then type the following code: 8 | 9 | [source,lisp] 10 | ---- 11 | (ql:quickload :swank) 12 | (swank:create-server :dont-close t) 13 | ---- 14 | 15 | You should now have a swank server started, listening on port `4005`. This is the default port that Conjure will use. 16 | 17 | Now simply open up any `.lisp` file in Conjure, and it will automatically connect to swank. 18 | 19 | -------------------------------------------------------------------------------- /dev/common-lisp/collider.lisp: -------------------------------------------------------------------------------- 1 | (ql:quickload :cl-collider) 2 | 3 | (in-package :sc-user) 4 | (named-readtables:in-readtable :sc) 5 | 6 | ;; please check *sc-synth-program*, *sc-plugin-paths*, *sc-synthdefs-path* 7 | ;; if you have different path then set to 8 | ;; 9 | ;; (setf *sc-synth-program* "/path/to/scsynth") 10 | ;; (setf *sc-plugin-paths* (list "/path/to/plugin_path" "/path/to/extension_plugin_path")) 11 | ;; (setf *sc-synthdefs-path* "/path/to/synthdefs_path") 12 | 13 | ;; `*s*` defines the server for the entire session 14 | ;; functions may use it internally. 15 | 16 | (setf *s* (make-external-server "localhost" :port 48800)) 17 | (server-boot *s*) 18 | 19 | ;; in Linux, maybe you need to call this function 20 | #+linux 21 | (jack-connect) 22 | 23 | ;; Hack music 24 | (defvar *synth*) 25 | (setf *synth* (play (sin-osc.ar [320 321] 0 .2))) 26 | 27 | ;; Stop music 28 | (free *synth*) 29 | 30 | ;; Quit SuperCollider server 31 | (server-quit *s*) 32 | -------------------------------------------------------------------------------- /dev/common-lisp/install-quicklisp.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | curl -o /tmp/ql.lisp http://beta.quicklisp.org/quicklisp.lisp 4 | sbcl --no-sysinit --no-userinit --load /tmp/ql.lisp \ 5 | --eval '(quicklisp-quickstart:install :path "~/.quicklisp")' \ 6 | --eval '(ql:add-to-init-file)' \ 7 | --quit 8 | -------------------------------------------------------------------------------- /dev/common-lisp/minimal.lisp: -------------------------------------------------------------------------------- 1 | (defun coeff (term) 2 | (car term)) 3 | 4 | (defun degree (term) 5 | (cadr term)) 6 | 7 | (degree '(3 4)) 8 | -------------------------------------------------------------------------------- /dev/common-lisp/ros-swank-server.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ros run --eval '(ql:quickload :swank)' --eval '(swank:create-server :dont-close t)' 4 | -------------------------------------------------------------------------------- /dev/common-lisp/sandbox.lisp: -------------------------------------------------------------------------------- 1 | ;;;; Common Lisp Sandbox 2 | 3 | ;; Even when commented out, the defpackage form is searched for the package 4 | ;; name for this buffer by the Conjure Common Lisp client. 5 | (defpackage :sandbox 6 | (:use :cl)) 7 | 8 | (in-package :sandbox) 9 | 10 | *package* 11 | 12 | ;; We can call regular functions 13 | (+ 1 2 3) 14 | 15 | ;; We can define functions 16 | (defun some-function (a b c) 17 | "This is a function that prints the first var 18 | and adds the second two" 19 | (princ a) 20 | (+ b c)) 21 | 22 | ;; Then we can call it: (press K for documentation 23 | (some-function 1 2 3) 24 | 25 | (reverse 26 | (list 1 2 3 "4" "5 6 7")) 27 | 28 | ;; you can of course, quote things out 29 | (quote (list 1 2 3)) 30 | 31 | (print '(list 1 2 3)) 32 | 33 | ;; and define and use macros 34 | 35 | (defmacro do-primes ((var start end) &body body) 36 | (let ((ending-value-name (gensym))) 37 | `(do ((,var (next-prime ,start ) (next-prime (1+ ,var))) 38 | (,ending-value-name ,end)) 39 | ((> ,var ,ending-value-name)) 40 | ,@body))) 41 | 42 | ;; try this for macro expansion: 43 | (macroexpand-1 '(do-primes (ending-value 0 10) (print ending-value))) 44 | 45 | ;; this will show up as an error, 46 | (do-primes (p 0 10) 47 | (format t "~d " p)) 48 | 49 | ;; until you define these functions: (Taken from Practical Common Lisp book) 50 | (defun primep (number) 51 | (when (> number 1) 52 | (loop for fac from 2 to (isqrt number) never (zerop (mod number fac))))) 53 | 54 | (defun next-prime (number) 55 | (loop for n from number when (primep n) return n)) 56 | 57 | ;; Now, evaluating the do-primes form works. 58 | (do-primes (p -1 10) 59 | (format t "~d " p)) 60 | 61 | -------------------------------------------------------------------------------- /dev/common-lisp/swank-server.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | 4 | sbcl --eval "(ql:quickload :swank)" --eval "(swank:create-server :dont-close t)" 5 | -------------------------------------------------------------------------------- /dev/fennel/.lnvim.fnl: -------------------------------------------------------------------------------- 1 | (module conjure.dev.fennel 2 | {require {nvim conjure.aniseed.nvim}}) 3 | 4 | (set nvim.g.conjure#filetype#fennel :conjure.client.fennel.stdio) 5 | (set nvim.g.conjure#debug false) 6 | -------------------------------------------------------------------------------- /dev/fennel/append.fnl: -------------------------------------------------------------------------------- 1 | (module conjure.dev.append 2 | {require {a aniseed.core}}) 3 | 4 | (a.spit "triforce.txt" "Fennel! (running inside Neovim's LuaJIT)\n") 5 | -------------------------------------------------------------------------------- /dev/fennel/deps.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | luarocks install --local jeejah 4 | luarocks install --local fennel 5 | -------------------------------------------------------------------------------- /dev/fennel/nrepl-jeejah.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | eval $(luarocks path) 4 | jeejah --fennel --debug 5 | -------------------------------------------------------------------------------- /dev/fennel/sandbox.fnl: -------------------------------------------------------------------------------- 1 | (fn add [a b] 2 | (+ a b)) 3 | 4 | (local foo "bar") 5 | (print "Hello, World!") 6 | 7 | (+ 1 2) 8 | (add 10 20) 9 | -------------------------------------------------------------------------------- /dev/guile/.gitignore: -------------------------------------------------------------------------------- 1 | *.socket 2 | guile-ares-rs/ 3 | .nrepl-port 4 | -------------------------------------------------------------------------------- /dev/guile/.nvim.fnl: -------------------------------------------------------------------------------- 1 | (set vim.g.conjure#filetype#scheme "conjure.client.guile.socket") 2 | (set vim.g.conjure#client#guile#socket#pipename "guile-repl.socket") 3 | -------------------------------------------------------------------------------- /dev/guile/.nvim.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] Compiled from dev/guile/.nvim.fnl by https://github.com/Olical/nfnl, do not edit. 2 | vim.g["conjure#filetype#scheme"] = "conjure.client.guile.socket" 3 | vim.g["conjure#client#guile#socket#pipename"] = "guile-repl.socket" 4 | return nil 5 | -------------------------------------------------------------------------------- /dev/guile/nrepl.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | git clone https://git.sr.ht/~abcdw/guile-ares-rs 4 | cd guile-ares-rs || exit 5 | make ares-rs 6 | -------------------------------------------------------------------------------- /dev/guile/repl.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -xe 4 | 5 | SOCKET=$(git rev-parse --show-toplevel)/dev/guile/guile-repl.socket 6 | if [[ -f $SOCKET ]]; then rm $SOCKET; fi 7 | guile --listen=$SOCKET 8 | rm $SOCKET 9 | -------------------------------------------------------------------------------- /dev/guile/sandbox.scm: -------------------------------------------------------------------------------- 1 | (define (add a b) 2 | (+ a b)) 3 | 4 | (display "hi") 5 | 6 | (+ 5 6) 7 | (add 1 2) 8 | 9 | (define (print-hi-and-return x) 10 | (begin 11 | (display "Hi") 12 | (newline)) 13 | x) 14 | 15 | (print-hi-and-return 123) 16 | 17 | (define (return-values) 18 | (values 123 "Hi")) 19 | 20 | (return-values) 21 | -------------------------------------------------------------------------------- /dev/hy/matplot-demo.hy: -------------------------------------------------------------------------------- 1 | (+ 10 20) 2 | 3 | (import matplotlib) 4 | (.use matplotlib "Qt5Agg") 5 | (.rcdefaults matplotlib) 6 | (.use matplotlib "Qt5Agg") 7 | 8 | (import [matplotlib [pyplot]]) 9 | 10 | (.ion pyplot) 11 | (pyplot.style.use "default") 12 | (pyplot.style.use "fivethirtyeight") 13 | 14 | (defn test [] 15 | "Plot a list." 16 | (setv fig (.figure pyplot)) 17 | (setv axes (.add_subplot fig)) 18 | (.plot axes (list (range 20))) 19 | {:figure fig :axes axes}) 20 | 21 | (test) 22 | -------------------------------------------------------------------------------- /dev/janet/append.janet: -------------------------------------------------------------------------------- 1 | (-> (file/open "triforce.txt" :a) 2 | (file/write "Janet!\n") 3 | (file/flush) 4 | (file/close)) 5 | -------------------------------------------------------------------------------- /dev/janet/netrepl.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "Be sure to install the dependencies with 'jpm install spork' first." 4 | janet -e "(import spork/netrepl) (netrepl/server)" 5 | -------------------------------------------------------------------------------- /dev/janet/other.janet: -------------------------------------------------------------------------------- 1 | (defn sub 2 | "It subtracts stuff." 3 | [a b] 4 | (- a b)) 5 | 6 | (sub 10 20) 7 | -------------------------------------------------------------------------------- /dev/janet/sandbox.janet: -------------------------------------------------------------------------------- 1 | (import ./other) 2 | 3 | (defn add 4 | "It adds things!" 5 | [a b] 6 | (+ a b)) 7 | 8 | (print "Hello, World!") 9 | (print "\e[32mHello, World!\e[0m") 10 | (print "\0") 11 | (eprint "ohno") 12 | 13 | (do 14 | (print "Hi...") 15 | (range 10)) 16 | 17 | (comment 18 | (explode)) 19 | 20 | (+ (add 10 20) (other/sub 10 5)) 21 | -------------------------------------------------------------------------------- /dev/julia/sandbox.jl: -------------------------------------------------------------------------------- 1 | using Pkg 2 | Pkg.activate("project") 3 | Pkg.activate 4 | 5 | rand(10000) 6 | 7 | 1 + 1 8 | 9 | (a, b) = (1, 2) 10 | 11 | function add(x, y) 12 | println("x is $x and y is $y") 13 | 14 | # Functions return the value of their last statement 15 | x + y 16 | end 17 | 18 | add(5, 6) 19 | # => x is 5 and y is 6 20 | # => 11 21 | 22 | # Compact assignment of functions 23 | f_add(x, y) = x + y # => f_add (generic function with 1 method) 24 | f_add(3, 4) # => 7 25 | 26 | # Function can also return multiple values as tuple 27 | fn(x, y) = x + y, x - y # => fn (generic function with 1 method) 28 | fn(3, 4) # => (7, -1) 29 | 30 | # You can define functions that take a variable number of 31 | # positional arguments 32 | function varargs(args...) 33 | return args 34 | # use the keyword return to return anywhere in the function 35 | end 36 | # => varargs (generic function with 1 method) 37 | 38 | varargs(1, 2, 3) # => (1,2,3) 39 | 40 | # The ... is called a splat. 41 | # We just used it in a function definition. 42 | # It can also be used in a function call, 43 | # where it will splat an Array or Tuple's contents into the argument list. 44 | add([5,6]...) # this is equivalent to add(5,6) 45 | 46 | x = (5, 6) # => (5,6) 47 | add(x...); # this is equivalent to add(5,6) 48 | 49 | 50 | # You can define functions with optional positional arguments 51 | function defaults(a, b, x=5, y=6) 52 | return "$a $b and $x $y" 53 | end 54 | # => defaults (generic function with 3 methods) 55 | 56 | defaults('h', 'g') # => "h g and 5 6" 57 | defaults('h', 'g', 'j') # => "h g and j 6" 58 | defaults('h', 'g', 'j', 'k') # => "h g and j k" 59 | -------------------------------------------------------------------------------- /dev/lua/api-example.lua: -------------------------------------------------------------------------------- 1 | local eval = require("conjure.eval") 2 | local client = require("conjure.client") 3 | local text = require("conjure.text") 4 | 5 | client["with-filetype"]("janet", eval["eval-str"], { 6 | origin = "my-awesome-plugin", 7 | code = "(+ 10 20)", 8 | ["passive?"] = true, 9 | ["on-result"] = function (r) 10 | local clean = text["strip-ansi-escape-sequences"](r) 11 | print("RESULT:", r) 12 | print("CLEANED:", clean) 13 | end 14 | }) 15 | -------------------------------------------------------------------------------- /dev/lua/other.lua: -------------------------------------------------------------------------------- 1 | -- add shouldn't exist, it should only be in sandbox.lua! 2 | print(add(10, 20)) 3 | print(50 + 5) 4 | -------------------------------------------------------------------------------- /dev/lua/sandbox.lua: -------------------------------------------------------------------------------- 1 | -- Evaluate the entire block when cursor is anywhere in it. 2 | local function add (a, b) 3 | return a + b 4 | end 5 | 6 | -- Evaluate function definition when cursor anywhere in it. 7 | -- Otherwise, evaluate entire block. 8 | local sub = function (a, b) 9 | return a - b 10 | end 11 | 12 | -- Evaluate statement when cursor anywhere in it. 13 | sub(2, 42) 14 | 15 | -- Evalutate if statement when cursor anywhere in it. 16 | -- Otherwise evaluate entire block. 17 | local function abs (a) 18 | if a < 0 then 19 | return -a 20 | else 21 | return a 22 | end 23 | end 24 | 25 | -- Evaluate function call when cursor anywhere in function call. 26 | -- Otherwise evaluate print statement. 27 | print(add(10, 20)) 28 | print(sub(10, 20)) 29 | print(abs(-20)) 30 | print(50 + 5) 31 | print("Hello, World!") 32 | 33 | -- Evaluate the entire statement when cursor is anywhere in it. 34 | vim.fn.filereadable('/usr/bin/bash') 35 | -------------------------------------------------------------------------------- /dev/python/sandbox.py: -------------------------------------------------------------------------------- 1 | # Should be able to evaluate all of these. 2 | 3 | def add(a, b): 4 | return a + b 5 | 6 | 7 | add(4, 29) 8 | 9 | 4 + 9 10 | 11 | 5 + 7 + 9 12 | 13 | "hello" 14 | 15 | print("hello world") 16 | 17 | a = "foo" 18 | print(a) 19 | 20 | a, b = [1, 2] 21 | 22 | 23 | def print_things_then_return(): 24 | """ 25 | Print things then return! 26 | """ 27 | for i in range(4): 28 | print(i) 29 | return "all done!" 30 | 31 | 32 | def newline_in_function_bug(): 33 | return "hey\n\n" + "\\n" + "\n" + "ho" 34 | 35 | 36 | newline_in_function_bug() 37 | 38 | print_things_then_return() 39 | 40 | for i in range(20): 41 | print(i) 42 | 43 | 44 | def fn_with_multiline_str(): 45 | description = """ 46 | This is a super long, 47 | descriptive, multiline string. 48 | """ 49 | print(f"Description: {description}") 50 | 51 | 52 | fn_with_multiline_str() 53 | 54 | import csv 55 | from datetime import datetime 56 | 57 | 58 | # Class definition 59 | # - from https://docs.python.org/3/tutorial/classes.html 60 | class Dog: 61 | 62 | def __init__(self, name): 63 | self.name = name 64 | self.tricks = [] 65 | 66 | def add_trick(self, trick): 67 | self.tricks.append(trick) 68 | 69 | d = Dog('Fido') 70 | e = Dog('Buddy') 71 | d.add_trick('roll_over') 72 | e.add_trick('play dead') 73 | d.tricks 74 | e.tricks 75 | 76 | 77 | # Class definition with decorator 78 | # - from https://docs.python.org/3.10/tutorial/classes.html 79 | from dataclasses import dataclass 80 | 81 | @dataclass 82 | class Employee: 83 | name: str 84 | dept: str 85 | salary: int 86 | 87 | john = Employee('john', 'computer lab', 1000) 88 | john.dept 89 | john.salary 90 | 91 | 92 | # Function definition with decorator 93 | # - https://docs.python.org/3.8/library/functools.html?highlight=decorator#functools.cached_property 94 | from functools import lru_cache 95 | 96 | @lru_cache(maxsize=None) 97 | def fib(n): 98 | if n < 2: 99 | return n 100 | return fib(n-1) + fib(n-2) 101 | 102 | [fib(n) for n in range(16)] 103 | # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610] 104 | 105 | fib.cache_info() 106 | # CacheInfo(hits=28, misses=16, maxsize=None, currsize=16) 107 | 108 | 109 | # Asyncio samples 110 | # - Add '-m asyncio' to the python command to evaluate these. 111 | 112 | """ 113 | async def slow_fn(): 114 | return "slow_fn result, this is async!" 115 | 116 | 117 | await slow_fn() 118 | 119 | result = None 120 | 121 | 122 | async def capture(): 123 | global result 124 | result = await slow_fn() 125 | 126 | 127 | await capture() 128 | result 129 | """ 130 | -------------------------------------------------------------------------------- /dev/racket/deps.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | raco pkg install https://gitlab.com/technomancy/ogion.git 4 | -------------------------------------------------------------------------------- /dev/racket/nrepl-ogion.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # TODO Is there a better / shorter way to do this? 4 | racket -e "(require (submod ogion main))" -- --debug 5 | -------------------------------------------------------------------------------- /dev/racket/other.rkt: -------------------------------------------------------------------------------- 1 | #lang racket/base 2 | 3 | (define (sub a b) 4 | (- a b)) 5 | 6 | (sub 3 2) 7 | -------------------------------------------------------------------------------- /dev/racket/sandbox.rkt: -------------------------------------------------------------------------------- 1 | #lang racket/base 2 | 3 | (define (add a b) 4 | (+ a b)) 5 | 6 | (+ 1 2) 7 | (add 10 20) 8 | 9 | (print "Hello, World!") 10 | -------------------------------------------------------------------------------- /dev/racket/stacker-test.rkt: -------------------------------------------------------------------------------- 1 | #lang reader "stacker.rkt" 2 | 4 3 | 8 4 | + 5 | 3 6 | * 7 | -------------------------------------------------------------------------------- /dev/racket/stacker.rkt: -------------------------------------------------------------------------------- 1 | #lang br/quicklang 2 | 3 | ;; You need `raco pkg install --auto beautiful-racket` for this. 4 | ;; The example comes from https://github.com/Olical/conjure/issues/643 5 | 6 | (define (read-syntax path port) 7 | (define src-lines 8 | (port->lines port)) 9 | 10 | (define src-datums 11 | (format-datums '(handle ~a) src-lines)) 12 | 13 | (define module-datum 14 | `(module stacker-mod "stacker.rkt" 15 | ,@src-datums)) 16 | 17 | (datum->syntax #f module-datum)) 18 | 19 | (provide read-syntax) 20 | 21 | (define-macro (stacker-module-begin HANDLE-EXPR ...) 22 | #'(#%module-begin 23 | HANDLE-EXPR ... 24 | (display (first stack)))) 25 | 26 | (provide (rename-out [stacker-module-begin #%module-begin])) 27 | 28 | (define stack empty) 29 | 30 | (define (pop-stack!) 31 | (define arg (first stack)) 32 | (set! stack (rest stack)) 33 | arg) 34 | 35 | (define (push-stack! arg) 36 | (set! stack (cons arg stack))) 37 | 38 | (define (handle [arg #f]) 39 | (cond 40 | [(number? arg) (push-stack! arg)] 41 | [(or (equal? * arg) (equal? + arg)) 42 | (define op-result 43 | (arg (pop-stack!) (pop-stack!))) 44 | (push-stack! op-result)])) 45 | 46 | (provide handle) 47 | 48 | (provide + *) 49 | -------------------------------------------------------------------------------- /dev/rust/readme.md: -------------------------------------------------------------------------------- 1 | # Using rust with conjure 2 | 3 | # Install 4 | Firstly, set up Rust and it's tools as normal. 5 | 6 | Install evcxr: 7 | ```bash 8 | cargo install evcxr_repl 9 | ``` 10 | 11 | For more info on how to install/use evcxr: 12 | https://github.com/google/evcxr/blob/main/evcxr_repl/README.md 13 | https://github.com/google/evcxr/blob/main/COMMON.md 14 | -------------------------------------------------------------------------------- /dev/rust/sandbox.rs: -------------------------------------------------------------------------------- 1 | // Examples from "Evcxr common usage information". 2 | // - https://github.com/evcxr/evcxr/blob/main/COMMON.md 3 | 4 | // With the cursor on the word, pub, evaluate form works. 5 | pub struct User { 6 | username: String 7 | } 8 | 9 | let user = User { username: String::from("John Doe") }; 10 | println!("{}", user.username); 11 | 12 | // The REPL will accept commands that are not legal Rust statements. 13 | // Select and evaluate this to load the rand crate from crates.io: 14 | // :dep rand = { version = "0.7.3" } 15 | let rand_x: u8 = rand::random(); 16 | println!("{}", rand_x); 17 | 18 | // nice error reporting 19 | let err_x = unknown(); 20 | 21 | let x = 0; 22 | let y = 1; 23 | // Select and evaluate this to see what variables have been defined: 24 | // :vars 25 | 26 | let all_values = vec![10, 20, 30, 40, 50]; 27 | // This line with a semi-colon produces an error. Without the semi-colon, it's syntactically OK. 28 | // To verify this, make a selection and evaluate it. 29 | // With a form-node? function defined for the Rust client, we can evaluate the line 30 | // when the cursor is anywhere on the line except on the semi-colon. This sends the line without 31 | // the semi-colon. 32 | all_values[2..3]; 33 | 34 | // This is an error because he variable `some_values` contains a reference with a non-static 35 | // lifetime and can't be persisted. 36 | let some_values = &all_values[2..3]; 37 | -------------------------------------------------------------------------------- /dev/scheme/sandbox.scm: -------------------------------------------------------------------------------- 1 | (define (add a b) 2 | (+ a b)) 3 | 4 | (display "Hello, World!") 5 | 6 | (+ 1 2) 7 | (add 10 20) 8 | -------------------------------------------------------------------------------- /dev/snd-s7/one-tone.snd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Olical/conjure/83c6394f916197d73f2a19538bd5615e08842d10/dev/snd-s7/one-tone.snd -------------------------------------------------------------------------------- /dev/snd-s7/sandbox.scm: -------------------------------------------------------------------------------- 1 | ;; Sample snd/s7 code 2 | ;; 3 | ;;-------------------------------------------------------------------------------- 4 | ;; NOTES: 5 | ;; 6 | ;; 1. This was tested with version 23.5 of snd downloaded from Sourceforge and 7 | ;; compiled on a Macbook Air 13-inch Early 2015 running Monterey (12.6.7). 8 | ;; snd program is compiled without a GUI (--without-gui). 9 | ;; 10 | ;; ********************************************************************** 11 | ;; *** Unfortunately, it doesn't accept multi-line input being sent *** 12 | ;; *** to it from Conjure. *** 13 | ;; ********************************************************************** 14 | ;; 15 | ;; 2. Setting command to "snd" or "snd -noinit" doesn't make a difference in 16 | ;; the snd REPL accepting multi-line input. 17 | ;; 18 | ;; - On the Neovim command line: 19 | ;; :let g:conjure#client#snd#stdio#command="snd -noinit" 20 | ;; :echo g:conjure#client#snd#stdio#command 21 | ;; 22 | ;; 3. Setting command to "snd -noinit" results in no return value from the 23 | ;; REPL. 24 | ;; 25 | ;; 4. Turn on debugging to see what's being sent to and received from the snd 26 | ;; REPL. 27 | ;; 28 | ;; - On the Neovim command line: 29 | ;; :let g:conjure#debug=v:true 30 | ;; :echo g:conjure#debug 31 | ;; 32 | ;;-------------------------------------------------------------------------------- 33 | 34 | ;; From https://github.com/Olical/conjure/issues/507 35 | ;; - @kflak (Kenneth Flak) 06/24/2023 36 | ;; Changed to use test.snd. 37 | ;; - This doesn't work because the snd/s7 REPL that this was originally tested 38 | ;; with. See the NOTES above. 39 | (begin 40 | (open-sound "test.snd") 41 | (scale-channel 0.1) 42 | (save-sound-as "test-scaled.wav")) 43 | 44 | ;; Start here and evaluated in order. 45 | ;; 1. Create a sound consisting of two violin tones and save in "test.snd" file. 46 | ;; test.snd will be overwritten each time that you evaluate this form. 47 | ;; From "clm-load" section of https://ccrma.stanford.edu/software/snd/snd/sndscm.html 48 | (with-sound () (fm-violin 0 1 440 .1) (fm-violin 1 1 660 .1)) ;=> "test.snd" 49 | (play 0) ;; I think this is 0. 50 | (play) ;; What sound instance does this play? Seems like the last one loaded 51 | ;; or created; not played. 52 | 53 | ;; 2. The value passed to scale-channel determines the volume of the sound. 54 | (begin (open-sound "test.snd") (scale-channel 1.5) (save-sound-as "test-scaled.wav")) 55 | (play 1) ;; test-scaled.wav is 1. 56 | (open-sound "test-scaled.wav") 57 | (play 2) ;; should be 2. 58 | 59 | (scale-channel 2.0) ;; This makes the previous sound (#2) lounder. 60 | (play 2) ;; check it out 61 | 62 | ;; 3. Load some other sounds. 63 | ;; This assumes that you started Neovim in the clone of the Conjure repo 64 | ;; on the branch that this is on. 65 | (open-sound "dev/snd-s7/one-tone.snd") 66 | (play 3) 67 | 68 | (open-sound "dev/snd-s7/three-tone.snd") 69 | (play 4) 70 | 71 | -------------------------------------------------------------------------------- /dev/snd-s7/three-tone.snd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Olical/conjure/83c6394f916197d73f2a19538bd5615e08842d10/dev/snd-s7/three-tone.snd -------------------------------------------------------------------------------- /dev/sql/pg-docker.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | docker run \ 4 | --name conjure_postgres_db \ 5 | --rm \ 6 | -p 5432:5432 \ 7 | -e POSTGRES_USER=postgres \ 8 | -e POSTGRES_PASSWORD=postgres \ 9 | -e POSTGRES_DB=postgres \ 10 | postgres 11 | -------------------------------------------------------------------------------- /doc/conjure-client-common-lisp-swank.txt: -------------------------------------------------------------------------------- 1 | *conjure-client-common-lisp-swank* 2 | 3 | ============================================================================== 4 | CONTENTS *conjure-client-common-lisp-swank-contents* 5 | 6 | 1. Introduction ..... |conjure-client-common-lisp-swank-introduction| 7 | 2. Mappings ............. |conjure-client-common-lisp-swank-mappings| 8 | 3. Configuration ... |conjure-client-common-lisp-swank-configuration| 9 | 10 | ============================================================================== 11 | INTRODUCTION *conjure-client-common-lisp-swank-introduction* 12 | 13 | Connecting Common Lisp to Conjure is an easy process if you have used swank, 14 | emacs, or quicklisp before. 15 | 16 | Firstly, set up Common Lisp and Quick Lisp as normal. 17 | 18 | Open up the CL REPL in another terminal, then type the following code: 19 | > 20 | (ql:quickload :swank) 21 | (swank:create-server :dont-close t) 22 | 23 | You should now have a swank server started, listening on port `4005`. This is 24 | the default port that conjure will use. 25 | 26 | Now simply open up any `.lisp` file in conjure, and it will automatically 27 | connect to swank. 28 | > 29 | * https://common-lisp.net/ 30 | 31 | ============================================================================== 32 | MAPPINGS *conjure-client-common-lisp-swank-mappings* 33 | 34 | These mappings are the defaults, you can change them as described in 35 | |conjure-mappings| and |conjure-configuration|. 36 | 37 | See |conjure-client-common-lisp-swank-configuration| for specific 38 | configuration options relevant to these mappings. 39 | 40 | cc Connect to a running swank REPL. 41 | 42 | cd Disconnect from the REPL. 43 | 44 | ============================================================================== 45 | CONFIGURATION *conjure-client-common-lisp-swank-configuration* 46 | 47 | All configuration can be set as described in |conjure-configuration|. 48 | 49 | 50 | *g:conjure#client#common_lisp#swank#mapping#start* 51 | `g:conjure#client#common_lisp#swank#mapping#connect` 52 | Connect to a running swank REPL. 53 | Default: `"cc"` 54 | 55 | *g:conjure#client#common_lisp#swank#mapping#stop* 56 | `g:conjure#client#common_lisp#swank#mapping#disconnect` 57 | Disconnect from the REPL. 58 | Default: `"cd"` 59 | 60 | *g:conjure#client#common_lisp#swank#connection#default_host* 61 | `g:conjure#client#common_lisp#swank#connection#default_host` 62 | The default swank host to connect to. 63 | Default: `"127.0.0.1"` 64 | 65 | *g:conjure#client#common_lisp#swank#connection#default_port* 66 | `g:conjure#client#common_lisp#swank#connection#default_port` 67 | The default swank port to connect to. 68 | Default: `"4005"` 69 | 70 | vim:tw=78:sw=2:ts=2:ft=help:norl:et:listchars= 71 | -------------------------------------------------------------------------------- /doc/conjure-client-fennel-nfnl.txt: -------------------------------------------------------------------------------- 1 | *conjure-client-fennel-nfnl* 2 | 3 | ============================================================================== 4 | CONTENTS *conjure-client-fennel-nfnl-contents* 5 | 6 | 1. Introduction ....... |conjure-client-fennel-nfnl-introduction| 7 | 8 | ============================================================================== 9 | INTRODUCTION *conjure-client-fennel-nfnl-introduction* 10 | 11 | Conjure itself is written in Fennel and compiled to Lua with nfnl 12 | (https://github.com/Olical/nfnl). This client is the default Fennel client and 13 | uses the bundled nfnl version inside of Conjure to evaluate your Fennel code 14 | on demand. 15 | 16 | There are no custom mappings or configurations for this client yet. 17 | 18 | vim:tw=78:sw=2:ts=2:ft=help:norl:et:listchars= 19 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | conjure.oli.me.uk 2 | -------------------------------------------------------------------------------- /docs/images/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Olical/conjure/83c6394f916197d73f2a19538bd5615e08842d10/docs/images/github.png -------------------------------------------------------------------------------- /docs/images/lillian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Olical/conjure/83c6394f916197d73f2a19538bd5615e08842d10/docs/images/lillian.png -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Conjure - Interactive evaluation for Neovim 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 | Lillian the Conjure witch and the Conjure logo 17 | GitHub logo 18 |
19 |
20 | 21 |
22 |
23 | 24 |
25 |
26 | 27 |
28 |
29 | 30 |
31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /docs/school: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | PREFIX="/tmp/conjure-school" 4 | 5 | if [ ! -d $PREFIX ]; then 6 | echo "Downloading Conjure into $PREFIX..." 7 | curl -LJ https://github.com/Olical/conjure/archive/main.zip -o $PREFIX.zip 8 | unzip -qq $PREFIX.zip -d $PREFIX 9 | rm $PREFIX.zip 10 | else 11 | echo "$PREFIX already exists, no need to download." 12 | fi 13 | 14 | nvim \ 15 | --cmd "set rtp+=$PREFIX/conjure-main" \ 16 | --cmd "source $PREFIX/conjure-main/plugin/conjure.lua" \ 17 | -c "au VimEnter * ++nested ConjureSchool" && 18 | echo "I hope you had a great time! Cleaning up $PREFIX and exiting." && 19 | rm -rf $PREFIX 20 | -------------------------------------------------------------------------------- /docs/styles/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: rgb(109,89,122); 3 | background: linear-gradient(180deg, rgba(109,89,122,1) 30%, rgba(53,80,112,1) 100%); 4 | 5 | color: white; 6 | font-family: Arial, Helvetica, sans-serif; 7 | } 8 | 9 | a { 10 | color: white; 11 | } 12 | 13 | .container { 14 | display: flex; 15 | align-items: center; 16 | flex-direction: column; 17 | margin-bottom: 2rem; 18 | } 19 | 20 | .block { 21 | display: flex; 22 | align-items: center; 23 | margin-top: 2rem; 24 | } 25 | 26 | .gap-left { 27 | margin-left: 1rem; 28 | } 29 | 30 | .asciicast { 31 | min-width: 878px; 32 | } 33 | -------------------------------------------------------------------------------- /fnl/conjure-benchmark/bencode.fnl: -------------------------------------------------------------------------------- 1 | (local {: define} (require :conjure.nfnl.module)) 2 | (local core (require :conjure.nfnl.core)) 3 | (local bencode (require :conjure.remote.transport.bencode)) 4 | 5 | (local M (define :conjure-benchmark.bencode)) 6 | 7 | (set M.name "bencode") 8 | 9 | (fn range [n] 10 | (let [acc []] 11 | (for [i 1 n] 12 | (table.insert acc i)) 13 | acc)) 14 | 15 | (fn split-into-chunks [str chunk-size] 16 | (let [len (string.len str) 17 | chunks []] 18 | (for [i 1 len chunk-size] 19 | (let [end (math.min (+ i (- chunk-size 1)) len)] 20 | (table.insert chunks (string.sub str i end)))) 21 | chunks)) 22 | 23 | (set 24 | M.tasks 25 | [{:name "simple encode and decode" 26 | :task-fn 27 | (fn [] 28 | (let [bs (bencode.new)] 29 | (bencode.decode-all 30 | bs 31 | (bencode.encode 32 | {:foo :bar :baz [1 2 3]}))))} 33 | {:name "big encode, chunked decode" 34 | :task-fn 35 | (fn [] 36 | (let [bs (bencode.new) 37 | data (bencode.encode 38 | (core.map 39 | (fn [] 40 | {:foo :bar :baz [1 2 3] :quux {:hello :world}}) 41 | (range 500)))] 42 | (core.run! 43 | (fn [chunk] 44 | (bencode.decode-all bs chunk)) 45 | (split-into-chunks data 512))))}]) 46 | 47 | M 48 | -------------------------------------------------------------------------------- /fnl/conjure-benchmark/run.fnl: -------------------------------------------------------------------------------- 1 | (set package.path 2 | (.. (vim.fn.getcwd) 3 | "/lua/?.lua;" 4 | (vim.fn.getcwd) 5 | "/lua/?/init.lua;" 6 | package.path)) 7 | 8 | (local core (require :conjure.nfnl.core)) 9 | (local iterations 1000) 10 | 11 | (fn benchmark-task [{: name : task-fn}] 12 | (let [start (vim.uv.now)] 13 | (for [_i 1 iterations] 14 | (task-fn)) 15 | (vim.uv.update_time) 16 | (let [duration (/ (- (vim.uv.now) start) iterations)] 17 | (print "##" name (.. "[" duration "ms]"))))) 18 | 19 | (fn benchmark-tasks [{: name : tasks}] 20 | (print "Iterations:" iterations) 21 | (print "#" name) 22 | (core.run! benchmark-task tasks)) 23 | 24 | (local bencode-bm (require "conjure-benchmark.bencode")) 25 | (benchmark-tasks bencode-bm) 26 | -------------------------------------------------------------------------------- /fnl/conjure-spec/.fs.test: -------------------------------------------------------------------------------- 1 | This is _also_ here to test some filesystem related things. 2 | -------------------------------------------------------------------------------- /fnl/conjure-spec/bridge_spec.fnl: -------------------------------------------------------------------------------- 1 | (local {: describe : it} (require :plenary.busted)) 2 | (local bridge (require :conjure.bridge)) 3 | (local assert (require :luassert.assert)) 4 | 5 | (describe "viml->lua" 6 | (fn [] 7 | (it "converts a module and function to a Lua require call without arguments" 8 | (fn [] 9 | (let [result (bridge.viml->lua "my.module" "my_function" nil)] 10 | (assert.equal result "lua require('my.module')['my_function']()")))) 11 | 12 | (it "converts a module and function to a Lua require call with arguments" 13 | (fn [] 14 | (let [result (bridge.viml->lua "my.module" "my_function" {:args "arg1, arg2"})] 15 | (assert.equal result "lua require('my.module')['my_function'](arg1, arg2)")))))) 16 | -------------------------------------------------------------------------------- /fnl/conjure-spec/client/clojure/nrepl/action_spec.fnl: -------------------------------------------------------------------------------- 1 | (local {: describe : it} (require :plenary.busted)) 2 | (local assert (require :luassert.assert)) 3 | (local action (require :conjure.client.clojure.nrepl.action)) 4 | 5 | (describe "client.clojure.nrepl.action" 6 | (fn [] 7 | (describe "extract-test-name-from-form" 8 | (fn [] 9 | ;; Simulate config items with [:test :current_form_names] for clojure client. 10 | (set vim.g.conjure#client#clojure#nrepl#test#current_form_names [:deftest]) 11 | 12 | (it "deftest form with missing name" 13 | (fn [] 14 | (assert.are.equals nil (action.extract-test-name-from-form "")))) 15 | (it "normal deftest form" 16 | (fn [] 17 | (assert.are.equals "foo" (action.extract-test-name-from-form "(deftest foo (+ 10 20))")))) 18 | (it "deftest form with extra spaces" 19 | (fn [] 20 | (assert.are.equals "foo" (action.extract-test-name-from-form "( deftest foo (+ 10 20))")))) 21 | (it "deftest form with metadata" 22 | (fn [] 23 | (assert.are.equals "foo" (action.extract-test-name-from-form "(deftest ^:kaocha/skip foo :xyz)")))))))) 24 | -------------------------------------------------------------------------------- /fnl/conjure-spec/client/clojure/nrepl/auto-repl_spec.fnl: -------------------------------------------------------------------------------- 1 | (local {: describe : it} (require :plenary.busted)) 2 | (local assert (require :luassert.assert)) 3 | (local auto-repl (require :conjure.client.clojure.nrepl.auto-repl)) 4 | 5 | (describe "client.clojure.nrepl.auto-repl" 6 | (fn [] 7 | (describe "enportify" 8 | (fn [] 9 | (it "subject is foo" 10 | (fn [] 11 | (assert.same {:subject "foo"} (auto-repl.enportify "foo")))) 12 | 13 | (let [{: subject : port} (auto-repl.enportify "foo:$port")] 14 | (it "port is in string form" 15 | (fn [] 16 | (assert.are.equals "string" (type port)))) 17 | (it "port number is between 1000 and 100000" 18 | (fn [] 19 | (assert.is_true (< 1000 (tonumber port) 100000)))) 20 | (it "subject is foo:port" 21 | (fn [] 22 | (assert.are.equals (.. "foo:" port) subject))) 23 | ) 24 | 25 | )) 26 | )) 27 | -------------------------------------------------------------------------------- /fnl/conjure-spec/client/clojure/nrepl/init_spec.fnl: -------------------------------------------------------------------------------- 1 | (local {: describe : it} (require :plenary.busted)) 2 | (local assert (require :luassert.assert)) 3 | (local clj (require :conjure.client.clojure.nrepl)) 4 | 5 | (describe "client.clojure.nrepl.init" 6 | (fn [] 7 | (describe "context" 8 | (fn [] 9 | 10 | (it "isn't a namespace" 11 | (fn [] 12 | (assert.are.equals nil (clj.context "not a namespace")))) 13 | (it "simplest form" 14 | (fn [] 15 | (assert.are.equals "foo" (clj.context "(ns foo)")))) 16 | (it "missing closing paren" 17 | (fn [] 18 | (assert.are.equals "foo" (clj.context "(ns foo")))) 19 | (it "short meta" 20 | (fn [] 21 | (assert.are.equals "foo" (clj.context "(ns ^:bar foo baz)")))) 22 | (it "short meta missing closing paren" 23 | (fn [] 24 | (assert.are.equals "foo" (clj.context "(ns ^:bar foo baz")))) 25 | (it "long meta" 26 | (fn [] 27 | (assert.are.equals "foo" (clj.context "(ns ^{:bar true} foo baz)")))) 28 | (it "newlines and docs" 29 | (fn [] 30 | (assert.are.equals "foo" (clj.context "(ns \n^{:bar true} foo\n \"some docs\"\n baz")))) 31 | (it "strip shebang" 32 | (fn [] 33 | (assert.are.equals "foo" (clj.context "#!/usr/bin/env bb\n(ns ^:bar foo)\n(def foo1 1)")))) 34 | 35 | (it "namespace metadata doesn't break evaluation" 36 | (fn [] 37 | ;; https://github.com/Olical/conjure/issues/204 38 | (assert.are.equals "foo" (clj.context "(ns ^{:clj-kondo/config {:lint-as '{my-awesome/defn-like-macro clojure.core/defn}}} foo)")) 39 | (assert.are.equals "foo" (clj.context "(ns ^{:clj-kondo/config {:lint-as (quote {my-awesome/defn-like-macro clojure.core/defn})}} foo)")))) 40 | (it ") before namespace" 41 | (fn [] 42 | ;; https://github.com/Olical/conjure/issues/207 43 | (assert.are.equals "foo" (clj.context "(ns ;)\n foo)")) 44 | (assert.are.equals "foo" (clj.context "(ns ^{:doc \"...... (....) (..)))...\"}\n foo)" b)))))))) 45 | -------------------------------------------------------------------------------- /fnl/conjure-spec/client/fennel/nfnl_spec.fnl: -------------------------------------------------------------------------------- 1 | (local {: describe : it} (require :plenary.busted)) 2 | (local assert (require :luassert.assert)) 3 | (local fs (require :conjure.nfnl.fs)) 4 | (local nfnlc (require :conjure.client.fennel.nfnl)) 5 | 6 | (describe "conjure.client.fennel.nfnl" 7 | (fn [] 8 | (describe "module-path" 9 | (fn [] 10 | (it "returns nil when given nil" 11 | (fn [] 12 | (assert.is.nil (nfnlc.module-path nil)) 13 | nil)) 14 | 15 | (it "handles single path segments" 16 | (fn [] 17 | (assert.are.equal "foo" (nfnlc.module-path (fs.full-path "fnl/foo.fnl"))) 18 | nil)) 19 | 20 | (it "handles multiple path segments" 21 | (fn [] 22 | (assert.are.equal "foo.bar.baz" (nfnlc.module-path (fs.full-path "fnl/foo/bar/baz.fnl"))) 23 | nil)))) 24 | 25 | (describe "repl-for-path" 26 | (fn [] 27 | (local path (fs.full-path "fnl/foo.fnl")) 28 | 29 | (it "returns a new repl for a path" 30 | (fn [] 31 | (assert.is.function (nfnlc.repl-for-path path)) 32 | nil)) 33 | 34 | (it "returns the same function each time" 35 | (fn [] 36 | (assert.is.equal (nfnlc.repl-for-path path) (nfnlc.repl-for-path path)) 37 | nil)) 38 | 39 | (it "executes fennel and returns the results" 40 | (fn [] 41 | (assert.are.same [30] ((nfnlc.repl-for-path path) "(+ 10 20)")) 42 | nil)))))) 43 | -------------------------------------------------------------------------------- /fnl/conjure-spec/client/sql/stdio_spec.fnl: -------------------------------------------------------------------------------- 1 | (local {: describe : it} (require :plenary.busted)) 2 | (local assert (require :luassert.assert)) 3 | (local sql (require :conjure.client.sql.stdio)) 4 | 5 | (describe "conjure.client.sql.stdio" 6 | (fn [] 7 | (describe "prep-code" 8 | (fn [] 9 | (it "prepares sql code appropriately" 10 | (fn [] 11 | ;; Remove trailing comments from meta commands 12 | ;; I may regret this when there's a meta command that takes double dash args... 13 | (assert.same 14 | "foo\n" 15 | (sql.prep-code 16 | {:code "foo -- bar" 17 | :node {:type (fn [] :meta)}})) 18 | 19 | ;; Only works on the last line so we don't mangle code, hopefully 20 | (assert.same 21 | "foo -- bar\nsomething\n" 22 | (sql.prep-code 23 | {:code "foo -- bar\nsomething -- quuz" 24 | :node {:type (fn [] :meta)}})) 25 | 26 | ;; If the last line has an extra blank line we do nothing, shouldn't really ever happen, but here's the behaviour anyway 27 | (assert.same 28 | "foo -- bar\nsomething -- quux\n\n" 29 | (sql.prep-code 30 | {:code "foo -- bar\nsomething -- quux\n" 31 | :node {:type (fn [] :meta)}})) 32 | 33 | ;; If something is a statement it gets a semi colon on the end too 34 | (assert.same 35 | "foo;\n" 36 | (sql.prep-code 37 | {:code "foo -- bar" 38 | :node {:type (fn [] :statement)}})) 39 | 40 | nil)))))) 41 | -------------------------------------------------------------------------------- /fnl/conjure-spec/config_spec.fnl: -------------------------------------------------------------------------------- 1 | (local {: describe : it } (require :plenary.busted)) 2 | (local assert (require :luassert.assert)) 3 | (local config (require :conjure.config)) 4 | (local core (require :conjure.nfnl.core)) 5 | 6 | (describe "get-in" 7 | (fn [] 8 | (it "takes a table of keys and fetches the config value from vim.b or vim.g variables." 9 | (fn [] 10 | (assert.is_true (config.get-in [:client_on_load])) 11 | (assert.same :conjure.client.clojure.nrepl (config.get-in [:filetype :clojure])))))) 12 | 13 | (describe "filetypes" 14 | (fn [] 15 | (it "returns the filetypes list" 16 | (fn [] 17 | (assert.same (config.get-in [:filetypes]) (config.filetypes)) 18 | (assert.same :clojure (core.first (config.filetypes))))))) 19 | 20 | (describe "get-in-fn" 21 | (fn [] 22 | (it "returns a function that works like get-in but with a path prefix" 23 | (fn [] 24 | (assert.same :conjure.client.sql.stdio ((config.get-in-fn [:filetype]) [:sql])))))) 25 | 26 | (describe "assoc-in" 27 | (fn [] 28 | (it "sets some new config" 29 | (fn [] 30 | (config.assoc-in [:foo :bar] :baz) 31 | (assert.same :baz (config.get-in [:foo :bar])))))) 32 | 33 | (describe "merge" 34 | (fn [] 35 | (it "merges more config into the tree, requires overwrite? if it already exists" 36 | (fn [] 37 | (config.merge {:foo {:bar :de_dust2}}) 38 | (assert.same :baz (config.get-in [:foo :bar])) 39 | (config.merge {:foo {:bar :de_dust2}} {:overwrite? true}) 40 | (assert.same :de_dust2 (config.get-in [:foo :bar])))))) 41 | -------------------------------------------------------------------------------- /fnl/conjure-spec/linked-list_spec.fnl: -------------------------------------------------------------------------------- 1 | (local {: describe : it} (require :plenary.busted)) 2 | (local assert (require :luassert.assert)) 3 | (local ll (require :conjure.linked-list)) 4 | 5 | (describe "conjure.linked-list" 6 | (fn [] 7 | 8 | (describe "basics" 9 | (fn [] 10 | (let [l (ll.create [1 2 3])] 11 | (it "get first value" 12 | (fn [] 13 | (assert.are.equals 1 (->> l (ll.val))))) 14 | (it "get second value" 15 | (fn [] 16 | (assert.are.equals 2 (->> l (ll.next) (ll.val))))) 17 | (it "forward and back" 18 | (fn [] 19 | (assert.are.equals 1 (->> l (ll.next) (ll.prev) (ll.val))))) 20 | (it "last by steps" 21 | (fn [] 22 | (assert.are.equals 3 (->> l (ll.next) (ll.next) (ll.val))))) 23 | (it "off the end" 24 | (fn [] 25 | (assert.are.equals nil (->> l (ll.next) (ll.next) (ll.next))))) 26 | (it "off the front" 27 | (fn [] 28 | (assert.are.equals nil (->> l (ll.prev))))) 29 | (it "val handles nils" 30 | (fn [] 31 | (assert.are.equals nil (ll.val nil)))) 32 | (it "last" 33 | (fn [] 34 | (assert.are.equals 3 (->> l (ll.last) (ll.val))))) 35 | (it "first" 36 | (fn [] 37 | (assert.are.equals 1 (->> l (ll.first) (ll.val))))) 38 | (it "last then first" 39 | (fn [] 40 | (assert.are.equals 1 (->> l (ll.last) (ll.first) (ll.val)))))))) 41 | 42 | (describe "until" 43 | (fn [] 44 | (let [l (ll.create [1 2 3 4 5])] 45 | 46 | (it "nil if not found" 47 | (fn [] 48 | (assert.are.equals nil (->> l (ll.until #(= 8 (ll.val $1))) (ll.val))))) 49 | (it "target node if found" 50 | (fn [] 51 | (assert.are.equals 3 (->> l (ll.until #(= 3 (ll.val $1))) (ll.val))))) 52 | (it "can find the one before" 53 | (fn [] 54 | (assert.are.equals 2 (->> l (ll.until #(= 3 (->> $1 (ll.next) (ll.val)))) (ll.val)))))))) 55 | 56 | (describe "cycle" 57 | (fn [] 58 | (let [l (ll.cycle (ll.create [1 2 3]))] 59 | (it "first is still first" 60 | (fn [] 61 | (assert.are.equals 1 (->> l (ll.val))))) 62 | (it "can still next" 63 | (fn [] 64 | (assert.are.equals 2 (->> l (ll.next) (ll.val))))) 65 | (it "can still next next (last)" 66 | (fn [] 67 | (assert.are.equals 3 (->> l (ll.next) (ll.next) (ll.val))))) 68 | (it "off the end loops" 69 | (fn [] 70 | (assert.are.equals 1 (->> l (ll.next) (ll.next) (ll.next) (ll.val))))) 71 | (it "off the front loops" 72 | (fn [] 73 | (assert.are.equals 3 (->> l (ll.prev) (ll.val)))))))))) 74 | 75 | -------------------------------------------------------------------------------- /fnl/conjure-spec/process_spec.fnl: -------------------------------------------------------------------------------- 1 | (local {: describe : it} (require :plenary.busted)) 2 | (local assert (require :luassert.assert)) 3 | (local nvim (require :conjure.aniseed.nvim)) 4 | (local process (require :conjure.process)) 5 | 6 | (describe "conjure.process" 7 | (fn [] 8 | (describe "executable?" 9 | (fn [] 10 | (it "thing's that don't exist return false" 11 | (fn [] 12 | (assert.are.equals false (process.executable? "nope-this-does-not-exist")))) 13 | (it "sh should always exist, I hope" 14 | (fn [] 15 | (assert.are.equals true (process.executable? "sh")))) 16 | (it "only the first word is checked" 17 | (fn [] 18 | (assert.are.equals true (process.executable? "sh foo bar")))))) 19 | 20 | (describe "execute-stop-lifecycle" 21 | (fn [] 22 | (let [sh (process.execute "sh")] 23 | (it "we get a table to identify the process" 24 | (fn [] 25 | (assert.are.equals :table (type sh)))) 26 | (it "it starts out as running" 27 | (fn [] 28 | (assert.are.equals true (process.running? sh)))) 29 | (it "the running check handles nils" 30 | (fn [] 31 | (assert.are.equals false (process.running? nil)))) 32 | (it "a buffer is created for the terminal / process" 33 | (fn [] 34 | (assert.are.equals 1 (nvim.fn.bufexists sh.buf)))) 35 | (it "stopping returns the process table" 36 | (fn [] 37 | (assert.are.equals sh (process.stop sh)))) 38 | (it "stopping is idempotent" 39 | (fn [] 40 | (assert.are.equals sh (process.stop sh)))) 41 | (it "now it's not running" 42 | (fn [] 43 | (assert.are.equals false (process.running? sh))))))) 44 | 45 | (describe "on-exit-hook" 46 | (fn [] 47 | (let [state {:args nil} 48 | sh (process.execute 49 | "sh" 50 | {:on-exit (fn [...] 51 | (tset state :args [...]))})] 52 | (it "called and given the proc" 53 | (fn [] 54 | (process.stop sh) 55 | (assert.same [sh] state.args)))))))) 56 | -------------------------------------------------------------------------------- /fnl/conjure-spec/promise_spec.fnl: -------------------------------------------------------------------------------- 1 | (local {: describe : it} (require :plenary.busted)) 2 | (local assert (require :luassert.assert)) 3 | (local promise (require :conjure.promise)) 4 | 5 | (describe "conjure.promise" 6 | (fn [] 7 | (describe "basics" 8 | (let [p (promise.new)] 9 | (fn [] 10 | (it "starts incomplete" 11 | (fn [] 12 | (assert.are.equals false (promise.done? p)))) 13 | (it "done after deliver" 14 | (fn [] 15 | (promise.deliver p :foo) 16 | (assert.are.equals true (promise.done? p)))) 17 | (it "returns the value on close" 18 | (fn [] 19 | (assert.are.equals :foo (promise.close p))))))) 20 | 21 | (describe "multiple-deliveries" 22 | (fn [] 23 | (let [p (promise.new)] 24 | (it "only the first delivery works" 25 | (fn [] 26 | (promise.deliver p :foo) 27 | (promise.deliver p :bar) 28 | (assert.are.equals :foo (promise.close p))))))) 29 | 30 | (describe "async" 31 | (let [p (promise.new) 32 | del (promise.deliver-fn p)] 33 | (vim.schedule (fn [] (del :later))) 34 | (fn [] 35 | (it "async delivery hasn't happened yet" 36 | (fn [] 37 | (assert.are.equals false (promise.done? p)))) 38 | (it "await returns 0 from wait()" 39 | (fn [] 40 | (assert.are.equals 0 (promise.await p)))) 41 | (it "complete after await" 42 | (fn [] 43 | (assert.are.equals true (promise.done? p)))) 44 | (it "value is correct" 45 | (fn [] 46 | (assert.are.equals :later (promise.close p))))))) 47 | )) 48 | -------------------------------------------------------------------------------- /fnl/conjure-spec/remote/stdio2_spec.fnl: -------------------------------------------------------------------------------- 1 | (local {: describe : it} (require :plenary.busted)) 2 | (local assert (require :luassert.assert)) 3 | (local stdio (require :conjure.remote.stdio2)) 4 | 5 | (describe "conjure.remote.stdio2" 6 | (fn [] 7 | (describe "parse-cmd" 8 | (fn [] 9 | (it "parses a string" 10 | (fn [] 11 | (assert.same {:cmd "foo" :args []} (stdio.parse-cmd "foo")))) 12 | (it "parses a list of one string" 13 | (fn [] 14 | (assert.same {:cmd "foo" :args []} (stdio.parse-cmd ["foo"])))) 15 | (it "parses a string with words separated by spaces" 16 | (fn [] 17 | (assert.same {:cmd "foo" :args ["bar" "baz"]} (stdio.parse-cmd "foo bar baz")))) 18 | (it "parses a list of more than one string" 19 | (fn [] 20 | (assert.same {:cmd "foo" :args ["bar" "baz"]} (stdio.parse-cmd ["foo" "bar" "baz"])))))))) 21 | -------------------------------------------------------------------------------- /fnl/conjure-spec/remote/stdio_spec.fnl: -------------------------------------------------------------------------------- 1 | (local {: describe : it} (require :plenary.busted)) 2 | (local assert (require :luassert.assert)) 3 | (local stdio (require :conjure.remote.stdio)) 4 | 5 | (describe "conjure.remote.stdio" 6 | (fn [] 7 | (describe "parse-cmd" 8 | (fn [] 9 | (it "parses a string" 10 | (fn [] 11 | (assert.same {:cmd "foo" :args []} (stdio.parse-cmd "foo")))) 12 | (it "parses a list of one string" 13 | (fn [] 14 | (assert.same {:cmd "foo" :args []} (stdio.parse-cmd ["foo"])))) 15 | (it "parses a string with words separated by spaces" 16 | (fn [] 17 | (assert.same {:cmd "foo" :args ["bar" "baz"]} (stdio.parse-cmd "foo bar baz")))) 18 | (it "parses a list of more than one string" 19 | (fn [] 20 | (assert.same {:cmd "foo" :args ["bar" "baz"]} (stdio.parse-cmd ["foo" "bar" "baz"])))))))) 21 | -------------------------------------------------------------------------------- /fnl/conjure-spec/remote/transport/base64_spec.fnl: -------------------------------------------------------------------------------- 1 | (local {: describe : it} (require :plenary.busted)) 2 | (local assert (require :luassert.assert)) 3 | (local b64 (require :conjure.remote.transport.base64)) 4 | 5 | (describe "conjure.remote.transport.base64" 6 | (fn [] 7 | (describe "basic" 8 | (fn [] 9 | (it "empty to empty" 10 | (fn [] 11 | (assert.are.equals "" (b64.encode "")))) 12 | (it "simple text to base64" 13 | (fn [] 14 | (assert.are.equals "SGVsbG8sIFdvcmxkIQ==" (b64.encode "Hello, World!")))) 15 | (it "base64 back to text" 16 | (fn [] 17 | (assert.are.equals "Hello, World!" (b64.decode "SGVsbG8sIFdvcmxkIQ==")))))))) 18 | -------------------------------------------------------------------------------- /fnl/conjure-spec/remote/transport/elisp_spec.fnl: -------------------------------------------------------------------------------- 1 | (local {: describe : it} (require :plenary.busted)) 2 | (local assert (require :luassert.assert)) 3 | (local elisp (require :conjure.remote.transport.elisp)) 4 | 5 | (describe "remote.transport.elisp" 6 | (fn [] 7 | (describe "reads" 8 | (fn [] 9 | (it "strings and symbols" 10 | (fn [] 11 | (assert.are.equals nil (elisp.read "")) 12 | (assert.are.equals "foo" (elisp.read "\"foo\"")) 13 | (assert.are.equals "foo" (elisp.read " \"foo\" ")) 14 | (assert.are.equals "foo" (elisp.read ":foo")) 15 | (assert.are.equals "foo" (elisp.read " :foo ")) 16 | (assert.are.equals "bar" (elisp.read " :foo \"hi\" \n :bar ")))) 17 | (it "numbers" 18 | (fn [] 19 | (assert.are.equals 0 (elisp.read "0")) 20 | (assert.are.equals 1 (elisp.read " 1 ")) 21 | (assert.are.equals 0.5 (elisp.read " 0.5")) 22 | (assert.are.equals 30 (elisp.read " 30 ")) 23 | (assert.are.equals 30.2 (elisp.read " 30.2 ")) 24 | (assert.are.equals 0.2 (elisp.read ".2 ")) 25 | (assert.are.equals -0.3 (elisp.read " -.3 ")) 26 | (assert.are.equals -20.25 (elisp.read " -20.25 ")))) 27 | (it "lists" 28 | (fn [] 29 | (assert.same [] (elisp.read "()")) 30 | (assert.same [ [] [] ] (elisp.read "(()())")) 31 | (assert.same [1 [2 3 4] 5 [6 :seven] :eight 9] (elisp.read "(1 (2 3 4) 5 (6 \"seven\") :eight 9)")) 32 | (assert.same [1 2 3] (elisp.read "(1 2 3)")))) 33 | (it "nested forms" 34 | (fn [] 35 | (assert.same 36 | ["Class" ": " ["value" "clojure.lang.PersistentArrayMap" 0] ["newline"] 37 | "Contents: " ["newline"] 38 | " " ["value" "a" 1] " = " ["value" "1" 2] ["newline"] 39 | " " ["value" "b" 3] " = " ["value" "2" 4] ["newline"]] 40 | (elisp.read "(\"Class\" \": \" (:value \"clojure.lang.PersistentArrayMap\" 0) (:newline) \"Contents: \" (:newline) \" \" (:value \"a\" 1) \" = \" (:value \"1\" 2) (:newline) \" \" (:value \"b\" 3) \" = \" (:value \"2\" 4) (:newline))")))))))) 41 | -------------------------------------------------------------------------------- /fnl/conjure-spec/school_spec.fnl: -------------------------------------------------------------------------------- 1 | (local {: describe : it} (require :plenary.busted)) 2 | (local assert (require :luassert.assert)) 3 | (local school (require :conjure.school)) 4 | (local nvim (require :conjure.aniseed.nvim)) 5 | 6 | (describe "running :ConjureSchool" 7 | (fn [] 8 | (school.start) 9 | 10 | (it "buffer has correct name" 11 | (fn [] 12 | (assert.are.equals "conjure-school.fnl" (nvim.fn.bufname)))) 13 | 14 | (it "buffer requires conjure.school module" 15 | (fn [] 16 | (assert.same ["(local school (require :conjure.school))"] (nvim.buf_get_lines 0 0 1 false)))) 17 | 18 | (nvim.ex.bdelete "conjure-school.fnl"))) 19 | -------------------------------------------------------------------------------- /fnl/conjure-spec/stack_spec.fnl: -------------------------------------------------------------------------------- 1 | (local {: describe : it} (require :plenary.busted)) 2 | (local assert (require :luassert.assert)) 3 | (local stack (require :conjure.stack)) 4 | 5 | (describe "conjure.stack" 6 | (fn [] 7 | (describe "push" 8 | (fn [] 9 | (it "item on a stack" 10 | (fn [] 11 | (assert.same [1 2 3] (-> (stack.push [] 1) 12 | (stack.push 2) 13 | (stack.push 3))))))) 14 | 15 | (describe "pop" 16 | (fn [] 17 | (it "top of stack" 18 | (fn [] 19 | (assert.same [1 2] (stack.pop [1 2 3])))) 20 | 21 | (it "empty stack" 22 | (fn [] 23 | (assert.same [] (stack.pop [])))))) 24 | 25 | (describe "peek" 26 | (fn [] 27 | (it "top of stack" 28 | (fn [] 29 | (assert.are.equals 3 (stack.peek [1 2 3])))) 30 | 31 | (it "empty stack" 32 | (fn [] 33 | (assert.are.equals nil (stack.peek [])))) 34 | )))) 35 | -------------------------------------------------------------------------------- /fnl/conjure-spec/util.fnl: -------------------------------------------------------------------------------- 1 | (local nvim (require :conjure.aniseed.nvim)) 2 | 3 | (fn with-buf [lines f] 4 | (let [at (fn [cursor] 5 | (nvim.win_set_cursor 0 cursor))] 6 | (nvim.ex.silent_ :syntax :on) 7 | (nvim.ex.silent_ :filetype :on) 8 | (nvim.ex.silent_ :set :filetype :clojure) 9 | (nvim.ex.silent_ :edit (.. (nvim.fn.tempname) "_test.clj")) 10 | (nvim.buf_set_lines 0 0 -1 false lines) 11 | (f at) 12 | (nvim.ex.silent_ :bdelete!))) 13 | 14 | {: with-buf} 15 | -------------------------------------------------------------------------------- /fnl/conjure-spec/util_spec.fnl: -------------------------------------------------------------------------------- 1 | (local {: describe : it} (require :plenary.busted)) 2 | (local assert (require :luassert.assert)) 3 | (local util (require :conjure.util)) 4 | 5 | (describe 6 | "wrap-require-fn-call" 7 | (fn [] 8 | (it "creates a fn that requries a file and calls a fn" 9 | (fn [] 10 | (set package.loaded.example-module 11 | {:wrapped-fn-example (fn [] :hello-world!)}) 12 | (assert.equals 13 | :hello-world! 14 | ((util.wrap-require-fn-call 15 | "example-module" 16 | "wrapped-fn-example"))))))) 17 | 18 | (describe 19 | "replace-termcodes" 20 | (fn [] 21 | (it "escapes sequences like " 22 | (fn [] 23 | (assert.equals 24 | "hello\015world" 25 | (util.replace-termcodes "helloworld")))))) 26 | -------------------------------------------------------------------------------- /fnl/conjure-spec/uuid_spec.fnl: -------------------------------------------------------------------------------- 1 | (local {: describe : it} (require :plenary.busted)) 2 | (local assert (require :luassert.assert)) 3 | (local a (require :conjure.nfnl.core)) 4 | (local uuid (require :conjure.uuid)) 5 | 6 | (describe "uuid" 7 | (fn [] 8 | ;; Helper: Is word in xs? 9 | (fn is-in [word xs] 10 | (a.some (fn [x] (= word x)) xs)) 11 | 12 | (describe "turns a UUID" 13 | (fn [] 14 | (it "into something human-readable" 15 | (fn [] 16 | (assert.are.equals 17 | "Wirehaired Pointing Griffon" 18 | (uuid.pretty "c7ef277c-160c-45f4-a5c3-03ac16a93788")))) 19 | (it "into something human-readable but wrong string" 20 | (fn [] 21 | (assert.are.not.equals 22 | "Wirehaired Pointing Griffon" 23 | (uuid.pretty "d7ef277c-160c-45f4-a5c3-03ac16a93788")))))) 24 | 25 | (describe "generated UUID" 26 | (fn [] 27 | (it "is turned into something human-readable" 28 | (fn [] 29 | (assert.are.equals 30 | true 31 | (is-in (uuid.pretty (uuid.v4)) 32 | uuid.cats-and-dogs)))) 33 | (it "has the correct format" 34 | (fn [] 35 | (assert.are.not.equals 36 | nil 37 | (string.match 38 | (uuid.v4) 39 | "^%x+-%x+-%x+-%x+-%x+$")))))))) 40 | -------------------------------------------------------------------------------- /fnl/conjure/bridge.fnl: -------------------------------------------------------------------------------- 1 | (fn viml->lua [m f opts] 2 | (.. "lua require('" m "')['" f "'](" 3 | (or (and opts opts.args) "") ")")) 4 | 5 | {: viml->lua} 6 | -------------------------------------------------------------------------------- /fnl/conjure/client/clojure/nrepl/auto-repl.fnl: -------------------------------------------------------------------------------- 1 | (local {: autoload} (require :conjure.nfnl.module)) 2 | (local a (autoload :conjure.aniseed.core)) 3 | (local client (autoload :conjure.client)) 4 | (local config (autoload :conjure.config)) 5 | (local log (autoload :conjure.log)) 6 | (local nvim (autoload :conjure.aniseed.nvim)) 7 | (local process (autoload :conjure.process)) 8 | (local state (autoload :conjure.client.clojure.nrepl.state)) 9 | 10 | (local cfg (config.get-in-fn [:client :clojure :nrepl])) 11 | 12 | (fn enportify [subject] 13 | "Given a string `subject`, look for `$port` and if there randomly search 14 | until we find an open port. Then return a table containing the subject with 15 | `$port` replaced by the found port and the port number itself. If there was 16 | no `$port` then it'll just return a table containing the subject on it's own." 17 | (if (subject:find "$port") 18 | (let [server (nvim.fn.serverstart "localhost:0") 19 | _ (nvim.fn.serverstop server) 20 | port (server:gsub "localhost:" "")] 21 | {:subject (subject:gsub "$port" port) 22 | :port port}) 23 | {:subject subject})) 24 | 25 | (fn delete-auto-repl-port-file [] 26 | (let [port-file (cfg [:connection :auto_repl :port_file]) 27 | port (state.get :auto-repl-port)] 28 | (when (and port-file port (= (a.slurp port-file) port)) 29 | (nvim.fn.delete port-file)))) 30 | 31 | (fn upsert-auto-repl-proc [] 32 | "Starts the auto REPL if executable and not already running." 33 | (let [{:subject cmd : port} (enportify (cfg [:connection :auto_repl :cmd])) 34 | port-file (cfg [:connection :auto_repl :port_file]) 35 | enabled? (cfg [:connection :auto_repl :enabled]) 36 | hidden? (cfg [:connection :auto_repl :hidden])] 37 | 38 | (when (and enabled? 39 | (not (process.running? (state.get :auto-repl-proc))) 40 | (process.executable? cmd)) 41 | 42 | (let [proc (process.execute 43 | cmd 44 | {:hidden? hidden? 45 | :on-exit (client.wrap delete-auto-repl-port-file)})] 46 | 47 | (a.assoc (state.get) :auto-repl-proc proc) 48 | (a.assoc (state.get) :auto-repl-port port) 49 | 50 | (when (and port-file port) 51 | (a.spit port-file port)) 52 | (log.append [(.. "; Starting auto-repl: " cmd)]) 53 | proc)))) 54 | 55 | {: delete-auto-repl-port-file : enportify : upsert-auto-repl-proc} 56 | -------------------------------------------------------------------------------- /fnl/conjure/client/clojure/nrepl/debugger.fnl: -------------------------------------------------------------------------------- 1 | (local {: autoload} (require :conjure.nfnl.module)) 2 | (local a (autoload :conjure.aniseed.core)) 3 | (local elisp (autoload :conjure.remote.transport.elisp)) 4 | (local extract (autoload :conjure.extract)) 5 | (local log (autoload :conjure.log)) 6 | (local server (autoload :conjure.client.clojure.nrepl.server)) 7 | (local str (autoload :conjure.aniseed.string)) 8 | (local text (autoload :conjure.text)) 9 | 10 | (local state {:last-request nil}) 11 | 12 | (fn init [] 13 | (log.append ["; Initialising CIDER debugger"] {:break? true}) 14 | (server.send 15 | {:op :init-debugger} 16 | (fn [msg] 17 | (log.append ["; CIDER debugger initialized"] {:break? true}) 18 | (log.dbg "init-debugger response" msg))) 19 | nil) 20 | 21 | (fn send [opts] 22 | (let [key (a.get-in state [:last-request :key])] 23 | (if key 24 | (server.send 25 | {:op :debug-input 26 | :input (a.get opts :input) 27 | :key key} 28 | (fn [msg] 29 | (log.dbg "debug-input response" msg) 30 | (set state.last-request nil))) 31 | (log.append 32 | ["; Debugger is not awaiting input"] 33 | {:break? true})))) 34 | 35 | (fn valid-inputs [] 36 | (let [input-types (a.get-in state [:last-request :input-type])] 37 | (a.filter 38 | (fn [input-type] 39 | (not= :stacktrace input-type)) 40 | (or input-types [])))) 41 | 42 | (fn render-inspect [inspect] 43 | (str.join 44 | (a.map 45 | (fn [v] 46 | (if (a.table? v) 47 | (let [head (a.first v)] 48 | (if 49 | (= :newline head) "\n" 50 | (= :value head) (a.second v))) 51 | v)) 52 | inspect))) 53 | 54 | (fn handle-input-request [msg] 55 | (set state.last-request msg) 56 | 57 | (log.append ["; CIDER debugger"] {:break? true}) 58 | 59 | (when (not (a.empty? msg.inspect)) 60 | (log.append 61 | (text.prefixed-lines 62 | (render-inspect (elisp.read msg.inspect)) 63 | "; " 64 | {}) 65 | {})) 66 | 67 | (when (not (a.nil? msg.debug-value)) 68 | (log.append [(a.str "; Evaluation result => " msg.debug-value)] {})) 69 | 70 | (if (a.empty? msg.prompt) 71 | (log.append 72 | ["; Respond with :ConjureCljDebugInput [input]" 73 | (.. "; Inputs: " (str.join ", " (valid-inputs)))] 74 | {}) 75 | (send {:input (extract.prompt msg.prompt)}))) 76 | 77 | (fn debug-input [opts] 78 | (if (a.some #(= opts.args $1) (valid-inputs)) 79 | (send {:input (.. ":" opts.args)}) 80 | (log.append 81 | [(.. "; Valid inputs: " (str.join ", " (valid-inputs)))]))) 82 | 83 | {: debug-input 84 | : handle-input-request 85 | : init 86 | : render-inspect 87 | : send 88 | : state 89 | : valid-inputs} 90 | -------------------------------------------------------------------------------- /fnl/conjure/client/clojure/nrepl/parse.fnl: -------------------------------------------------------------------------------- 1 | (fn strip-meta [s] 2 | (-?> s 3 | (string.gsub "%^:.-%s+" "") 4 | (string.gsub "%^%b{}%s+" ""))) 5 | 6 | (fn strip-comments [s] 7 | (-?> s 8 | (string.gsub ";.-[\n$]" ""))) 9 | 10 | (fn strip-shebang [s] 11 | (-?> s 12 | (string.gsub "^#![^\n]*\n" ""))) 13 | 14 | {: strip-comments : strip-meta : strip-shebang} 15 | -------------------------------------------------------------------------------- /fnl/conjure/client/clojure/nrepl/state.fnl: -------------------------------------------------------------------------------- 1 | (local {: autoload} (require :conjure.nfnl.module)) 2 | (local client (autoload :conjure.client)) 3 | 4 | (local get 5 | (client.new-state 6 | (fn [] 7 | {:conn nil 8 | :auto-repl-port nil 9 | :auto-repl-proc nil 10 | :join-next {:key nil}}))) 11 | 12 | {: get} 13 | -------------------------------------------------------------------------------- /fnl/conjure/client/clojure/nrepl/ui.fnl: -------------------------------------------------------------------------------- 1 | (local {: autoload} (require :conjure.nfnl.module)) 2 | (local a (autoload :conjure.aniseed.core)) 3 | (local config (autoload :conjure.config)) 4 | (local log (autoload :conjure.log)) 5 | (local state (autoload :conjure.client.clojure.nrepl.state)) 6 | (local str (autoload :conjure.aniseed.string)) 7 | (local text (autoload :conjure.text)) 8 | 9 | (local cfg (config.get-in-fn [:client :clojure :nrepl])) 10 | 11 | (fn handle-join-line [resp] 12 | (let [next-key (if resp.out :out resp.err :err) 13 | key (state.get :join-next :key)] 14 | (when (or next-key resp.value) 15 | (a.assoc (state.get) :join-next 16 | (when (and next-key 17 | (not (text.trailing-newline? 18 | (a.get resp next-key)))) 19 | {:key next-key}))) 20 | (and next-key (= key next-key)))) 21 | 22 | (fn display-result [resp opts] 23 | (local opts (or opts {})) 24 | (let [joined? (handle-join-line resp)] 25 | (log.append 26 | (if 27 | resp.out 28 | (text.prefixed-lines 29 | (text.trim-last-newline resp.out) 30 | (if 31 | (or opts.raw-out? (cfg [:eval :raw_out])) "" 32 | opts.simple-out? "; " 33 | "; (out) ") 34 | {:skip-first? joined?}) 35 | 36 | resp.err 37 | (text.prefixed-lines 38 | (text.trim-last-newline resp.err) 39 | "; (err) " 40 | {:skip-first? joined?}) 41 | 42 | resp.value 43 | (when (not (and opts.ignore-nil? (= "nil" resp.value))) 44 | (text.split-lines resp.value)) 45 | 46 | nil) 47 | {:join-first? joined? 48 | :low-priority? (not (not (or resp.out resp.err)))}))) 49 | 50 | (fn display-sessions [sessions cb] 51 | (let [current (state.get :conn :session)] 52 | (log.append 53 | (a.concat [(.. "; Sessions (" (a.count sessions) "):")] 54 | (a.map-indexed 55 | (fn [[idx session]] 56 | (str.join 57 | ["; " (if (= current session.id) ">" " ") 58 | idx " - " (session.str)])) 59 | sessions)) 60 | {:break? true}) 61 | (when cb 62 | (cb)))) 63 | 64 | {: display-result : display-sessions } 65 | -------------------------------------------------------------------------------- /fnl/conjure/dynamic.fnl: -------------------------------------------------------------------------------- 1 | (local {: autoload} (require :conjure.nfnl.module)) 2 | (local a (autoload :conjure.aniseed.core)) 3 | 4 | (local get-stack-key :conjure.dynamic/get-stack) 5 | 6 | (fn assert-value-function! [value] 7 | (when (not= :function (type value)) 8 | (error "conjure.dynamic values must always be wrapped in a function"))) 9 | 10 | (fn new [base-value] 11 | (assert-value-function! base-value) 12 | (var stack [base-value]) 13 | (fn [x ...] 14 | (if (= get-stack-key x) stack 15 | ((a.last stack) x ...)))) 16 | 17 | (fn run-binds! [f binds] 18 | (a.map-indexed 19 | (fn [[dyn new-value]] 20 | (assert-value-function! new-value) 21 | (f (dyn get-stack-key) new-value)) 22 | binds)) 23 | 24 | (fn bind [binds f ...] 25 | (run-binds! table.insert binds) 26 | (let [(ok? result) (pcall f ...)] 27 | (run-binds! #(table.remove $1) binds) 28 | (if ok? 29 | result 30 | (error result)))) 31 | 32 | (fn set! [dyn new-value] 33 | (assert-value-function! new-value) 34 | (let [stack (dyn get-stack-key) 35 | depth (a.count stack)] 36 | (a.assoc stack depth new-value)) 37 | nil) 38 | 39 | (fn set-root! [dyn new-value] 40 | (assert-value-function! new-value) 41 | (a.assoc (dyn get-stack-key) 1 new-value) 42 | nil) 43 | 44 | {: new 45 | : bind 46 | : set! 47 | : set-root!} 48 | -------------------------------------------------------------------------------- /fnl/conjure/editor.fnl: -------------------------------------------------------------------------------- 1 | (local {: autoload} (require :conjure.nfnl.module)) 2 | (local a (autoload :conjure.aniseed.core)) 3 | (local fs (autoload :conjure.fs)) 4 | (local nvim (autoload :conjure.aniseed.nvim)) 5 | (local util (autoload :conjure.util)) 6 | 7 | (fn percent-fn [total-fn] 8 | (fn [pc] 9 | (math.floor (* (/ (total-fn) 100) (* pc 100))))) 10 | 11 | (fn width [] 12 | vim.o.columns) 13 | 14 | (fn height [] 15 | vim.o.lines) 16 | 17 | (local percent-width (percent-fn width)) 18 | (local percent-height (percent-fn height)) 19 | 20 | (fn cursor-left [] 21 | (vim.fn.screencol)) 22 | 23 | (fn cursor-top [] 24 | (vim.fn.screenrow)) 25 | 26 | (fn go-to [path-or-win line column] 27 | (when (a.string? path-or-win) 28 | (nvim.ex.edit (fs.localise-path path-or-win))) 29 | 30 | (nvim.win_set_cursor 31 | (if (= :number (type path-or-win)) 32 | path-or-win 33 | 0) 34 | [line (a.dec column)])) 35 | 36 | (fn go-to-mark [m] 37 | (nvim.ex.normal_ (.. "`" m))) 38 | 39 | (fn go-back [] 40 | (nvim.ex.normal_ (util.replace-termcodes ""))) 41 | 42 | (fn has-filetype? [ft] 43 | (a.some #(= ft $1) (nvim.fn.getcompletion ft :filetype))) 44 | 45 | {: width 46 | : height 47 | : percent-width 48 | : percent-height 49 | : cursor-left 50 | : cursor-top 51 | : go-to 52 | : go-to-mark 53 | : go-back 54 | : has-filetype?} 55 | -------------------------------------------------------------------------------- /fnl/conjure/event.fnl: -------------------------------------------------------------------------------- 1 | (local {: autoload} (require :conjure.nfnl.module)) 2 | (local nvim (autoload :conjure.aniseed.nvim)) 3 | (local a (autoload :conjure.aniseed.core)) 4 | (local text (autoload :conjure.text)) 5 | (local client (autoload :conjure.client)) 6 | (local str (autoload :conjure.aniseed.string)) 7 | 8 | (fn emit [...] 9 | (let [names (a.map text.upper-first [...])] 10 | (client.schedule 11 | (fn [] 12 | (while (not (a.empty? names)) 13 | (nvim.ex.doautocmd :User (.. :Conjure (str.join names))) 14 | (table.remove names))))) 15 | nil) 16 | 17 | {: emit} 18 | -------------------------------------------------------------------------------- /fnl/conjure/hook.fnl: -------------------------------------------------------------------------------- 1 | (local {: autoload} (require :conjure.nfnl.module)) 2 | (local a (autoload :conjure.aniseed.core)) 3 | (local str (autoload :conjure.aniseed.string)) 4 | 5 | ;; These are originals defined by Conjure. 6 | (local hook-fns {}) 7 | 8 | ;; These are user defined overrides. 9 | (local hook-override-fns {}) 10 | 11 | (fn define [name f] 12 | (a.assoc hook-fns name f)) 13 | 14 | (fn override [name f] 15 | (a.assoc hook-override-fns name f)) 16 | 17 | (fn get [name] 18 | (a.get hook-fns name)) 19 | 20 | (fn exec [name ...] 21 | (let [f (or (a.get hook-override-fns name) 22 | (a.get hook-fns name))] 23 | (if f 24 | (f ...) 25 | (error (str.join " " ["conjure.hook: Hook not found, can not exec" name]))))) 26 | 27 | { 28 | : hook-fns 29 | : hook-override-fns 30 | : define 31 | : override 32 | : get 33 | : exec 34 | } 35 | -------------------------------------------------------------------------------- /fnl/conjure/inline.fnl: -------------------------------------------------------------------------------- 1 | (local {: autoload} (require :conjure.nfnl.module)) 2 | (local a (autoload :conjure.aniseed.core)) 3 | (local config (autoload :conjure.config)) 4 | 5 | (local ns-id (vim.api.nvim_create_namespace :conjure.inline)) 6 | 7 | (fn sanitise-text [s] 8 | (if (a.string? s) 9 | (s:gsub "%s+" " ") 10 | "")) 11 | 12 | (fn clear [opts] 13 | "Clear all (Conjure related) virtual text for opts.buf, defaults to 0 which 14 | is the current buffer." 15 | (pcall 16 | (fn [] 17 | (vim.api.nvim_buf_clear_namespace (a.get opts :buf 0) ns-id 0 -1)))) 18 | 19 | (fn display [opts] 20 | "Display virtual text for opts.buf on opts.line containing opts.text." 21 | (local hl-group (config.get-in [:eval :inline :highlight])) 22 | (pcall 23 | (fn [] 24 | (clear) 25 | (vim.api.nvim_buf_set_virtual_text 26 | (a.get opts :buf 0) ns-id opts.line 27 | [[(sanitise-text opts.text) hl-group]] 28 | {})))) 29 | 30 | {: sanitise-text 31 | : clear 32 | : display} 33 | -------------------------------------------------------------------------------- /fnl/conjure/linked-list.fnl: -------------------------------------------------------------------------------- 1 | (local {: autoload} (require :conjure.nfnl.module)) 2 | (local a (autoload :conjure.aniseed.core)) 3 | 4 | (fn create [xs prev] 5 | (when (not (a.empty? xs)) 6 | (let [rest (a.rest xs) 7 | node {}] 8 | (a.assoc node :val (a.first xs)) 9 | (a.assoc node :prev prev) 10 | (a.assoc node :next (create rest node))))) 11 | 12 | (fn val [l] 13 | (-?> l (a.get :val))) 14 | 15 | (fn next [l] 16 | (-?> l (a.get :next))) 17 | 18 | (fn prev [l] 19 | (-?> l (a.get :prev))) 20 | 21 | (fn first [l] 22 | (var c l) 23 | (while (prev c) 24 | (set c (prev c))) 25 | c) 26 | 27 | (fn last [l] 28 | (var c l) 29 | (while (next c) 30 | (set c (next c))) 31 | c) 32 | 33 | (fn until [f l] 34 | (var c l) 35 | (var r false) 36 | (fn step [] 37 | (set r (f c)) 38 | r) 39 | (while (and c (not (step))) 40 | (set c (next c))) 41 | (when r 42 | c)) 43 | 44 | (fn cycle [l] 45 | (let [start (first l) 46 | end (last l)] 47 | (a.assoc start :prev end) 48 | (a.assoc end :next start) 49 | l)) 50 | 51 | { 52 | : create 53 | : val 54 | : next 55 | : prev 56 | : first 57 | : last 58 | : until 59 | : cycle 60 | } 61 | 62 | -------------------------------------------------------------------------------- /fnl/conjure/macros.fnl: -------------------------------------------------------------------------------- 1 | ;; [nfnl-macro] 2 | 3 | ;; TODO Deprecated, we should remove this, just use the vim.* API. 4 | {:augroup 5 | (fn [name ...] 6 | `(do 7 | (nvim.ex.augroup ,(tostring name)) 8 | (nvim.ex.autocmd_) 9 | ,... 10 | (nvim.ex.augroup :END))) 11 | 12 | :autocmd 13 | (fn [...] 14 | `(nvim.ex.autocmd ,...)) 15 | 16 | :_: 17 | (fn [name ...] 18 | `((. nvim.ex ,(tostring name)) ,...))} 19 | -------------------------------------------------------------------------------- /fnl/conjure/main.fnl: -------------------------------------------------------------------------------- 1 | (local {: autoload} (require :conjure.nfnl.module)) 2 | (local mapping (autoload :conjure.mapping)) 3 | (local config (autoload :conjure.config)) 4 | 5 | (fn main [] 6 | (mapping.init (config.filetypes))) 7 | 8 | {: main} 9 | -------------------------------------------------------------------------------- /fnl/conjure/net.fnl: -------------------------------------------------------------------------------- 1 | (local {: autoload : define} (require :conjure.nfnl.module)) 2 | (local a (autoload :conjure.aniseed.core)) 3 | 4 | (import-macros {: augroup : autocmd} :conjure.macros) 5 | 6 | (local M (define :conjure.net {})) 7 | 8 | (fn M.resolve [host] 9 | ;; Mostly to work around jeejah binding to localhost instead of 127.0.0.1 and 10 | ;; libuv net requiring IP addresses. 11 | (if (= host "::") 12 | host 13 | (-> host 14 | (->> (vim.loop.getaddrinfo) 15 | (a.filter #(= "inet" (a.get $1 :family))) 16 | (a.first)) 17 | (a.get :addr)))) 18 | 19 | (local state {:sock-drawer []}) 20 | 21 | (fn destroy-sock [sock] 22 | (when (not (sock:is_closing)) 23 | (sock:read_stop) 24 | (sock:shutdown) 25 | (sock:close)) 26 | 27 | (set state.sock-drawer (a.filter #(not= sock $1) state.sock-drawer))) 28 | 29 | (fn M.connect [{: host : port : cb}] 30 | (let [sock (vim.loop.new_tcp) 31 | resolved-host (M.resolve host)] 32 | 33 | (when (not resolved-host) 34 | (error "Failed to resolve host for Conjure connection")) 35 | 36 | (sock:connect resolved-host port cb) 37 | (table.insert state.sock-drawer sock) 38 | {:sock sock 39 | :resolved-host resolved-host 40 | :destroy #(destroy-sock sock) 41 | :host host 42 | :port port})) 43 | 44 | (fn destroy-all-socks [] 45 | (a.run! destroy-sock state.sock-drawer)) 46 | 47 | (local group (vim.api.nvim_create_augroup "conjure-net-sock-cleanup" {})) 48 | (vim.api.nvim_create_autocmd 49 | :VimLeavePre 50 | {: group 51 | :pattern "*" 52 | :callback destroy-all-socks}) 53 | 54 | M 55 | -------------------------------------------------------------------------------- /fnl/conjure/nfnl/macros.fnl: -------------------------------------------------------------------------------- 1 | ;; [nfnl-macro] 2 | 3 | (fn time [...] 4 | `(let [start# (vim.loop.hrtime) 5 | result# (do ,...) 6 | end# (vim.loop.hrtime)] 7 | (print (.. "Elapsed time: " (/ (- end# start#) 1000000) " msecs")) 8 | result#)) 9 | 10 | (fn conditional-let [branch bindings ...] 11 | (assert (= 2 (length bindings)) "expected a single binding pair") 12 | 13 | (let [[bind-expr value-expr] bindings] 14 | (if 15 | ;; Simple symbols 16 | ;; [foo bar] 17 | (sym? bind-expr) 18 | `(let [,bind-expr ,value-expr] 19 | (,branch ,bind-expr ,...)) 20 | 21 | ;; List / values destructure 22 | ;; [(a b) c] 23 | (list? bind-expr) 24 | (do 25 | ;; Even if the user isn't using the first slot, we will. 26 | ;; [(_ val) (pcall #:foo)] 27 | ;; => [(bindGENSYM12345 val) (pcall #:foo)] 28 | (when (= `_ (. bind-expr 1)) 29 | (tset bind-expr 1 (gensym "bind"))) 30 | 31 | `(let [,bind-expr ,value-expr] 32 | (,branch ,(. bind-expr 1) ,...))) 33 | 34 | ;; Sequential and associative table destructure 35 | ;; [[a b] c] 36 | ;; [{: a : b} c] 37 | (table? bind-expr) 38 | `(let [value# ,value-expr 39 | ,bind-expr (or value# {})] 40 | (,branch value# ,...)) 41 | 42 | ;; We should never get here, but just in case. 43 | (assert (.. "unknown bind-expr type: " (type bind-expr)))))) 44 | 45 | (fn if-let [bindings ...] 46 | (assert (<= (length [...]) 2) (.. "if-let does not support more than two branches")) 47 | (conditional-let `if bindings ...)) 48 | 49 | (fn when-let [bindings ...] 50 | (conditional-let `when bindings ...)) 51 | 52 | {: time 53 | : if-let 54 | : when-let} 55 | -------------------------------------------------------------------------------- /fnl/conjure/nfnl/macros/aniseed.fnl: -------------------------------------------------------------------------------- 1 | ;; [nfnl-macro] 2 | 3 | ;; Copied over from Aniseed. Contains all of the def* module macro systems. 4 | ;; https://github.com/Olical/aniseed 5 | 6 | ;; This has been heavily slimmed down from the original implementation, the 7 | ;; `(module ...) macro can now ONLY define your module, it can not be used 8 | ;; to require dependencies. 9 | 10 | ;; We had to slim things down because the Fennel compiler no longer supports 11 | ;; the weird tricks we were using. 12 | 13 | ;; In nfnl they are not automatically required, you must use import-macros to 14 | ;; require them explicitly when migrating your Aniseed based projects. 15 | 16 | ;; Avoids the compiler complaining that we're introducing locals without gensym. 17 | (local mod-str :*module*) 18 | (local mod-sym (sym mod-str)) 19 | 20 | ;; Upserts the existence of the module for subsequent def forms. 21 | ;; 22 | ;; (module foo 23 | ;; {:some-optional-base :table-of-things 24 | ;; :to-base :the-module-off-of}) 25 | (fn module [mod-name mod-base] 26 | `(local 27 | ,mod-sym 28 | (let [pkg# (require :package)] 29 | (tset pkg#.loaded ,(tostring mod-name) ,(or mod-base {})) 30 | (. pkg#.loaded ,(tostring mod-name))))) 31 | 32 | (fn def- [name value] 33 | `(local ,name ,value)) 34 | 35 | (fn def [name value] 36 | `(local ,name (do (tset ,mod-sym ,(tostring name) ,value) (. ,mod-sym ,(tostring name))))) 37 | 38 | (fn defn- [name ...] 39 | `(fn ,name ,...)) 40 | 41 | (fn defn [name ...] 42 | `(def ,name (fn ,name ,...))) 43 | 44 | (fn defonce- [name value] 45 | `(def- ,name (or ,name ,value))) 46 | 47 | (fn defonce [name value] 48 | `(def ,name (or (. ,mod-sym ,(tostring name)) ,value))) 49 | 50 | {:module module 51 | :def- def- :def def 52 | :defn- defn- :defn defn 53 | :defonce- defonce- :defonce defonce} 54 | -------------------------------------------------------------------------------- /fnl/conjure/process.fnl: -------------------------------------------------------------------------------- 1 | (local {: autoload} (require :conjure.nfnl.module)) 2 | (local a (autoload :conjure.aniseed.core)) 3 | (local nvim (autoload :conjure.aniseed.nvim)) 4 | (local str (autoload :conjure.aniseed.string)) 5 | 6 | ;; For the execution of external processes through Neovim's terminal 7 | ;; integration. This module only cares about checking for some required program 8 | ;; and then executing it with some arguments in a terminal buffer. It doesn't 9 | ;; manage the lifecycle past that point, so it's very much on it's own after it 10 | ;; begins. 11 | ;; 12 | ;; The initial use case for this is to start a babashka REPL for Clojure files 13 | ;; if no nREPL connection can be established. 14 | 15 | (fn executable? [cmd] 16 | "Check if the given program name can be found on the system. If you give it a 17 | full command with arguments it'll just check the first word." 18 | (= 1 (nvim.fn.executable (a.first (str.split cmd "%s+"))))) 19 | 20 | (fn running? [proc] 21 | (if proc 22 | (. proc :running?) 23 | false)) 24 | 25 | (local state {:jobs {}}) 26 | 27 | (fn on-exit [job-id] 28 | (let [proc (. state.jobs job-id)] 29 | (when (running? proc) 30 | (a.assoc proc :running? false) 31 | (tset state.jobs proc.job-id nil) 32 | (pcall nvim.buf_delete proc.buf {:force true}) 33 | (let [on-exit (a.get-in proc [:opts :on-exit])] 34 | (when on-exit 35 | (on-exit proc)))))) 36 | 37 | ;; TODO When Neovim 0.5 is stable we can pass a Lua function across this 38 | ;; boundary. Until then, yucky gross stuff. 39 | ;; This is absolutely horrible, but there's no other way to do it if I want to 40 | ;; support anything < 0.5 for now. 41 | ;; So rather than just using a closure to pass the proc into the exit fn, I 42 | ;; have to go through a VimL function that relies on a global table of jobs to 43 | ;; look the data back up. 44 | (nvim.ex.function_ 45 | (str.join 46 | "\n" 47 | ["ConjureProcessOnExit(...)" 48 | "call luaeval(\"require('conjure.process')['on-exit'](unpack(_A))\", a:000)" 49 | "endfunction"])) 50 | 51 | (fn execute [cmd opts] 52 | (let [win (nvim.tabpage_get_win 0) 53 | original-buf (nvim.win_get_buf win) 54 | term-buf (nvim.create_buf (not (?. opts :hidden?)) true) 55 | proc {:cmd cmd :buf term-buf 56 | :running? true 57 | :opts opts} 58 | job-id (do 59 | (nvim.win_set_buf win term-buf) 60 | (nvim.fn.termopen cmd {:on_exit "ConjureProcessOnExit"}))] 61 | (match job-id 62 | 0 (error "invalid arguments or job table full") 63 | -1 (error (.. "'" cmd "' is not executable"))) 64 | (nvim.win_set_buf win original-buf) 65 | (tset state.jobs job-id proc) 66 | (a.assoc proc :job-id job-id))) 67 | 68 | (fn stop [proc] 69 | (when (running? proc) 70 | (nvim.fn.jobstop proc.job-id) 71 | (on-exit proc.job-id)) 72 | proc) 73 | 74 | { 75 | : executable? 76 | : running? 77 | : on-exit 78 | : execute 79 | : stop 80 | } 81 | -------------------------------------------------------------------------------- /fnl/conjure/promise.fnl: -------------------------------------------------------------------------------- 1 | (local {: autoload} (require :conjure.nfnl.module)) 2 | (local a (autoload :conjure.aniseed.core)) 3 | (local nvim (autoload :conjure.aniseed.nvim)) 4 | (local uuid (autoload :conjure.uuid)) 5 | 6 | (local state {}) 7 | 8 | (fn new [] 9 | (let [id (uuid.v4)] 10 | (a.assoc 11 | state id 12 | {:id id 13 | :val nil 14 | :done? false}) 15 | id)) 16 | 17 | (fn done? [id] 18 | (a.get-in state [id :done?])) 19 | 20 | (fn deliver [id val] 21 | (when (= false (done? id)) 22 | (a.assoc-in state [id :val] val) 23 | (a.assoc-in state [id :done?] true)) 24 | nil) 25 | 26 | (fn deliver-fn [id] 27 | #(deliver id $1)) 28 | 29 | (fn close [id] 30 | (let [val (a.get-in state [id :val])] 31 | (a.assoc state id nil) 32 | val)) 33 | 34 | (fn await [id opts] 35 | (nvim.fn.wait 36 | (a.get opts :timeout 10000) 37 | (.. "luaeval(\"require('conjure.promise')['done?']('" id "')\")") 38 | (a.get opts :interval 50))) 39 | 40 | { 41 | : new 42 | : done? 43 | : deliver 44 | : deliver-fn 45 | : close 46 | : await 47 | } 48 | -------------------------------------------------------------------------------- /fnl/conjure/remote/netrepl.fnl: -------------------------------------------------------------------------------- 1 | (local {: autoload} (require :conjure.nfnl.module)) 2 | (local a (autoload :conjure.aniseed.core)) 3 | (local client (autoload :conjure.client)) 4 | (local log (autoload :conjure.log)) 5 | (local net (autoload :conjure.net)) 6 | (local trn (autoload :conjure.remote.transport.netrepl)) 7 | 8 | (fn send [conn msg cb prompt?] 9 | "Send a message to the given connection, call the callback when a response is received. 10 | If a prompt is expected in addition to the response, prompt? should be set to true." 11 | (log.dbg "send" msg) 12 | (table.insert conn.queue 1 (or cb false)) 13 | (when prompt? 14 | (table.insert conn.queue 1 false)) 15 | (conn.sock:write (trn.encode msg)) 16 | nil) 17 | 18 | (fn connect [opts] 19 | "Connects to a remote netrepl server. 20 | * opts.host: The host string. 21 | * opts.port: Port as a string. 22 | * opts.name: Name of the client to send post-connection, defaults to `Conjure`. 23 | * opts.on-failure: Function to call after a failed connection with the error. 24 | * opts.on-success: Function to call on a successful connection. 25 | * opts.on-error: Function to call when we receive an error (passed as argument) or a nil response. 26 | Returns a connection table containing a `destroy` function." 27 | 28 | (var conn 29 | {:decode (trn.decoder) 30 | :queue []}) 31 | 32 | (fn handle-message [err chunk] 33 | (if (or err (not chunk)) 34 | (opts.on-error err) 35 | (->> (conn.decode chunk) 36 | (a.run! 37 | (fn [msg] 38 | (log.dbg "receive" msg) 39 | (let [cb (table.remove conn.queue)] 40 | (when cb 41 | (cb msg)))))))) 42 | 43 | (set conn 44 | (a.merge 45 | conn 46 | (net.connect 47 | {:host opts.host 48 | :port opts.port 49 | :cb (client.schedule-wrap 50 | (fn [err] 51 | (if err 52 | (opts.on-failure err) 53 | 54 | (do 55 | (send conn (or opts.name "Conjure")) 56 | (conn.sock:read_start (client.schedule-wrap handle-message)) 57 | (opts.on-success)))))}))) 58 | 59 | conn) 60 | 61 | ;; Example: 62 | ; (def c (connect 63 | ; {:host "127.0.0.1" 64 | ; :port "9365" 65 | ; :on-failure (fn [err] (a.println "oh no" err)) 66 | ; :on-success (fn [] (a.println "Yay!")) 67 | ; :on-error (fn [err] (a.println "uh oh :(" err))})) 68 | ; (send c "{:hello :world}" a.println) 69 | ; (c.destroy) 70 | 71 | {: connect : send} 72 | -------------------------------------------------------------------------------- /fnl/conjure/remote/stdio2.fnl: -------------------------------------------------------------------------------- 1 | (local {: autoload} (require :conjure.nfnl.module)) 2 | (local a (autoload :conjure.aniseed.core)) 3 | (local str (autoload :conjure.aniseed.string)) 4 | (local client (autoload :conjure.client)) 5 | (local log (autoload :conjure.log)) 6 | 7 | (local uv vim.loop) 8 | 9 | (fn parse-cmd [x] 10 | (if 11 | (a.table? x) 12 | {:cmd (a.first x) 13 | :args (a.rest x)} 14 | 15 | (a.string? x) 16 | (parse-cmd (str.split x "%s")))) 17 | 18 | {: parse-cmd} 19 | -------------------------------------------------------------------------------- /fnl/conjure/remote/swank.fnl: -------------------------------------------------------------------------------- 1 | (local {: autoload} (require :conjure.nfnl.module)) 2 | (local a (autoload :conjure.aniseed.core)) 3 | (local client (autoload :conjure.client)) 4 | (local net (autoload :conjure.net)) 5 | (local trn (autoload :conjure.remote.transport.swank)) 6 | 7 | (fn send [conn msg cb] 8 | "Send a message to the given connection, call the callback when a response is received." 9 | ; (log.dbg "send" msg) 10 | (table.insert conn.queue 1 (or cb false)) 11 | (conn.sock:write (trn.encode msg)) 12 | nil) 13 | 14 | (fn connect [opts] 15 | "Connects to a remote swank server. 16 | * opts.host: The host string. 17 | * opts.port: Port as a string. 18 | * opts.name: Name of the client to send post-connection, defaults to `Conjure`. 19 | * opts.on-failure: Function to call after a failed connection with the error. 20 | * opts.on-success: Function to call on a successful connection. 21 | * opts.on-error: Function to call when we receive an error (passed as argument) or a nil response. 22 | Returns a connection table containing a `destroy` function." 23 | 24 | (var conn 25 | {:decode trn.decode 26 | :queue []}) 27 | 28 | (fn handle-message [err chunk] 29 | (if (or err (not chunk)) 30 | (opts.on-error err) 31 | (->> (conn.decode chunk) 32 | ((fn [msg] 33 | ; (log.dbg "receive" msg) 34 | (let [cb (table.remove conn.queue)] 35 | (when cb 36 | (cb msg)))))))) 37 | 38 | (set conn 39 | (a.merge 40 | conn 41 | (net.connect 42 | {:host opts.host 43 | :port opts.port 44 | :cb (client.schedule-wrap 45 | (fn [err] 46 | (if err 47 | (opts.on-failure err) 48 | 49 | (do 50 | (conn.sock:read_start (client.schedule-wrap handle-message)) 51 | (opts.on-success)))))}))) 52 | 53 | ; (send conn (or opts.name "Conjure")) 54 | conn) 55 | 56 | {: send 57 | : connect} 58 | -------------------------------------------------------------------------------- /fnl/conjure/remote/transport/base64.fnl: -------------------------------------------------------------------------------- 1 | ;; From https://stackoverflow.com/a/35303321/455137 2 | ;; Converted to Fennel by antifennel. 3 | 4 | (local b "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/") 5 | 6 | (fn encode [data] 7 | (.. (: (.. (data:gsub "." 8 | (fn [x] 9 | (var (r b) (values "" (x:byte))) 10 | (for [i 8 1 (- 1)] 11 | (set r 12 | (.. r 13 | (or (and (> (- (% b (^ 2 i)) 14 | (% b 15 | (^ 2 16 | (- i 1)))) 17 | 0) 18 | :1) 19 | :0)))) 20 | r)) :0000) 21 | :gsub "%d%d%d?%d?%d?%d?" 22 | (fn [x] 23 | (when (< (length x) 6) (lua "return \"\"")) 24 | (var c 0) 25 | (for [i 1 6] 26 | (set c 27 | (+ c 28 | (or (and (= (x:sub i i) :1) (^ 2 (- 6 i))) 29 | 0)))) 30 | (b:sub (+ c 1) (+ c 1)))) 31 | (. ["" "==" "="] (+ (% (length data) 3) 1)))) 32 | 33 | (fn decode [data] 34 | (set-forcibly! data (string.gsub data (.. "[^" b "=]") "")) 35 | (: (data:gsub "." 36 | (fn [x] 37 | (when (= x "=") (lua "return \"\"")) 38 | (var (r f) (values "" (- (b:find x) 1))) 39 | (for [i 6 1 (- 1)] 40 | (set r 41 | (.. r 42 | (or (and (> (- (% f (^ 2 i)) 43 | (% f 44 | (^ 2 (- i 1)))) 45 | 0) 46 | :1) 47 | :0)))) 48 | r)) :gsub 49 | "%d%d%d?%d?%d?%d?%d?%d?" 50 | (fn [x] 51 | (when (not= (length x) 8) (lua "return \"\"")) 52 | (var c 0) 53 | (for [i 1 8] 54 | (set c 55 | (+ c 56 | (or (and (= (x:sub i i) :1) (^ 2 (- 8 i))) 57 | 0)))) 58 | (string.char c)))) 59 | 60 | {: encode 61 | : decode} 62 | -------------------------------------------------------------------------------- /fnl/conjure/remote/transport/netrepl.fnl: -------------------------------------------------------------------------------- 1 | (local {: autoload} (require :conjure.nfnl.module)) 2 | (local a (autoload :conjure.aniseed.core)) 3 | (local bit (autoload :bit)) 4 | 5 | (fn encode [msg] 6 | (let [n (a.count msg)] 7 | (.. (string.char 8 | (bit.band n 0xFF) 9 | (bit.band (bit.rshift n 8) 0xFF) 10 | (bit.band (bit.rshift n 16) 0xFF) 11 | (bit.band (bit.rshift n 24) 0xFF)) 12 | msg))) 13 | 14 | (fn split [chunk] 15 | (let [(b0 b1 b2 b3) (string.byte chunk 1 4)] 16 | (values 17 | (bit.bor 18 | (bit.band b0 0xFF) 19 | (bit.lshift (bit.band b1 0xFF) 8) 20 | (bit.lshift (bit.band b2 0xFF) 16) 21 | (bit.lshift (bit.band b3 0xFF) 24)) 22 | (string.sub chunk 5)))) 23 | 24 | (fn decoder [] 25 | (var awaiting nil) 26 | (var buffer "") 27 | 28 | (fn reset [] 29 | (set awaiting nil) 30 | (set buffer "")) 31 | 32 | (fn decode [chunk acc] 33 | (local acc (or acc [])) 34 | 35 | (if awaiting 36 | (do 37 | (local before (a.count buffer)) 38 | (local seen (a.count chunk)) 39 | (set buffer (.. buffer chunk)) 40 | 41 | (if 42 | ;; More than expected. 43 | ;; Consume part of the buffer reset state and recur. 44 | (> seen awaiting) 45 | (let [consumed (string.sub buffer 1 (+ before awaiting)) 46 | next-chunk (string.sub chunk (a.inc awaiting))] 47 | (table.insert acc consumed) 48 | (reset) 49 | (decode next-chunk acc)) 50 | 51 | ;; Exact amount required. 52 | ;; Consume whole buffer, reset state and return. 53 | (= seen awaiting) 54 | (do 55 | (table.insert acc buffer) 56 | (reset) 57 | acc) 58 | 59 | ;; Else, less than expected. 60 | ;; Mark off what we have so far, return. 61 | (do 62 | (set awaiting (- awaiting seen)) 63 | acc))) 64 | 65 | (let [(n rem) (split chunk)] 66 | (set awaiting n) 67 | (decode rem acc))))) 68 | 69 | {: decoder : encode} 70 | -------------------------------------------------------------------------------- /fnl/conjure/remote/transport/swank.fnl: -------------------------------------------------------------------------------- 1 | (local {: autoload} (require :conjure.nfnl.module)) 2 | (local a (autoload :conjure.aniseed.core)) 3 | (local log (autoload :conjure.log)) 4 | 5 | (fn encode [msg] 6 | (let [n (a.count msg) 7 | header (string.format "%06x" (+ 1 n))] ; Additional 1 for trailing newline 8 | (.. header msg "\n"))) 9 | 10 | (fn decode [msg] 11 | (let [len (tonumber (string.sub msg 1 7) 16) 12 | cmd (string.sub msg 7 len)] 13 | cmd)) 14 | 15 | {: encode : decode} 16 | -------------------------------------------------------------------------------- /fnl/conjure/sponsors.fnl: -------------------------------------------------------------------------------- 1 | [ ;; Generated by: make sponsors 2 | "AbhinavOmprakash" 3 | "Akeboshiwind" 4 | "aleksandersumowski" 5 | "AlexChalk" 6 | "Aljendro" 7 | "alloy-d" 8 | "anthony-khong" 9 | "axvr" 10 | "beanpuppy" 11 | "Brailor" 12 | "campbellr" 13 | "daveyarwood" 14 | "davidmh" 15 | "dharrigan" 16 | "djwhitt" 17 | "edlandm" 18 | "extradosages" 19 | "frenchy64" 20 | "fuadsaud" 21 | "harrygallagher4" 22 | "jackkinsey" 23 | "jacobobryant" 24 | "jamesreprise" 25 | "jcpsantiago" 26 | "jkrasnay" 27 | "ketansrivastav" 28 | "kevinkrouse" 29 | "lanjoni" 30 | "lucasdf" 31 | "lucaslollobrigida" 32 | "matheusfrancisco" 33 | "mraveloarinjaka" 34 | "NickCellino" 35 | "NoahTheDuke" 36 | "orestis" 37 | "penryu" 38 | "qnkhuat" 39 | "rafaeldelboni" 40 | "rbatista" 41 | "rgm" 42 | "stelcodes" 43 | "terjesb" 44 | "theplatters" 45 | "thiru" 46 | "TimoKramer" 47 | "trev-dev" 48 | "valsen" 49 | "victorb" 50 | "zhming0" 51 | ] 52 | -------------------------------------------------------------------------------- /fnl/conjure/stack.fnl: -------------------------------------------------------------------------------- 1 | (local {: autoload} (require :conjure.nfnl.module)) 2 | (local a (autoload :conjure.aniseed.core)) 3 | 4 | (fn push [s v] 5 | (table.insert s v) 6 | s) 7 | 8 | (fn pop [s] 9 | (table.remove s) 10 | s) 11 | 12 | (fn peek [s] 13 | (a.last s)) 14 | 15 | { 16 | : push 17 | : pop 18 | : peek 19 | } 20 | 21 | -------------------------------------------------------------------------------- /fnl/conjure/text.fnl: -------------------------------------------------------------------------------- 1 | (local {: autoload} (require :conjure.nfnl.module)) 2 | (local a (autoload :conjure.aniseed.core)) 3 | (local str (autoload :conjure.aniseed.string)) 4 | 5 | (fn trailing-newline? [s] 6 | (string.match s "\r?\n$")) 7 | 8 | (fn trim-last-newline [s] 9 | (string.gsub s "\r?\n$" "")) 10 | 11 | (fn left-sample [s limit] 12 | (let [flat (-> (string.gsub s "\n" " ") 13 | (string.gsub "%s+" " ") 14 | (str.trim))] 15 | (if (>= limit (a.count flat)) 16 | flat 17 | (.. (string.sub flat 0 (a.dec limit)) "...")))) 18 | 19 | (fn right-sample [s limit] 20 | (string.reverse (left-sample (string.reverse s) limit))) 21 | 22 | (fn split-lines [s] 23 | (str.split s "\r?\n")) 24 | 25 | (fn prefixed-lines [s prefix opts] 26 | (->> (split-lines s) 27 | (a.map-indexed 28 | (fn [[n line]] 29 | (if (and (= 1 n) 30 | (a.get opts :skip-first?)) 31 | line 32 | (.. prefix line)))))) 33 | 34 | (fn starts-with [str start] 35 | (when (and str start) 36 | (vim.startswith str start))) 37 | 38 | (fn ends-with [str end] 39 | (when (and str end) 40 | (or (= end "") 41 | (vim.endswith str end)))) 42 | 43 | (fn first-and-last-chars [str] 44 | (when str 45 | (if (> (a.count str) 1) 46 | (.. (string.sub str 1 1) 47 | (string.sub str -1 -1)) 48 | str))) 49 | 50 | (fn strip-ansi-escape-sequences [s] 51 | (-> s 52 | (string.gsub "\x1b%[%d+;%d+;%d+;%d+;%d+m" "") 53 | (string.gsub "\x1b%[%d+;%d+;%d+;%d+m" "") 54 | (string.gsub "\x1b%[%d+;%d+;%d+m" "") 55 | (string.gsub "\x1b%[%d+;%d+m" "") 56 | (string.gsub "\x1b%[%d+m" ""))) 57 | 58 | (fn chars [s] 59 | (local res []) 60 | (when s 61 | (each [c (string.gmatch s ".")] 62 | (table.insert res c))) 63 | res) 64 | 65 | (fn upper-first [s] 66 | (when s 67 | (s:gsub "^%l" string.upper))) 68 | 69 | { 70 | : trailing-newline? 71 | : trim-last-newline 72 | : left-sample 73 | : right-sample 74 | : split-lines 75 | : prefixed-lines 76 | : starts-with 77 | : ends-with 78 | : first-and-last-chars 79 | : strip-ansi-escape-sequences 80 | : chars 81 | : upper-first 82 | } 83 | -------------------------------------------------------------------------------- /fnl/conjure/timer.fnl: -------------------------------------------------------------------------------- 1 | (local {: define} (require :conjure.nfnl.module)) 2 | 3 | (local M (define :conjure.timer)) 4 | 5 | (fn M.defer [f ms] 6 | (let [t (vim.uv.new_timer)] 7 | (t:start ms 0 (vim.schedule_wrap f)) 8 | t)) 9 | 10 | (fn M.destroy [t] 11 | (when t 12 | (t:stop) 13 | (t:close)) 14 | nil) 15 | 16 | M 17 | -------------------------------------------------------------------------------- /fnl/conjure/util.fnl: -------------------------------------------------------------------------------- 1 | (fn wrap-require-fn-call [mod f] 2 | "We deliberately don't pass args through here because functions can behave 3 | very differently if they blindly accept args. If you need the args you should 4 | do your own function wrapping and not use this shorthand." 5 | (fn [] 6 | ((. (require mod) f)))) 7 | 8 | (fn replace-termcodes [s] 9 | (vim.api.nvim_replace_termcodes s true false true)) 10 | 11 | {: wrap-require-fn-call 12 | : replace-termcodes} 13 | -------------------------------------------------------------------------------- /lua/conjure-benchmark/bencode.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure-benchmark/bencode.fnl 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local define = _local_1_["define"] 4 | local core = require("conjure.nfnl.core") 5 | local bencode = require("conjure.remote.transport.bencode") 6 | local M = define("conjure-benchmark.bencode") 7 | M.name = "bencode" 8 | local function range(n) 9 | local acc = {} 10 | for i = 1, n do 11 | table.insert(acc, i) 12 | end 13 | return acc 14 | end 15 | local function split_into_chunks(str, chunk_size) 16 | local len = string.len(str) 17 | local chunks = {} 18 | for i = 1, len, chunk_size do 19 | local _end = math.min((i + (chunk_size - 1)), len) 20 | table.insert(chunks, string.sub(str, i, _end)) 21 | end 22 | return chunks 23 | end 24 | local function _2_() 25 | local bs = bencode.new() 26 | return bencode["decode-all"](bs, bencode.encode({foo = "bar", baz = {1, 2, 3}})) 27 | end 28 | local function _3_() 29 | local bs = bencode.new() 30 | local data 31 | local function _4_() 32 | return {foo = "bar", baz = {1, 2, 3}, quux = {hello = "world"}} 33 | end 34 | data = bencode.encode(core.map(_4_, range(500))) 35 | local function _5_(chunk) 36 | return bencode["decode-all"](bs, chunk) 37 | end 38 | return core["run!"](_5_, split_into_chunks(data, 512)) 39 | end 40 | M.tasks = {{name = "simple encode and decode", ["task-fn"] = _2_}, {name = "big encode, chunked decode", ["task-fn"] = _3_}} 41 | return M 42 | -------------------------------------------------------------------------------- /lua/conjure-benchmark/run.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure-benchmark/run.fnl 2 | package.path = (vim.fn.getcwd() .. "/lua/?.lua;" .. vim.fn.getcwd() .. "/lua/?/init.lua;" .. package.path) 3 | local core = require("conjure.nfnl.core") 4 | local iterations = 1000 5 | local function benchmark_task(_1_) 6 | local name = _1_["name"] 7 | local task_fn = _1_["task-fn"] 8 | local start = vim.uv.now() 9 | for _i = 1, iterations do 10 | task_fn() 11 | end 12 | vim.uv.update_time() 13 | local duration = ((vim.uv.now() - start) / iterations) 14 | return print("##", name, ("[" .. duration .. "ms]")) 15 | end 16 | local function benchmark_tasks(_2_) 17 | local name = _2_["name"] 18 | local tasks = _2_["tasks"] 19 | print("Iterations:", iterations) 20 | print("#", name) 21 | return core["run!"](benchmark_task, tasks) 22 | end 23 | local bencode_bm = require("conjure-benchmark.bencode") 24 | return benchmark_tasks(bencode_bm) 25 | -------------------------------------------------------------------------------- /lua/conjure-spec/bridge_spec.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure-spec/bridge_spec.fnl 2 | local _local_1_ = require("plenary.busted") 3 | local describe = _local_1_["describe"] 4 | local it = _local_1_["it"] 5 | local bridge = require("conjure.bridge") 6 | local assert = require("luassert.assert") 7 | local function _2_() 8 | local function _3_() 9 | local result = bridge["viml->lua"]("my.module", "my_function", nil) 10 | return assert.equal(result, "lua require('my.module')['my_function']()") 11 | end 12 | it("converts a module and function to a Lua require call without arguments", _3_) 13 | local function _4_() 14 | local result = bridge["viml->lua"]("my.module", "my_function", {args = "arg1, arg2"}) 15 | return assert.equal(result, "lua require('my.module')['my_function'](arg1, arg2)") 16 | end 17 | return it("converts a module and function to a Lua require call with arguments", _4_) 18 | end 19 | return describe("viml->lua", _2_) 20 | -------------------------------------------------------------------------------- /lua/conjure-spec/client/clojure/nrepl/action_spec.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure-spec/client/clojure/nrepl/action_spec.fnl 2 | local _local_1_ = require("plenary.busted") 3 | local describe = _local_1_["describe"] 4 | local it = _local_1_["it"] 5 | local assert = require("luassert.assert") 6 | local action = require("conjure.client.clojure.nrepl.action") 7 | local function _2_() 8 | local function _3_() 9 | vim.g["conjure#client#clojure#nrepl#test#current_form_names"] = {"deftest"} 10 | local function _4_() 11 | return assert.are.equals(nil, action["extract-test-name-from-form"]("")) 12 | end 13 | it("deftest form with missing name", _4_) 14 | local function _5_() 15 | return assert.are.equals("foo", action["extract-test-name-from-form"]("(deftest foo (+ 10 20))")) 16 | end 17 | it("normal deftest form", _5_) 18 | local function _6_() 19 | return assert.are.equals("foo", action["extract-test-name-from-form"]("( deftest foo (+ 10 20))")) 20 | end 21 | it("deftest form with extra spaces", _6_) 22 | local function _7_() 23 | return assert.are.equals("foo", action["extract-test-name-from-form"]("(deftest ^:kaocha/skip foo :xyz)")) 24 | end 25 | return it("deftest form with metadata", _7_) 26 | end 27 | return describe("extract-test-name-from-form", _3_) 28 | end 29 | return describe("client.clojure.nrepl.action", _2_) 30 | -------------------------------------------------------------------------------- /lua/conjure-spec/client/clojure/nrepl/auto-repl_spec.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure-spec/client/clojure/nrepl/auto-repl_spec.fnl 2 | local _local_1_ = require("plenary.busted") 3 | local describe = _local_1_["describe"] 4 | local it = _local_1_["it"] 5 | local assert = require("luassert.assert") 6 | local auto_repl = require("conjure.client.clojure.nrepl.auto-repl") 7 | local function _2_() 8 | local function _3_() 9 | local function _4_() 10 | return assert.same({subject = "foo"}, auto_repl.enportify("foo")) 11 | end 12 | it("subject is foo", _4_) 13 | local _let_5_ = auto_repl.enportify("foo:$port") 14 | local subject = _let_5_["subject"] 15 | local port = _let_5_["port"] 16 | local function _6_() 17 | return assert.are.equals("string", type(port)) 18 | end 19 | it("port is in string form", _6_) 20 | local function _7_() 21 | local _8_ = tonumber(port) 22 | return assert.is_true(((1000 < _8_) and (_8_ < 100000))) 23 | end 24 | it("port number is between 1000 and 100000", _7_) 25 | local function _9_() 26 | return assert.are.equals(("foo:" .. port), subject) 27 | end 28 | return it("subject is foo:port", _9_) 29 | end 30 | return describe("enportify", _3_) 31 | end 32 | return describe("client.clojure.nrepl.auto-repl", _2_) 33 | -------------------------------------------------------------------------------- /lua/conjure-spec/client/clojure/nrepl/init_spec.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure-spec/client/clojure/nrepl/init_spec.fnl 2 | local _local_1_ = require("plenary.busted") 3 | local describe = _local_1_["describe"] 4 | local it = _local_1_["it"] 5 | local assert = require("luassert.assert") 6 | local clj = require("conjure.client.clojure.nrepl") 7 | local function _2_() 8 | local function _3_() 9 | local function _4_() 10 | return assert.are.equals(nil, clj.context("not a namespace")) 11 | end 12 | it("isn't a namespace", _4_) 13 | local function _5_() 14 | return assert.are.equals("foo", clj.context("(ns foo)")) 15 | end 16 | it("simplest form", _5_) 17 | local function _6_() 18 | return assert.are.equals("foo", clj.context("(ns foo")) 19 | end 20 | it("missing closing paren", _6_) 21 | local function _7_() 22 | return assert.are.equals("foo", clj.context("(ns ^:bar foo baz)")) 23 | end 24 | it("short meta", _7_) 25 | local function _8_() 26 | return assert.are.equals("foo", clj.context("(ns ^:bar foo baz")) 27 | end 28 | it("short meta missing closing paren", _8_) 29 | local function _9_() 30 | return assert.are.equals("foo", clj.context("(ns ^{:bar true} foo baz)")) 31 | end 32 | it("long meta", _9_) 33 | local function _10_() 34 | return assert.are.equals("foo", clj.context("(ns \n^{:bar true} foo\n \"some docs\"\n baz")) 35 | end 36 | it("newlines and docs", _10_) 37 | local function _11_() 38 | return assert.are.equals("foo", clj.context("#!/usr/bin/env bb\n(ns ^:bar foo)\n(def foo1 1)")) 39 | end 40 | it("strip shebang", _11_) 41 | local function _12_() 42 | assert.are.equals("foo", clj.context("(ns ^{:clj-kondo/config {:lint-as '{my-awesome/defn-like-macro clojure.core/defn}}} foo)")) 43 | return assert.are.equals("foo", clj.context("(ns ^{:clj-kondo/config {:lint-as (quote {my-awesome/defn-like-macro clojure.core/defn})}} foo)")) 44 | end 45 | it("namespace metadata doesn't break evaluation", _12_) 46 | local function _13_() 47 | assert.are.equals("foo", clj.context("(ns ;)\n foo)")) 48 | return assert.are.equals("foo", clj.context("(ns ^{:doc \"...... (....) (..)))...\"}\n foo)", b)) 49 | end 50 | return it(") before namespace", _13_) 51 | end 52 | return describe("context", _3_) 53 | end 54 | return describe("client.clojure.nrepl.init", _2_) 55 | -------------------------------------------------------------------------------- /lua/conjure-spec/client/fennel/nfnl_spec.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure-spec/client/fennel/nfnl_spec.fnl 2 | local _local_1_ = require("plenary.busted") 3 | local describe = _local_1_["describe"] 4 | local it = _local_1_["it"] 5 | local assert = require("luassert.assert") 6 | local fs = require("conjure.nfnl.fs") 7 | local nfnlc = require("conjure.client.fennel.nfnl") 8 | local function _2_() 9 | local function _3_() 10 | local function _4_() 11 | assert.is["nil"](nfnlc["module-path"](nil)) 12 | return nil 13 | end 14 | it("returns nil when given nil", _4_) 15 | local function _5_() 16 | assert.are.equal("foo", nfnlc["module-path"](fs["full-path"]("fnl/foo.fnl"))) 17 | return nil 18 | end 19 | it("handles single path segments", _5_) 20 | local function _6_() 21 | assert.are.equal("foo.bar.baz", nfnlc["module-path"](fs["full-path"]("fnl/foo/bar/baz.fnl"))) 22 | return nil 23 | end 24 | return it("handles multiple path segments", _6_) 25 | end 26 | describe("module-path", _3_) 27 | local function _7_() 28 | local path = fs["full-path"]("fnl/foo.fnl") 29 | local function _8_() 30 | assert.is["function"](nfnlc["repl-for-path"](path)) 31 | return nil 32 | end 33 | it("returns a new repl for a path", _8_) 34 | local function _9_() 35 | assert.is.equal(nfnlc["repl-for-path"](path), nfnlc["repl-for-path"](path)) 36 | return nil 37 | end 38 | it("returns the same function each time", _9_) 39 | local function _10_() 40 | assert.are.same({30}, nfnlc["repl-for-path"](path)("(+ 10 20)")) 41 | return nil 42 | end 43 | return it("executes fennel and returns the results", _10_) 44 | end 45 | return describe("repl-for-path", _7_) 46 | end 47 | return describe("conjure.client.fennel.nfnl", _2_) 48 | -------------------------------------------------------------------------------- /lua/conjure-spec/client/sql/stdio_spec.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure-spec/client/sql/stdio_spec.fnl 2 | local _local_1_ = require("plenary.busted") 3 | local describe = _local_1_["describe"] 4 | local it = _local_1_["it"] 5 | local assert = require("luassert.assert") 6 | local sql = require("conjure.client.sql.stdio") 7 | local function _2_() 8 | local function _3_() 9 | local function _4_() 10 | local function _5_() 11 | return "meta" 12 | end 13 | assert.same("foo\n", sql["prep-code"]({code = "foo -- bar", node = {type = _5_}})) 14 | local function _6_() 15 | return "meta" 16 | end 17 | assert.same("foo -- bar\nsomething\n", sql["prep-code"]({code = "foo -- bar\nsomething -- quuz", node = {type = _6_}})) 18 | local function _7_() 19 | return "meta" 20 | end 21 | assert.same("foo -- bar\nsomething -- quux\n\n", sql["prep-code"]({code = "foo -- bar\nsomething -- quux\n", node = {type = _7_}})) 22 | local function _8_() 23 | return "statement" 24 | end 25 | assert.same("foo;\n", sql["prep-code"]({code = "foo -- bar", node = {type = _8_}})) 26 | return nil 27 | end 28 | return it("prepares sql code appropriately", _4_) 29 | end 30 | return describe("prep-code", _3_) 31 | end 32 | return describe("conjure.client.sql.stdio", _2_) 33 | -------------------------------------------------------------------------------- /lua/conjure-spec/config_spec.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure-spec/config_spec.fnl 2 | local _local_1_ = require("plenary.busted") 3 | local describe = _local_1_["describe"] 4 | local it = _local_1_["it"] 5 | local assert = require("luassert.assert") 6 | local config = require("conjure.config") 7 | local core = require("conjure.nfnl.core") 8 | local function _2_() 9 | local function _3_() 10 | assert.is_true(config["get-in"]({"client_on_load"})) 11 | return assert.same("conjure.client.clojure.nrepl", config["get-in"]({"filetype", "clojure"})) 12 | end 13 | return it("takes a table of keys and fetches the config value from vim.b or vim.g variables.", _3_) 14 | end 15 | describe("get-in", _2_) 16 | local function _4_() 17 | local function _5_() 18 | assert.same(config["get-in"]({"filetypes"}), config.filetypes()) 19 | return assert.same("clojure", core.first(config.filetypes())) 20 | end 21 | return it("returns the filetypes list", _5_) 22 | end 23 | describe("filetypes", _4_) 24 | local function _6_() 25 | local function _7_() 26 | return assert.same("conjure.client.sql.stdio", config["get-in-fn"]({"filetype"})({"sql"})) 27 | end 28 | return it("returns a function that works like get-in but with a path prefix", _7_) 29 | end 30 | describe("get-in-fn", _6_) 31 | local function _8_() 32 | local function _9_() 33 | config["assoc-in"]({"foo", "bar"}, "baz") 34 | return assert.same("baz", config["get-in"]({"foo", "bar"})) 35 | end 36 | return it("sets some new config", _9_) 37 | end 38 | describe("assoc-in", _8_) 39 | local function _10_() 40 | local function _11_() 41 | config.merge({foo = {bar = "de_dust2"}}) 42 | assert.same("baz", config["get-in"]({"foo", "bar"})) 43 | config.merge({foo = {bar = "de_dust2"}}, {["overwrite?"] = true}) 44 | return assert.same("de_dust2", config["get-in"]({"foo", "bar"})) 45 | end 46 | return it("merges more config into the tree, requires overwrite? if it already exists", _11_) 47 | end 48 | return describe("merge", _10_) 49 | -------------------------------------------------------------------------------- /lua/conjure-spec/process_spec.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure-spec/process_spec.fnl 2 | local _local_1_ = require("plenary.busted") 3 | local describe = _local_1_["describe"] 4 | local it = _local_1_["it"] 5 | local assert = require("luassert.assert") 6 | local nvim = require("conjure.aniseed.nvim") 7 | local process = require("conjure.process") 8 | local function _2_() 9 | local function _3_() 10 | local function _4_() 11 | return assert.are.equals(false, process["executable?"]("nope-this-does-not-exist")) 12 | end 13 | it("thing's that don't exist return false", _4_) 14 | local function _5_() 15 | return assert.are.equals(true, process["executable?"]("sh")) 16 | end 17 | it("sh should always exist, I hope", _5_) 18 | local function _6_() 19 | return assert.are.equals(true, process["executable?"]("sh foo bar")) 20 | end 21 | return it("only the first word is checked", _6_) 22 | end 23 | describe("executable?", _3_) 24 | local function _7_() 25 | local sh = process.execute("sh") 26 | local function _8_() 27 | return assert.are.equals("table", type(sh)) 28 | end 29 | it("we get a table to identify the process", _8_) 30 | local function _9_() 31 | return assert.are.equals(true, process["running?"](sh)) 32 | end 33 | it("it starts out as running", _9_) 34 | local function _10_() 35 | return assert.are.equals(false, process["running?"](nil)) 36 | end 37 | it("the running check handles nils", _10_) 38 | local function _11_() 39 | return assert.are.equals(1, nvim.fn.bufexists(sh.buf)) 40 | end 41 | it("a buffer is created for the terminal / process", _11_) 42 | local function _12_() 43 | return assert.are.equals(sh, process.stop(sh)) 44 | end 45 | it("stopping returns the process table", _12_) 46 | local function _13_() 47 | return assert.are.equals(sh, process.stop(sh)) 48 | end 49 | it("stopping is idempotent", _13_) 50 | local function _14_() 51 | return assert.are.equals(false, process["running?"](sh)) 52 | end 53 | return it("now it's not running", _14_) 54 | end 55 | describe("execute-stop-lifecycle", _7_) 56 | local function _15_() 57 | local state = {args = nil} 58 | local sh 59 | local function _16_(...) 60 | state["args"] = {...} 61 | return nil 62 | end 63 | sh = process.execute("sh", {["on-exit"] = _16_}) 64 | local function _17_() 65 | process.stop(sh) 66 | return assert.same({sh}, state.args) 67 | end 68 | return it("called and given the proc", _17_) 69 | end 70 | return describe("on-exit-hook", _15_) 71 | end 72 | return describe("conjure.process", _2_) 73 | -------------------------------------------------------------------------------- /lua/conjure-spec/promise_spec.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure-spec/promise_spec.fnl 2 | local _local_1_ = require("plenary.busted") 3 | local describe = _local_1_["describe"] 4 | local it = _local_1_["it"] 5 | local assert = require("luassert.assert") 6 | local promise = require("conjure.promise") 7 | local function _2_() 8 | local function _3_() 9 | local p = promise.new() 10 | local function _4_() 11 | local function _5_() 12 | return assert.are.equals(false, promise["done?"](p)) 13 | end 14 | it("starts incomplete", _5_) 15 | local function _6_() 16 | promise.deliver(p, "foo") 17 | return assert.are.equals(true, promise["done?"](p)) 18 | end 19 | it("done after deliver", _6_) 20 | local function _7_() 21 | return assert.are.equals("foo", promise.close(p)) 22 | end 23 | return it("returns the value on close", _7_) 24 | end 25 | return _4_ 26 | end 27 | describe("basics", _3_()) 28 | local function _8_() 29 | local p = promise.new() 30 | local function _9_() 31 | promise.deliver(p, "foo") 32 | promise.deliver(p, "bar") 33 | return assert.are.equals("foo", promise.close(p)) 34 | end 35 | return it("only the first delivery works", _9_) 36 | end 37 | describe("multiple-deliveries", _8_) 38 | local function _10_() 39 | local p = promise.new() 40 | local del = promise["deliver-fn"](p) 41 | local function _11_() 42 | return del("later") 43 | end 44 | vim.schedule(_11_) 45 | local function _12_() 46 | local function _13_() 47 | return assert.are.equals(false, promise["done?"](p)) 48 | end 49 | it("async delivery hasn't happened yet", _13_) 50 | local function _14_() 51 | return assert.are.equals(0, promise.await(p)) 52 | end 53 | it("await returns 0 from wait()", _14_) 54 | local function _15_() 55 | return assert.are.equals(true, promise["done?"](p)) 56 | end 57 | it("complete after await", _15_) 58 | local function _16_() 59 | return assert.are.equals("later", promise.close(p)) 60 | end 61 | return it("value is correct", _16_) 62 | end 63 | return _12_ 64 | end 65 | return describe("async", _10_()) 66 | end 67 | return describe("conjure.promise", _2_) 68 | -------------------------------------------------------------------------------- /lua/conjure-spec/remote/stdio2_spec.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure-spec/remote/stdio2_spec.fnl 2 | local _local_1_ = require("plenary.busted") 3 | local describe = _local_1_["describe"] 4 | local it = _local_1_["it"] 5 | local assert = require("luassert.assert") 6 | local stdio = require("conjure.remote.stdio2") 7 | local function _2_() 8 | local function _3_() 9 | local function _4_() 10 | return assert.same({cmd = "foo", args = {}}, stdio["parse-cmd"]("foo")) 11 | end 12 | it("parses a string", _4_) 13 | local function _5_() 14 | return assert.same({cmd = "foo", args = {}}, stdio["parse-cmd"]({"foo"})) 15 | end 16 | it("parses a list of one string", _5_) 17 | local function _6_() 18 | return assert.same({cmd = "foo", args = {"bar", "baz"}}, stdio["parse-cmd"]("foo bar baz")) 19 | end 20 | it("parses a string with words separated by spaces", _6_) 21 | local function _7_() 22 | return assert.same({cmd = "foo", args = {"bar", "baz"}}, stdio["parse-cmd"]({"foo", "bar", "baz"})) 23 | end 24 | return it("parses a list of more than one string", _7_) 25 | end 26 | return describe("parse-cmd", _3_) 27 | end 28 | return describe("conjure.remote.stdio2", _2_) 29 | -------------------------------------------------------------------------------- /lua/conjure-spec/remote/stdio_spec.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure-spec/remote/stdio_spec.fnl 2 | local _local_1_ = require("plenary.busted") 3 | local describe = _local_1_["describe"] 4 | local it = _local_1_["it"] 5 | local assert = require("luassert.assert") 6 | local stdio = require("conjure.remote.stdio") 7 | local function _2_() 8 | local function _3_() 9 | local function _4_() 10 | return assert.same({cmd = "foo", args = {}}, stdio["parse-cmd"]("foo")) 11 | end 12 | it("parses a string", _4_) 13 | local function _5_() 14 | return assert.same({cmd = "foo", args = {}}, stdio["parse-cmd"]({"foo"})) 15 | end 16 | it("parses a list of one string", _5_) 17 | local function _6_() 18 | return assert.same({cmd = "foo", args = {"bar", "baz"}}, stdio["parse-cmd"]("foo bar baz")) 19 | end 20 | it("parses a string with words separated by spaces", _6_) 21 | local function _7_() 22 | return assert.same({cmd = "foo", args = {"bar", "baz"}}, stdio["parse-cmd"]({"foo", "bar", "baz"})) 23 | end 24 | return it("parses a list of more than one string", _7_) 25 | end 26 | return describe("parse-cmd", _3_) 27 | end 28 | return describe("conjure.remote.stdio", _2_) 29 | -------------------------------------------------------------------------------- /lua/conjure-spec/remote/transport/base64_spec.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure-spec/remote/transport/base64_spec.fnl 2 | local _local_1_ = require("plenary.busted") 3 | local describe = _local_1_["describe"] 4 | local it = _local_1_["it"] 5 | local assert = require("luassert.assert") 6 | local b64 = require("conjure.remote.transport.base64") 7 | local function _2_() 8 | local function _3_() 9 | local function _4_() 10 | return assert.are.equals("", b64.encode("")) 11 | end 12 | it("empty to empty", _4_) 13 | local function _5_() 14 | return assert.are.equals("SGVsbG8sIFdvcmxkIQ==", b64.encode("Hello, World!")) 15 | end 16 | it("simple text to base64", _5_) 17 | local function _6_() 18 | return assert.are.equals("Hello, World!", b64.decode("SGVsbG8sIFdvcmxkIQ==")) 19 | end 20 | return it("base64 back to text", _6_) 21 | end 22 | return describe("basic", _3_) 23 | end 24 | return describe("conjure.remote.transport.base64", _2_) 25 | -------------------------------------------------------------------------------- /lua/conjure-spec/remote/transport/elisp_spec.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure-spec/remote/transport/elisp_spec.fnl 2 | local _local_1_ = require("plenary.busted") 3 | local describe = _local_1_["describe"] 4 | local it = _local_1_["it"] 5 | local assert = require("luassert.assert") 6 | local elisp = require("conjure.remote.transport.elisp") 7 | local function _2_() 8 | local function _3_() 9 | local function _4_() 10 | assert.are.equals(nil, elisp.read("")) 11 | assert.are.equals("foo", elisp.read("\"foo\"")) 12 | assert.are.equals("foo", elisp.read(" \"foo\" ")) 13 | assert.are.equals("foo", elisp.read(":foo")) 14 | assert.are.equals("foo", elisp.read(" :foo ")) 15 | return assert.are.equals("bar", elisp.read(" :foo \"hi\" \n :bar ")) 16 | end 17 | it("strings and symbols", _4_) 18 | local function _5_() 19 | assert.are.equals(0, elisp.read("0")) 20 | assert.are.equals(1, elisp.read(" 1 ")) 21 | assert.are.equals(0.5, elisp.read(" 0.5")) 22 | assert.are.equals(30, elisp.read(" 30 ")) 23 | assert.are.equals(30.2, elisp.read(" 30.2 ")) 24 | assert.are.equals(0.2, elisp.read(".2 ")) 25 | assert.are.equals(-0.3, elisp.read(" -.3 ")) 26 | return assert.are.equals(-20.25, elisp.read(" -20.25 ")) 27 | end 28 | it("numbers", _5_) 29 | local function _6_() 30 | assert.same({}, elisp.read("()")) 31 | assert.same({{}, {}}, elisp.read("(()())")) 32 | assert.same({1, {2, 3, 4}, 5, {6, "seven"}, "eight", 9}, elisp.read("(1 (2 3 4) 5 (6 \"seven\") :eight 9)")) 33 | return assert.same({1, 2, 3}, elisp.read("(1 2 3)")) 34 | end 35 | it("lists", _6_) 36 | local function _7_() 37 | return assert.same({"Class", ": ", {"value", "clojure.lang.PersistentArrayMap", 0}, {"newline"}, "Contents: ", {"newline"}, " ", {"value", "a", 1}, " = ", {"value", "1", 2}, {"newline"}, " ", {"value", "b", 3}, " = ", {"value", "2", 4}, {"newline"}}, elisp.read("(\"Class\" \": \" (:value \"clojure.lang.PersistentArrayMap\" 0) (:newline) \"Contents: \" (:newline) \" \" (:value \"a\" 1) \" = \" (:value \"1\" 2) (:newline) \" \" (:value \"b\" 3) \" = \" (:value \"2\" 4) (:newline))")) 38 | end 39 | return it("nested forms", _7_) 40 | end 41 | return describe("reads", _3_) 42 | end 43 | return describe("remote.transport.elisp", _2_) 44 | -------------------------------------------------------------------------------- /lua/conjure-spec/school_spec.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure-spec/school_spec.fnl 2 | local _local_1_ = require("plenary.busted") 3 | local describe = _local_1_["describe"] 4 | local it = _local_1_["it"] 5 | local assert = require("luassert.assert") 6 | local school = require("conjure.school") 7 | local nvim = require("conjure.aniseed.nvim") 8 | local function _2_() 9 | school.start() 10 | local function _3_() 11 | return assert.are.equals("conjure-school.fnl", nvim.fn.bufname()) 12 | end 13 | it("buffer has correct name", _3_) 14 | local function _4_() 15 | return assert.same({"(local school (require :conjure.school))"}, nvim.buf_get_lines(0, 0, 1, false)) 16 | end 17 | it("buffer requires conjure.school module", _4_) 18 | return nvim.ex.bdelete("conjure-school.fnl") 19 | end 20 | return describe("running :ConjureSchool", _2_) 21 | -------------------------------------------------------------------------------- /lua/conjure-spec/stack_spec.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure-spec/stack_spec.fnl 2 | local _local_1_ = require("plenary.busted") 3 | local describe = _local_1_["describe"] 4 | local it = _local_1_["it"] 5 | local assert = require("luassert.assert") 6 | local stack = require("conjure.stack") 7 | local function _2_() 8 | local function _3_() 9 | local function _4_() 10 | return assert.same({1, 2, 3}, stack.push(stack.push(stack.push({}, 1), 2), 3)) 11 | end 12 | return it("item on a stack", _4_) 13 | end 14 | describe("push", _3_) 15 | local function _5_() 16 | local function _6_() 17 | return assert.same({1, 2}, stack.pop({1, 2, 3})) 18 | end 19 | it("top of stack", _6_) 20 | local function _7_() 21 | return assert.same({}, stack.pop({})) 22 | end 23 | return it("empty stack", _7_) 24 | end 25 | describe("pop", _5_) 26 | local function _8_() 27 | local function _9_() 28 | return assert.are.equals(3, stack.peek({1, 2, 3})) 29 | end 30 | it("top of stack", _9_) 31 | local function _10_() 32 | return assert.are.equals(nil, stack.peek({})) 33 | end 34 | return it("empty stack", _10_) 35 | end 36 | return describe("peek", _8_) 37 | end 38 | return describe("conjure.stack", _2_) 39 | -------------------------------------------------------------------------------- /lua/conjure-spec/util.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure-spec/util.fnl 2 | local nvim = require("conjure.aniseed.nvim") 3 | local function with_buf(lines, f) 4 | local at 5 | local function _1_(cursor) 6 | return nvim.win_set_cursor(0, cursor) 7 | end 8 | at = _1_ 9 | nvim.ex.silent_("syntax", "on") 10 | nvim.ex.silent_("filetype", "on") 11 | nvim.ex.silent_("set", "filetype", "clojure") 12 | nvim.ex.silent_("edit", (nvim.fn.tempname() .. "_test.clj")) 13 | nvim.buf_set_lines(0, 0, -1, false, lines) 14 | f(at) 15 | return nvim.ex.silent_("bdelete!") 16 | end 17 | return {["with-buf"] = with_buf} 18 | -------------------------------------------------------------------------------- /lua/conjure-spec/util_spec.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure-spec/util_spec.fnl 2 | local _local_1_ = require("plenary.busted") 3 | local describe = _local_1_["describe"] 4 | local it = _local_1_["it"] 5 | local assert = require("luassert.assert") 6 | local util = require("conjure.util") 7 | local function _2_() 8 | local function _3_() 9 | local function _4_() 10 | return "hello-world!" 11 | end 12 | package.loaded["example-module"] = {["wrapped-fn-example"] = _4_} 13 | return assert.equals("hello-world!", util["wrap-require-fn-call"]("example-module", "wrapped-fn-example")()) 14 | end 15 | return it("creates a fn that requries a file and calls a fn", _3_) 16 | end 17 | describe("wrap-require-fn-call", _2_) 18 | local function _5_() 19 | local function _6_() 20 | return assert.equals("hello\15world", util["replace-termcodes"]("helloworld")) 21 | end 22 | return it("escapes sequences like ", _6_) 23 | end 24 | return describe("replace-termcodes", _5_) 25 | -------------------------------------------------------------------------------- /lua/conjure-spec/uuid_spec.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure-spec/uuid_spec.fnl 2 | local _local_1_ = require("plenary.busted") 3 | local describe = _local_1_["describe"] 4 | local it = _local_1_["it"] 5 | local assert = require("luassert.assert") 6 | local a = require("conjure.nfnl.core") 7 | local uuid = require("conjure.uuid") 8 | local function _2_() 9 | local function is_in(word, xs) 10 | local function _3_(x) 11 | return (word == x) 12 | end 13 | return a.some(_3_, xs) 14 | end 15 | local function _4_() 16 | local function _5_() 17 | return assert.are.equals("Wirehaired Pointing Griffon", uuid.pretty("c7ef277c-160c-45f4-a5c3-03ac16a93788")) 18 | end 19 | it("into something human-readable", _5_) 20 | local function _6_() 21 | return assert.are["not"].equals("Wirehaired Pointing Griffon", uuid.pretty("d7ef277c-160c-45f4-a5c3-03ac16a93788")) 22 | end 23 | return it("into something human-readable but wrong string", _6_) 24 | end 25 | describe("turns a UUID", _4_) 26 | local function _7_() 27 | local function _8_() 28 | return assert.are.equals(true, is_in(uuid.pretty(uuid.v4()), uuid["cats-and-dogs"])) 29 | end 30 | it("is turned into something human-readable", _8_) 31 | local function _9_() 32 | return assert.are["not"].equals(nil, string.match(uuid.v4(), "^%x+-%x+-%x+-%x+-%x+$")) 33 | end 34 | return it("has the correct format", _9_) 35 | end 36 | return describe("generated UUID", _7_) 37 | end 38 | return describe("uuid", _2_) 39 | -------------------------------------------------------------------------------- /lua/conjure/aniseed/autoload.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/aniseed/autoload.fnl" 2 | local _2amodule_name_2a = "conjure.aniseed.autoload" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local function autoload(name) 14 | local res = {["aniseed/autoload-enabled?"] = true, ["aniseed/autoload-module"] = false} 15 | local function ensure() 16 | if res["aniseed/autoload-module"] then 17 | return res["aniseed/autoload-module"] 18 | else 19 | local m = require(name) 20 | do end (res)["aniseed/autoload-module"] = m 21 | return m 22 | end 23 | end 24 | local function _2_(t, ...) 25 | return ensure()(...) 26 | end 27 | local function _3_(t, k) 28 | return ensure()[k] 29 | end 30 | local function _4_(t, k, v) 31 | ensure()[k] = v 32 | return nil 33 | end 34 | return setmetatable(res, {__call = _2_, __index = _3_, __newindex = _4_}) 35 | end 36 | _2amodule_2a["autoload"] = autoload 37 | return _2amodule_2a 38 | -------------------------------------------------------------------------------- /lua/conjure/aniseed/env.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/aniseed/env.fnl" 2 | local _2amodule_name_2a = "conjure.aniseed.env" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local autoload = (require("conjure.aniseed.autoload")).autoload 14 | local compile, fennel, fs, nvim = autoload("conjure.aniseed.compile"), autoload("conjure.aniseed.fennel"), autoload("conjure.aniseed.fs"), autoload("conjure.aniseed.nvim") 15 | do end (_2amodule_locals_2a)["compile"] = compile 16 | _2amodule_locals_2a["fennel"] = fennel 17 | _2amodule_locals_2a["fs"] = fs 18 | _2amodule_locals_2a["nvim"] = nvim 19 | local config_dir = nvim.fn.stdpath("config") 20 | do end (_2amodule_locals_2a)["config-dir"] = config_dir 21 | local function quiet_require(m) 22 | local ok_3f, err = nil, nil 23 | local function _1_() 24 | return require(m) 25 | end 26 | ok_3f, err = pcall(_1_) 27 | if (not ok_3f and not err:find(("module '" .. m .. "' not found"))) then 28 | return nvim.ex.echoerr(err) 29 | else 30 | return nil 31 | end 32 | end 33 | _2amodule_locals_2a["quiet-require"] = quiet_require 34 | local function init(opts) 35 | local opts0 36 | if ("table" == type(opts)) then 37 | opts0 = opts 38 | else 39 | opts0 = {} 40 | end 41 | local glob_expr = "**/*.fnl" 42 | local fnl_dir = nvim.fn.expand((opts0.input or (config_dir .. fs["path-sep"] .. "fnl"))) 43 | local lua_dir = nvim.fn.expand((opts0.output or (config_dir .. fs["path-sep"] .. "lua"))) 44 | if opts0.output then 45 | package.path = (package.path .. ";" .. lua_dir .. fs["path-sep"] .. "?.lua") 46 | else 47 | end 48 | local function _5_(path) 49 | if fs["macro-file-path?"](path) then 50 | return path 51 | else 52 | return string.gsub(path, ".fnl$", ".lua") 53 | end 54 | end 55 | if (((false ~= opts0.compile) or os.getenv("ANISEED_ENV_COMPILE")) and fs["glob-dir-newer?"](fnl_dir, lua_dir, glob_expr, _5_)) then 56 | fennel["add-path"]((fnl_dir .. fs["path-sep"] .. "?.fnl")) 57 | compile.glob(glob_expr, fnl_dir, lua_dir, opts0) 58 | else 59 | end 60 | return quiet_require((opts0.module or "init")) 61 | end 62 | _2amodule_2a["init"] = init 63 | return _2amodule_2a 64 | -------------------------------------------------------------------------------- /lua/conjure/aniseed/eval.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/aniseed/eval.fnl" 2 | local _2amodule_name_2a = "conjure.aniseed.eval" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local autoload = (require("conjure.aniseed.autoload")).autoload 14 | local a, compile, fennel, fs, nvim = autoload("conjure.aniseed.core"), autoload("conjure.aniseed.compile"), autoload("conjure.aniseed.fennel"), autoload("conjure.aniseed.fs"), autoload("conjure.aniseed.nvim") 15 | do end (_2amodule_locals_2a)["a"] = a 16 | _2amodule_locals_2a["compile"] = compile 17 | _2amodule_locals_2a["fennel"] = fennel 18 | _2amodule_locals_2a["fs"] = fs 19 | _2amodule_locals_2a["nvim"] = nvim 20 | local function str(code, opts) 21 | local fnl = fennel.impl() 22 | local function _1_() 23 | return fnl.eval(compile["wrap-macros"](code, opts), a.merge({compilerEnv = _G}, opts)) 24 | end 25 | return xpcall(_1_, fnl.traceback) 26 | end 27 | _2amodule_2a["str"] = str 28 | local function clean_values(vals) 29 | local function _2_(val) 30 | if a["table?"](val) then 31 | return (compile["delete-marker"] ~= a.first(val)) 32 | else 33 | return true 34 | end 35 | end 36 | return a.filter(_2_, vals) 37 | end 38 | _2amodule_locals_2a["clean-values"] = clean_values 39 | local function clean_error(err) 40 | return string.gsub(string.gsub(err, "^%b[string .-%b]:%d+: ", ""), "^Compile error in .-:%d+\n%s+", "") 41 | end 42 | _2amodule_2a["clean-error"] = clean_error 43 | local function repl(opts) 44 | local eval_values = nil 45 | local fnl = fennel.impl() 46 | local opts0 = (opts or {}) 47 | local co 48 | local function _4_() 49 | local function _5_(_241) 50 | eval_values = clean_values(_241) 51 | return nil 52 | end 53 | local function _6_(_241, _242) 54 | return (opts0["error-handler"] or nvim.err_writeln)(clean_error(_242)) 55 | end 56 | return fnl.repl(a.merge({compilerEnv = _G, pp = a.identity, readChunk = coroutine.yield, onValues = _5_, onError = _6_}, opts0)) 57 | end 58 | co = coroutine.create(_4_) 59 | coroutine.resume(co) 60 | coroutine.resume(co, compile["wrap-macros"](nil, opts0)) 61 | eval_values = nil 62 | local function _7_(code) 63 | ANISEED_STATIC_MODULES = false 64 | coroutine.resume(co, code) 65 | local prev_eval_values = eval_values 66 | eval_values = nil 67 | return prev_eval_values 68 | end 69 | return _7_ 70 | end 71 | _2amodule_2a["repl"] = repl 72 | return _2amodule_2a 73 | -------------------------------------------------------------------------------- /lua/conjure/aniseed/fennel.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/aniseed/fennel.fnl" 2 | local _2amodule_name_2a = "conjure.aniseed.fennel" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local autoload = (require("conjure.aniseed.autoload")).autoload 14 | local a, fs, nvim, str = autoload("conjure.aniseed.core"), autoload("conjure.aniseed.fs"), autoload("conjure.aniseed.nvim"), autoload("conjure.aniseed.string") 15 | do end (_2amodule_locals_2a)["a"] = a 16 | _2amodule_locals_2a["fs"] = fs 17 | _2amodule_locals_2a["nvim"] = nvim 18 | _2amodule_locals_2a["str"] = str 19 | local function sync_rtp(compiler) 20 | local fnl_suffix = (fs["path-sep"] .. "fnl" .. fs["path-sep"] .. "?.fnl") 21 | local lua_suffix = (fs["path-sep"] .. "lua" .. fs["path-sep"] .. "?.fnl") 22 | local rtps = nvim.list_runtime_paths() 23 | local fnl_paths 24 | local function _1_(_241) 25 | return (_241 .. fnl_suffix) 26 | end 27 | fnl_paths = a.map(_1_, rtps) 28 | local lua_paths 29 | local function _2_(_241) 30 | return (_241 .. lua_suffix) 31 | end 32 | lua_paths = a.map(_2_, rtps) 33 | do end (compiler)["macro-path"] = str.join(";", a.concat(fnl_paths, lua_paths)) 34 | return nil 35 | end 36 | _2amodule_2a["sync-rtp"] = sync_rtp 37 | local state = {["compiler-loaded?"] = false} 38 | _2amodule_locals_2a["state"] = state 39 | local function impl() 40 | local compiler = require("conjure.aniseed.deps.fennel") 41 | if not state["compiler-loaded?"] then 42 | state["compiler-loaded?"] = true 43 | sync_rtp(compiler) 44 | else 45 | end 46 | return compiler 47 | end 48 | _2amodule_2a["impl"] = impl 49 | local function add_path(path) 50 | local fnl = impl() 51 | do end (fnl)["macro-path"] = (fnl["macro-path"] .. ";" .. path) 52 | return nil 53 | end 54 | _2amodule_2a["add-path"] = add_path 55 | return _2amodule_2a 56 | -------------------------------------------------------------------------------- /lua/conjure/aniseed/fs.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/aniseed/fs.fnl" 2 | local _2amodule_name_2a = "conjure.aniseed.fs" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local autoload = (require("conjure.aniseed.autoload")).autoload 14 | local a, nvim = autoload("conjure.aniseed.core"), autoload("conjure.aniseed.nvim") 15 | do end (_2amodule_locals_2a)["a"] = a 16 | _2amodule_locals_2a["nvim"] = nvim 17 | local function basename(path) 18 | return nvim.fn.fnamemodify(path, ":h") 19 | end 20 | _2amodule_2a["basename"] = basename 21 | local function mkdirp(dir) 22 | return nvim.fn.mkdir(dir, "p") 23 | end 24 | _2amodule_2a["mkdirp"] = mkdirp 25 | local function relglob(dir, expr) 26 | local dir_len = a.inc(string.len(dir)) 27 | local function _1_(_241) 28 | return string.sub(_241, dir_len) 29 | end 30 | return a.map(_1_, nvim.fn.globpath(dir, expr, true, true)) 31 | end 32 | _2amodule_2a["relglob"] = relglob 33 | local function glob_dir_newer_3f(a_dir, b_dir, expr, b_dir_path_fn) 34 | local newer_3f = false 35 | for _, path in ipairs(relglob(a_dir, expr)) do 36 | if (nvim.fn.getftime((a_dir .. path)) > nvim.fn.getftime((b_dir .. b_dir_path_fn(path)))) then 37 | newer_3f = true 38 | else 39 | end 40 | end 41 | return newer_3f 42 | end 43 | _2amodule_2a["glob-dir-newer?"] = glob_dir_newer_3f 44 | local path_sep 45 | do 46 | local os = string.lower(jit.os) 47 | if (("linux" == os) or ("osx" == os) or ("bsd" == os)) then 48 | path_sep = "/" 49 | else 50 | path_sep = "\\" 51 | end 52 | end 53 | _2amodule_2a["path-sep"] = path_sep 54 | local function macro_file_path_3f(path) 55 | return (a["string?"](string.match(path, "macros?.fnl$")) or a["string?"](string.match(path, (path_sep .. "macros?" .. path_sep)))) 56 | end 57 | _2amodule_2a["macro-file-path?"] = macro_file_path_3f 58 | return _2amodule_2a 59 | -------------------------------------------------------------------------------- /lua/conjure/aniseed/macros/autocmds.fnl: -------------------------------------------------------------------------------- 1 | (fn autocmd [event opt] 2 | `(vim.api.nvim_create_autocmd 3 | ,event ,opt)) 4 | 5 | (fn autocmds [...] 6 | (var form `(do)) 7 | (each [_ v (ipairs [...])] 8 | (table.insert form (autocmd (unpack v)))) 9 | (table.insert form 'nil) 10 | form) 11 | 12 | (fn augroup [name ...] 13 | (var cmds `(do)) 14 | (var group (sym :group)) 15 | (each [_ v (ipairs [...])] 16 | (let [(event opt) (unpack v)] 17 | (tset opt :group group) 18 | (table.insert cmds (autocmd event opt)))) 19 | (table.insert cmds 'nil) 20 | `(let [,group 21 | (vim.api.nvim_create_augroup ,name {:clear true})] 22 | ,cmds 23 | ,group)) 24 | 25 | {:autocmd autocmd 26 | :autocmds autocmds 27 | :augroup augroup} 28 | -------------------------------------------------------------------------------- /lua/conjure/aniseed/nvim.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/aniseed/nvim.fnl" 2 | local _2amodule_name_2a = "conjure.aniseed.nvim" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = require("conjure.aniseed.deps.nvim") 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | -------------------------------------------------------------------------------- /lua/conjure/aniseed/nvim/util.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/aniseed/nvim/util.fnl" 2 | local _2amodule_name_2a = "conjure.aniseed.nvim.util" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local autoload = (require("conjure.aniseed.autoload")).autoload 14 | local nvim = autoload("conjure.aniseed.nvim") 15 | do end (_2amodule_locals_2a)["nvim"] = nvim 16 | local function normal(keys) 17 | return nvim.ex.silent(("exe \"normal! " .. keys .. "\"")) 18 | end 19 | _2amodule_2a["normal"] = normal 20 | local function fn_bridge(viml_name, mod, lua_name, opts) 21 | local _let_1_ = (opts or {}) 22 | local range = _let_1_["range"] 23 | local _return = _let_1_["return"] 24 | local function _2_() 25 | if range then 26 | return " range" 27 | else 28 | return "" 29 | end 30 | end 31 | local function _3_() 32 | if (_return ~= false) then 33 | return "return" 34 | else 35 | return "call" 36 | end 37 | end 38 | local function _4_() 39 | if range then 40 | return "\" . a:firstline . \", \" . a:lastline . \", " 41 | else 42 | return "" 43 | end 44 | end 45 | return nvim.ex.function_((viml_name .. "(...)" .. _2_() .. "\n " .. _3_() .. " luaeval(\"require('" .. mod .. "')['" .. lua_name .. "'](" .. _4_() .. "unpack(_A))\", a:000)\n endfunction")) 46 | end 47 | _2amodule_2a["fn-bridge"] = fn_bridge 48 | local function with_out_str(f) 49 | nvim.ex.redir("=> g:aniseed_nvim_util_out_str") 50 | do 51 | local ok_3f, err = pcall(f) 52 | nvim.ex.redir("END") 53 | nvim.ex.echon("") 54 | nvim.ex.redraw() 55 | if not ok_3f then 56 | error(err) 57 | else 58 | end 59 | end 60 | return string.gsub(nvim.g.aniseed_nvim_util_out_str, "^(\n?)(.*)$", "%2%1") 61 | end 62 | _2amodule_2a["with-out-str"] = with_out_str 63 | return _2amodule_2a 64 | -------------------------------------------------------------------------------- /lua/conjure/aniseed/setup.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/aniseed/setup.fnl" 2 | local _2amodule_name_2a = "conjure.aniseed.setup" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local autoload = (require("conjure.aniseed.autoload")).autoload 14 | local a, env, eval, nvim = autoload("conjure.aniseed.core"), autoload("conjure.aniseed.env"), autoload("conjure.aniseed.eval"), autoload("conjure.aniseed.nvim") 15 | do end (_2amodule_locals_2a)["a"] = a 16 | _2amodule_locals_2a["env"] = env 17 | _2amodule_locals_2a["eval"] = eval 18 | _2amodule_locals_2a["nvim"] = nvim 19 | local function init() 20 | if (1 == nvim.fn.has("nvim-0.7")) then 21 | local function _1_(cmd) 22 | local ok_3f, res = eval.str(cmd.args, {}) 23 | if ok_3f then 24 | return nvim.echo(res) 25 | else 26 | return nvim.err_writeln(res) 27 | end 28 | end 29 | nvim.create_user_command("AniseedEval", _1_, {nargs = 1}) 30 | local function _3_(cmd) 31 | local code 32 | local function _4_() 33 | if ("" == cmd.args) then 34 | return nvim.buf_get_name(nvim.get_current_buf()) 35 | else 36 | return cmd.args 37 | end 38 | end 39 | code = a.slurp(_4_()) 40 | if code then 41 | local ok_3f, res = eval.str(code, {}) 42 | if ok_3f then 43 | return nvim.echo(res) 44 | else 45 | return nvim.err_writeln(res) 46 | end 47 | else 48 | return nvim.err_writeln(("File '" .. (cmd.args or "nil") .. "' not found")) 49 | end 50 | end 51 | nvim.create_user_command("AniseedEvalFile", _3_, {nargs = "?", complete = "file"}) 52 | else 53 | end 54 | if nvim.g["aniseed#env"] then 55 | return env.init(nvim.g["aniseed#env"]) 56 | else 57 | return nil 58 | end 59 | end 60 | _2amodule_2a["init"] = init 61 | return _2amodule_2a 62 | -------------------------------------------------------------------------------- /lua/conjure/aniseed/string.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/aniseed/string.fnl" 2 | local _2amodule_name_2a = "conjure.aniseed.string" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local autoload = (require("conjure.aniseed.autoload")).autoload 14 | local a = autoload("conjure.aniseed.core") 15 | do end (_2amodule_locals_2a)["a"] = a 16 | local function join(...) 17 | local args = {...} 18 | local function _2_(...) 19 | if (2 == a.count(args)) then 20 | return args 21 | else 22 | return {"", a.first(args)} 23 | end 24 | end 25 | local _let_1_ = _2_(...) 26 | local sep = _let_1_[1] 27 | local xs = _let_1_[2] 28 | local len = a.count(xs) 29 | local result = {} 30 | if (len > 0) then 31 | for i = 1, len do 32 | local x = xs[i] 33 | local _3_ 34 | if ("string" == type(x)) then 35 | _3_ = x 36 | elseif (nil == x) then 37 | _3_ = x 38 | else 39 | _3_ = a["pr-str"](x) 40 | end 41 | if (_3_ ~= nil) then 42 | table.insert(result, _3_) 43 | else 44 | end 45 | end 46 | else 47 | end 48 | return table.concat(result, sep) 49 | end 50 | _2amodule_2a["join"] = join 51 | local function split(s, pat) 52 | local done_3f = false 53 | local acc = {} 54 | local index = 1 55 | while not done_3f do 56 | local start, _end = string.find(s, pat, index) 57 | if ("nil" == type(start)) then 58 | table.insert(acc, string.sub(s, index)) 59 | done_3f = true 60 | else 61 | table.insert(acc, string.sub(s, index, (start - 1))) 62 | index = (_end + 1) 63 | end 64 | end 65 | return acc 66 | end 67 | _2amodule_2a["split"] = split 68 | local function blank_3f(s) 69 | return (a["empty?"](s) or not string.find(s, "[^%s]")) 70 | end 71 | _2amodule_2a["blank?"] = blank_3f 72 | local function triml(s) 73 | return string.gsub(s, "^%s*(.-)", "%1") 74 | end 75 | _2amodule_2a["triml"] = triml 76 | local function trimr(s) 77 | return string.gsub(s, "(.-)%s*$", "%1") 78 | end 79 | _2amodule_2a["trimr"] = trimr 80 | local function trim(s) 81 | return string.gsub(s, "^%s*(.-)%s*$", "%1") 82 | end 83 | _2amodule_2a["trim"] = trim 84 | return _2amodule_2a 85 | -------------------------------------------------------------------------------- /lua/conjure/aniseed/view.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/aniseed/view.fnl" 2 | local _2amodule_name_2a = "conjure.aniseed.view" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local fnl = require("conjure.aniseed.fennel") 14 | do end (_2amodule_locals_2a)["fnl"] = fnl 15 | local function serialise(...) 16 | return fnl.impl().view(...) 17 | end 18 | _2amodule_2a["serialise"] = serialise 19 | return _2amodule_2a 20 | -------------------------------------------------------------------------------- /lua/conjure/bridge.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/bridge.fnl 2 | local function viml__3elua(m, f, opts) 3 | return ("lua require('" .. m .. "')['" .. f .. "'](" .. ((opts and opts.args) or "") .. ")") 4 | end 5 | return {["viml->lua"] = viml__3elua} 6 | -------------------------------------------------------------------------------- /lua/conjure/client/clojure/nrepl/auto-repl.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/client/clojure/nrepl/auto-repl.fnl 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local a = autoload("conjure.aniseed.core") 5 | local client = autoload("conjure.client") 6 | local config = autoload("conjure.config") 7 | local log = autoload("conjure.log") 8 | local nvim = autoload("conjure.aniseed.nvim") 9 | local process = autoload("conjure.process") 10 | local state = autoload("conjure.client.clojure.nrepl.state") 11 | local cfg = config["get-in-fn"]({"client", "clojure", "nrepl"}) 12 | local function enportify(subject) 13 | if subject:find("$port") then 14 | local server = nvim.fn.serverstart("localhost:0") 15 | local _ = nvim.fn.serverstop(server) 16 | local port = server:gsub("localhost:", "") 17 | return {subject = subject:gsub("$port", port), port = port} 18 | else 19 | return {subject = subject} 20 | end 21 | end 22 | local function delete_auto_repl_port_file() 23 | local port_file = cfg({"connection", "auto_repl", "port_file"}) 24 | local port = state.get("auto-repl-port") 25 | if (port_file and port and (a.slurp(port_file) == port)) then 26 | return nvim.fn.delete(port_file) 27 | else 28 | return nil 29 | end 30 | end 31 | local function upsert_auto_repl_proc() 32 | local _let_4_ = enportify(cfg({"connection", "auto_repl", "cmd"})) 33 | local cmd = _let_4_["subject"] 34 | local port = _let_4_["port"] 35 | local port_file = cfg({"connection", "auto_repl", "port_file"}) 36 | local enabled_3f = cfg({"connection", "auto_repl", "enabled"}) 37 | local hidden_3f = cfg({"connection", "auto_repl", "hidden"}) 38 | if (enabled_3f and not process["running?"](state.get("auto-repl-proc")) and process["executable?"](cmd)) then 39 | local proc = process.execute(cmd, {["hidden?"] = hidden_3f, ["on-exit"] = client.wrap(delete_auto_repl_port_file)}) 40 | a.assoc(state.get(), "auto-repl-proc", proc) 41 | a.assoc(state.get(), "auto-repl-port", port) 42 | if (port_file and port) then 43 | a.spit(port_file, port) 44 | else 45 | end 46 | log.append({("; Starting auto-repl: " .. cmd)}) 47 | return proc 48 | else 49 | return nil 50 | end 51 | end 52 | return {["delete-auto-repl-port-file"] = delete_auto_repl_port_file, enportify = enportify, ["upsert-auto-repl-proc"] = upsert_auto_repl_proc} 53 | -------------------------------------------------------------------------------- /lua/conjure/client/clojure/nrepl/parse.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/client/clojure/nrepl/parse.fnl 2 | local function strip_meta(s) 3 | if (nil ~= s) then 4 | local tmp_3_ = string.gsub(s, "%^:.-%s+", "") 5 | if (nil ~= tmp_3_) then 6 | return string.gsub(tmp_3_, "%^%b{}%s+", "") 7 | else 8 | return nil 9 | end 10 | else 11 | return nil 12 | end 13 | end 14 | local function strip_comments(s) 15 | if (nil ~= s) then 16 | return string.gsub(s, ";.-[\n$]", "") 17 | else 18 | return nil 19 | end 20 | end 21 | local function strip_shebang(s) 22 | if (nil ~= s) then 23 | return string.gsub(s, "^#![^\n]*\n", "") 24 | else 25 | return nil 26 | end 27 | end 28 | return {["strip-comments"] = strip_comments, ["strip-meta"] = strip_meta, ["strip-shebang"] = strip_shebang} 29 | -------------------------------------------------------------------------------- /lua/conjure/client/clojure/nrepl/state.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/client/clojure/nrepl/state.fnl 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local client = autoload("conjure.client") 5 | local get 6 | local function _2_() 7 | return {conn = nil, ["auto-repl-port"] = nil, ["auto-repl-proc"] = nil, ["join-next"] = {key = nil}} 8 | end 9 | get = client["new-state"](_2_) 10 | return {get = get} 11 | -------------------------------------------------------------------------------- /lua/conjure/client/clojure/nrepl/ui.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/client/clojure/nrepl/ui.fnl 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local a = autoload("conjure.aniseed.core") 5 | local config = autoload("conjure.config") 6 | local log = autoload("conjure.log") 7 | local state = autoload("conjure.client.clojure.nrepl.state") 8 | local str = autoload("conjure.aniseed.string") 9 | local text = autoload("conjure.text") 10 | local cfg = config["get-in-fn"]({"client", "clojure", "nrepl"}) 11 | local function handle_join_line(resp) 12 | local next_key 13 | if resp.out then 14 | next_key = "out" 15 | elseif resp.err then 16 | next_key = "err" 17 | else 18 | next_key = nil 19 | end 20 | local key = state.get("join-next", "key") 21 | if (next_key or resp.value) then 22 | local function _3_() 23 | if (next_key and not text["trailing-newline?"](a.get(resp, next_key))) then 24 | return {key = next_key} 25 | else 26 | return nil 27 | end 28 | end 29 | a.assoc(state.get(), "join-next", _3_()) 30 | else 31 | end 32 | return (next_key and (key == next_key)) 33 | end 34 | local function display_result(resp, opts) 35 | local opts0 = (opts or {}) 36 | local joined_3f = handle_join_line(resp) 37 | local _5_ 38 | if resp.out then 39 | local _6_ 40 | if (opts0["raw-out?"] or cfg({"eval", "raw_out"})) then 41 | _6_ = "" 42 | elseif opts0["simple-out?"] then 43 | _6_ = "; " 44 | else 45 | _6_ = "; (out) " 46 | end 47 | _5_ = text["prefixed-lines"](text["trim-last-newline"](resp.out), _6_, {["skip-first?"] = joined_3f}) 48 | elseif resp.err then 49 | _5_ = text["prefixed-lines"](text["trim-last-newline"](resp.err), "; (err) ", {["skip-first?"] = joined_3f}) 50 | elseif resp.value then 51 | if not (opts0["ignore-nil?"] and ("nil" == resp.value)) then 52 | _5_ = text["split-lines"](resp.value) 53 | else 54 | _5_ = nil 55 | end 56 | else 57 | _5_ = nil 58 | end 59 | return log.append(_5_, {["join-first?"] = joined_3f, ["low-priority?"] = not not (resp.out or resp.err)}) 60 | end 61 | local function display_sessions(sessions, cb) 62 | local current = state.get("conn", "session") 63 | local function _11_(_10_) 64 | local idx = _10_[1] 65 | local session = _10_[2] 66 | local _12_ 67 | if (current == session.id) then 68 | _12_ = ">" 69 | else 70 | _12_ = " " 71 | end 72 | return str.join({"; ", _12_, idx, " - ", session.str()}) 73 | end 74 | log.append(a.concat({("; Sessions (" .. a.count(sessions) .. "):")}, a["map-indexed"](_11_, sessions)), {["break?"] = true}) 75 | if cb then 76 | return cb() 77 | else 78 | return nil 79 | end 80 | end 81 | return {["display-result"] = display_result, ["display-sessions"] = display_sessions} 82 | -------------------------------------------------------------------------------- /lua/conjure/dynamic.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/dynamic.fnl 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local a = autoload("conjure.aniseed.core") 5 | local get_stack_key = "conjure.dynamic/get-stack" 6 | local function assert_value_function_21(value) 7 | if ("function" ~= type(value)) then 8 | return error("conjure.dynamic values must always be wrapped in a function") 9 | else 10 | return nil 11 | end 12 | end 13 | local function new(base_value) 14 | assert_value_function_21(base_value) 15 | local stack = {base_value} 16 | local function _3_(x, ...) 17 | if (get_stack_key == x) then 18 | return stack 19 | else 20 | return a.last(stack)(x, ...) 21 | end 22 | end 23 | return _3_ 24 | end 25 | local function run_binds_21(f, binds) 26 | local function _6_(_5_) 27 | local dyn = _5_[1] 28 | local new_value = _5_[2] 29 | assert_value_function_21(new_value) 30 | return f(dyn(get_stack_key), new_value) 31 | end 32 | return a["map-indexed"](_6_, binds) 33 | end 34 | local function bind(binds, f, ...) 35 | run_binds_21(table.insert, binds) 36 | local ok_3f, result = pcall(f, ...) 37 | local function _7_(_241) 38 | return table.remove(_241) 39 | end 40 | run_binds_21(_7_, binds) 41 | if ok_3f then 42 | return result 43 | else 44 | return error(result) 45 | end 46 | end 47 | local function set_21(dyn, new_value) 48 | assert_value_function_21(new_value) 49 | do 50 | local stack = dyn(get_stack_key) 51 | local depth = a.count(stack) 52 | a.assoc(stack, depth, new_value) 53 | end 54 | return nil 55 | end 56 | local function set_root_21(dyn, new_value) 57 | assert_value_function_21(new_value) 58 | a.assoc(dyn(get_stack_key), 1, new_value) 59 | return nil 60 | end 61 | return {new = new, bind = bind, ["set!"] = set_21, ["set-root!"] = set_root_21} 62 | -------------------------------------------------------------------------------- /lua/conjure/editor.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/editor.fnl 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local a = autoload("conjure.aniseed.core") 5 | local fs = autoload("conjure.fs") 6 | local nvim = autoload("conjure.aniseed.nvim") 7 | local util = autoload("conjure.util") 8 | local function percent_fn(total_fn) 9 | local function _2_(pc) 10 | return math.floor(((total_fn() / 100) * (pc * 100))) 11 | end 12 | return _2_ 13 | end 14 | local function width() 15 | return vim.o.columns 16 | end 17 | local function height() 18 | return vim.o.lines 19 | end 20 | local percent_width = percent_fn(width) 21 | local percent_height = percent_fn(height) 22 | local function cursor_left() 23 | return vim.fn.screencol() 24 | end 25 | local function cursor_top() 26 | return vim.fn.screenrow() 27 | end 28 | local function go_to(path_or_win, line, column) 29 | if a["string?"](path_or_win) then 30 | nvim.ex.edit(fs["localise-path"](path_or_win)) 31 | else 32 | end 33 | local _4_ 34 | if ("number" == type(path_or_win)) then 35 | _4_ = path_or_win 36 | else 37 | _4_ = 0 38 | end 39 | return nvim.win_set_cursor(_4_, {line, a.dec(column)}) 40 | end 41 | local function go_to_mark(m) 42 | return nvim.ex.normal_(("`" .. m)) 43 | end 44 | local function go_back() 45 | return nvim.ex.normal_(util["replace-termcodes"]("")) 46 | end 47 | local function has_filetype_3f(ft) 48 | local function _6_(_241) 49 | return (ft == _241) 50 | end 51 | return a.some(_6_, nvim.fn.getcompletion(ft, "filetype")) 52 | end 53 | return {width = width, height = height, ["percent-width"] = percent_width, ["percent-height"] = percent_height, ["cursor-left"] = cursor_left, ["cursor-top"] = cursor_top, ["go-to"] = go_to, ["go-to-mark"] = go_to_mark, ["go-back"] = go_back, ["has-filetype?"] = has_filetype_3f} 54 | -------------------------------------------------------------------------------- /lua/conjure/event.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/event.fnl 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local nvim = autoload("conjure.aniseed.nvim") 5 | local a = autoload("conjure.aniseed.core") 6 | local text = autoload("conjure.text") 7 | local client = autoload("conjure.client") 8 | local str = autoload("conjure.aniseed.string") 9 | local function emit(...) 10 | do 11 | local names = a.map(text["upper-first"], {...}) 12 | local function _2_() 13 | while not a["empty?"](names) do 14 | nvim.ex.doautocmd("User", ("Conjure" .. str.join(names))) 15 | table.remove(names) 16 | end 17 | return nil 18 | end 19 | client.schedule(_2_) 20 | end 21 | return nil 22 | end 23 | return {emit = emit} 24 | -------------------------------------------------------------------------------- /lua/conjure/hook.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/hook.fnl 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local a = autoload("conjure.aniseed.core") 5 | local str = autoload("conjure.aniseed.string") 6 | local hook_fns = {} 7 | local hook_override_fns = {} 8 | local function define(name, f) 9 | return a.assoc(hook_fns, name, f) 10 | end 11 | local function override(name, f) 12 | return a.assoc(hook_override_fns, name, f) 13 | end 14 | local function get(name) 15 | return a.get(hook_fns, name) 16 | end 17 | local function exec(name, ...) 18 | local f = (a.get(hook_override_fns, name) or a.get(hook_fns, name)) 19 | if f then 20 | return f(...) 21 | else 22 | return error(str.join(" ", {"conjure.hook: Hook not found, can not exec", name})) 23 | end 24 | end 25 | return {["hook-fns"] = hook_fns, ["hook-override-fns"] = hook_override_fns, define = define, override = override, get = get, exec = exec} 26 | -------------------------------------------------------------------------------- /lua/conjure/inline.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/inline.fnl 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local a = autoload("conjure.aniseed.core") 5 | local config = autoload("conjure.config") 6 | local ns_id = vim.api.nvim_create_namespace("conjure.inline") 7 | local function sanitise_text(s) 8 | if a["string?"](s) then 9 | return s:gsub("%s+", " ") 10 | else 11 | return "" 12 | end 13 | end 14 | local function clear(opts) 15 | local function _3_() 16 | return vim.api.nvim_buf_clear_namespace(a.get(opts, "buf", 0), ns_id, 0, -1) 17 | end 18 | return pcall(_3_) 19 | end 20 | local function display(opts) 21 | local hl_group = config["get-in"]({"eval", "inline", "highlight"}) 22 | local function _4_() 23 | clear() 24 | return vim.api.nvim_buf_set_virtual_text(a.get(opts, "buf", 0), ns_id, opts.line, {{sanitise_text(opts.text), hl_group}}, {}) 25 | end 26 | return pcall(_4_) 27 | end 28 | return {["sanitise-text"] = sanitise_text, clear = clear, display = display} 29 | -------------------------------------------------------------------------------- /lua/conjure/linked-list.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/linked-list.fnl 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local a = autoload("conjure.aniseed.core") 5 | local function create(xs, prev) 6 | if not a["empty?"](xs) then 7 | local rest = a.rest(xs) 8 | local node = {} 9 | a.assoc(node, "val", a.first(xs)) 10 | a.assoc(node, "prev", prev) 11 | return a.assoc(node, "next", create(rest, node)) 12 | else 13 | return nil 14 | end 15 | end 16 | local function val(l) 17 | if (nil ~= l) then 18 | return a.get(l, "val") 19 | else 20 | return nil 21 | end 22 | end 23 | local function next(l) 24 | if (nil ~= l) then 25 | return a.get(l, "next") 26 | else 27 | return nil 28 | end 29 | end 30 | local function prev(l) 31 | if (nil ~= l) then 32 | return a.get(l, "prev") 33 | else 34 | return nil 35 | end 36 | end 37 | local function first(l) 38 | local c = l 39 | while prev(c) do 40 | c = prev(c) 41 | end 42 | return c 43 | end 44 | local function last(l) 45 | local c = l 46 | while next(c) do 47 | c = next(c) 48 | end 49 | return c 50 | end 51 | local function _until(f, l) 52 | local c = l 53 | local r = false 54 | local function step() 55 | r = f(c) 56 | return r 57 | end 58 | while (c and not step()) do 59 | c = next(c) 60 | end 61 | if r then 62 | return c 63 | else 64 | return nil 65 | end 66 | end 67 | local function cycle(l) 68 | local start = first(l) 69 | local _end = last(l) 70 | a.assoc(start, "prev", _end) 71 | a.assoc(_end, "next", start) 72 | return l 73 | end 74 | return {create = create, val = val, next = next, prev = prev, first = first, last = last, ["until"] = _until, cycle = cycle} 75 | -------------------------------------------------------------------------------- /lua/conjure/main.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/main.fnl 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local mapping = autoload("conjure.mapping") 5 | local config = autoload("conjure.config") 6 | local function main() 7 | return mapping.init(config.filetypes()) 8 | end 9 | return {main = main} 10 | -------------------------------------------------------------------------------- /lua/conjure/net.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/net.fnl 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local define = _local_1_["define"] 5 | local a = autoload("conjure.aniseed.core") 6 | local M = define("conjure.net", {}) 7 | M.resolve = function(host) 8 | if (host == "::") then 9 | return host 10 | else 11 | local function _2_(_241) 12 | return ("inet" == a.get(_241, "family")) 13 | end 14 | return a.get(a.first(a.filter(_2_, vim.loop.getaddrinfo(host))), "addr") 15 | end 16 | end 17 | local state = {["sock-drawer"] = {}} 18 | local function destroy_sock(sock) 19 | if not sock:is_closing() then 20 | sock:read_stop() 21 | sock:shutdown() 22 | sock:close() 23 | else 24 | end 25 | local function _5_(_241) 26 | return (sock ~= _241) 27 | end 28 | state["sock-drawer"] = a.filter(_5_, state["sock-drawer"]) 29 | return nil 30 | end 31 | M.connect = function(_6_) 32 | local host = _6_["host"] 33 | local port = _6_["port"] 34 | local cb = _6_["cb"] 35 | local sock = vim.loop.new_tcp() 36 | local resolved_host = M.resolve(host) 37 | if not resolved_host then 38 | error("Failed to resolve host for Conjure connection") 39 | else 40 | end 41 | sock:connect(resolved_host, port, cb) 42 | table.insert(state["sock-drawer"], sock) 43 | local function _8_() 44 | return destroy_sock(sock) 45 | end 46 | return {sock = sock, ["resolved-host"] = resolved_host, destroy = _8_, host = host, port = port} 47 | end 48 | local function destroy_all_socks() 49 | return a["run!"](destroy_sock, state["sock-drawer"]) 50 | end 51 | local group = vim.api.nvim_create_augroup("conjure-net-sock-cleanup", {}) 52 | vim.api.nvim_create_autocmd("VimLeavePre", {group = group, pattern = "*", callback = destroy_all_socks}) 53 | return M 54 | -------------------------------------------------------------------------------- /lua/conjure/nfnl/api.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] Compiled from fnl/nfnl/api.fnl by https://github.com/Olical/nfnl, do not edit. 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local core = autoload("conjure.nfnl.core") 5 | local compile = autoload("conjure.nfnl.compile") 6 | local config = autoload("conjure.nfnl.config") 7 | local notify = autoload("conjure.nfnl.notify") 8 | local fs = autoload("conjure.nfnl.fs") 9 | local mod = {} 10 | mod["compile-file"] = function(_2_) 11 | local path = _2_["path"] 12 | local dir = _2_["dir"] 13 | local dir0 = (dir or vim.fn.getcwd()) 14 | local _let_3_ = config["find-and-load"](dir0) 15 | local config0 = _let_3_["config"] 16 | local root_dir = _let_3_["root-dir"] 17 | local cfg = _let_3_["cfg"] 18 | if config0 then 19 | local path0 = fs["join-path"]({root_dir, vim.fn.expand((path or "%"))}) 20 | local result = compile["into-file"]({["root-dir"] = root_dir, cfg = cfg, path = path0, source = core.slurp(path0), ["batch?"] = true}) 21 | notify.info("Compilation complete.\n", result) 22 | return result 23 | else 24 | notify.warn("No .nfnl.fnl configuration found.") 25 | return {} 26 | end 27 | end 28 | mod["compile-all-files"] = function(dir) 29 | local dir0 = (dir or vim.fn.getcwd()) 30 | local _let_5_ = config["find-and-load"](dir0) 31 | local config0 = _let_5_["config"] 32 | local root_dir = _let_5_["root-dir"] 33 | local cfg = _let_5_["cfg"] 34 | if config0 then 35 | local results = compile["all-files"]({["root-dir"] = root_dir, cfg = cfg}) 36 | notify.info("Compilation complete.\n", results) 37 | return results 38 | else 39 | notify.warn("No .nfnl.fnl configuration found.") 40 | return {} 41 | end 42 | end 43 | mod.dofile = function(file) 44 | return dofile(fs["fnl-path->lua-path"](vim.fn.expand((file or "%")))) 45 | end 46 | return mod 47 | -------------------------------------------------------------------------------- /lua/conjure/nfnl/init.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] Compiled from fnl/nfnl/init.fnl by https://github.com/Olical/nfnl, do not edit. 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local callback = autoload("conjure.nfnl.callback") 5 | local minimum_neovim_version = "0.9.0" 6 | if vim then 7 | if (0 == vim.fn.has(("nvim-" .. minimum_neovim_version))) then 8 | error(("nfnl requires Neovim > v" .. minimum_neovim_version)) 9 | else 10 | end 11 | vim.api.nvim_create_autocmd({"Filetype"}, {group = vim.api.nvim_create_augroup("nfnl-setup", {}), pattern = "fennel", callback = callback["fennel-filetype-callback"]}) 12 | if ("fennel" == vim.o.filetype) then 13 | callback["fennel-filetype-callback"]({file = vim.fn.expand("%"), buf = vim.api.nvim_get_current_buf()}) 14 | else 15 | end 16 | else 17 | end 18 | local function setup(opts) 19 | if opts then 20 | vim.g["nfnl#compile_on_write"] = opts.compile_on_write 21 | return nil 22 | else 23 | return nil 24 | end 25 | end 26 | return {setup = setup} 27 | -------------------------------------------------------------------------------- /lua/conjure/nfnl/module.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] Compiled from fnl/nfnl/module.fnl by https://github.com/Olical/nfnl, do not edit. 2 | local module_key = "nfnl/autoload-module" 3 | local enabled_key = "nfnl/autoload-enabled?" 4 | local M = {} 5 | M.autoload = function(name) 6 | local res = {[enabled_key] = true, [module_key] = false} 7 | local ensure 8 | local function _1_() 9 | if res[module_key] then 10 | return res[module_key] 11 | else 12 | local m = require(name) 13 | res[module_key] = m 14 | return m 15 | end 16 | end 17 | ensure = _1_ 18 | local function _3_(t, ...) 19 | return ensure()(...) 20 | end 21 | local function _4_(t, k) 22 | return ensure()[k] 23 | end 24 | local function _5_(t, k, v) 25 | ensure()[k] = v 26 | return nil 27 | end 28 | return setmetatable(res, {__call = _3_, __index = _4_, __newindex = _5_}) 29 | end 30 | M.define = function(mod_name, base) 31 | local loaded = package.loaded[mod_name] 32 | if (type(loaded) == type(base)) then 33 | return loaded 34 | else 35 | return (base or {}) 36 | end 37 | end 38 | return M 39 | -------------------------------------------------------------------------------- /lua/conjure/nfnl/notify.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] Compiled from fnl/nfnl/notify.fnl by https://github.com/Olical/nfnl, do not edit. 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local core = autoload("conjure.nfnl.core") 5 | local function notify(level, ...) 6 | return vim.api.nvim_notify(core.str(...), level, {}) 7 | end 8 | local function debug(...) 9 | return notify(vim.log.levels.DEBUG, ...) 10 | end 11 | local function error(...) 12 | return notify(vim.log.levels.ERROR, ...) 13 | end 14 | local function info(...) 15 | return notify(vim.log.levels.INFO, ...) 16 | end 17 | local function trace(...) 18 | return notify(vim.log.levels.TRACE, ...) 19 | end 20 | local function warn(...) 21 | return notify(vim.log.levels.WARN, ...) 22 | end 23 | return {debug = debug, error = error, info = info, trace = trace, warn = warn} 24 | -------------------------------------------------------------------------------- /lua/conjure/nfnl/nvim.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] Compiled from fnl/nfnl/nvim.fnl by https://github.com/Olical/nfnl, do not edit. 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local str = autoload("conjure.nfnl.string") 5 | local function get_buf_content_as_string(buf) 6 | return (str.join("\n", vim.api.nvim_buf_get_lines((buf or 0), 0, -1, false)) or "") 7 | end 8 | return {["get-buf-content-as-string"] = get_buf_content_as_string} 9 | -------------------------------------------------------------------------------- /lua/conjure/nfnl/repl.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] Compiled from fnl/nfnl/repl.fnl by https://github.com/Olical/nfnl, do not edit. 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local core = autoload("conjure.nfnl.core") 5 | local fennel = autoload("conjure.nfnl.fennel") 6 | local notify = autoload("conjure.nfnl.notify") 7 | local str = autoload("conjure.nfnl.string") 8 | local function new(opts) 9 | local results_to_return = nil 10 | local cfg 11 | do 12 | local t_2_ = opts 13 | if (nil ~= t_2_) then 14 | t_2_ = t_2_.cfg 15 | else 16 | end 17 | cfg = t_2_ 18 | end 19 | local co 20 | local function _4_() 21 | local function _5_(results) 22 | results_to_return = core.concat(results_to_return, results) 23 | return nil 24 | end 25 | local function _6_(err_type, err, lua_source) 26 | local _8_ 27 | do 28 | local t_7_ = opts 29 | if (nil ~= t_7_) then 30 | t_7_ = t_7_["on-error"] 31 | else 32 | end 33 | _8_ = t_7_ 34 | end 35 | if _8_ then 36 | return opts["on-error"](err_type, err, lua_source) 37 | else 38 | return notify.error(str.trim(str.join("\n\n", {("[" .. err_type .. "] " .. err), lua_source}))) 39 | end 40 | end 41 | local function _11_() 42 | if cfg then 43 | return cfg({"compiler-options"}) 44 | else 45 | return nil 46 | end 47 | end 48 | return fennel.repl(core["merge!"]({pp = core.identity, readChunk = coroutine.yield, env = core.merge(_G), onValues = _5_, onError = _6_}, _11_())) 49 | end 50 | co = coroutine.create(_4_) 51 | coroutine.resume(co) 52 | local function _12_(input) 53 | if cfg then 54 | fennel.path = cfg({"fennel-path"}) 55 | fennel["macro-path"] = cfg({"fennel-macro-path"}) 56 | else 57 | end 58 | coroutine.resume(co, input) 59 | local prev_eval_values = results_to_return 60 | results_to_return = nil 61 | return prev_eval_values 62 | end 63 | return _12_ 64 | end 65 | return {new = new} 66 | -------------------------------------------------------------------------------- /lua/conjure/nfnl/string.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] Compiled from fnl/nfnl/string.fnl by https://github.com/Olical/nfnl, do not edit. 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local core = autoload("conjure.nfnl.core") 5 | local function join(...) 6 | local args = {...} 7 | local function _2_(...) 8 | if (2 == core.count(args)) then 9 | return args 10 | else 11 | return {"", core.first(args)} 12 | end 13 | end 14 | local _let_3_ = _2_(...) 15 | local sep = _let_3_[1] 16 | local xs = _let_3_[2] 17 | local len = core.count(xs) 18 | local result = {} 19 | if (len > 0) then 20 | for i = 1, len do 21 | local x = xs[i] 22 | local tmp_6_ 23 | if ("string" == type(x)) then 24 | tmp_6_ = x 25 | elseif (nil == x) then 26 | tmp_6_ = x 27 | else 28 | tmp_6_ = core["pr-str"](x) 29 | end 30 | if (tmp_6_ ~= nil) then 31 | table.insert(result, tmp_6_) 32 | else 33 | end 34 | end 35 | else 36 | end 37 | return table.concat(result, sep) 38 | end 39 | local function split(s, pat) 40 | local done_3f = false 41 | local acc = {} 42 | local index = 1 43 | while not done_3f do 44 | local start, _end = string.find(s, pat, index) 45 | if ("nil" == type(start)) then 46 | table.insert(acc, string.sub(s, index)) 47 | done_3f = true 48 | else 49 | table.insert(acc, string.sub(s, index, (start - 1))) 50 | index = (_end + 1) 51 | end 52 | end 53 | return acc 54 | end 55 | local function blank_3f(s) 56 | return (core["empty?"](s) or not string.find(s, "[^%s]")) 57 | end 58 | local function triml(s) 59 | return string.gsub(s, "^%s*(.-)", "%1") 60 | end 61 | local function trimr(s) 62 | return string.gsub(s, "(.-)%s*$", "%1") 63 | end 64 | local function trim(s) 65 | return string.gsub(s, "^%s*(.-)%s*$", "%1") 66 | end 67 | local function ends_with_3f(s, suffix) 68 | local suffix_len = #suffix 69 | local s_len = #s 70 | if (s_len >= suffix_len) then 71 | return (suffix == string.sub(s, (s_len - suffix_len - -1))) 72 | else 73 | return false 74 | end 75 | end 76 | return {join = join, split = split, ["blank?"] = blank_3f, triml = triml, trimr = trimr, trim = trim, ["ends-with?"] = ends_with_3f} 77 | -------------------------------------------------------------------------------- /lua/conjure/process.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/process.fnl 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local a = autoload("conjure.aniseed.core") 5 | local nvim = autoload("conjure.aniseed.nvim") 6 | local str = autoload("conjure.aniseed.string") 7 | local function executable_3f(cmd) 8 | return (1 == nvim.fn.executable(a.first(str.split(cmd, "%s+")))) 9 | end 10 | local function running_3f(proc) 11 | if proc then 12 | return proc["running?"] 13 | else 14 | return false 15 | end 16 | end 17 | local state = {jobs = {}} 18 | local function on_exit(job_id) 19 | local proc = state.jobs[job_id] 20 | if running_3f(proc) then 21 | a.assoc(proc, "running?", false) 22 | state.jobs[proc["job-id"]] = nil 23 | pcall(nvim.buf_delete, proc.buf, {force = true}) 24 | local on_exit0 = a["get-in"](proc, {"opts", "on-exit"}) 25 | if on_exit0 then 26 | return on_exit0(proc) 27 | else 28 | return nil 29 | end 30 | else 31 | return nil 32 | end 33 | end 34 | nvim.ex.function_(str.join("\n", {"ConjureProcessOnExit(...)", "call luaeval(\"require('conjure.process')['on-exit'](unpack(_A))\", a:000)", "endfunction"})) 35 | local function execute(cmd, opts) 36 | local win = nvim.tabpage_get_win(0) 37 | local original_buf = nvim.win_get_buf(win) 38 | local term_buf 39 | local _6_ 40 | do 41 | local t_5_ = opts 42 | if (nil ~= t_5_) then 43 | t_5_ = t_5_["hidden?"] 44 | else 45 | end 46 | _6_ = t_5_ 47 | end 48 | term_buf = nvim.create_buf(not _6_, true) 49 | local proc = {cmd = cmd, buf = term_buf, ["running?"] = true, opts = opts} 50 | local job_id 51 | do 52 | nvim.win_set_buf(win, term_buf) 53 | job_id = nvim.fn.termopen(cmd, {on_exit = "ConjureProcessOnExit"}) 54 | end 55 | if (job_id == 0) then 56 | error("invalid arguments or job table full") 57 | elseif (job_id == -1) then 58 | error(("'" .. cmd .. "' is not executable")) 59 | else 60 | end 61 | nvim.win_set_buf(win, original_buf) 62 | state.jobs[job_id] = proc 63 | return a.assoc(proc, "job-id", job_id) 64 | end 65 | local function stop(proc) 66 | if running_3f(proc) then 67 | nvim.fn.jobstop(proc["job-id"]) 68 | on_exit(proc["job-id"]) 69 | else 70 | end 71 | return proc 72 | end 73 | return {["executable?"] = executable_3f, ["running?"] = running_3f, ["on-exit"] = on_exit, execute = execute, stop = stop} 74 | -------------------------------------------------------------------------------- /lua/conjure/promise.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/promise.fnl 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local a = autoload("conjure.aniseed.core") 5 | local nvim = autoload("conjure.aniseed.nvim") 6 | local uuid = autoload("conjure.uuid") 7 | local state = {} 8 | local function new() 9 | local id = uuid.v4() 10 | a.assoc(state, id, {id = id, val = nil, ["done?"] = false}) 11 | return id 12 | end 13 | local function done_3f(id) 14 | return a["get-in"](state, {id, "done?"}) 15 | end 16 | local function deliver(id, val) 17 | if (false == done_3f(id)) then 18 | a["assoc-in"](state, {id, "val"}, val) 19 | a["assoc-in"](state, {id, "done?"}, true) 20 | else 21 | end 22 | return nil 23 | end 24 | local function deliver_fn(id) 25 | local function _3_(_241) 26 | return deliver(id, _241) 27 | end 28 | return _3_ 29 | end 30 | local function close(id) 31 | local val = a["get-in"](state, {id, "val"}) 32 | a.assoc(state, id, nil) 33 | return val 34 | end 35 | local function await(id, opts) 36 | return nvim.fn.wait(a.get(opts, "timeout", 10000), ("luaeval(\"require('conjure.promise')['done?']('" .. id .. "')\")"), a.get(opts, "interval", 50)) 37 | end 38 | return {new = new, ["done?"] = done_3f, deliver = deliver, ["deliver-fn"] = deliver_fn, close = close, await = await} 39 | -------------------------------------------------------------------------------- /lua/conjure/remote/netrepl.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/remote/netrepl.fnl 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local a = autoload("conjure.aniseed.core") 5 | local client = autoload("conjure.client") 6 | local log = autoload("conjure.log") 7 | local net = autoload("conjure.net") 8 | local trn = autoload("conjure.remote.transport.netrepl") 9 | local function send(conn, msg, cb, prompt_3f) 10 | log.dbg("send", msg) 11 | table.insert(conn.queue, 1, (cb or false)) 12 | if prompt_3f then 13 | table.insert(conn.queue, 1, false) 14 | else 15 | end 16 | conn.sock:write(trn.encode(msg)) 17 | return nil 18 | end 19 | local function connect(opts) 20 | local conn = {decode = trn.decoder(), queue = {}} 21 | local function handle_message(err, chunk) 22 | if (err or not chunk) then 23 | return opts["on-error"](err) 24 | else 25 | local function _3_(msg) 26 | log.dbg("receive", msg) 27 | local cb = table.remove(conn.queue) 28 | if cb then 29 | return cb(msg) 30 | else 31 | return nil 32 | end 33 | end 34 | return a["run!"](_3_, conn.decode(chunk)) 35 | end 36 | end 37 | local function _6_(err) 38 | if err then 39 | return opts["on-failure"](err) 40 | else 41 | send(conn, (opts.name or "Conjure")) 42 | conn.sock:read_start(client["schedule-wrap"](handle_message)) 43 | return opts["on-success"]() 44 | end 45 | end 46 | conn = a.merge(conn, net.connect({host = opts.host, port = opts.port, cb = client["schedule-wrap"](_6_)})) 47 | return conn 48 | end 49 | return {connect = connect, send = send} 50 | -------------------------------------------------------------------------------- /lua/conjure/remote/stdio2.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/remote/stdio2.fnl 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local a = autoload("conjure.aniseed.core") 5 | local str = autoload("conjure.aniseed.string") 6 | local client = autoload("conjure.client") 7 | local log = autoload("conjure.log") 8 | local uv = vim.loop 9 | local function parse_cmd(x) 10 | if a["table?"](x) then 11 | return {cmd = a.first(x), args = a.rest(x)} 12 | elseif a["string?"](x) then 13 | return parse_cmd(str.split(x, "%s")) 14 | else 15 | return nil 16 | end 17 | end 18 | return {["parse-cmd"] = parse_cmd} 19 | -------------------------------------------------------------------------------- /lua/conjure/remote/swank.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/remote/swank.fnl 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local a = autoload("conjure.aniseed.core") 5 | local client = autoload("conjure.client") 6 | local net = autoload("conjure.net") 7 | local trn = autoload("conjure.remote.transport.swank") 8 | local function send(conn, msg, cb) 9 | table.insert(conn.queue, 1, (cb or false)) 10 | conn.sock:write(trn.encode(msg)) 11 | return nil 12 | end 13 | local function connect(opts) 14 | local conn = {decode = trn.decode, queue = {}} 15 | local function handle_message(err, chunk) 16 | if (err or not chunk) then 17 | return opts["on-error"](err) 18 | else 19 | local function _2_(msg) 20 | local cb = table.remove(conn.queue) 21 | if cb then 22 | return cb(msg) 23 | else 24 | return nil 25 | end 26 | end 27 | return _2_(conn.decode(chunk)) 28 | end 29 | end 30 | local function _5_(err) 31 | if err then 32 | return opts["on-failure"](err) 33 | else 34 | conn.sock:read_start(client["schedule-wrap"](handle_message)) 35 | return opts["on-success"]() 36 | end 37 | end 38 | conn = a.merge(conn, net.connect({host = opts.host, port = opts.port, cb = client["schedule-wrap"](_5_)})) 39 | return conn 40 | end 41 | return {send = send, connect = connect} 42 | -------------------------------------------------------------------------------- /lua/conjure/remote/transport/base64.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/remote/transport/base64.fnl 2 | local b = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" 3 | local function encode(data) 4 | local function _1_(x) 5 | local r, b0 = "", x:byte() 6 | for i = 8, 1, ( - 1) do 7 | r = (r .. (((((b0 % (2 ^ i)) - (b0 % (2 ^ (i - 1)))) > 0) and "1") or "0")) 8 | end 9 | return r 10 | end 11 | local function _2_(x) 12 | if (#x < 6) then 13 | return "" 14 | else 15 | end 16 | local c = 0 17 | for i = 1, 6 do 18 | c = (c + (((x:sub(i, i) == "1") and (2 ^ (6 - i))) or 0)) 19 | end 20 | return b:sub((c + 1), (c + 1)) 21 | end 22 | return ((data:gsub(".", _1_) .. "0000"):gsub("%d%d%d?%d?%d?%d?", _2_) .. ({"", "==", "="})[((#data % 3) + 1)]) 23 | end 24 | local function decode(data) 25 | data = string.gsub(data, ("[^" .. b .. "=]"), "") 26 | local function _4_(x) 27 | if (x == "=") then 28 | return "" 29 | else 30 | end 31 | local r, f = "", (b:find(x) - 1) 32 | for i = 6, 1, ( - 1) do 33 | r = (r .. (((((f % (2 ^ i)) - (f % (2 ^ (i - 1)))) > 0) and "1") or "0")) 34 | end 35 | return r 36 | end 37 | local function _6_(x) 38 | if (#x ~= 8) then 39 | return "" 40 | else 41 | end 42 | local c = 0 43 | for i = 1, 8 do 44 | c = (c + (((x:sub(i, i) == "1") and (2 ^ (8 - i))) or 0)) 45 | end 46 | return string.char(c) 47 | end 48 | return data:gsub(".", _4_):gsub("%d%d%d?%d?%d?%d?%d?%d?", _6_) 49 | end 50 | return {encode = encode, decode = decode} 51 | -------------------------------------------------------------------------------- /lua/conjure/remote/transport/netrepl.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/remote/transport/netrepl.fnl 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local a = autoload("conjure.aniseed.core") 5 | local bit = autoload("bit") 6 | local function encode(msg) 7 | local n = a.count(msg) 8 | return (string.char(bit.band(n, 255), bit.band(bit.rshift(n, 8), 255), bit.band(bit.rshift(n, 16), 255), bit.band(bit.rshift(n, 24), 255)) .. msg) 9 | end 10 | local function split(chunk) 11 | local b0, b1, b2, b3 = string.byte(chunk, 1, 4) 12 | return bit.bor(bit.band(b0, 255), bit.lshift(bit.band(b1, 255), 8), bit.lshift(bit.band(b2, 255), 16), bit.lshift(bit.band(b3, 255), 24)), string.sub(chunk, 5) 13 | end 14 | local function decoder() 15 | local awaiting = nil 16 | local buffer = "" 17 | local function reset() 18 | awaiting = nil 19 | buffer = "" 20 | return nil 21 | end 22 | local function decode(chunk, acc) 23 | local acc0 = (acc or {}) 24 | if awaiting then 25 | local before = a.count(buffer) 26 | local seen = a.count(chunk) 27 | buffer = (buffer .. chunk) 28 | if (seen > awaiting) then 29 | local consumed = string.sub(buffer, 1, (before + awaiting)) 30 | local next_chunk = string.sub(chunk, a.inc(awaiting)) 31 | table.insert(acc0, consumed) 32 | reset() 33 | return decode(next_chunk, acc0) 34 | elseif (seen == awaiting) then 35 | table.insert(acc0, buffer) 36 | reset() 37 | return acc0 38 | else 39 | awaiting = (awaiting - seen) 40 | return acc0 41 | end 42 | else 43 | local n, rem = split(chunk) 44 | awaiting = n 45 | return decode(rem, acc0) 46 | end 47 | end 48 | return decode 49 | end 50 | return {decoder = decoder, encode = encode} 51 | -------------------------------------------------------------------------------- /lua/conjure/remote/transport/swank.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/remote/transport/swank.fnl 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local a = autoload("conjure.aniseed.core") 5 | local log = autoload("conjure.log") 6 | local function encode(msg) 7 | local n = a.count(msg) 8 | local header = string.format("%06x", (1 + n)) 9 | return (header .. msg .. "\n") 10 | end 11 | local function decode(msg) 12 | local len = tonumber(string.sub(msg, 1, 7), 16) 13 | local cmd = string.sub(msg, 7, len) 14 | return cmd 15 | end 16 | return {encode = encode, decode = decode} 17 | -------------------------------------------------------------------------------- /lua/conjure/sponsors.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/sponsors.fnl 2 | return {"AbhinavOmprakash", "Akeboshiwind", "aleksandersumowski", "AlexChalk", "Aljendro", "alloy-d", "anthony-khong", "axvr", "beanpuppy", "Brailor", "campbellr", "daveyarwood", "davidmh", "dharrigan", "djwhitt", "edlandm", "extradosages", "frenchy64", "fuadsaud", "harrygallagher4", "jackkinsey", "jacobobryant", "jamesreprise", "jcpsantiago", "jkrasnay", "ketansrivastav", "kevinkrouse", "lanjoni", "lucasdf", "lucaslollobrigida", "matheusfrancisco", "mraveloarinjaka", "NickCellino", "NoahTheDuke", "orestis", "penryu", "qnkhuat", "rafaeldelboni", "rbatista", "rgm", "stelcodes", "terjesb", "theplatters", "thiru", "TimoKramer", "trev-dev", "valsen", "victorb", "zhming0"} 3 | -------------------------------------------------------------------------------- /lua/conjure/stack.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/stack.fnl 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local a = autoload("conjure.aniseed.core") 5 | local function push(s, v) 6 | table.insert(s, v) 7 | return s 8 | end 9 | local function pop(s) 10 | table.remove(s) 11 | return s 12 | end 13 | local function peek(s) 14 | return a.last(s) 15 | end 16 | return {push = push, pop = pop, peek = peek} 17 | -------------------------------------------------------------------------------- /lua/conjure/text.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/text.fnl 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local autoload = _local_1_["autoload"] 4 | local a = autoload("conjure.aniseed.core") 5 | local str = autoload("conjure.aniseed.string") 6 | local function trailing_newline_3f(s) 7 | return string.match(s, "\r?\n$") 8 | end 9 | local function trim_last_newline(s) 10 | return string.gsub(s, "\r?\n$", "") 11 | end 12 | local function left_sample(s, limit) 13 | local flat = str.trim(string.gsub(string.gsub(s, "\n", " "), "%s+", " ")) 14 | if (limit >= a.count(flat)) then 15 | return flat 16 | else 17 | return (string.sub(flat, 0, a.dec(limit)) .. "...") 18 | end 19 | end 20 | local function right_sample(s, limit) 21 | return string.reverse(left_sample(string.reverse(s), limit)) 22 | end 23 | local function split_lines(s) 24 | return str.split(s, "\r?\n") 25 | end 26 | local function prefixed_lines(s, prefix, opts) 27 | local function _4_(_3_) 28 | local n = _3_[1] 29 | local line = _3_[2] 30 | if ((1 == n) and a.get(opts, "skip-first?")) then 31 | return line 32 | else 33 | return (prefix .. line) 34 | end 35 | end 36 | return a["map-indexed"](_4_, split_lines(s)) 37 | end 38 | local function starts_with(str0, start) 39 | if (str0 and start) then 40 | return vim.startswith(str0, start) 41 | else 42 | return nil 43 | end 44 | end 45 | local function ends_with(str0, _end) 46 | if (str0 and _end) then 47 | return ((_end == "") or vim.endswith(str0, _end)) 48 | else 49 | return nil 50 | end 51 | end 52 | local function first_and_last_chars(str0) 53 | if str0 then 54 | if (a.count(str0) > 1) then 55 | return (string.sub(str0, 1, 1) .. string.sub(str0, -1, -1)) 56 | else 57 | return str0 58 | end 59 | else 60 | return nil 61 | end 62 | end 63 | local function strip_ansi_escape_sequences(s) 64 | return string.gsub(string.gsub(string.gsub(string.gsub(string.gsub(s, "\27%[%d+;%d+;%d+;%d+;%d+m", ""), "\27%[%d+;%d+;%d+;%d+m", ""), "\27%[%d+;%d+;%d+m", ""), "\27%[%d+;%d+m", ""), "\27%[%d+m", "") 65 | end 66 | local function chars(s) 67 | local res = {} 68 | if s then 69 | for c in string.gmatch(s, ".") do 70 | table.insert(res, c) 71 | end 72 | else 73 | end 74 | return res 75 | end 76 | local function upper_first(s) 77 | if s then 78 | return s:gsub("^%l", string.upper) 79 | else 80 | return nil 81 | end 82 | end 83 | return {["trailing-newline?"] = trailing_newline_3f, ["trim-last-newline"] = trim_last_newline, ["left-sample"] = left_sample, ["right-sample"] = right_sample, ["split-lines"] = split_lines, ["prefixed-lines"] = prefixed_lines, ["starts-with"] = starts_with, ["ends-with"] = ends_with, ["first-and-last-chars"] = first_and_last_chars, ["strip-ansi-escape-sequences"] = strip_ansi_escape_sequences, chars = chars, ["upper-first"] = upper_first} 84 | -------------------------------------------------------------------------------- /lua/conjure/timer.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/timer.fnl 2 | local _local_1_ = require("conjure.nfnl.module") 3 | local define = _local_1_["define"] 4 | local M = define("conjure.timer") 5 | M.defer = function(f, ms) 6 | local t = vim.uv.new_timer() 7 | t:start(ms, 0, vim.schedule_wrap(f)) 8 | return t 9 | end 10 | M.destroy = function(t) 11 | if t then 12 | t:stop() 13 | t:close() 14 | else 15 | end 16 | return nil 17 | end 18 | return M 19 | -------------------------------------------------------------------------------- /lua/conjure/util.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] fnl/conjure/util.fnl 2 | local function wrap_require_fn_call(mod, f) 3 | local function _1_() 4 | return require(mod)[f]() 5 | end 6 | return _1_ 7 | end 8 | local function replace_termcodes(s) 9 | return vim.api.nvim_replace_termcodes(s, true, false, true) 10 | end 11 | return {["wrap-require-fn-call"] = wrap_require_fn_call, ["replace-termcodes"] = replace_termcodes} 12 | -------------------------------------------------------------------------------- /mise.toml: -------------------------------------------------------------------------------- 1 | [tasks.sponsors] 2 | run = "scripts/sponsors.sh" 3 | 4 | [tasks.test] 5 | run = ["bash ./scripts/setup-test-deps", "bash ./scripts/test"] 6 | 7 | [tasks.benchmark] 8 | run = "nvim -l lua/conjure-benchmark/run.lua" 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "conjure", 3 | "version": "1.0.0", 4 | "description": "= Conjure", 5 | "main": "index.js", 6 | "directories": { 7 | "doc": "doc", 8 | "test": "test" 9 | }, 10 | "dependencies": {}, 11 | "devDependencies": { 12 | "shadow-cljs": "^2.8.97" 13 | }, 14 | "scripts": { 15 | "test": "echo \"Error: no test specified\" && exit 1" 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "git+https://github.com/Olical/conjure.git" 20 | }, 21 | "author": "", 22 | "license": "ISC", 23 | "bugs": { 24 | "url": "https://github.com/Olical/conjure/issues" 25 | }, 26 | "homepage": "https://github.com/Olical/conjure#readme" 27 | } 28 | -------------------------------------------------------------------------------- /plugin/conjure.fnl: -------------------------------------------------------------------------------- 1 | (local minimum-version "0.9") 2 | (if (= 1 (vim.fn.has (.. "nvim-" minimum-version))) 3 | (let [main (require :conjure.main)] 4 | (main.main)) 5 | (vim.notify_once (.. "Conjure requires Neovim > v" minimum-version) vim.log.levels.ERROR)) 6 | -------------------------------------------------------------------------------- /plugin/conjure.lua: -------------------------------------------------------------------------------- 1 | -- [nfnl] plugin/conjure.fnl 2 | local minimum_version = "0.9" 3 | if (1 == vim.fn.has(("nvim-" .. minimum_version))) then 4 | local main = require("conjure.main") 5 | return main.main() 6 | else 7 | return vim.notify_once(("Conjure requires Neovim > v" .. minimum_version), vim.log.levels.ERROR) 8 | end 9 | -------------------------------------------------------------------------------- /project.clj: -------------------------------------------------------------------------------- 1 | (defproject dev "0.1.0-SNAPSHOT" 2 | :description "FIXME: write description" 3 | :url "http://example.com/FIXME" 4 | :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0" 5 | :url "https://www.eclipse.org/legal/epl-2.0/"} 6 | :dependencies [[org.clojure/clojure "1.10.1"] 7 | [org.clojure/tools.logging "1.1.0"]] 8 | :plugins [[cider/cider-nrepl "0.24.0"]] 9 | :source-paths ["dev/clojure/src"] 10 | :repl-options {:init-ns dev.sandbox}) 11 | -------------------------------------------------------------------------------- /rplugin/python3/deoplete/sources/conjure.py: -------------------------------------------------------------------------------- 1 | import time 2 | from .base import Base 3 | import deoplete.logger 4 | 5 | class Source(Base): 6 | def __init__(self, vim): 7 | Base.__init__(self, vim) 8 | 9 | self.vim = vim 10 | 11 | self.name = "conjure" 12 | self.filetypes = self.lua("conjure.config", "filetypes") 13 | self.rank = 500 14 | 15 | def lua(self, module, f, *args): 16 | return self.vim.exec_lua("return require('" + module + "')['" + f + "'](...)", *args) 17 | 18 | def gather_candidates(self, context): 19 | p = self.lua("conjure.eval", "completions-promise", context["complete_str"]) 20 | while not self.lua("conjure.promise", "done?", p): 21 | time.sleep(0.02) 22 | return self.lua("conjure.promise", "close", p) 23 | -------------------------------------------------------------------------------- /scripts/docker.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CONJURE_DIR=/root/.local/share/nvim/site/pack/conjure/start/conjure 4 | 5 | docker build . -t conjure 6 | docker run \ 7 | -v $(pwd):$CONJURE_DIR \ 8 | -ti --rm conjure \ 9 | nvim --cmd "cd $CONJURE_DIR" $@ 10 | -------------------------------------------------------------------------------- /scripts/setup-test-deps: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | PACK_DIR=.test/nvim/pack/main/start 4 | 5 | mkdir -p "$PACK_DIR" 6 | 7 | if [ -d "$PACK_DIR/plenary.nvim" ]; then 8 | echo "plenary.nvim already exists" 9 | else 10 | git clone https://github.com/nvim-lua/plenary.nvim.git "$PACK_DIR/plenary.nvim" 11 | fi 12 | 13 | if [ -d "$PACK_DIR/fennel.vim" ]; then 14 | echo "fennel.vim already exists" 15 | else 16 | git clone https://github.com/bakpakin/fennel.vim.git "$PACK_DIR/fennel.vim" 17 | fi 18 | 19 | if [ -d "$PACK_DIR/aniseed" ]; then 20 | echo "aniseed already exists" 21 | else 22 | git clone https://github.com/Olical/aniseed.git "$PACK_DIR/aniseed" 23 | fi 24 | 25 | if [ -d "$PACK_DIR/nfnl" ]; then 26 | echo "nfnl already exists" 27 | else 28 | git clone https://github.com/Olical/nfnl.git "$PACK_DIR/nfnl" 29 | fi 30 | 31 | rm -f "$PACK_DIR/conjure" 32 | ln -s "../../../../../" "$PACK_DIR/conjure" 33 | -------------------------------------------------------------------------------- /scripts/sponsors.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "[ ;; Generated by: scripts/sponsors.sh" >fnl/conjure/sponsors.fnl 4 | curl https://github.com/sponsors/Olical | 5 | grep '"avatar avatar-user"' | 6 | sed 's/.*alt="@\(.*\)".*/"\1"/' | 7 | tail -n +2 | 8 | sort \ 9 | >>fnl/conjure/sponsors.fnl 10 | echo "]" >>fnl/conjure/sponsors.fnl 11 | nvim fnl/conjure/sponsors.fnl +wq 12 | -------------------------------------------------------------------------------- /scripts/test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | XDG_CONFIG_HOME=$(pwd)/.test 4 | export XDG_CONFIG_HOME 5 | 6 | nvim --headless -c 'PlenaryBustedDirectory lua/conjure-spec' 7 | -------------------------------------------------------------------------------- /shadow-cljs.edn: -------------------------------------------------------------------------------- 1 | ;; shadow-cljs configuration 2 | {:source-paths 3 | ["dev/clojure/src"] 4 | 5 | :dependencies 6 | [[cider/cider-nrepl "0.24.0"]] 7 | 8 | :dev-http {8080 "dev/clojure/public"} 9 | 10 | :builds 11 | {:app {:target :browser 12 | :output-dir "dev/clojure/public/js" 13 | :asset-path "/js" 14 | :modules {:main {:entries [dev.sandbox]}}}}} 15 | -------------------------------------------------------------------------------- /tests.edn: -------------------------------------------------------------------------------- 1 | #kaocha/v1 2 | {:tests [{:id :unit 3 | :test-paths ["dev/clojure"] 4 | :ns-patterns [".*"]}]} 5 | --------------------------------------------------------------------------------