diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 0000000..295523b
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,149 @@
+name: main
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+ types: [opened, synchronize]
+
+env:
+ LUA_LS_VERSION: 3.7.4
+
+concurrency:
+ group: github.head_ref
+ cancel-in-progress: true
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+ name: lint
+ steps:
+ - uses: actions/checkout@v4
+
+ - uses: JohnnyMorganz/stylua-action@v4
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ version: latest
+ args: --check . -g '*.lua' -g '!deps/'
+
+ documentation:
+ runs-on: ubuntu-latest
+ name: documentation
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 2
+
+ - name: setup neovim
+ uses: rhysd/action-setup-vim@v1
+ with:
+ neovim: true
+ version: v0.10.1
+
+ - name: generate documentation
+ run: make documentation-ci
+
+ - name: check docs diff
+ run: exit $(git status --porcelain doc | wc -l | tr -d " ")
+
+ tests:
+ needs:
+ - lint
+ - documentation
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ neovim_version: ['v0.9.5', 'v0.10.1']
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - run: date +%F > todays-date
+
+ - name: restore cache for today's nightly.
+ uses: actions/cache@v4
+ with:
+ path: _neovim
+ key: ${{ runner.os }}-x64-${{ hashFiles('todays-date') }}
+
+ - name: restore luals cache
+ uses: actions/cache@v4
+ id: cache
+ with:
+ path: .ci/lua-ls
+ key: ${{ env.LUA_LS_VERSION }}
+
+ - name: setup luals
+ if: ${{ steps.cache.outputs.cache-hit != 'true' }}
+ run: mkdir -p .ci/lua-ls && curl -sL "https://github.com/LuaLS/lua-language-server/releases/download/${{ env.LUA_LS_VERSION }}/lua-language-server-${{ env.LUA_LS_VERSION }}-linux-x64.tar.gz" | tar xzf - -C "${PWD}/.ci/lua-ls"
+
+ - name: setup neovim
+ uses: rhysd/action-setup-vim@v1
+ with:
+ neovim: true
+ version: ${{ matrix.neovim_version }}
+
+ - uses: cachix/install-nix-action@v25
+ - uses: cachix/cachix-action@v14
+ with:
+ name: forester
+ signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
+
+ - run: nix profile install sourcehut:~jonsterling/ocaml-forester
+
+ - name: run tests
+ run: make test-ci
+
+ - name: Release
+ uses: softprops/action-gh-release@v2
+ if: startsWith(github.ref, 'refs/tags/')
+
+ tests-nightly:
+ needs:
+ - lint
+ - documentation
+ runs-on: ubuntu-latest
+ continue-on-error: true
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - run: date +%F > todays-date
+
+ - name: restore cache for today's nightly.
+ uses: actions/cache@v4
+ with:
+ path: _neovim
+ key: ${{ runner.os }}-x64-${{ hashFiles('todays-date') }}
+
+ - name: restore luals cache
+ uses: actions/cache@v4
+ id: cache
+ with:
+ path: .ci/lua-ls
+ key: ${{ env.LUA_LS_VERSION }}
+
+ - name: setup luals
+ if: ${{ steps.cache.outputs.cache-hit != 'true' }}
+ run: mkdir -p .ci/lua-ls && curl -sL "https://github.com/LuaLS/lua-language-server/releases/download/${{ env.LUA_LS_VERSION }}/lua-language-server-${{ env.LUA_LS_VERSION }}-linux-x64.tar.gz" | tar xzf - -C "${PWD}/.ci/lua-ls"
+
+ - name: setup neovim
+ uses: rhysd/action-setup-vim@v1
+ with:
+ neovim: true
+ version: nightly
+
+ - uses: cachix/install-nix-action@v25
+ - uses: cachix/cachix-action@v14
+ with:
+ name: forester
+ signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
+
+ - run: nix profile install sourcehut:~jonsterling/ocaml-forester
+
+ - name: run tests
+ run: make test-ci
+
+ - name: Release
+ uses: softprops/action-gh-release@v2
+ if: startsWith(github.ref, 'refs/tags/')
diff --git a/.gitignore b/.gitignore
index 5d44fa5..30e68fe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+deps
forest.json
forest.toml
build/
diff --git a/Makefile b/Makefile
index 387e43d..b5b1645 100644
--- a/Makefile
+++ b/Makefile
@@ -1,28 +1,22 @@
-.PHONY: test lint docs init
+# Run all test files
+test: deps/mini.nvim
+ nvim --headless --noplugin -u ./scripts/minimal_init.lua -c "lua MiniTest.run()"
-TESTS_DIR := test/
-PLUGIN_DIR := lua/
+# Run test from file at `$FILE` environment variable
+test_file: deps/mini.nvim
+ nvim --headless --noplugin -u ./scripts/minimal_init.lua -c "lua MiniTest.run_file('$(FILE)')"
-DOC_GEN_SCRIPT := ./scripts/docs.lua
-MINIMAL_INIT := ./scripts/minimal_init.lua
+# Download 'mini.nvim' to use its 'mini.test' testing module
+deps:
+ @mkdir -p deps
+ git clone --filter=blob:none https://github.com/echasnovski/mini.nvim $@/mini.nvim
+ git clone --filter=blob:none https://github.com/nvim-lua/plenary.nvim $@/plenary.nvim
+ git clone --filter=blob:none https://github.com/nvim-telescope/telescope.nvim $@/telescope.nvim
+ git clone --filter=blob:none https://github.com/nvim-treesitter/nvim-treesitter $@/nvim-treesitter
-test:
- nvim --headless --noplugin -u ${MINIMAL_INIT} \
- -c "PlenaryBustedDirectory ${TESTS_DIR} { minimal_init = '${MINIMAL_INIT}' }"
+documentation:
+ nvim --headless --noplugin -u ./scripts/minimal_init.lua -c "luafile scripts/minidoc.lua" -c "qa!"
-lint:
- luacheck ${PLUGIN_DIR}
+documentation-ci: deps documentation
-docs:
- nvim --headless --noplugin -u ${MINIMAL_INIT} \
- -c "luafile ${DOC_GEN_SCRIPT}" -c 'qa'
-
-init:
- @nvim --headless --noplugin \
- -c "vimgrep /my_awesome_plugin/gj **/*.lua **/*.vim Makefile" \
- -c "cfdo %s/my_awesome_plugin/$(name)/ge | update" \
- -c "qa"
- @find . -depth -type d -name '*my_awesome_plugin*' | \
- while read dir; do mv "$$dir" "$${dir//my_awesome_plugin/$(name)}"; done
- @find . -type f -name '*my_awesome_plugin*' | \
- while read file; do mv "$$file" "$${file//my_awesome_plugin/$(name)}"; done
+test-ci: deps test
diff --git a/README.md b/README.md
index bca3f2d..3493041 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,13 @@
# 🌲 forester.nvim 🌲
+[![main](https://github.com/kentookura/forester.nvim/actions/workflows/main.yml/badge.svg)](https://github.com/kentookura/forester.nvim/actions/workflows/main.yml)
+
Filetype plugin for [forester](https://sr.ht/~jonsterling/forester/), a tool
for writing mathematical hypertext
# Features
-- Tree-sitter syntax highlighting
+- Tree-sitter syntax highlighting.
Please report any issues with the grammar in the [relevant repository](https://github.com/kentookura/tree-sitter-forester)
- following links and transclusions with `gf`
- Searching for trees by title with [telescope](https://github.com/nvim-telescope/telescope.nvim)
diff --git a/doc/demo.tree b/doc/demo.tree
deleted file mode 100644
index 1c41d83..0000000
--- a/doc/demo.tree
+++ /dev/null
@@ -1,52 +0,0 @@
-\title{Highlighting}
-\taxon{demo}
-\meta{external}{https://github.com/kentookura/forester.nvim}
-
-\tag{neovim}
-\tag{treesitter}
-
-\p{
- \ul{
- \li{list}
- \li{items}
- \li{Todo: show surrounding braces when inside list}
-
-
- }
- \ol{
- \li{ordered list items would be awesome. Need to compute stuff in lua}
- \li{Querying section numbering via forester 👀 }
- }
-
- [Install the plugin](foo-0001) and try it out! See the example [neovim config](./init.lua)
-
-
- Embedded syntax highlighting would be awesome. Requires syntax change in forester.
- \code{
- def function()
- end
- }
-
- #{a = b}
-
- ##{
- \f\relax{x} = \int_{-\infty}^\infty
- \f\hat\xi\,e^{2 \pi i \xi x}
- \,d\xi
- }
-}
-
-
-\def\my-object{
- \object[self]{
- [method1]{
- the implementation of this method \em{asdf} \strong{asdf}
- }
- [method2]{
- the implementation of another method
- \self#method1
- }
- }
-}
-
-
diff --git a/doc/forester.nvim.txt b/doc/forester.nvim.txt
deleted file mode 100644
index dac1843..0000000
--- a/doc/forester.nvim.txt
+++ /dev/null
@@ -1,109 +0,0 @@
-*forester.nvim.txt* For NVIM v0.8.0 Last change: 2024 May 23
-
-==============================================================================
-Table of Contents *forester.nvim-table-of-contents*
-
-1. 🌲 forester.nvim 🌲 |forester.nvim-🌲-forester.nvim-🌲|
-2. Features |forester.nvim-features|
-3. Installation |forester.nvim-installation|
-4. Configuration |forester.nvim-configuration|
-5. Roadmap |forester.nvim-roadmap|
-6. Links |forester.nvim-links|
-
-==============================================================================
-1. 🌲 forester.nvim 🌲 *forester.nvim-🌲-forester.nvim-🌲*
-
-DOES NOT YET WORK WITH FORESTER 4.0
-
-DOES NOT YET WORK WITH FORESTER 4.0
-
-Filetype plugin for forester , a tool for
-writing mathematical hypertext
-
-
-==============================================================================
-2. Features *forester.nvim-features*
-
-This plugin is pre-alpha, expect breaking changes.
-
-- Tree-sitter syntax highlighting
-
-Please report any issues with the grammar in the relevant repository
-
-
-- following links and transclusions with `gf`
-- Browsing forests with telescope
-- Creating new trees within neovim
-
-Available user commands:
-
-- `Forester browse`: Telescope picker, search trees by title. TODO: support browsing by tag/taxon/…
-- `Forester new`: Create a new tree by specifying a prefix
-- `Forester config`: Choose the config file from which to source the tree directories
-
-These features need work:
-
-- `Forester transclude`: transclude a new tree at cursor position
-- `Forester link`: link a new tree at cursor position
-
-
-==============================================================================
-3. Installation *forester.nvim-installation*
-
-With lazy:
-
->lua
- {
- "kentookura/forester.nvim",
- dependencies = {
- { "nvim-treesitter/nvim-treesitter" },
- { "nvim-lua/plenary.nvim" },
- { "hrsh7th/nvim-cmp" },
- },
- },
-<
-
-You might need to run `:TSInstall toml`
-
-
-==============================================================================
-4. Configuration *forester.nvim-configuration*
-
->lua
- {
- opts = {
- forests = { "~/forest/"}, -- Global forests
- tree_dirs = {"trees", "notes"} -- Where the plugin will look for trees relative to the current directory.
- }; -- Works outside of global forests
-
- config = function()
- local forester = require("forester")
- vim.g.mapleader = " "
-
- vim.keymap.set("n", "n.", "Forester browse", { silent = true })
- vim.keymap.set("n", "nn", "Forester new", { silent = true })
- vim.keymap.set("i", "", "Forester transclude", { silent = true })
- vim.keymap.set("i", "", "Forester link", { silent = true })
- end,
- }
-
- require("nvim-web-devicons").setup({ override_by_extension = { ["tree"] = { icon = "🌲" } } })
-<
-
-
-==============================================================================
-5. Roadmap *forester.nvim-roadmap*
-
-- Adding more telescope pickers and previewers, making use of the `forester query` commands
-- Link & transclude existing trees at cursor position.
-- autocomplete
-- …
-
-==============================================================================
-6. Links *forester.nvim-links*
-
-1. *Screenshot showcasing the conceal feature*: ./doc/highlight.png
-
-Generated by panvimdoc
-
-vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/doc/forester.txt b/doc/forester.txt
new file mode 100644
index 0000000..5910212
--- /dev/null
+++ b/doc/forester.txt
@@ -0,0 +1,23 @@
+*forester.nvim* Forester filetype plugin
+
+=========================================================================
+
+Supported features:
+- Autocomplete
+- following links via `gf`
+- fuzzy finding
+
+# Setup ~
+
+Initialize the plugin via `require("forester").setup()`
+
+In your `forest.toml`, add the list of prefixes you wish to use:
+>toml
+prefixes = ["foo", "bar"]
+<
+This plugin currently does not support user configuration via lua.
+I think it is preferrable to use the forester configuration files and
+extracting the relevant keys via treesitter
+
+
+ vim:tw=78:ts=8:noet:ft=help:norl:
\ No newline at end of file
diff --git a/doc/nvm-0001.tree b/doc/nvm-0001.tree
deleted file mode 100644
index f86890a..0000000
--- a/doc/nvm-0001.tree
+++ /dev/null
@@ -1,39 +0,0 @@
-\title{Forester.nvim}
-\date{2024-01-08}
-\tag{todo}
-\tag{documentation}
-\taxon{README}
-
-\subtree{
- \title{asdf}
-}
-
-\scope{
- \put\transclude/title{Installation}
- \transclude{nvm-0002}
- }
-
-\p{
- See the example [[init.lua]] for installing with
- [lazy.vim](https://github.com/folke/lazy.nvim).
-}
-
-
-\scope{\put\transclude/title{Todos}
- \query{ \query/tag{todo} }
-}
-
-\p{
- increment/decrement tree addrs using \code{} and \code{}
- \code{h: nrformats}
-}
-
-\p{
- no commands for inserting existing links, this should be handled by
- completion provider.
-}
-
-\p{
- nixvim
-}
-
diff --git a/doc/nvm-0002.tree b/doc/nvm-0002.tree
deleted file mode 100644
index 2e2400c..0000000
--- a/doc/nvm-0002.tree
+++ /dev/null
@@ -1,7 +0,0 @@
-\title{templating}
-\tag{feature}
-
-\p{
- It might actually be better to use neovim templates than forester's
- builtin templating functionality.
-}
diff --git a/doc/nvm-0003.tree b/doc/nvm-0003.tree
deleted file mode 100644
index 397712b..0000000
--- a/doc/nvm-0003.tree
+++ /dev/null
@@ -1,7 +0,0 @@
-\title{templating}
-\tag{bug}
-\tag{todo}
-
-\p{
- strip leading whitespace and otherwise verify user inputh
-}
diff --git a/doc/tags b/doc/tags
new file mode 100644
index 0000000..86a0c1e
--- /dev/null
+++ b/doc/tags
@@ -0,0 +1 @@
+forester.nvim forester.txt /*forester.nvim*
diff --git a/flake.lock b/flake.lock
index 3ed6b42..f84c9cc 100644
--- a/flake.lock
+++ b/flake.lock
@@ -131,17 +131,18 @@
"opam-repository": "opam-repository_2"
},
"locked": {
- "lastModified": 1716654291,
- "narHash": "sha256-ZtsGU0XSBOKBEUZZzSiChvL+dmxWc0bn2TqzMj3Kvz8=",
- "owner": "~jonsterling",
- "repo": "ocaml-forester",
- "rev": "f106b90b6ac9bd12703a026c0271908ea66ada4e",
- "type": "sourcehut"
+ "lastModified": 1728590048,
+ "narHash": "sha256-GAB7PFn8vCXewUNj/smfzo63/irXVOMWyvFL3Mp5Ris=",
+ "ref": "iri",
+ "rev": "10c214207f56454d7f7bcd8c7ac2bfb0b33ad3f2",
+ "revCount": 692,
+ "type": "git",
+ "url": "file:///home/kento/ocaml-forester"
},
"original": {
- "owner": "~jonsterling",
- "repo": "ocaml-forester",
- "type": "sourcehut"
+ "ref": "iri",
+ "type": "git",
+ "url": "file:///home/kento/ocaml-forester"
}
},
"mirage-opam-overlays": {
@@ -192,16 +193,18 @@
},
"nixpkgs_3": {
"locked": {
- "lastModified": 1714809261,
- "narHash": "sha256-hfBmnYFyz9I1mdrC3tX1A+dF9cOUcds5PIMPxrT+cRk=",
+ "lastModified": 1725634671,
+ "narHash": "sha256-v3rIhsJBOMLR8e/RNWxr828tB+WywYIoajrZKFM+0Gg=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "d32560238207b8e26d88b265207b216ee46b8450",
+ "rev": "574d1eac1c200690e27b8eb4e24887f8df7ac27c",
"type": "github"
},
"original": {
- "id": "nixpkgs",
- "type": "indirect"
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
}
},
"nixpkgs_4": {
@@ -245,11 +248,11 @@
"opam2json": "opam2json"
},
"locked": {
- "lastModified": 1712645768,
- "narHash": "sha256-9dUh8nElGtC74Q4gIDV6DM0FKgF1oXh0PUkCxdbp+sg=",
+ "lastModified": 1716292162,
+ "narHash": "sha256-UOJNCbqvxABD56JZtZkv3C9ufdqrs7/Ep4AKkCHgPuo=",
"owner": "tweag",
"repo": "opam-nix",
- "rev": "464863fba44c7ecc50bd1a2967274482a2c33daf",
+ "rev": "1d3cbd6d3f247db77cb581c88c9a1d72e4acad60",
"type": "github"
},
"original": {
@@ -293,11 +296,11 @@
"opam-repository_2": {
"flake": false,
"locked": {
- "lastModified": 1714767341,
- "narHash": "sha256-JNtvibn9cj63fA258op64OzTyanjgF9YVqTKnl5F/Kk=",
+ "lastModified": 1725740801,
+ "narHash": "sha256-hlf57jytCuBRZnFwQilT59q4HP2g6XMiQLKdxl4dho0=",
"owner": "ocaml",
"repo": "opam-repository",
- "rev": "3648176cc095f9106427fe05f07f0dc87ca27773",
+ "rev": "16e8d80cc51ddd05b3fa5c000eb2739cf0ee3a74",
"type": "github"
},
"original": {
diff --git a/flake.nix b/flake.nix
index b46534e..0f77110 100644
--- a/flake.nix
+++ b/flake.nix
@@ -2,14 +2,28 @@
inputs = {
flake-utils.url = "github:numtide/flake-utils";
forest-server.url = "github:kentookura/forest-server";
- forester = { url = "sourcehut:~jonsterling/ocaml-forester"; };
+ forester = {
+ # url = "sourcehut:~jonsterling/ocaml-forester";
+ url = "/home/kento/ocaml-forester/?ref=iri";
+ };
};
- outputs = { self, forest-server, flake-utils, nixpkgs, forester }@inputs:
- flake-utils.lib.eachDefaultSystem (system:
- let pkgs = import nixpkgs { inherit system; };
- in {
+ outputs =
+ {
+ self,
+ forest-server,
+ flake-utils,
+ nixpkgs,
+ forester,
+ }@inputs:
+ flake-utils.lib.eachDefaultSystem (
+ system:
+ let
+ pkgs = import nixpkgs { inherit system; };
+ in
+ {
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
+ act
teseq
forester.packages.${system}.default
tree-sitter
@@ -26,5 +40,6 @@
forest-server.packages.${system}.default
];
};
- });
+ }
+ );
}
diff --git a/lua/forester.lua b/lua/forester.lua
index 840533d..2fc05d7 100644
--- a/lua/forester.lua
+++ b/lua/forester.lua
@@ -1,3 +1,25 @@
+--- *forester.nvim* Forester filetype plugin
+---
+--- =========================================================================
+---
+--- Supported features:
+--- - Autocomplete
+--- - following links via `gf`
+--- - fuzzy finding
+---
+--- # Setup ~
+---
+--- Initialize the plugin via `require("forester").setup()`
+---
+--- In your `forest.toml`, add the list of prefixes you wish to use:
+--- >toml
+--- prefixes = ["foo", "bar"]
+--- <
+--- This plugin currently does not support user configuration via lua.
+--- I think it is preferrable to use the forester configuration files and
+--- extracting the relevant keys via treesitter
+---
+
local completionSource = require("forester.completion")
local commands = require("forester.commands")
local ui = require("forester.ui")
@@ -22,6 +44,7 @@ end
local function setup()
vim.filetype.add({ extension = { tree = "forester" } })
+ local forester_group = vim.api.nvim_create_augroup("ForesterGroup", { clear = true })
local cfg = config.find_default_config()
if cfg ~= "" then
@@ -45,6 +68,24 @@ local function setup()
})
end
+ -- Make links followable with `gf`
+ local add_treedirs_to_path = function()
+ pcall(function()
+ local dirs = config.tree_dirs()
+ for _, v in pairs(dirs) do
+ vim.opt.path:append(v)
+ end
+ end)
+ end
+
+ vim.api.nvim_create_autocmd("User", {
+ group = forester_group,
+ pattern = "SwitchedForesterConfig",
+ callback = function()
+ add_treedirs_to_path()
+ end,
+ })
+
local cmp = require("cmp")
cmp.register_source("forester", completionSource)
@@ -52,15 +93,9 @@ local function setup()
add_treesitter_config()
- -- Make links followable with `gf`
-
- local _ = pcall(function()
- local dirs = config.tree_dirs()
- for _, v in pairs(dirs) do
- vim.opt.path:append(v)
- end
- end)
vim.opt.suffixesadd:prepend(".tree")
+
+ add_treedirs_to_path()
ui.setup()
end
diff --git a/lua/forester/bindings.lua b/lua/forester/bindings.lua
index acd08b7..6282a7b 100644
--- a/lua/forester/bindings.lua
+++ b/lua/forester/bindings.lua
@@ -11,13 +11,35 @@ local Job = require("plenary.job")
local bindings = {}
+local function init(dir)
+ local d_arg
+ if dir then
+ d_arg = { "--dir", dir }
+ else
+ d_arg = {}
+ end
+ return Job:new({ command = "forester", args = { "init", table.unpack(d_arg) } })
+end
+
local function watch(tree_dir, port)
local _port = port or 1234
return Job:new({ command = "forest", args = { "watch", _port, tree_dir } })
end
-local function build(config)
- local job = Job:new({ command = "forester", args = { "build", config } })
+local function build(config, opts)
+ opts = opts or {}
+ local args = { "build" }
+ if opts.no_assets ~= nil and opts.no_assets then
+ table.insert(args, "--no-assets=true")
+ end
+ if opts.no_theme ~= nil and opts.no_theme then
+ table.insert(args, "--no-theme=true")
+ end
+ if opts.render_only ~= nil then
+ table.insert(args, "--render-only=" .. opts.render_only)
+ end
+ table.insert(args, config)
+ local job = Job:new({ command = "forester", args = args })
job:sync()
return job:result()
end
@@ -119,6 +141,7 @@ local function template(pfx, tmpl_addr, dest, config)
end
bindings.watch = watch
+bindings.init = init
bindings.build = build
bindings.query = query
bindings.query_all = query_all
diff --git a/lua/forester/commands.lua b/lua/forester/commands.lua
index 5e1d111..f61ebd3 100644
--- a/lua/forester/commands.lua
+++ b/lua/forester/commands.lua
@@ -2,12 +2,13 @@ local util = require("forester.util")
local Forester = require("forester.bindings")
local Job = require("plenary.job")
local pickers = require("forester.pickers")
-local Config = require("forester.config")
+local config = require("forester.config")
local M = {}
M.commands = {
+ -- Select the forester configuration file to use
config = function()
- Config.switch_config()
+ config.switch()
end,
build = function()
@@ -31,7 +32,7 @@ M.commands = {
end,
new_random = function()
- local prefixes = Config.all_prefixes()
+ local prefixes = config.all_prefixes()
vim.ui.select(prefixes, { -- TODO: Don't select when #all_prefixes == 1
format_item = function(item)
return item
@@ -43,7 +44,7 @@ M.commands = {
end
else
do
- local path = Config.dir_of_latest_tree_of_prefix(choice)
+ local path = config.dir_of_latest_tree_of_prefix(choice)
local new_tree = Forester.new_random(choice, path, vim.g.forester_current_config)[1]
vim.cmd("edit " .. new_tree)
end
@@ -52,7 +53,7 @@ M.commands = {
end,
new = function()
- local prefixes = Config.all_prefixes()
+ local prefixes = config.all_prefixes()
vim.ui.select(prefixes, { -- TODO: Don't select when #all_prefixes == 1
format_item = function(item)
return item
@@ -64,7 +65,7 @@ M.commands = {
end
else
do
- local path = Config.dir_of_latest_tree_of_prefix(choice)
+ local path = config.dir_of_latest_tree_of_prefix(choice)
local new_tree = Forester.new(choice, path, vim.g.forester_current_config)[1]
vim.cmd("edit " .. new_tree)
end
@@ -73,7 +74,7 @@ M.commands = {
end,
transclude_new = function()
- local prefixes = Config.all_prefixes()
+ local prefixes = config.all_prefixes()
vim.ui.select(prefixes, { -- TODO: Don't select when #all_prefixes == 1
format_item = function(item)
return item
@@ -85,7 +86,7 @@ M.commands = {
end
else
do
- local path = Config.dir_of_latest_tree_of_prefix(choice)
+ local path = config.dir_of_latest_tree_of_prefix(choice)
local new_tree = Forester.new(choice, path, vim.g.forester_current_config)[1]
local addr = util.filename(new_tree):match("(.+)%..+$")
local content = { "\\transclude{" .. addr .. "}" }
@@ -96,7 +97,7 @@ M.commands = {
end,
link_new = function()
- local prefixes = Config.all_prefixes()
+ local prefixes = config.all_prefixes()
vim.ui.select(prefixes, {
format_item = function(item)
return item
@@ -108,7 +109,7 @@ M.commands = {
end
else
do
- local path = Config.dir_of_latest_tree_of_prefix(choice)
+ local path = config.dir_of_latest_tree_of_prefix(choice)
local new_tree = Forester.new(choice, path)[1]
local addr = util.filename(new_tree):match("(.+)%..+$")
local content = { "[](" .. addr .. ")" } -- NOTE: We should improve the workflow with snippets or something similar
diff --git a/lua/forester/completion.lua b/lua/forester/completion.lua
index 68797fc..e09b8d1 100644
--- a/lua/forester/completion.lua
+++ b/lua/forester/completion.lua
@@ -1,3 +1,4 @@
+--- Autocomplete for builtin functions and tree addresses
local forester = require("forester.bindings")
local config = require("forester.config")
local util = require("forester.util")
diff --git a/lua/forester/config.lua b/lua/forester/config.lua
index a56bf7b..14a691d 100644
--- a/lua/forester/config.lua
+++ b/lua/forester/config.lua
@@ -2,7 +2,6 @@ local pickers = require("forester.pickers")
local Scan = require("plenary.scandir")
local Path = require("plenary.path")
local util = require("forester.util")
---local Config = require("forester.config")
local M = {}
@@ -103,13 +102,14 @@ local function all_prefixes()
return pfxs
end
-local function switch_config()
+local function switch()
local configs = all_configs()
pickers.pick_config(configs)
+ vim.api.nvim_exec_autocmds("User", { pattern = "SwitchedForesterConfig" })
end
M.all_prefixes = all_prefixes
M.tree_dirs = tree_dirs
-M.switch_config = switch_config
+M.switch_config = switch
return M
diff --git a/lua/forester/util.lua b/lua/forester/util.lua
index 774daf1..93d5510 100644
--- a/lua/forester/util.lua
+++ b/lua/forester/util.lua
@@ -1,7 +1,7 @@
-local Scan = require("plenary.scandir")
-local Path = require("plenary.path")
+local scan = require("plenary.scandir")
+local path = require("plenary.path")
-local os_sep = Path.path.sep
+local os_sep = path.path.sep
local M = {}
@@ -17,13 +17,13 @@ local function filename(url)
return url:match("[^/]+$")
end
-local split_path = function(path)
+local split_path = function(p)
-- Returns the Path, Filename, and Extension as 3 values
- return string.match(path, "^(.-)([^\\/]-)(%.[^\\/%.]-)%.?$")
+ return string.match(p, "^(.-)([^\\/]-)(%.[^\\/%.]-)%.?$")
end
-local to_addr = function(path)
- local _, addr, _ = split_path(path)
+local to_addr = function(p)
+ local _, addr, _ = split_path(p)
return addr
end
@@ -188,7 +188,7 @@ local extract_id = function(fname)
end
local highest_in_dir = function(pfx, dir)
- local files = map(Scan.scan_dir(dir), function(file)
+ local files = map(scan.scan_dir(dir), function(file)
local split = vim.split(file, os_sep)
return split[#split]
end)
diff --git a/scripts/docs.lua b/scripts/docs.lua
deleted file mode 100644
index 49e6602..0000000
--- a/scripts/docs.lua
+++ /dev/null
@@ -1,37 +0,0 @@
-local docgen = require("docgen")
-
-local docs = {}
-
-docs.test = function()
- -- Filepaths that should generate docs
- local input_files = {
- "./lua/forester/bindings.lua",
- "./lua/forester/commands.lua",
- "./lua/forester/config.lua",
- "./lua/forester/generate.lua",
- "./lua/forester/navigation.lua",
- "./lua/forester/ui.lua",
- }
-
- -- Maybe sort them that depends what you want and need
- table.sort(input_files, function(a, b)
- return #a < #b
- end)
-
- -- Output file
- local output_file = "./doc/forester.txt"
- local output_file_handle = io.open(output_file, "w")
- assert(output_file_handle, "Could not open " .. output_file)
-
- for _, input_file in ipairs(input_files) do
- docgen.write(input_file, output_file_handle)
- end
-
- output_file_handle:write(" vim:tw=78:ts=8:ft=help:norl:\n")
- output_file_handle:close()
- vim.cmd([[checktime]])
-end
-
-docs.test()
-
-return docs
diff --git a/scripts/minidoc.lua b/scripts/minidoc.lua
new file mode 100644
index 0000000..7386975
--- /dev/null
+++ b/scripts/minidoc.lua
@@ -0,0 +1,17 @@
+local minidoc = require("mini.doc")
+
+if _G.MiniDoc == nil then
+ minidoc.setup()
+end
+
+local hooks = vim.deepcopy(MiniDoc.default_hooks)
+
+hooks.write_pre = function(lines)
+ -- Remove first two lines with `======` and `------` delimiters to comply
+ -- with `:h local-additions` template
+ table.remove(lines, 1)
+ table.remove(lines, 1)
+ return lines
+end
+
+MiniDoc.generate({ "lua/forester/commands.lua", "lua/forester.lua" }, "doc/forester.txt", { hooks = hooks })
diff --git a/scripts/minimal_init.lua b/scripts/minimal_init.lua
index 24ed2d8..6d394b1 100644
--- a/scripts/minimal_init.lua
+++ b/scripts/minimal_init.lua
@@ -1,122 +1,19 @@
-vim.g.mapleader = " "
-
-local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
-if not vim.loop.fs_stat(lazypath) then
- vim.fn.system({
- "git",
- "clone",
- "--filter=blob:none",
- "https://github.com/folke/lazy.nvim.git",
- "--branch=stable",
- lazypath,
- })
-end
-vim.opt.rtp:prepend(lazypath)
-
-require("lazy").setup({
-
- { "L3MON4D3/LuaSnip" },
- { "hrsh7th/nvim-cmp" },
- {
- dir = "./.", -- change this to line to: "kentookura/neovim",
- name = "forester.nvim",
- opts = {
- forests = { "~/glade/notes", "~/forest" }, -- global forest config
- tree_dirs = { "trees" }, -- plugin will check if current directory contains these
- preview = { port = "1234" },
- conceal = true,
- },
- config = function(opts)
- local forester = require("forester").setup()
-
- -- vim.keymap.set("n", "k", require("hover").hover, { desc = "hover.nvim" })
- vim.keymap.set("n", "n.", "Forester browse", { silent = true })
- -- vim.keymap.set("n", "nn", "Forester new", { silent = true })
- -- vim.keymap.set("i", "", "Forester transclude", { silent = true })
- -- vim.keymap.set("i", "", "Forester link", { silent = true })
- end,
- dependencies = {
- { "nvim-telescope/telescope.nvim" },
- { "nvim-treesitter/nvim-treesitter" },
- { "nvim-lua/plenary.nvim" },
- { "hrsh7th/nvim-cmp" },
- { "MunifTanjim/nui.nvim" },
- -- { "lewis6991/hover.nvim" },
- },
- },
- { "nvim-treesitter/nvim-treesitter" },
- { "nvim-lualine/lualine.nvim", dependencies = { "nvim-tree/nvim-web-devicons" } },
- {
- "nvim-neo-tree/neo-tree.nvim",
- config = function()
- require("neo-tree").setup({
- sources = { "filesystem"},
- forest = {
- window = {
- mappings = {
- --
- },
- },
- },
- })
- vim.keymap.set("n", "f", ":Neotree forest")
- vim.keymap.set("n", "\\", ":Neotree toggle")
- end,
- },
- {
- "navarasu/onedark.nvim",
- priority = 1000,
- config = function()
- vim.cmd.colorscheme("onedark")
- end,
- },
-})
-
-local cmp = require("cmp")
-local luasnip = require("luasnip")
-luasnip.config.setup({})
-cmp.setup({
- snippet = {
- expand = function(args)
- luasnip.lsp_expand(args.body)
- end,
- },
- completion = { completeopt = "menu,menuone,noinsert" },
-
- mapping = cmp.mapping.preset.insert({
- [""] = cmp.mapping.select_next_item(),
- [""] = cmp.mapping.select_prev_item(),
- [""] = cmp.mapping.scroll_docs(-4),
- [""] = cmp.mapping.scroll_docs(4),
- [""] = cmp.mapping.complete({}),
- [""] = cmp.mapping.confirm({
- behavior = cmp.ConfirmBehavior.Replace,
- select = true,
- }),
- [""] = cmp.mapping(function(fallback)
- if cmp.visible() then
- cmp.select_next_item()
- elseif luasnip.expand_or_locally_jumpable() then
- luasnip.expand_or_jump()
- else
- fallback()
- end
- end, { "i", "s" }),
- [""] = cmp.mapping(function(fallback)
- if cmp.visible() then
- cmp.select_prev_item()
- elseif luasnip.locally_jumpable(-1) then
- luasnip.jump(-1)
- else
- fallback()
- end
- end, { "i", "s" }),
- }),
-})
-
-require("nvim-web-devicons").setup({ override_by_extension = { ["tree"] = { icon = "🌲" } } })
-require("lualine").setup()
-
-vim.keymap.set("n", "t", "PlenaryTestFile %")
-vim.keymap.set("n", "r", "Lazy reload forester.nvim")
-vim.opt.termguicolors = true
+-- Add current directory to 'runtimepath' to be able to use 'lua' files
+vim.cmd([[let &rtp.=','.getcwd()]])
+
+-- Set up 'mini.test' only when calling headless Neovim (like with `make test`)
+-- if #vim.api.nvim_list_uis() == 0 then
+-- Add 'mini.nvim' to 'runtimepath' to be able to use 'mini.test'
+-- Assumed that 'mini.nvim' is stored in 'deps/mini.nvim'
+vim.cmd("set rtp+=deps/plenary.nvim")
+vim.cmd("set rtp+=deps/mini.nvim")
+vim.cmd("set rtp+=deps/telescope.nvim")
+vim.cmd("set rtp+=deps/nvim-treesitter")
+vim.cmd("set rtp+=scripts/minidoc")
+
+require("nvim-treesitter.configs").setup({ ensure_installed = { "toml" }, auto_install = true, sync_install = true })
+
+require("mini.test").setup()
+require("mini.doc").setup()
+-- require("mini.doc").setup()
+-- end
diff --git a/test/bindings.lua b/test/bindings.lua
deleted file mode 100644
index a000d58..0000000
--- a/test/bindings.lua
+++ /dev/null
@@ -1,42 +0,0 @@
-local forester = require("forester.bindings")
-local util = require("forester.util")
-local scan = require("plenary.scandir")
-
-local tree_dir = "test/trees"
-
-describe("forester bindings", function()
- --describe("complete", function()
- -- it("works", function()
- -- assert(
- -- vim.deep_equal(
- -- forester.titles(tree_dir),
- -- { { addr = "foo-0001", title = "foo" }, { addr = "foo-0002", title = "bar" } }
- -- )
- -- )
- -- end)
- --end)
- --describe("query", function()
- -- it("works", function()
- -- assert(vim.deep_equal(forester.query("prefix", tree_dir), { "foo" }))
- -- end)
- --end)
- describe("new", function()
- it("creates a new tree", function()
- local count = 0
- scan.scan_dir(tree_dir, {
- on_insert = function()
- count = count + 1
- end,
- })
- local output = forester.new("foo", tree_dir)
- vim.print(vim.inspect(output))
- local scan_again = scan.scan_dir(tree_dir, {})
- assert(count + 1 == #scan_again)
- end)
- end)
- --describe("template", function()
- -- it("works", function()
- -- --forester.template("foo", "test", "test")
- -- end)
- --end)
-end)
diff --git a/test/forester.lua b/test/forester.lua
deleted file mode 100644
index eb389b6..0000000
--- a/test/forester.lua
+++ /dev/null
@@ -1,8 +0,0 @@
-local forester = require("forester")
-local util = require("forester.util")
-local scan = require("plenary.scandir")
-
-local tree_dir = "test/trees"
-
-forester.transclude_tree(tree_dir)
-forester.link_tree(tree_dir)
diff --git a/test/init.lua b/test/init.lua
deleted file mode 100644
index 84b3121..0000000
--- a/test/init.lua
+++ /dev/null
@@ -1,101 +0,0 @@
-vim.g.mapleader = " "
-
-local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
-if not vim.loop.fs_stat(lazypath) then
- vim.fn.system({
- "git",
- "clone",
- "--filter=blob:none",
- "https://github.com/folke/lazy.nvim.git",
- "--branch=stable",
- lazypath,
- })
-end
-vim.opt.rtp:prepend(lazypath)
-
-require("lazy").setup({
- {
- dir = "./.", -- change this to line to: "kentookura/neovim",
- name = "forester.nvim",
- config = function()
- local forester = require("forester").setup()
-
- vim.keymap.set("n", "n.", "Forester browse", { silent = true })
- vim.keymap.set("n", "nn", "Forester new", { silent = true })
- -- vim.keymap.set("n", "k", require("hover").hover, { desc = "hover.nvim" })
- -- vim.keymap.set("i", "", "Forester transclude", { silent = true })
- -- vim.keymap.set("i", "", "Forester link", { silent = true })
- end,
- dependencies = {
- { "L3MON4D3/LuaSnip" },
- { "nvim-telescope/telescope.nvim" },
- {
- "nvim-telescope/telescope-fzf-native.nvim",
- build = "make",
- cond = function()
- return vim.fn.executable("make") == 1
- end,
- },
- { "nvim-treesitter/nvim-treesitter" },
- { "nvim-lua/plenary.nvim" },
- { "hrsh7th/nvim-cmp" },
- { "MunifTanjim/nui.nvim" },
- -- { "lewis6991/hover.nvim" },
- },
- },
- { "nvim-treesitter/nvim-treesitter" },
-})
-
-local cmp = require("cmp")
-local luasnip = require("luasnip")
-
-cmp.setup({
- snippet = {
- expand = function(args)
- luasnip.lsp_expand(args.body)
- end,
- },
- completion = {
- completeopt = "menu,menuone,noinsert",
- },
- mapping = cmp.mapping.preset.insert({
- [""] = cmp.mapping.select_next_item(),
- [""] = cmp.mapping.select_prev_item(),
- [""] = cmp.mapping.scroll_docs(-4),
- [""] = cmp.mapping.scroll_docs(4),
- [""] = cmp.mapping.complete({}),
- [""] = cmp.mapping.confirm({
- behavior = cmp.ConfirmBehavior.Replace,
- select = true,
- }),
- [""] = cmp.mapping(function(fallback)
- if cmp.visible() then
- cmp.select_next_item()
- elseif luasnip.expand_or_locally_jumpable() then
- luasnip.expand_or_jump()
- else
- fallback()
- end
- end, { "i", "s" }),
- [""] = cmp.mapping(function(fallback)
- if cmp.visible() then
- cmp.select_prev_item()
- elseif luasnip.locally_jumpable(-1) then
- luasnip.jump(-1)
- else
- fallback()
- end
- end, { "i", "s" }),
- }),
- sources = {
- { name = "nvim_lsp" },
- { name = "luasnip" },
- { name = "path" },
- { name = "forester" },
- },
-})
-
---require("nvim-web-devicons").setup({ override_by_extension = { ["tree"] = { icon = "🌲" } } })
-vim.keymap.set("n", "t", "PlenaryTestFile %")
-vim.keymap.set("n", "r", "Lazy reload forester.nvim")
-vim.opt.termguicolors = true
diff --git a/test/util.lua b/test/util.lua
deleted file mode 100644
index f2ae1d4..0000000
--- a/test/util.lua
+++ /dev/null
@@ -1,29 +0,0 @@
-local forester = require("forester")
-local util = require("forester.util")
-local scan = require("plenary.scandir")
-
-describe("forester functions", function()
- describe("pad_addr", function()
- it("works", function()
- assert("0001" == util.pad_addr(1))
- assert("01TA" == util.pad_addr(2350))
- end)
- end)
- describe("next_addr", function()
- it("works", function()
- assert("foo-0002" == util.inc_addr("foo", 1))
- assert("foo-000A" == util.inc_addr("foo", 9))
- assert("foo-000F" == util.inc_addr("foo", 14))
- assert("foo-1000" == util.inc_addr("foo", 46655)) -- base36: ZZZ
- end)
- end)
-
- describe("prev_addr", function()
- it("works", function()
- assert("foo-0001" == util.decr_addr("foo", 2))
- assert("foo-0009" == util.decr_addr("foo", 10))
- assert("foo-000D" == util.decr_addr("foo", 14))
- assert("foo-0ZZY" == util.decr_addr("foo", 46655)) -- base36: ZZZ
- end)
- end)
-end)
diff --git a/tests/test_bindings.lua b/tests/test_bindings.lua
new file mode 100644
index 0000000..3cd2434
--- /dev/null
+++ b/tests/test_bindings.lua
@@ -0,0 +1,47 @@
+local forester = require("forester.bindings")
+local config = require("forester.config")
+local path = require("plenary.path")
+local map = require("forester.util").map
+local expect, eq = MiniTest.expect, MiniTest.expect.equality
+local T = MiniTest.new_set()
+
+local test_forest = path:new("test_forest")
+local cfg = path:new("forest.toml")
+
+local clean_test_forest = function()
+ path.rmdir(test_forest)
+ path.rm(cfg)
+end
+
+local setup_test_forest = function()
+ local p = path:new("trees")
+ p:mkdir()
+ cfg:write(
+ '[forest]\
+trees = ["trees", "foo", "bar"]\
+prefixes = ["test", "pfx"]',
+ "w",
+ 438
+ )
+ vim.g.forester_current_config = "forest.toml"
+end
+
+T["bindings"] = MiniTest.new_set({ hooks = { pre_once = setup_test_forest, post_once = clean_test_forest } })
+
+T["bindings"]["config"] = function()
+ local expected_tree_dirs = { "trees", "foo", "bar" }
+ local cwd = map(expected_tree_dirs, function(p)
+ return path:new(p):absolute()
+ end)
+ eq(config.all_prefixes(), { "test", "pfx" })
+ eq(config.tree_dirs(), cwd)
+end
+
+T["bindings"]["build"] = function()
+ local res = forester.build("forest.toml", { no_assets = true, no_theme = true })
+ eq(res, {})
+end
+
+T["bindings"]["new_tree"] = function() end
+
+return T
diff --git a/tests/test_forester.lua b/tests/test_forester.lua
new file mode 100644
index 0000000..795dc0e
--- /dev/null
+++ b/tests/test_forester.lua
@@ -0,0 +1,15 @@
+local new_set = MiniTest.new_set
+local expect, eq = MiniTest.expect, MiniTest.expect.equality
+
+local T = new_set()
+
+-- Actual tests definitions will go here
+
+T["works"] = function()
+ local x = 1 + 1
+ if x ~= 2 then
+ error("`x` is not equal to 2")
+ end
+end
+
+return T
diff --git a/tests/test_util.lua b/tests/test_util.lua
new file mode 100644
index 0000000..91436fb
--- /dev/null
+++ b/tests/test_util.lua
@@ -0,0 +1,25 @@
+local T = MiniTest.new_set()
+local expect, eq = MiniTest.expect, MiniTest.expect.equality
+
+local util = require("forester.util")
+
+T["pad_addr"] = function()
+ eq("0001", util.pad_addr(1))
+ eq("01TA", util.pad_addr(2350))
+end
+
+T["next_addr"] = function()
+ eq("foo-0002", util.inc_addr("foo", 1))
+ eq("foo-000A", util.inc_addr("foo", 9))
+ eq("foo-000F", util.inc_addr("foo", 14))
+ eq("foo-1000", util.inc_addr("foo", 46655)) -- base36: ZZZ
+end
+
+T["prev_addr"] = function()
+ eq("foo-0001", util.decr_addr("foo", 2))
+ eq("foo-0009", util.decr_addr("foo", 10))
+ eq("foo-000D", util.decr_addr("foo", 14))
+ eq("foo-0ZZY", util.decr_addr("foo", 46655)) -- base36: ZZZ
+end
+
+return T