From ed3be410c591c9bfaf28fcaec29c0ef47b7dbb09 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Mon, 9 Dec 2024 09:28:18 +0300 Subject: [PATCH 01/10] meta: update release info (0.8) --- release.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release.json b/release.json index 28c5eb7f..a80b41ea 100644 --- a/release.json +++ b/release.json @@ -1,4 +1,4 @@ { - "release": "v0.7", - "isReleaseBranch": true + "release": "v0.8", + "isReleaseBranch": false } From a36935236564323b3fa37d5be9056bc91e18c7f7 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Mon, 9 Dec 2024 09:28:23 +0300 Subject: [PATCH 02/10] languages/typst: add `typst-preview.nvim` as an extension --- docs/release-notes/rl-0.8.md | 8 ++++ flake.lock | 17 ++++++++ flake.nix | 5 +++ modules/plugins/languages/typst.nix | 62 +++++++++++++++++++++++++++-- 4 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 docs/release-notes/rl-0.8.md diff --git a/docs/release-notes/rl-0.8.md b/docs/release-notes/rl-0.8.md new file mode 100644 index 00000000..128ecd19 --- /dev/null +++ b/docs/release-notes/rl-0.8.md @@ -0,0 +1,8 @@ +# Release 0.8 {#sec-release-0.8} + +[NotAShelf](https://github.com/notashelf): + +[typst-preview.nvim]: https://github.com/chomosuke/typst-preview.nvim + +- Add [typst-preview.nvim] under + `languages.typst.extensions.typst-preview-nvim`. diff --git a/flake.lock b/flake.lock index e84beb3a..d5532b4b 100644 --- a/flake.lock +++ b/flake.lock @@ -1902,6 +1902,22 @@ "type": "github" } }, + "plugin-typst-preview-nvim": { + "flake": false, + "locked": { + "lastModified": 1733120663, + "narHash": "sha256-uYMZ2PONiiI3UDvCgNvyy4+jhzmUDbAyxX0phKxELXw=", + "owner": "chomosuke", + "repo": "typst-preview.nvim", + "rev": "0cb5f5627312f50ce089f785ec42b55a85f30ce7", + "type": "github" + }, + "original": { + "owner": "chomosuke", + "repo": "typst-preview.nvim", + "type": "github" + } + }, "plugin-vim-dirtytalk": { "flake": false, "locked": { @@ -2151,6 +2167,7 @@ "plugin-tokyonight": "plugin-tokyonight", "plugin-trouble": "plugin-trouble", "plugin-ts-error-translator": "plugin-ts-error-translator", + "plugin-typst-preview-nvim": "plugin-typst-preview-nvim", "plugin-vim-dirtytalk": "plugin-vim-dirtytalk", "plugin-vim-fugitive": "plugin-vim-fugitive", "plugin-vim-illuminate": "plugin-vim-illuminate", diff --git a/flake.nix b/flake.nix index e52f9416..65c802f2 100644 --- a/flake.nix +++ b/flake.nix @@ -206,6 +206,11 @@ flake = false; }; + plugin-typst-preview-nvim = { + url = "github:chomosuke/typst-preview.nvim"; + flake = false; + }; + plugin-nvim-metals = { url = "github:scalameta/nvim-metals"; flake = false; diff --git a/modules/plugins/languages/typst.nix b/modules/plugins/languages/typst.nix index fbb090e8..24097e2c 100644 --- a/modules/plugins/languages/typst.nix +++ b/modules/plugins/languages/typst.nix @@ -7,10 +7,13 @@ inherit (lib.options) mkEnableOption mkOption; inherit (lib.modules) mkIf mkMerge; inherit (lib.lists) isList; - inherit (lib.types) enum either listOf package str; + inherit (lib.types) nullOr enum either attrsOf listOf package str; inherit (lib.attrsets) attrNames; - inherit (lib.nvim.lua) expToLua; - inherit (lib.nvim.types) mkGrammarOption; + inherit (lib.generators) mkLuaInline; + inherit (lib.meta) getExe; + inherit (lib.nvim.lua) expToLua toLuaObject; + inherit (lib.nvim.types) mkGrammarOption mkPluginSetupOption; + inherit (lib.nvim.dag) entryAnywhere; cfg = config.vim.languages.typst; @@ -33,6 +36,7 @@ } ''; }; + tinymist = { package = pkgs.tinymist; lspConfig = '' @@ -120,6 +124,50 @@ in { default = formats.${cfg.format.type}.package; }; }; + + extensions = { + typst-preview-nvim = { + enable = + mkEnableOption '' + [typst-preview.nvim]: https://github.com/chomosuke/typst-preview.nvim + + Low latency typst preview for Neovim via [typst-preview.nvim] + '' + // {default = true;}; + + setupOpts = mkPluginSetupOption "typst-preview-nvim" { + open_cmd = mkOption { + type = nullOr str; + default = null; + example = "firefox %s -P typst-preview --class typst-preview"; + description = '' + Custom format string to open the output link provided with `%s` + ''; + }; + + dependencies_bin = mkOption { + type = attrsOf str; + default = { + "tinymist" = getExe servers.tinymist.package; + "websocat" = getExe pkgs.websocat; + }; + + description = '' + Provide the path to binaries for dependencies. Setting this + to a non-null value will skip the download of the binary by + the plugin. + ''; + }; + + extra_args = mkOption { + type = nullOr (listOf str); + default = null; + example = ["--input=ver=draft" "--ignore-system-fonts"]; + description = "A list of extra arguments (or `null`) to be passed to previewer"; + }; + }; + }; + }; }; config = mkIf cfg.enable (mkMerge [ (mkIf cfg.treesitter.enable { @@ -136,5 +184,13 @@ in { vim.lsp.lspconfig.enable = true; vim.lsp.lspconfig.sources.typst-lsp = servers.${cfg.lsp.server}.lspConfig; }) + + # Extensions + (mkIf cfg.extensions.typst-preview-nvim.enable { + vim.startPlugins = ["typst-preview-nvim"]; + vim.pluginRC.typst-preview-nvim = entryAnywhere '' + require("typst-preview").setup(${toLuaObject cfg.extensions.typst-preview-nvim.setupOpts}) + ''; + }) ]); } From 37dc96575d3b9960df8b3abef16ede47832f9ba4 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Mon, 9 Dec 2024 10:27:01 +0300 Subject: [PATCH 03/10] docs: add search widget to options page --- .editorconfig | 2 +- docs/manual.nix | 4 +++- docs/static/script/search.js | 40 ++++++++++++++++++++++++++++++++++++ docs/static/style.scss | 18 ++++++++++++++++ 4 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 docs/static/script/search.js diff --git a/.editorconfig b/.editorconfig index 5f4be94c..43456223 100644 --- a/.editorconfig +++ b/.editorconfig @@ -14,7 +14,7 @@ indent_style = space indent_size = 2 trim_trailing_whitespace = false -[*.{nix,yml,yaml}] +[*.{js,nix,yml,yaml}] indent_style = space indent_size = 2 tab_width = 2 diff --git a/docs/manual.nix b/docs/manual.nix index 113fb789..4becdf2d 100644 --- a/docs/manual.nix +++ b/docs/manual.nix @@ -62,7 +62,8 @@ in # Copy anchor scripts to the script directory in document root. cp -vt "$dest"/script \ ${./static/script}/anchor-min.js \ - ${./static/script}/anchor-use.js + ${./static/script}/anchor-use.js \ + ${./static/script}/search.js substituteInPlace ./options.md \ --subst-var-by OPTIONS_JSON ./config-options.json @@ -100,6 +101,7 @@ in --script highlightjs/loader.js \ --script script/anchor-use.js \ --script script/anchor-min.js \ + --script script/search.js \ --toc-depth 2 \ --section-toc-depth 1 \ manual.md \ diff --git a/docs/static/script/search.js b/docs/static/script/search.js new file mode 100644 index 00000000..34ce28bd --- /dev/null +++ b/docs/static/script/search.js @@ -0,0 +1,40 @@ +document.addEventListener("DOMContentLoaded", () => { + if (!window.location.pathname.endsWith("options.html")) return; + + const searchBar = document.createDocumentFragment(); + const searchDiv = document.createElement("div"); + searchDiv.id = "search-bar"; + searchDiv.innerHTML = ` + +
+ `; + searchBar.appendChild(searchDiv); + document.body.prepend(searchDiv); + + const dtElements = Array.from(document.querySelectorAll("dt")); + const ddElements = Array.from(document.querySelectorAll("dd")); + const dtOptionIds = dtElements.map( + (dt) => dt.querySelector("a")?.id.toLowerCase() || "", + ); + + if (dtElements.length === 0 || ddElements.length === 0) { + console.warn("Something went wrong, page may be loaded incorrectly."); + return; + } + + let debounceTimeout; + document.getElementById("search-input").addEventListener("input", (event) => { + clearTimeout(debounceTimeout); + debounceTimeout = setTimeout(() => { + const query = event.target.value.toLowerCase(); + dtElements.forEach((dt, index) => { + const isMatch = dtOptionIds[index].includes(query); + + if (dt.classList.contains("hidden") !== !isMatch) { + dt.classList.toggle("hidden", !isMatch); + ddElements[index]?.classList.toggle("hidden", !isMatch); + } + }); + }, 200); + }); +}); diff --git a/docs/static/style.scss b/docs/static/style.scss index 718302f3..3b148739 100644 --- a/docs/static/style.scss +++ b/docs/static/style.scss @@ -233,6 +233,24 @@ li { } } +#search-bar { + position: sticky; + top: 0; + background: white; + padding: 10px; + border-bottom: 1px solid #ccc; + z-index: 1000; +} +#search-input { + width: 100%; + padding: 8px; + border: 1px solid #ccc; + border-radius: 4px; +} +.hidden { + display: none; +} + div.titlepage { margin: 40px 0; From 0a3855cdc277b3cb402a22850f943c31f9f8f700 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Tue, 10 Dec 2024 12:46:50 +0300 Subject: [PATCH 04/10] docs: properly theme searchbar on prefers-dark --- docs/static/style.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/static/style.scss b/docs/static/style.scss index 3b148739..1c0b57e5 100644 --- a/docs/static/style.scss +++ b/docs/static/style.scss @@ -240,13 +240,19 @@ li { padding: 10px; border-bottom: 1px solid #ccc; z-index: 1000; + @media (prefers-color-scheme: dark) { + background: $color-gray-900; + color: $color-gray-50; + } } + #search-input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; } + .hidden { display: none; } From 9fad42374f3f4cdaa67ec13483824896ba55f174 Mon Sep 17 00:00:00 2001 From: Ching Pei Yang Date: Tue, 10 Dec 2024 11:34:18 +0100 Subject: [PATCH 05/10] docs: fix search bar style in dark mode --- docs/static/style.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/static/style.scss b/docs/static/style.scss index 1c0b57e5..d5f739e5 100644 --- a/docs/static/style.scss +++ b/docs/static/style.scss @@ -251,6 +251,8 @@ li { padding: 8px; border: 1px solid #ccc; border-radius: 4px; + background: inherit; + color: inherit; } .hidden { From 781385f991f26a36102fe289f0e44770ff581ec5 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Tue, 10 Dec 2024 17:15:23 +0300 Subject: [PATCH 06/10] docs: perform DOM manipulation in batches; preprocess data --- docs/static/script/search.js | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/docs/static/script/search.js b/docs/static/script/search.js index 34ce28bd..1537b235 100644 --- a/docs/static/script/search.js +++ b/docs/static/script/search.js @@ -1,14 +1,12 @@ document.addEventListener("DOMContentLoaded", () => { if (!window.location.pathname.endsWith("options.html")) return; - const searchBar = document.createDocumentFragment(); const searchDiv = document.createElement("div"); searchDiv.id = "search-bar"; searchDiv.innerHTML = `
`; - searchBar.appendChild(searchDiv); document.body.prepend(searchDiv); const dtElements = Array.from(document.querySelectorAll("dt")); @@ -22,18 +20,27 @@ document.addEventListener("DOMContentLoaded", () => { return; } + const dtElementsData = dtElements.map((dt, index) => ({ + element: dt, + id: dtOptionIds[index], + ddElement: ddElements[index], + })); + let debounceTimeout; document.getElementById("search-input").addEventListener("input", (event) => { clearTimeout(debounceTimeout); debounceTimeout = setTimeout(() => { const query = event.target.value.toLowerCase(); - dtElements.forEach((dt, index) => { - const isMatch = dtOptionIds[index].includes(query); - if (dt.classList.contains("hidden") !== !isMatch) { - dt.classList.toggle("hidden", !isMatch); - ddElements[index]?.classList.toggle("hidden", !isMatch); - } + requestAnimationFrame(() => { + const fragment = document.createDocumentFragment(); + dtElementsData.forEach(({ element, id, ddElement }) => { + const isMatch = id.includes(query); + if (element.classList.contains("hidden") !== !isMatch) { + element.classList.toggle("hidden", !isMatch); + ddElement?.classList.toggle("hidden", !isMatch); + } + }); }); }, 200); }); From f8e185662017aa3a7a8f2a72b8170c9889ea8a38 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Tue, 10 Dec 2024 23:10:05 +0300 Subject: [PATCH 07/10] docs: better performance in the resource widget ft. Keira and Michaili --- docs/static/script/search.js | 27 +++++++++++++++++++-------- docs/static/style.scss | 11 +++++++---- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/docs/static/script/search.js b/docs/static/script/search.js index 1537b235..e20c2314 100644 --- a/docs/static/script/search.js +++ b/docs/static/script/search.js @@ -26,21 +26,32 @@ document.addEventListener("DOMContentLoaded", () => { ddElement: ddElements[index], })); + const hiddenClass = "hidden"; + const hiddenStyle = document.createElement("style"); + hiddenStyle.innerHTML = `.${hiddenClass} { display: none; }`; + document.head.appendChild(hiddenStyle); + let debounceTimeout; document.getElementById("search-input").addEventListener("input", (event) => { clearTimeout(debounceTimeout); debounceTimeout = setTimeout(() => { const query = event.target.value.toLowerCase(); + const matches = []; + const nonMatches = []; + + dtElementsData.forEach(({ element, id, ddElement }) => { + const isMatch = id.includes(query); + if (isMatch) { + matches.push(element, ddElement); + } else { + nonMatches.push(element, ddElement); + } + }); + requestAnimationFrame(() => { - const fragment = document.createDocumentFragment(); - dtElementsData.forEach(({ element, id, ddElement }) => { - const isMatch = id.includes(query); - if (element.classList.contains("hidden") !== !isMatch) { - element.classList.toggle("hidden", !isMatch); - ddElement?.classList.toggle("hidden", !isMatch); - } - }); + matches.forEach((el) => el?.classList.remove(hiddenClass)); + nonMatches.forEach((el) => el?.classList.add(hiddenClass)); }); }, 200); }); diff --git a/docs/static/style.scss b/docs/static/style.scss index d5f739e5..d6becd0c 100644 --- a/docs/static/style.scss +++ b/docs/static/style.scss @@ -189,14 +189,16 @@ th { dt { margin: 1.2rem 0 0.8rem; + content-visibility: auto; + contain-intrinsic-size: auto 42px; } - dd { margin-left: 2rem; + content-visibility: auto; + contain-intrinsic-size: auto 500px; } -div.book { -} +div.book {} ul { @include margined; @@ -238,11 +240,12 @@ li { top: 0; background: white; padding: 10px; - border-bottom: 1px solid #ccc; + border-bottom: 1px solid $color-gray-200; z-index: 1000; @media (prefers-color-scheme: dark) { background: $color-gray-900; color: $color-gray-50; + border-bottom: 1px solid black; } } From cece170a41f794da8d630b6bb0adc15c6e28dc02 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Tue, 10 Dec 2024 23:21:00 +0300 Subject: [PATCH 08/10] docs: mention lazy-loading capability in README --- .github/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/README.md b/.github/README.md index 029f2fc8..fdc878d6 100644 --- a/.github/README.md +++ b/.github/README.md @@ -69,7 +69,7 @@ [Home-Manager module]: https://notashelf.github.io/nvf/index.xhtml#ch-standalone-hm - **Simple**: One language to rule them all! Use Nix to configure everything, - with additional Lua Support + with optional Lua support for robust configurability! - **Reproducible**: Your configuration will behave the same _anywhere_. No surprises, promise! - **Portable**: nvf depends _solely_ on your Nix store, and nothing else. No @@ -77,8 +77,9 @@ - Options to install [standalone], [NixOS module] or [Home-Manager module]. - **Customizable**: There are _almost no defaults_ to annoy you. nvf is fully customizable through the Nix module system. -- Not comfortable with a full-nix config or want to bring your Lua config? You - can do just that, no unnecessary restrictions. + - Not comfortable with a full-nix config or want to bring your Lua config? You + can do just that, no unnecessary restrictions. + - Lazyloading? We got it! Lazyload both internal and external plugins at will. - **Well-documented**: Documentation is priority. You will _never_ face undocumented, obscure behaviour. - **Idiomatic**: nvf does things ✨ _the right way_ ✨ - the codebase is, and From c3a4686fa18715ff373b0aedc34eb08a6a735e7c Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Tue, 10 Dec 2024 23:34:08 +0300 Subject: [PATCH 09/10] wrapper/rc: use `mkOption` in `enableLuaLoader` description `mkEnableOption` seems to be clobbering the markdown syntax. --- modules/wrapper/rc/options.nix | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/modules/wrapper/rc/options.nix b/modules/wrapper/rc/options.nix index 4680190a..ab541419 100644 --- a/modules/wrapper/rc/options.nix +++ b/modules/wrapper/rc/options.nix @@ -12,22 +12,28 @@ cfg = config.vim; in { options.vim = { - enableLuaLoader = mkEnableOption '' - [{option}`official documentation`]: https://neovim.io/doc/user/lua.html#vim.loader.enable() + enableLuaLoader = mkOption { + type = bool; + default = false; + example = true; + description = '' + [{option}`official documentation`]: https://neovim.io/doc/user/lua.html#vim.loader.enable() - the experimental Lua module loader to speed up the start up process + the experimental Lua module loader to speed up the start up process - If `true`, this will enable the experimental Lua module loader which: - - overrides loadfile - - adds the lua loader using the byte-compilation cache - - adds the libs loader - - removes the default Neovim loader + If `true`, this will enable the experimental Lua module loader which: + - overrides loadfile + - adds the lua loader using the byte-compilation cache + - adds the libs loader + - removes the default Neovim loader - ::: {.note} - This is disabled by default. Before setting this option, please - take a look at the [{option}`official documentation`]. - ::: - ''; + ::: {.note} + The Lua module loader is *disabled* by default. Before setting this option, please + take a look at the [{option}`official documentation`]. This option may be enabled by + default in the future. + ::: + ''; + }; additionalRuntimePaths = mkOption { type = listOf (either path str); From 6567b463ee001d984a7ac9eaf3effe80a557f7b8 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Tue, 10 Dec 2024 23:37:32 +0300 Subject: [PATCH 10/10] docs: update release notes --- docs/release-notes/rl-0.8.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/release-notes/rl-0.8.md b/docs/release-notes/rl-0.8.md index 128ecd19..52a9ae64 100644 --- a/docs/release-notes/rl-0.8.md +++ b/docs/release-notes/rl-0.8.md @@ -6,3 +6,5 @@ - Add [typst-preview.nvim] under `languages.typst.extensions.typst-preview-nvim`. + +- Add a search widget to the options page in the nvf manual.