diff --git a/configuration.nix b/configuration.nix index 2159edc8..594e292f 100644 --- a/configuration.nix +++ b/configuration.nix @@ -175,6 +175,7 @@ isMaximal: { icon-picker.enable = isMaximal; surround.enable = isMaximal; diffview-nvim.enable = true; + yanky-nvim.enable = false; motion = { hop.enable = true; leap.enable = true; diff --git a/docs/release-notes/rl-0.8.md b/docs/release-notes/rl-0.8.md index f5e9d0a0..661aee1d 100644 --- a/docs/release-notes/rl-0.8.md +++ b/docs/release-notes/rl-0.8.md @@ -4,6 +4,7 @@ [typst-preview.nvim]: https://github.com/chomosuke/typst-preview.nvim [render-markdown.nvim]: https://github.com/MeanderingProgrammer/render-markdown.nvim +[yanky.nvim]: https://github.com/gbprod/yanky.nvim - Add [typst-preview.nvim] under `languages.typst.extensions.typst-preview-nvim`. @@ -33,10 +34,13 @@ - Add [](#opt-vim.lsp.lightbulb.autocmd.enable) for manually managing the previously managed lightbulb autocommand. + - A warning will occur if [](#opt-vim.lsp.lightbulb.autocmd.enable) and `vim.lsp.lightbulb.setupOpts.autocmd.enabled` are both set at the same time. Pick only one. +- Add [yanky.nvim] to available plugins, under `vim.utility.yanky-nvim`. + [amadaluzia](https://github.com/amadaluzia): [haskell-tools.nvim]: https://github.com/MrcJkb/haskell-tools.nvim diff --git a/flake.lock b/flake.lock index ee19b7c8..8e5a40d7 100644 --- a/flake.lock +++ b/flake.lock @@ -1836,15 +1836,15 @@ "plugin-nvim-colorizer-lua": { "flake": false, "locked": { - "lastModified": 1735384185, - "narHash": "sha256-quqs3666vQc/4ticc/Z5BHzGxV6UUVE9jVGT07MEMQQ=", - "owner": "NvChad", + "lastModified": 1738229011, + "narHash": "sha256-IEgZnIUeNXRKZ4eV1+KknluyKZj68HBWe1EW+LueuGA=", + "owner": "catgoose", "repo": "nvim-colorizer.lua", - "rev": "8a65c448122fc8fac9c67b2e857b6e830a4afd0b", + "rev": "9b5fe0450bfb2521c6cea29391e5ec571f129136", "type": "github" }, "original": { - "owner": "NvChad", + "owner": "catgoose", "repo": "nvim-colorizer.lua", "type": "github" } @@ -2460,11 +2460,11 @@ "plugin-rustaceanvim": { "flake": false, "locked": { - "lastModified": 1735431742, - "narHash": "sha256-ucZXGbxHtbSKf5n11lL3vb6rD2BxJacIDOgcx32PLzA=", + "lastModified": 1738187731, + "narHash": "sha256-Z4aCPO4MR0Q2ZojT6YBGSa8fb7u5Nd+4Z/rekqhXqDY=", "owner": "mrcjkb", "repo": "rustaceanvim", - "rev": "51c097ebfb65d83baa71f48000b1e5c0a8dcc4fb", + "rev": "4a2f2d2cc04f5b0aa0981f98bb7d002c898318ad", "type": "github" }, "original": { @@ -2761,6 +2761,22 @@ "type": "github" } }, + "plugin-yanky-nvim": { + "flake": false, + "locked": { + "lastModified": 1737126873, + "narHash": "sha256-Gt8kb6sZoNIM2SDWUPyAF5Tw99qMZl+ltUCfyMXgJsU=", + "owner": "gbprod", + "repo": "yanky.nvim", + "rev": "d2696b30e389dced94d5acab728f524a25f308d2", + "type": "github" + }, + "original": { + "owner": "gbprod", + "repo": "yanky.nvim", + "type": "github" + } + }, "root": { "inputs": { "flake-parts": "flake-parts", @@ -2934,6 +2950,7 @@ "plugin-vim-repeat": "plugin-vim-repeat", "plugin-vim-startify": "plugin-vim-startify", "plugin-which-key": "plugin-which-key", + "plugin-yanky-nvim": "plugin-yanky-nvim", "systems": "systems_2" } }, diff --git a/flake.nix b/flake.nix index 4372eee4..07d86a16 100644 --- a/flake.nix +++ b/flake.nix @@ -590,6 +590,11 @@ flake = false; }; + plugin-yanky-nvim = { + url = "github:gbprod/yanky.nvim"; + flake = false; + }; + # Note-taking plugin-obsidian-nvim = { url = "github:epwalsh/obsidian.nvim"; @@ -640,7 +645,7 @@ }; plugin-nvim-colorizer-lua = { - url = "github:NvChad/nvim-colorizer.lua"; + url = "github:catgoose/nvim-colorizer.lua"; flake = false; }; diff --git a/modules/plugins/languages/tex/default.nix b/modules/plugins/languages/tex/default.nix index 98ac5f1c..518361d7 100644 --- a/modules/plugins/languages/tex/default.nix +++ b/modules/plugins/languages/tex/default.nix @@ -13,6 +13,7 @@ in { ./treesitter.nix ./lsp ./build + ./pdfViewer ]; options.vim.languages.tex = { diff --git a/modules/plugins/languages/tex/lsp/texlab.nix b/modules/plugins/languages/tex/lsp/texlab.nix index 58c55f5a..06b8819e 100644 --- a/modules/plugins/languages/tex/lsp/texlab.nix +++ b/modules/plugins/languages/tex/lsp/texlab.nix @@ -226,31 +226,34 @@ in { package = mkOption { type = package; - default = pkgs.okular; + default = cfg.pdfViewer.package; description = '' The package to use as your PDF viewer. This viewer needs to support Synctex. + + By default it is set to the package of the pdfViewer option. ''; }; executable = mkOption { type = str; - default = "okular"; + default = cfg.pdfViewer.executable; description = '' Defines the executable of the PDF previewer. The previewer needs to support SyncTeX. + + By default it is set to the executable of the pdfViewer option. ''; }; args = mkOption { type = listOf str; - default = [ - "--unique" - "file:%p#src:%l%f" - ]; + default = cfg.pdfViewer.args; description = '' Defines additional arguments that are passed to the configured previewer to perform the forward search. The placeholders %f, %p, %l will be replaced by the server. + By default it is set to the args of the pdfViewer option. + Placeholders: - %f: The path of the current TeX file. - %p: The path of the current PDF file. diff --git a/modules/plugins/languages/tex/pdfViewer/custom.nix b/modules/plugins/languages/tex/pdfViewer/custom.nix new file mode 100644 index 00000000..ec4b331b --- /dev/null +++ b/modules/plugins/languages/tex/pdfViewer/custom.nix @@ -0,0 +1,42 @@ +{ + pkgs, + lib, + ... +} @ moduleInheritencePackage: let + # The name of the pdf viewer + name = "custom"; + + # The viewer template + template = import ./viewerTemplate.nix; + + inherit (lib.options) mkOption mkEnableOption; + inherit (lib.types) package str listOf; +in ( + template { + inherit name moduleInheritencePackage; + + options = { + enable = mkEnableOption "enable using a custom pdf viewer."; + + package = mkOption { + type = package; + example = pkgs.okular; + description = "custom viewer package"; + }; + + executable = mkOption { + type = str; + example = "okular"; + description = "The executable name to call the viewer."; + }; + + args = mkOption { + type = listOf str; + example = ["--unique" "file:%p#src:%l%f"]; + description = "Arguments to pass to the viewer."; + }; + }; + + argsFunction = viewerCfg: (viewerCfg.args); + } +) diff --git a/modules/plugins/languages/tex/pdfViewer/default.nix b/modules/plugins/languages/tex/pdfViewer/default.nix new file mode 100644 index 00000000..43a16907 --- /dev/null +++ b/modules/plugins/languages/tex/pdfViewer/default.nix @@ -0,0 +1,145 @@ +{ + config, + lib, + ... +}: let + defaultPdfViewerName = "okular"; + + inherit (lib.options) mkOption; + inherit (lib.types) str package listOf; + inherit (builtins) filter isAttrs hasAttr attrNames length elemAt; + + cfg = config.vim.languages.tex; + viewerCfg = cfg.pdfViewer; + + enabledPdfViewersInfo = let + # This function will sort through the pdf viewer options and count how many + # pdf viewers have been enabled. + # If no viewers have been enabled, the count will be 0 and the name of the + # enabled viewer will be the default pdf viewer defined above. + getEnabledPdfViewersInfo = { + enabledPdfViewersCount ? 0, + index ? 0, + pdfViewerNamesList ? ( + filter ( + x: let + y = viewerCfg.${x}; + in ( + isAttrs y + && hasAttr "enable" y + && hasAttr "package" y + && hasAttr "executable" y + && hasAttr "args" y + ) + ) (attrNames viewerCfg) + ), + currentEnabledPdfViewerName ? defaultPdfViewerName, + }: let + # Get the name of the current pdf viewer being checked if it is enabled + currentPdfViewerName = elemAt pdfViewerNamesList index; + + # Get the current pdf viewer object + currentPdfViewer = viewerCfg.${currentPdfViewerName}; + + # Get the index that will be used for the next iteration + nextIndex = index + 1; + + # Increment the count that is recording the number of enabled pdf viewers if + # this viewer is enabled, otherwise leave it as is. + newEnabledPdfViewersCount = + if currentPdfViewer.enable + then + if enabledPdfViewersCount > 0 + then throw "nvf-tex-language does not support having more than 1 pdf viewer enabled!" + else enabledPdfViewersCount + 1 + else enabledPdfViewersCount; + + # If this pdf viewer is enabled, set is as the enabled viewer. + newEnabledPdfViewerName = + if currentPdfViewer.enable + then currentPdfViewerName + else currentEnabledPdfViewerName; + in + # Check that the end of the list of viewers has not been reached + if length pdfViewerNamesList > nextIndex + # If the end of the viewers list has not been reached, call the next iteration + # of the function to process the next viewer + then + getEnabledPdfViewersInfo { + inherit pdfViewerNamesList; + enabledPdfViewersCount = newEnabledPdfViewersCount; + index = nextIndex; + currentEnabledPdfViewerName = newEnabledPdfViewerName; + } + # If the end of the viewers list has been reached, then return the total number + # of viewers that have been enabled and the name of the last viewer that was enabled. + else { + count = newEnabledPdfViewersCount; + enabledViewerName = newEnabledPdfViewerName; + }; + in (getEnabledPdfViewersInfo {}); + + enabledPdfViewerCfg = viewerCfg.${enabledPdfViewersInfo.enabledViewerName}; +in { + imports = [ + ./custom.nix + ./okular.nix + ./sioyek.nix + ./qpdfview.nix + ./zathura.nix + ]; + + options.vim.languages.tex.pdfViewer = { + name = mkOption { + type = str; + default = enabledPdfViewerCfg.name; + description = '' + The name of the pdf viewer to use. + + This value will be automatically set when any of the viewers are enabled. + + Setting this option option manually is not recommended but can be used for some very technical nix-ing. + If you wish to use a custom viewer, please use the `custom` entry provided under `viewers`. + ''; + }; + + package = mkOption { + type = package; + default = enabledPdfViewerCfg.package; + description = '' + The package of the pdf viewer to use. + + This value will be automatically set when any of the viewers are enabled. + + Setting this option option manually is not recommended but can be used for some very technical nix-ing. + If you wish to use a custom viewer, please use the `custom` entry provided under `viewers`. + ''; + }; + + executable = mkOption { + type = str; + default = enabledPdfViewerCfg.executable; + description = '' + The executable for the pdf viewer to use. + + This value will be automatically set when any of the viewers are enabled. + + Setting this option option manually is not recommended but can be used for some very technical nix-ing. + If you wish to use a custom viewer, please use the `custom` entry provided under `viewers`. + ''; + }; + + args = mkOption { + type = listOf str; + default = enabledPdfViewerCfg.args; + description = '' + The command line arguments to use when calling the pdf viewer command. + + This value will be automatically set when any of the viewers are enabled. + + Setting this option option manually is not recommended but can be used for some very technical nix-ing. + If you wish to use a custom viewer, please use the `custom` entry provided under `viewers`. + ''; + }; + }; +} diff --git a/modules/plugins/languages/tex/pdfViewer/okular.nix b/modules/plugins/languages/tex/pdfViewer/okular.nix new file mode 100644 index 00000000..74cb88b7 --- /dev/null +++ b/modules/plugins/languages/tex/pdfViewer/okular.nix @@ -0,0 +1,42 @@ +{ + pkgs, + lib, + ... +} @ moduleInheritencePackage: let + # The name of the pdf viewer + name = "okular"; + + # The viewer template + template = import ./viewerTemplate.nix; + + inherit (lib.options) mkOption mkEnableOption; + inherit (lib.types) package str listOf; +in ( + template { + inherit name moduleInheritencePackage; + + options = { + enable = mkEnableOption "enable okular as the pdf file previewer."; + + package = mkOption { + type = package; + default = pkgs.okular; + description = "okular package"; + }; + + executable = mkOption { + type = str; + default = "okular"; + description = "The executable name to call the viewer."; + }; + + args = mkOption { + type = listOf str; + default = ["--unique" "file:%p#src:%l%f"]; + description = "Arguments to pass to the viewer."; + }; + }; + + argsFunction = viewerCfg: (viewerCfg.args); + } +) diff --git a/modules/plugins/languages/tex/pdfViewer/qpdfview.nix b/modules/plugins/languages/tex/pdfViewer/qpdfview.nix new file mode 100644 index 00000000..dafe93f4 --- /dev/null +++ b/modules/plugins/languages/tex/pdfViewer/qpdfview.nix @@ -0,0 +1,42 @@ +{ + pkgs, + lib, + ... +} @ moduleInheritencePackage: let + # The name of the pdf viewer + name = "qpdfview"; + + # The viewer template + template = import ./viewerTemplate.nix; + + inherit (lib.options) mkOption mkEnableOption; + inherit (lib.types) package str listOf; +in ( + template { + inherit name moduleInheritencePackage; + + options = { + enable = mkEnableOption "enable qpdfview as the pdf file previewer."; + + package = mkOption { + type = package; + default = pkgs.qpdfview; + description = "qpdfview package"; + }; + + executable = mkOption { + type = str; + default = "qpdfview"; + description = "The executable name to call the viewer."; + }; + + args = mkOption { + type = listOf str; + default = ["--unique" "%p#src:%f:%l:1"]; + description = "Arguments to pass to the viewer."; + }; + }; + + argsFunction = viewerCfg: (viewerCfg.args); + } +) diff --git a/modules/plugins/languages/tex/pdfViewer/sioyek.nix b/modules/plugins/languages/tex/pdfViewer/sioyek.nix new file mode 100644 index 00000000..9ea9f3f8 --- /dev/null +++ b/modules/plugins/languages/tex/pdfViewer/sioyek.nix @@ -0,0 +1,59 @@ +{ + pkgs, + lib, + ... +} @ moduleInheritencePackage: let + # The name of the pdf viewer + name = "sioyek"; + + # The viewer template + template = import ./viewerTemplate.nix; + + inherit (lib.options) mkOption mkEnableOption; + inherit (lib.types) package str listOf; +in ( + template { + inherit name moduleInheritencePackage; + + options = { + enable = mkEnableOption "enable sioyek as the pdf file previewer."; + + package = mkOption { + type = package; + default = pkgs.sioyek; + description = "sioyek package"; + }; + + executable = mkOption { + type = str; + default = "sioyek"; + description = "The executable name to call the viewer."; + }; + + args = mkOption { + type = listOf str; + default = [ + "--reuse-window" + "--execute-command" + "toggle_synctex" + "--inverse-search" + "texlab inverse-search -i \"%%1\" -l %%2" + "--forward-search-file" + "%f" + "--forward-search-line" + "%l" + "%p" + ]; + description = '' + Arguments to pass to the viewer. + + By default, this is the only viewer that supports the inverse search feature by + command line arguments and doesn't explicitly require extra tinkering else where + in your config. + ''; + }; + }; + + argsFunction = viewerCfg: (viewerCfg.args); + } +) diff --git a/modules/plugins/languages/tex/pdfViewer/viewerTemplate.nix b/modules/plugins/languages/tex/pdfViewer/viewerTemplate.nix new file mode 100644 index 00000000..7b2ba93b --- /dev/null +++ b/modules/plugins/languages/tex/pdfViewer/viewerTemplate.nix @@ -0,0 +1,67 @@ +# This function acts as a template for creating new pdf viewers. +# It enforces providing all the parameters required for creating +# a new pdf viewer for it to be able to work in the existing code. +# +# The first layer requirements are as follows: +{ + # This is the name of the pdf viewer, it will only be used internally and + # MUST match the .nix file that the pdf viewer is implemented in. + name, + # + # Module attribute set. This is the attribute set that the module that is + # defining a pdf viewer is passed as its input. + moduleInheritencePackage, + # + # These are the standard options for the pdf viewer just like creating any + # other module. Some options are required and are described below but + # it will also accept any other options that are provided to it. + options, + # + # These are the command line arguments that will accompany the executable + # when the view command is called. + # This is a function that will take in the cfg of its own pdf viewer. + # i.e. it will be called as "args cfg.pdfViewer.${name}" + argsFunction, + ... +}: let + # Inherit the necessary variables available to any module. + inherit (moduleInheritencePackage) lib config; + # + # Inherit other useful functions. + inherit (lib.modules) mkIf; + # + # Set the cfg variable + cfg = config.vim.languages.tex; + # + # Set the cfg of the viewer itself + viewerCfg = cfg.pdfViewer.${name}; +in { + # These are the options for the pdf viewer. It will accept any options + # provided to it but some options are mandatory: + options.vim.languages.tex.pdfViewer.${name} = ({ + # The enable option. This one is self explanatory. + enable, + # + # This is the package option for the pdf viewer. + package, + # + # This is the executable that will be used to call the pdf viewer. + # It, along with package will result in: + # "/bin/" + executable, + # + # Any other options provided are accepted. + ... + } @ opts: + opts) + options; + + # Check that the language and this pdf viewer have been enabled before making any config. + config = mkIf (cfg.enable && viewerCfg.enable) { + vim.languages.tex.pdfViewer = { + inherit name; + inherit (viewerCfg) package executable; + args = argsFunction viewerCfg; + }; + }; +} diff --git a/modules/plugins/languages/tex/pdfViewer/zathura.nix b/modules/plugins/languages/tex/pdfViewer/zathura.nix new file mode 100644 index 00000000..b1589b5a --- /dev/null +++ b/modules/plugins/languages/tex/pdfViewer/zathura.nix @@ -0,0 +1,42 @@ +{ + pkgs, + lib, + ... +} @ moduleInheritencePackage: let + # The name of the pdf viewer + name = "zathura"; + + # The viewer template + template = import ./viewerTemplate.nix; + + inherit (lib.options) mkOption mkEnableOption; + inherit (lib.types) package str listOf; +in ( + template { + inherit name moduleInheritencePackage; + + options = { + enable = mkEnableOption "enable zathura as the pdf file previewer."; + + package = mkOption { + type = package; + default = pkgs.zathura; + description = "zathura package"; + }; + + executable = mkOption { + type = str; + default = "zathura"; + description = "The executable name to call the viewer."; + }; + + args = mkOption { + type = listOf str; + default = ["--synctex-forward" "%l:1:%f" "%p"]; + description = "Arguments to pass to the viewer."; + }; + }; + + argsFunction = viewerCfg: (viewerCfg.args); + } +) diff --git a/modules/plugins/utility/default.nix b/modules/plugins/utility/default.nix index 8b25ea8f..65ef8680 100644 --- a/modules/plugins/utility/default.nix +++ b/modules/plugins/utility/default.nix @@ -1,19 +1,19 @@ { imports = [ - ./outline ./binds ./ccc + ./diffview + ./fzf-lua ./gestures - ./motion - ./new-file-template - ./telescope ./icon-picker ./images - ./telescope - ./diffview - ./wakatime - ./surround + ./motion + ./new-file-template + ./outline ./preview - ./fzf-lua + ./surround + ./telescope + ./wakatime + ./yanky-nvim ]; } diff --git a/modules/plugins/utility/yanky-nvim/config.nix b/modules/plugins/utility/yanky-nvim/config.nix new file mode 100644 index 00000000..138fd07d --- /dev/null +++ b/modules/plugins/utility/yanky-nvim/config.nix @@ -0,0 +1,32 @@ +{ + config, + pkgs, + lib, + ... +}: let + inherit (lib.modules) mkIf; + inherit (lib.lists) optionals concatLists; + inherit (lib.nvim.lua) toLuaObject; + inherit (lib.nvim.dag) entryAnywhere; + + cfg = config.vim.utility.yanky-nvim; + usingSqlite = cfg.setupOpts.ring.storage == "sqlite"; +in { + config = mkIf cfg.enable { + vim = { + # TODO: this could probably be lazyloaded. I'm not yet sure which event is + # ideal, so it's loaded normally for now. + startPlugins = concatLists [ + ["yanky-nvim"] + + # If using the sqlite backend, sqlite-lua must be loaded + # alongside yanky. + (optionals usingSqlite [pkgs.vimPlugins.sqlite-lua]) + ]; + + pluginRC.yanky-nvim = entryAnywhere '' + require("yanky").setup(${toLuaObject cfg.setupOpts}); + ''; + }; + }; +} diff --git a/modules/plugins/utility/yanky-nvim/default.nix b/modules/plugins/utility/yanky-nvim/default.nix new file mode 100644 index 00000000..05cb2bea --- /dev/null +++ b/modules/plugins/utility/yanky-nvim/default.nix @@ -0,0 +1,6 @@ +{ + imports = [ + ./config.nix + ./yanky-nvim.nix + ]; +} diff --git a/modules/plugins/utility/yanky-nvim/yanky-nvim.nix b/modules/plugins/utility/yanky-nvim/yanky-nvim.nix new file mode 100644 index 00000000..95d6a211 --- /dev/null +++ b/modules/plugins/utility/yanky-nvim/yanky-nvim.nix @@ -0,0 +1,28 @@ +{lib, ...}: let + inherit (lib.options) mkEnableOption mkOption; + inherit (lib.types) enum; +in { + options.vim.utility.yanky-nvim = { + enable = mkEnableOption '' + improved Yank and Put functionalities for Neovim [yanky-nvim] + ''; + + setupOpts = { + ring.storage = mkOption { + type = enum ["shada" "sqlite" "memory"]; + default = "shada"; + example = "sqlite"; + description = '' + storage mode for ring values. + + - shada: this will save pesistantly using Neovim ShaDa feature. + This means that history will be persisted between each session of Neovim. + - memory: each Neovim instance will have his own history and it will be + lost between sessions. + - sqlite: more reliable than `shada`, requires `sqlite.lua` as a dependency. + nvf will add this dependency to `PATH` automatically. + ''; + }; + }; + }; +}