feat: replace nvim with nvf

This commit is contained in:
danny 2025-09-06 21:37:48 +08:00
parent 7db16b1462
commit 9ed1af62e4
32 changed files with 978 additions and 1299 deletions

View file

@ -59,6 +59,7 @@ in
);
settings = {
"$mainMod" = mainMod;
debug = {
disable_logs = true;
};

763
home/user/nvf.nix Normal file
View file

@ -0,0 +1,763 @@
{
pkgs,
lib,
...
}: let
inherit (lib.generators) mkLuaInline;
suda-nvim = pkgs.vimUtils.buildVimPlugin {
name = "vim-suda";
src = pkgs.fetchFromGitHub {
owner = "lambdalisue";
repo = "vim-suda";
rev = "9adda7d195222d4e2854efb2a88005a120296c47";
hash = "sha256-46sy3rAdOCULVt1RkIoGdweoV3MqQaB33Et9MrxI6Lk=";
};
};
in {
programs.nvf = {
enable = true;
settings = {
vim = {
enableLuaLoader = true;
clipboard = {
enable = true;
providers = {
wl-copy.enable = true;
};
registers = "unnamedplus";
};
extraPlugins = with pkgs.vimPlugins; {
transparent = {
package = transparent-nvim;
setup =
# lua
''
require("transparent").setup({
extra_groups = {
"NormalFloat",
"NvimTreeNormal",
"TreesitterContext",
"FloatBorder",
"FoldColumn",
"Folded",
"BlinkCmpMenu",
"BlinkCmpBorder",
"BlinkCmpKind",
"WarningMsg",
"ErrorMsg",
"BlinkCmpMenuBorder",
"FzfLuaBackdrop",
"VertSplit",
"Pmenu",
"PmenuSbar",
"DiffText",
"DiffViewNormal",
"CursorColumn",
"ColorColumn",
"QuickFixLine",
"Error",
"NoiceScrollbar"
},
})
require("transparent").clear_prefix("NeoTree")
require("transparent").clear_prefix("GitGutter")
'';
};
suda = {
package = suda-nvim;
};
};
keymaps = [
# === Files === #
# Explorer
{
key = "<leader>e";
mode = ["n"];
action = ":Neotree toggle<CR>";
silent = true;
desc = "Toggle file explorer";
}
# Fzf lua
{
key = "<Leader><Space>";
silent = true;
mode = ["n"];
action = ":FzfLua files<CR>";
nowait = true;
unique = true;
desc = "Find file";
}
{
key = "<Leader>/";
mode = ["n"];
action = ":FzfLua live_grep<CR>";
nowait = true;
unique = true;
desc = "Live grep";
}
# Lsp symbol document
{
key = "<Leader>ss";
silent = true;
mode = ["n"];
action = ":FzfLua lsp_document_symbols<CR>";
nowait = true;
unique = true;
desc = "Find symbols (document)";
}
# Lsp symbol workspace
{
key = "<Leader>sS";
silent = true;
mode = ["n"];
action = ":FzfLua lsp_workspace_symbols<CR>";
unique = true;
nowait = true;
desc = "Find symbols (workspace)";
}
# === Buffer === #
{
key = "<Leader>bo";
mode = ["n"];
action = ":BufferLineCloseOther<CR>";
desc = "Close other buffer";
}
{
key = "<Leader>bS";
mode = ["n"];
action = ":SudaWrite<CR>";
desc = "Save file as root";
}
# === General Control === #
# Save file
{
key = "<C-s>";
mode = [
"n"
"i"
"v"
];
action = "<C-\\><C-n>:w<CR>";
desc = "Save file";
}
{
key = "<S-Tab>";
mode = ["i"];
action = "<C-d>";
desc = "Shift left";
}
{
key = "gd";
mode = ["n"];
action = ":FzfLua lsp_definitions<CR>";
nowait = true;
desc = "Go to definition";
}
{
key = "gD";
mode = ["n"];
action = ":FzfLua lsp_declarations<CR>";
nowait = true;
desc = "Go to declaration";
}
{
key = "gi";
mode = ["n"];
action = ":FzfLua lsp_implementations<CR>";
nowait = true;
desc = "Go to implementation";
}
{
key = "gr";
mode = ["n"];
action = ":FzfLua lsp_references<CR>";
nowait = true;
desc = "List references";
}
{
key = "<Leader>n";
mode = ["n"];
action = ":NoiceAll<CR>";
nowait = true;
desc = "Notifications";
}
# === Tab === #
{
key = ">";
mode = ["v"];
action = ">gv";
silent = true;
desc = "Shift right";
}
{
key = "<";
mode = ["v"];
action = "<gv";
silent = true;
desc = "Shift left";
}
# === Terminal === #
{
key = "<C-/>";
mode = ["t"];
action = "<C-\\><C-n>:ToggleTerm<CR>";
}
{
key = "<ESC><ESC>";
mode = ["t"];
action = "<C-\\><C-n>";
}
{
key = "<C-j>";
mode = ["n" "t"];
action = "<C-\\><C-n><C-w>j";
nowait = true;
}
{
key = "<C-k>";
mode = ["n" "t"];
action = "<C-\\><C-n><C-w>k";
nowait = true;
}
{
key = "<C-l>";
mode = ["n" "t"];
action = "<C-\\><C-n><C-w>l";
nowait = true;
}
{
key = "<C-h>";
mode = ["n" "t"];
action = "<C-\\><C-n><C-w>h";
nowait = true;
}
# New Term
{
key = "<Leader>tn";
mode = ["n"];
action = ":TermNew<CR>";
nowait = true;
desc = "Spawn new terminal";
}
# Select Term
{
key = "<Leader>tt";
mode = ["n"];
action = ":TermSelect<CR>";
nowait = true;
desc = "Select terminal";
}
# Send current selection to Term
{
key = "<Leader>ts";
mode = ["v"];
action = ":ToggleTermSendVisualSelection<CR>";
nowait = true;
desc = "Send current selection to terminal";
}
# === Fold (nvim-ufo) === #
{
key = "zR";
mode = ["n"];
action = ''
require("ufo").openAllFolds
'';
lua = true;
}
{
key = "zM";
mode = ["n"];
action = ''
require("ufo").closeAllFolds
'';
lua = true;
}
];
autocmds = [
{
event = ["TextYankPost"];
callback =
mkLuaInline
# lua
''
function()
vim.highlight.on_yank({ higroup = "IncSearch", timeout = 150 })
end
'';
desc = "Highlight yanked";
}
];
globals = {
transparent_enabled = true;
};
vimAlias = true;
options = {
foldcolumn = "0";
foldlevel = 99;
foldlevelstart = 99;
foldenable = true;
spelllang = "en,cjk";
expandtab = true;
tabstop = 2;
softtabstop = 2;
shiftwidth = 2;
autoindent = true;
smartindent = true;
fillchars = "eob: ";
};
lsp = {
enable = true;
formatOnSave = true;
otter-nvim.enable = true;
nvim-docs-view.enable = true;
lspkind.enable = true;
trouble = {
enable = true;
mappings = {
documentDiagnostics = "<Leader>xx";
};
};
};
debugger = {
nvim-dap = {
enable = true;
ui.enable = true;
};
};
diagnostics = {
enable = true;
config = {
float = {
border = "rounded";
};
virtual_text.format =
mkLuaInline
# lua
''
function(diagnostic)
return string.format("%s (%s)", diagnostic.message, diagnostic.source)
end
'';
};
};
languages = {
enableFormat = true;
enableTreesitter = true;
enableExtraDiagnostics = true;
bash.enable = true;
css.enable = true;
rust.enable = true;
nix = {
enable = true;
lsp = {
enable = true;
};
};
sql.enable = true;
clang.enable = true;
ts.enable = true;
python.enable = true;
markdown.enable = true;
html.enable = true;
lua.enable = true;
};
visuals = {
nvim-web-devicons.enable = true;
nvim-cursorline.enable = true;
cinnamon-nvim = {
enable = true;
setupOpts.keymaps = {
basic = true;
};
};
fidget-nvim = {
enable = true;
setupOpts.notification = {
window = {
border = "none";
winblend = 100;
};
};
};
highlight-undo.enable = true;
indent-blankline.enable = true;
};
statusline = {
lualine = {
enable = true;
activeSection = {
a = lib.mkForce [
''
{
"mode",
icons_enabled = true,
separator = {
left = "",
right = ""
},
}
''
''
{
"",
draw_empty = true,
separator = { left = '', right = '' }
}
''
];
b = lib.mkForce [
''
{
"filetype",
colored = true,
icon_only = true,
icon = { align = 'left' }
}
''
''
{
"filename",
symbols = {modified = ' ', readonly = ' '},
separator = { left = '', right = ''}
}
''
''
{
"",
draw_empty = true,
separator = { left = '', right = '' }
}
''
];
c = lib.mkForce [
''
{
"diff",
colored = false,
diff_color = {
-- Same color values as the general color option can be used here.
added = 'DiffAdd', -- Changes the diff's added color
modified = 'DiffChange', -- Changes the diff's modified color
removed = 'DiffDelete', -- Changes the diff's removed color you
},
symbols = {added = '+', modified = '~', removed = '-'}, -- Changes the diff symbols
separator = {right = ''}
}
''
];
x = lib.mkForce [
''
{
-- Lsp server name
function()
local buf_ft = vim.bo.filetype
local excluded_buf_ft = { toggleterm = true, NvimTree = true, ["neo-tree"] = true, TelescopePrompt = true }
if excluded_buf_ft[buf_ft] then
return ""
end
local bufnr = vim.api.nvim_get_current_buf()
local clients = vim.lsp.get_clients({ bufnr = bufnr })
if vim.tbl_isempty(clients) then
return "No Active LSP"
end
local active_clients = {}
for _, client in ipairs(clients) do
table.insert(active_clients, client.name)
end
return table.concat(active_clients, ", ")
end,
icon = ' ',
separator = {left = ''},
}
''
''
{
"diagnostics",
sources = {'nvim_lsp', 'nvim_diagnostic', 'nvim_diagnostic', 'vim_lsp', 'coc'},
symbols = {error = '󰅙 ', warn = ' ', info = ' ', hint = '󰌵 '},
colored = true,
update_in_insert = false,
always_visible = false,
diagnostics_color = {
color_error = { fg = 'red' },
color_warn = { fg = 'yellow' },
color_info = { fg = 'cyan' },
},
}
''
];
y = lib.mkForce [
''
{
"",
draw_empty = true,
separator = { left = '', right = '' }
}
''
''
{
'searchcount',
maxcount = 999,
timeout = 120,
separator = {left = ''}
}
''
''
{
"branch",
icon = ' ',
separator = {left = ''}
}
''
];
z = lib.mkForce [
''
{
"",
draw_empty = true,
separator = { left = '', right = '' }
}
''
''
{
"progress",
separator = {left = ''}
}
''
''
{"location"}
''
''
{
"fileformat",
color = {fg='black'},
symbols = {
unix = '', -- e843
dos = '', -- e70f
mac = '', -- e711
}
}
''
];
};
componentSeparator = {
left = "";
right = "";
};
sectionSeparator = {
left = "";
right = "";
};
};
};
autopairs.nvim-autopairs.enable = true;
autocomplete = {
blink-cmp.enable = true;
};
snippets.luasnip = {
enable = true;
providers = ["blink-cmp"];
setupOpts.enable_autosnippets = true;
};
git = {
enable = true;
};
filetree = {
neo-tree = {
enable = true;
setupOpts = {
window = {
position = "right";
mappings = {
"l" = "open";
"h" = "close_node";
};
};
};
};
};
tabline = {
nvimBufferline = {
enable = true;
setupOpts = {
options = {
show_close_icon = false;
separator_style = "slope";
numbers = "none";
indicator = {
style = "none";
};
diagnostic = "nvim_lsp";
};
};
mappings = {
closeCurrent = "<Leader>bd";
cycleNext = "L";
cyclePrevious = "H";
};
};
};
binds = {
whichKey.enable = true;
};
fzf-lua.enable = true;
dashboard = {
alpha.enable = true;
};
notify = {
nvim-notify = {
enable = true;
setupOpts.background_colour = "#020202";
};
};
projects = {
project-nvim.enable = true;
};
utility = {
diffview-nvim.enable = true;
icon-picker.enable = true;
surround.enable = true;
multicursors.enable = true;
undotree.enable = true;
images = {
img-clip.enable = true;
};
};
notes = {
todo-comments.enable = true;
};
terminal = {
toggleterm = {
enable = true;
lazygit.enable = true;
mappings = {
open = "<C-/>";
};
setupOpts.winbar.name_formatter =
mkLuaInline
# lua
''
function(term)
return " " .. term.id
end
'';
};
};
ui = {
noice = {
enable = true;
setupOpts.routes = [
# Hide neo-tree notification
{
filter = {
event = "notify";
kind = "info";
any = [
{find = "hidden";}
];
};
}
];
};
colorizer.enable = true;
fastaction.enable = true;
nvim-ufo = {
enable = true;
setupOpts = {
fold_virt_text_handler =
mkLuaInline
# lua
''
function(virtText, lnum, endLnum, width, truncate)
local newVirtText = {}
local suffix = (' 󰁂 %d '):format(endLnum - lnum)
local sufWidth = vim.fn.strdisplaywidth(suffix)
local targetWidth = width - sufWidth
local curWidth = 0
for _, chunk in ipairs(virtText) do
local chunkText = chunk[1]
local chunkWidth = vim.fn.strdisplaywidth(chunkText)
if targetWidth > curWidth + chunkWidth then
table.insert(newVirtText, chunk)
else
chunkText = truncate(chunkText, targetWidth - curWidth)
local hlGroup = chunk[2]
table.insert(newVirtText, {chunkText, hlGroup})
chunkWidth = vim.fn.strdisplaywidth(chunkText)
-- str width returned from truncate() may less than 2nd argument, need padding
if curWidth + chunkWidth < targetWidth then
suffix = suffix .. (' '):rep(targetWidth - curWidth - chunkWidth)
end
break
end
curWidth = curWidth + chunkWidth
end
table.insert(newVirtText, {suffix, 'MoreMsg'})
return newVirtText
end
'';
provider_selector =
mkLuaInline
# lua
''
function(bufnr, filetype, buftype)
return {'treesitter', 'indent'}
end
'';
};
};
borders = {
enable = true;
plugins = {
lspsaga.enable = true;
fastaction.enable = true;
lsp-signature.enable = true;
which-key.enable = true;
};
};
};
};
};
};
}

View file

@ -1,393 +0,0 @@
{
lib,
pkgs,
inputs,
...
}:
{
home.packages = with pkgs; [
gh
ripgrep
fd
lua-language-server
nodejs_22
nixfmt-rfc-style
markdownlint-cli2
shfmt
nixd
marksman
nginx-language-server
bash-language-server
tailwindcss-language-server
vscode-langservers-extracted
gopls
pyright
yaml-language-server
marksman
lazygit
# formatter
prettierd
black
# SystemVerilog
verible
];
programs.neovim = {
enable = true;
package = inputs.neovim-nightly-overlay.packages.${pkgs.system}.default;
withPython3 = true;
extraPython3Packages = (
ps: with ps; [
debugpy
]
);
withNodeJs = true;
extraPackages = with pkgs; [
lua-language-server
ripgrep
stylua
vue-language-server
dockerfile-language-server-nodejs
ruff
hadolint
cmake-language-server
cmake-lint
cmake-format
markdownlint-cli2
marksman
csharpier
netcoredbg
black
prettierd
biome
eslint
typescript-language-server
typescript
vtsls
stylelint-lsp
stylelint
clang-tools
taplo
zls
vscode-js-debug
neocmakelsp
ghostscript
];
plugins = with pkgs.vimPlugins; [
lazy-nvim
];
extraLuaConfig =
let
plugins = with pkgs.vimPlugins; [
LazyVim
bufferline-nvim
cmp-buffer
cmp-nvim-lsp
cmp-path
cmp-git
blink-cmp
crates-nvim
conform-nvim
dashboard-nvim
dressing-nvim
flash-nvim
friendly-snippets
gitsigns-nvim
grug-far-nvim
indent-blankline-nvim
lazydev-nvim
lualine-nvim
luvit-meta
neotest
noice-nvim
nui-nvim
nvim-cmp
nvim-lint
nvim-lspconfig
nvim-snippets
nvim-treesitter
nvim-treesitter-context
nvim-treesitter-textobjects
nvim-ts-autotag
nvim-ts-context-commentstring
nvim-web-devicons
persistence-nvim
plenary-nvim
snacks-nvim
telescope-fzf-native-nvim
telescope-nvim
todo-comments-nvim
tokyonight-nvim
trouble-nvim
ts-comments-nvim
which-key-nvim
vim-markdown-toc
nvim-dap
nvim-dap-ui
nvim-dap-virtual-text
nvim-nio
one-small-step-for-vimkind
none-ls-nvim
render-markdown-nvim
markdown-preview-nvim
markdown-nvim
image-nvim
hover-nvim
# Python
neotest-python
nvim-dap-python
# C#
omnisharp-extended-lsp-nvim
neotest-dotnet
# Cmake
cmake-tools-nvim
SchemaStore-nvim
{
name = "LuaSnip";
path = luasnip;
}
{
name = "catppuccin";
path = catppuccin-nvim;
}
{
name = "mini.ai";
path = mini-nvim;
}
{
name = "mini.bufremove";
path = mini-nvim;
}
{
name = "mini.comment";
path = mini-nvim;
}
{
name = "mini.indentscope";
path = mini-nvim;
}
{
name = "mini.pairs";
path = mini-nvim;
}
{
name = "mini.surround";
path = mini-nvim;
}
];
mkEntryFromDrv =
drv:
if lib.isDerivation drv then
{
name = "${lib.getName drv}";
path = drv;
}
else
drv;
lazyPath = pkgs.linkFarm "lazy-plugins" (builtins.map mkEntryFromDrv plugins);
in
# lua
''
require("lazy").setup({
defaults = {
lazy = true,
},
dev = {
-- reuse files from pkgs.vimPlugins.*
path = "${lazyPath}",
patterns = { "" },
-- fallback to download
fallback = true,
},
spec = {
{ "LazyVim/LazyVim", import = "lazyvim.plugins" },
-- The following configs are needed for fixing lazyvim on nix
-- force enable telescope-fzf-native.nvim
-- { "nvim-telescope/telescope-fzf-native.nvim", enabled = true },
{ import = "lazyvim.plugins.extras.coding.blink" },
{ import = "lazyvim.plugins.extras.coding.luasnip" },
{ import = "lazyvim.plugins.extras.coding.mini-surround" },
{ import = "lazyvim.plugins.extras.coding.yanky" },
{ import = "lazyvim.plugins.extras.coding.neogen" },
{ import = "lazyvim.plugins.extras.dap.core" },
{ import = "lazyvim.plugins.extras.dap.nlua" },
{ import = "lazyvim.plugins.extras.editor.dial" },
-- { import = "lazyvim.plugins.extras.formatting.biome" },
{ import = "lazyvim.plugins.extras.formatting.black" },
{ import = "lazyvim.plugins.extras.formatting.prettier" },
{ import = "lazyvim.plugins.extras.lang.cmake" },
{ import = "lazyvim.plugins.extras.lang.docker" },
{ import = "lazyvim.plugins.extras.lang.git" },
{ import = "lazyvim.plugins.extras.lang.json" },
{ import = "lazyvim.plugins.extras.lang.nix" },
{ import = "lazyvim.plugins.extras.lang.go" },
{ import = "lazyvim.plugins.extras.lang.zig" },
{ import = "lazyvim.plugins.extras.lang.markdown" },
{ import = "lazyvim.plugins.extras.lang.nushell" },
{ import = "lazyvim.plugins.extras.lang.omnisharp" },
{ import = "lazyvim.plugins.extras.lang.clangd" },
{ import = "lazyvim.plugins.extras.lang.python" },
{ import = "lazyvim.plugins.extras.lang.rust" },
{ import = "lazyvim.plugins.extras.lang.tailwind" },
{ import = "lazyvim.plugins.extras.lang.toml" },
{ import = "lazyvim.plugins.extras.lang.yaml" },
{ import = "lazyvim.plugins.extras.linting.eslint" },
{ import = "lazyvim.plugins.extras.ui.mini-animate" },
{ import = "lazyvim.plugins.extras.ui.mini-indentscope" },
{ import = "lazyvim.plugins.extras.ui.smear-cursor" },
{ import = "lazyvim.plugins.extras.ui.treesitter-context" },
{ import = "lazyvim.plugins.extras.util.dot" },
{ import = "lazyvim.plugins.extras.util.mini-hipatterns" },
{ import = "lazyvim.plugins.extras.util.project" },
{ import = "lazyvim.plugins.extras.util.rest" },
{ import = "lazyvim.plugins.extras.editor.refactoring" },
{ import = "lazyvim.plugins.extras.editor.harpoon2" },
{ import = "lazyvim.plugins.extras.editor.snacks_explorer" },
{ import = "lazyvim.plugins.extras.editor.snacks_picker" },
-- import/override your plugins
{ import = "plugins" },
-- Vue & Typescript
{
"neovim/nvim-lspconfig",
opts = function(_, opts)
table.insert(opts.servers.vtsls.filetypes, "vue")
LazyVim.extend(opts.servers.vtsls, "settings.vtsls.tsserver.globalPlugins", {
{
name = "@vue/typescript-plugin",
location = "${pkgs.vue-language-server}/lib/node_modules/@vue/language-server",
languages = { "vue" },
configNamespace = "typescript",
enableForWorkspaceTypeScriptVersions = true,
},
})
end
},
-- Python debugpy
{
{
"mfussenegger/nvim-dap-python",
config = function ()
require("dap-python").setup("python3")
end
},
},
-- Nix
{
"neovim/nvim-lspconfig",
opts = {
servers = {
nixd = {
cmd = { "nixd" },
filetypes = { "nix" },
settings = {
nixd = {
nixpkgs = {
expr = "import <nixpkgs> { }",
},
formatting = {
command = { "nixfmt" },
},
}
}
}
}
}
},
-- disable mason.nvim, use config.extraPackages
{ "williamboman/mason-lspconfig.nvim", enabled = false },
{ "williamboman/mason.nvim", enabled = false },
{ "jay-babu/mason-nvim-dap.nvim", enabled = false },
-- put this line at the end of spec to clear ensure_installed
{ "nvim-treesitter/nvim-treesitter", opts = function(_, opts) opts.ensure_installed = {} end },
},
})
'';
};
xdg.configFile."nvim/parser".source =
let
parsers = pkgs.symlinkJoin {
name = "treesitter-parsers";
paths =
(pkgs.vimPlugins.nvim-treesitter.withPlugins (
plugins: with plugins; [
c
cpp
c_sharp
lua
bash
comment
css
scss
nu
ninja
rst
# rust
rust
ron
# docker
dockerfile
fish
# cmake
cmake
# git
gitattributes
gitignore
git_config
gitcommit
git_rebase
go
gomod
gowork
gosum
hcl
javascript
jq
json5
lua
make
markdown
nix
python
toml
typescript
vue
yaml
zig
]
)).dependencies;
};
in
"${parsers}/parser";
xdg.configFile."nvim/lua".source = ../config/nvim/lua;
}

View file

@ -31,7 +31,7 @@
settings = {
unfocused-split-opacity = 0.85;
desktop-notifications = false;
background-opacity = 0;
background-opacity = 0.4;
background-blur = false;
wait-after-command = false;

View file

@ -129,7 +129,7 @@ in
#memory,
#cpu,
#pulseaudio {
font-size: ${toString (osConfig.stylix.fonts.sizes.desktop + 2)}px;
font-size: ${toString (osConfig.stylix.fonts.sizes.desktop + 1)}px;
}
/* Main bar */