mirror of
https://github.com/nmasur/dotfiles
synced 2025-07-05 20:50:15 +00:00
neovim first init
This commit is contained in:
@ -1,13 +0,0 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
|
||||
# Plugin for aligning text programmatically
|
||||
|
||||
plugins = [ pkgs.vimPlugins.tabular ];
|
||||
lua = ''
|
||||
-- Align
|
||||
vim.keymap.set("", "<Leader>ta", ":Tabularize /")
|
||||
vim.keymap.set("", "<Leader>t#", ":Tabularize /#<CR>")
|
||||
vim.keymap.set("", "<Leader>tl", ":Tabularize /---<CR>")
|
||||
'';
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
|
||||
# Shows buffers in a VSCode-style tab layout
|
||||
|
||||
plugins = [
|
||||
pkgs.vimPlugins.bufferline-nvim
|
||||
pkgs.vimPlugins.vim-bbye # Better closing of buffers
|
||||
pkgs.vimPlugins.snipe-nvim # Jump between open buffers
|
||||
];
|
||||
setup.bufferline = {
|
||||
options = {
|
||||
diagnostics = "nvim_lsp";
|
||||
always_show_bufferline = false;
|
||||
separator_style = "slant";
|
||||
offsets = [ { filetype = "NvimTree"; } ];
|
||||
};
|
||||
};
|
||||
setup.snipe = { };
|
||||
lua = ''
|
||||
-- Move buffers
|
||||
vim.keymap.set("n", "L", ":BufferLineCycleNext<CR>", { silent = true })
|
||||
vim.keymap.set("n", "H", ":BufferLineCyclePrev<CR>", { silent = true })
|
||||
|
||||
-- Kill buffer
|
||||
vim.keymap.set("n", "<Leader>x", " :Bdelete<CR>", { silent = true })
|
||||
|
||||
-- Jump to buffer
|
||||
vim.keymap.set("n", "gb", require("snipe").open_buffer_menu, { silent = true }) '';
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
{
|
||||
|
||||
# Sets Neovim colors based on Nix colorscheme
|
||||
|
||||
options.colors = lib.mkOption {
|
||||
type = lib.types.attrsOf lib.types.str;
|
||||
description = "Attrset of base16 colorscheme key value pairs.";
|
||||
};
|
||||
|
||||
config = {
|
||||
plugins = [ pkgs.vimPlugins.base16-nvim ];
|
||||
setup.base16-colorscheme = config.colors;
|
||||
|
||||
# Telescope isn't working, shut off for now
|
||||
lua = ''
|
||||
require('base16-colorscheme').with_config {
|
||||
telescope = false,
|
||||
}
|
||||
'';
|
||||
};
|
||||
}
|
@ -1,183 +0,0 @@
|
||||
{ pkgs, dsl, ... }:
|
||||
{
|
||||
|
||||
plugins = [
|
||||
pkgs.vimPlugins.nvim-cmp
|
||||
pkgs.vimPlugins.cmp-nvim-lsp
|
||||
pkgs.vimPlugins.cmp-buffer
|
||||
pkgs.vimPlugins.cmp-path
|
||||
pkgs.vimPlugins.cmp-cmdline
|
||||
pkgs.vimPlugins.cmp-nvim-lua
|
||||
pkgs.vimPlugins.luasnip
|
||||
pkgs.vimPlugins.cmp_luasnip
|
||||
pkgs.vimPlugins.cmp-rg
|
||||
];
|
||||
|
||||
use.cmp.setup = dsl.callWith {
|
||||
|
||||
# Disable in telescope buffers
|
||||
enabled = dsl.rawLua ''
|
||||
function()
|
||||
if vim.bo.buftype == "prompt" then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
'';
|
||||
|
||||
# Basic completion keybinds
|
||||
mapping = {
|
||||
"['<C-n>']" =
|
||||
dsl.rawLua "require('cmp').mapping.select_next_item({ behavior = require('cmp').SelectBehavior.Insert }, { 'i', 'c' })";
|
||||
"['<C-p>']" =
|
||||
dsl.rawLua "require('cmp').mapping.select_prev_item({ behavior = require('cmp').SelectBehavior.Insert }, { 'i', 'c' })";
|
||||
"['<Down>']" =
|
||||
dsl.rawLua "require('cmp').mapping.select_next_item({ behavior = require('cmp').SelectBehavior.Select }, { 'i', 'c' })";
|
||||
"['<Up>']" =
|
||||
dsl.rawLua "require('cmp').mapping.select_prev_item({ behavior = require('cmp').SelectBehavior.Select }, { 'i', 'c' })";
|
||||
"['<C-d>']" = dsl.rawLua "require('cmp').mapping.scroll_docs(-4)";
|
||||
"['<C-f>']" = dsl.rawLua "require('cmp').mapping.scroll_docs(4)";
|
||||
"['<C-e>']" = dsl.rawLua "require('cmp').mapping.abort()";
|
||||
"['<C-y>']" =
|
||||
dsl.rawLua "require('cmp').mapping.confirm({ behavior = require('cmp').ConfirmBehavior.Insert, select = true, }, { 'i', 'c' })";
|
||||
"['<C-r>']" =
|
||||
dsl.rawLua "require('cmp').mapping.confirm({ behavior = require('cmp').ConfirmBehavior.Replace, select = true, }, { 'i', 'c' })";
|
||||
"['<Esc>']" = dsl.rawLua ''
|
||||
function(_)
|
||||
cmp.mapping({
|
||||
i = cmp.mapping.abort(),
|
||||
c = cmp.mapping.close(),
|
||||
})
|
||||
vim.cmd("stopinsert") --- Abort and leave insert mode
|
||||
end
|
||||
'';
|
||||
"['<C-k>']" = dsl.rawLua ''
|
||||
cmp.mapping(function(_)
|
||||
if require("luasnip").expand_or_jumpable() then
|
||||
require("luasnip").expand_or_jump()
|
||||
end
|
||||
end, { "i", "s" })
|
||||
'';
|
||||
};
|
||||
|
||||
# These are where the completion engine gets its suggestions
|
||||
sources = [
|
||||
{ name = "nvim_lua"; } # Fills in common Neovim lua functions
|
||||
{ name = "nvim_lsp"; } # LSP results
|
||||
{ name = "path"; } # Shell completion from current PATH
|
||||
{
|
||||
name = "buffer"; # Grep for text from the current text buffer
|
||||
keyword_length = 3;
|
||||
max_item_count = 10;
|
||||
}
|
||||
{
|
||||
name = "rg"; # Grep for text from the current directory
|
||||
keyword_length = 6;
|
||||
max_item_count = 10;
|
||||
option = {
|
||||
additional_arguments = "--ignore-case";
|
||||
};
|
||||
}
|
||||
];
|
||||
|
||||
# Styling of the completion menu
|
||||
formatting = {
|
||||
fields = [
|
||||
"kind"
|
||||
"abbr"
|
||||
"menu"
|
||||
];
|
||||
format = dsl.rawLua ''
|
||||
function(entry, vim_item)
|
||||
local kind_icons = {
|
||||
Text = "",
|
||||
Method = "m",
|
||||
Function = "",
|
||||
Constructor = "",
|
||||
Field = "",
|
||||
Variable = "",
|
||||
Class = "",
|
||||
Interface = "",
|
||||
Module = "",
|
||||
Property = "",
|
||||
Unit = "",
|
||||
Value = "",
|
||||
Enum = "",
|
||||
Keyword = "",
|
||||
Snippet = "",
|
||||
Color = "",
|
||||
File = "",
|
||||
Reference = "",
|
||||
Folder = "",
|
||||
EnumMember = "",
|
||||
Constant = "",
|
||||
Struct = "",
|
||||
Event = "",
|
||||
Operator = "",
|
||||
TypeParameter = "",
|
||||
}
|
||||
vim_item.kind = string.format("%s", kind_icons[vim_item.kind])
|
||||
vim_item.menu = ({
|
||||
buffer = "[Buffer]",
|
||||
path = "[Path]",
|
||||
rg = "[Grep]",
|
||||
nvim_lsp = "[LSP]",
|
||||
nvim_lua = "[Lua]",
|
||||
})[entry.source.name]
|
||||
return vim_item
|
||||
end
|
||||
'';
|
||||
};
|
||||
|
||||
experimental = {
|
||||
native_menu = false; # Use cmp menu instead of Vim menu
|
||||
ghost_text = true; # Show preview auto-completion
|
||||
};
|
||||
};
|
||||
|
||||
lua' = ''
|
||||
-- Use buffer source for `/`
|
||||
require('cmp').setup.cmdline("/", {
|
||||
mapping = {
|
||||
['<C-n>'] = {
|
||||
c = require('cmp').mapping.select_next_item({ behavior = require('cmp').SelectBehavior.Insert }, { 'i', 'c' })
|
||||
},
|
||||
['<C-p>'] = {
|
||||
c = require('cmp').mapping.select_prev_item({ behavior = require('cmp').SelectBehavior.Insert }, { 'i', 'c' })
|
||||
},
|
||||
['<C-y>'] = {
|
||||
c = require('cmp').mapping.confirm({ behavior = require('cmp').ConfirmBehavior.Insert, select = true, }, { 'i', 'c' })
|
||||
},
|
||||
['<C-r>'] = {
|
||||
c = require('cmp').mapping.confirm({ behavior = require('cmp').ConfirmBehavior.Replace, select = true, }, { 'i', 'c' })
|
||||
},
|
||||
},
|
||||
sources = require('cmp').config.sources({
|
||||
{ name = "buffer", keyword_length = 5 },
|
||||
}),
|
||||
})
|
||||
|
||||
-- Use cmdline & path source for ':'
|
||||
require('cmp').setup.cmdline(":", {
|
||||
mapping = {
|
||||
['<C-n>'] = {
|
||||
c = require('cmp').mapping.select_next_item({ behavior = require('cmp').SelectBehavior.Insert }, { 'i', 'c' })
|
||||
},
|
||||
['<C-p>'] = {
|
||||
c = require('cmp').mapping.select_prev_item({ behavior = require('cmp').SelectBehavior.Insert }, { 'i', 'c' })
|
||||
},
|
||||
['<C-y>'] = {
|
||||
c = require('cmp').mapping.confirm({ behavior = require('cmp').ConfirmBehavior.Insert, select = true, }, { 'i', 'c' })
|
||||
},
|
||||
['<C-r>'] = {
|
||||
c = require('cmp').mapping.confirm({ behavior = require('cmp').ConfirmBehavior.Replace, select = true, }, { 'i', 'c' })
|
||||
},
|
||||
},
|
||||
sources = require('cmp').config.sources({
|
||||
{ name = "path" },
|
||||
}, {
|
||||
{ name = "cmdline" },
|
||||
}),
|
||||
})
|
||||
'';
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
-- Keymap to open file in GitHub web
|
||||
vim.keymap.set("n", "<Leader>gr", ":!gh browse %<CR><CR>", { silent = true })
|
||||
|
||||
-- Pop a terminal to watch the current run
|
||||
local gitwatch = require("toggleterm.terminal").Terminal:new({
|
||||
cmd = "fish --interactive --init-command 'gh run watch'",
|
||||
hidden = true,
|
||||
direction = "float",
|
||||
})
|
||||
|
||||
-- Set a toggle for this terminal
|
||||
function GITWATCH_TOGGLE()
|
||||
gitwatch:toggle()
|
||||
end
|
||||
|
||||
-- Keymap to toggle the run
|
||||
vim.keymap.set("n", "<Leader>W", GITWATCH_TOGGLE)
|
@ -1,35 +0,0 @@
|
||||
vim.keymap.set("", "<Space>", "<Nop>", { silent = true })
|
||||
vim.g.mapleader = " "
|
||||
vim.g.maplocalleader = " "
|
||||
|
||||
local gitsigns = require("gitsigns")
|
||||
vim.keymap.set("n", "<Leader>gB", gitsigns.blame_line)
|
||||
vim.keymap.set("n", "<Leader>gp", gitsigns.preview_hunk)
|
||||
vim.keymap.set("v", "<Leader>gp", gitsigns.preview_hunk)
|
||||
vim.keymap.set("n", "<Leader>gd", gitsigns.diffthis)
|
||||
vim.keymap.set("v", "<Leader>gd", gitsigns.diffthis)
|
||||
vim.keymap.set("n", "<Leader>rgf", gitsigns.reset_buffer)
|
||||
vim.keymap.set("v", "<Leader>hs", gitsigns.stage_hunk)
|
||||
vim.keymap.set("n", "<Leader>hr", gitsigns.reset_hunk)
|
||||
vim.keymap.set("v", "<Leader>hr", gitsigns.reset_hunk)
|
||||
|
||||
-- Navigation
|
||||
vim.keymap.set("n", "]g", function()
|
||||
if vim.wo.diff then
|
||||
return "]g"
|
||||
end
|
||||
vim.schedule(function()
|
||||
gitsigns.next_hunk()
|
||||
end)
|
||||
return "<Ignore>"
|
||||
end, { expr = true })
|
||||
|
||||
vim.keymap.set("n", "[g", function()
|
||||
if vim.wo.diff then
|
||||
return "[g"
|
||||
end
|
||||
vim.schedule(function()
|
||||
gitsigns.prev_hunk()
|
||||
end)
|
||||
return "<Ignore>"
|
||||
end, { expr = true })
|
@ -1,6 +0,0 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
plugins = [ pkgs.vimPlugins.gitsigns-nvim ];
|
||||
setup.gitsigns = { };
|
||||
lua = builtins.readFile ./gitsigns.lua;
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
local k9s = require("toggleterm.terminal").Terminal:new({ cmd = "k9s" })
|
||||
function K9S_TOGGLE()
|
||||
k9s:toggle()
|
||||
end
|
||||
|
||||
vim.keymap.set("n", "<Leader>9", K9S_TOGGLE)
|
@ -1,10 +0,0 @@
|
||||
vim.keymap.set("n", "gd", vim.lsp.buf.definition)
|
||||
vim.keymap.set("n", "gT", vim.lsp.buf.type_definition)
|
||||
vim.keymap.set("n", "gi", vim.lsp.buf.implementation)
|
||||
vim.keymap.set("n", "gh", vim.lsp.buf.hover)
|
||||
-- vim.keymap.set("n", "gr", telescope.lsp_references)
|
||||
vim.keymap.set("n", "<Leader>R", vim.lsp.buf.rename)
|
||||
vim.keymap.set("n", "]e", vim.diagnostic.goto_next)
|
||||
vim.keymap.set("n", "[e", vim.diagnostic.goto_prev)
|
||||
vim.keymap.set("n", "<Leader>de", vim.diagnostic.open_float)
|
||||
vim.keymap.set("n", "<Leader>E", vim.lsp.buf.code_action)
|
@ -1,146 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
dsl,
|
||||
...
|
||||
}:
|
||||
{
|
||||
|
||||
# Terraform optional because non-free
|
||||
options.terraform = lib.mkEnableOption "Whether to enable Terraform LSP";
|
||||
options.github = lib.mkEnableOption "Whether to enable GitHub features";
|
||||
options.kubernetes = lib.mkEnableOption "Whether to enable Kubernetes features";
|
||||
|
||||
config = {
|
||||
plugins = [
|
||||
pkgs.vimPlugins.nvim-lspconfig
|
||||
pkgs.vimPlugins.conform-nvim
|
||||
pkgs.vimPlugins.fidget-nvim
|
||||
pkgs.vimPlugins.nvim-lint
|
||||
pkgs.vimPlugins.vim-table-mode
|
||||
pkgs.vimPlugins.tiny-inline-diagnostic-nvim
|
||||
];
|
||||
|
||||
setup.fidget = { };
|
||||
setup.tiny-inline-diagnostic = { };
|
||||
|
||||
use.lspconfig.lua_ls.setup = dsl.callWith {
|
||||
settings = {
|
||||
Lua = {
|
||||
diagnostics = {
|
||||
globals = [
|
||||
"vim"
|
||||
"hs"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
capabilities = dsl.rawLua "require('cmp_nvim_lsp').default_capabilities()";
|
||||
cmd = [ "${pkgs.lua-language-server}/bin/lua-language-server" ];
|
||||
};
|
||||
|
||||
use.lspconfig.nixd.setup = dsl.callWith {
|
||||
cmd = [ "${pkgs.nixd}/bin/nixd" ];
|
||||
capabilities = dsl.rawLua "require('cmp_nvim_lsp').default_capabilities()";
|
||||
};
|
||||
|
||||
use.lspconfig.pyright.setup = dsl.callWith {
|
||||
cmd = [
|
||||
"${pkgs.pyright}/bin/pyright-langserver"
|
||||
"--stdio"
|
||||
];
|
||||
};
|
||||
|
||||
use.lspconfig.terraformls.setup = dsl.callWith {
|
||||
cmd =
|
||||
if config.terraform then
|
||||
[
|
||||
"${pkgs.terraform-ls}/bin/terraform-ls"
|
||||
"serve"
|
||||
]
|
||||
else
|
||||
[ "echo" ];
|
||||
};
|
||||
|
||||
use.lspconfig.rust_analyzer.setup = dsl.callWith {
|
||||
cmd = [ "${pkgs.rust-analyzer}/bin/rust-analyzer" ];
|
||||
settings = {
|
||||
"['rust-analyzer']" = {
|
||||
check = {
|
||||
command = "clippy";
|
||||
};
|
||||
files = {
|
||||
excludeDirs = [ ".direnv" ];
|
||||
};
|
||||
cargo = {
|
||||
features = "all";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
setup.conform = {
|
||||
format_on_save = {
|
||||
# These options will be passed to conform.format()
|
||||
timeout_ms = 1500;
|
||||
lsp_fallback = true;
|
||||
};
|
||||
formatters_by_ft = {
|
||||
lua = [ "stylua" ];
|
||||
python = [ "black" ];
|
||||
fish = [ "fish_indent" ];
|
||||
nix = [ "nixfmt" ];
|
||||
rust = [ "rustfmt" ];
|
||||
sh = [ "shfmt" ];
|
||||
terraform = if config.terraform then [ "terraform_fmt" ] else [ ];
|
||||
hcl = [ "hcl" ];
|
||||
};
|
||||
formatters = {
|
||||
lua.command = "${pkgs.stylua}/bin/stylua";
|
||||
black.command = "${pkgs.black}/bin/black";
|
||||
fish_indent.command = "${pkgs.fish}/bin/fish_indent";
|
||||
nixfmt.command = "${pkgs.nixfmt-rfc-style}/bin/nixfmt";
|
||||
rustfmt.command = "${pkgs.rustfmt}/bin/rustfmt";
|
||||
shfmt = {
|
||||
command = "${pkgs.shfmt}/bin/shfmt";
|
||||
prepend_args = [
|
||||
"-i"
|
||||
"4"
|
||||
"-ci"
|
||||
];
|
||||
};
|
||||
terraform_fmt.command = if config.terraform then "${pkgs.terraform}/bin/terraform" else "";
|
||||
hcl.command = "${pkgs.hclfmt}/bin/hclfmt";
|
||||
};
|
||||
};
|
||||
|
||||
use.lint = {
|
||||
linters_by_ft = dsl.toTable {
|
||||
python = [ "ruff" ];
|
||||
sh = [ "shellcheck" ];
|
||||
};
|
||||
};
|
||||
|
||||
vim.api.nvim_create_autocmd = dsl.callWith [
|
||||
(dsl.toTable [
|
||||
"BufEnter"
|
||||
"BufWritePost"
|
||||
])
|
||||
(dsl.rawLua "{ callback = function() require('lint').try_lint() end }")
|
||||
];
|
||||
|
||||
lua = ''
|
||||
${builtins.readFile ./lsp.lua}
|
||||
|
||||
local ruff = require('lint').linters.ruff; ruff.cmd = "${pkgs.ruff}/bin/ruff"
|
||||
local shellcheck = require('lint').linters.shellcheck; shellcheck.cmd = "${pkgs.shellcheck}/bin/shellcheck"
|
||||
|
||||
-- Prevent infinite log size (change this when debugging)
|
||||
vim.lsp.set_log_level("off")
|
||||
|
||||
-- Hide buffer diagnostics (use tiny-inline-diagnostic.nvim instead)
|
||||
vim.diagnostic.config({ virtual_text = false })
|
||||
'';
|
||||
};
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
dsl,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
{
|
||||
plugins = [
|
||||
pkgs.vimPlugins.vim-surround # Keybinds for surround characters
|
||||
pkgs.vimPlugins.vim-eunuch # File manipulation commands
|
||||
pkgs.vimPlugins.vim-fugitive # Git commands
|
||||
pkgs.vimPlugins.vim-repeat # Better repeat using .
|
||||
pkgs.vimPlugins.vim-abolish # Keep capitalization in substitute (Subvert)
|
||||
pkgs.vimPlugins.markview-nvim # Markdown preview
|
||||
pkgs.vimPlugins.nvim-colorizer-lua # Hex color previews
|
||||
pkgs.vimPlugins.which-key-nvim # Keybind helper
|
||||
];
|
||||
|
||||
# Initialize some plugins
|
||||
setup.colorizer = {
|
||||
user_default_options = {
|
||||
names = false;
|
||||
};
|
||||
};
|
||||
setup.markview = { };
|
||||
setup.which-key = { };
|
||||
|
||||
vim.o = {
|
||||
termguicolors = true; # Set to truecolor
|
||||
hidden = true; # Don't unload buffers when leaving them
|
||||
list = true; # Reveal whitespace with dashes
|
||||
expandtab = true; # Tabs into spaces
|
||||
shiftwidth = 4; # Amount to shift with > key
|
||||
softtabstop = 4; # Amount to shift with <TAB> key
|
||||
ignorecase = true; # Ignore case when searching
|
||||
smartcase = true; # Check case when using capitals in search
|
||||
infercase = true; # Don't match cases when completing suggestions
|
||||
incsearch = true; # Search while typing
|
||||
visualbell = true; # No sounds
|
||||
scrolljump = 1; # Number of lines to scroll
|
||||
scrolloff = 3; # Margin of lines to see while scrolling
|
||||
splitright = true; # Vertical splits on the right side
|
||||
splitbelow = true; # Horizontal splits on the bottom side
|
||||
clipboard = "unnamedplus"; # Uses system clipboard for yanking
|
||||
updatetime = 300; # Faster diagnostics
|
||||
mouse = "nv"; # Mouse interaction / scrolling
|
||||
inccommand = "split"; # Live preview search and replace
|
||||
};
|
||||
|
||||
vim.wo = {
|
||||
number = true; # Show line numbers
|
||||
relativenumber = true; # Relative numbers instead of absolute
|
||||
};
|
||||
|
||||
# For which-key-nvim
|
||||
vim.o.timeout = true;
|
||||
vim.o.timeoutlen = 300;
|
||||
|
||||
# Better backup, swap and undo storage
|
||||
vim.o.backup = true; # Easier to recover and more secure
|
||||
vim.opt.undofile = true; # Keeps undos after quit
|
||||
vim.opt.swapfile = false; # Instead of swaps, create backups
|
||||
vim.o.backupdir = dsl.rawLua ''vim.fn.expand("~/.local/state/nvim/backup//")'';
|
||||
vim.o.undodir = dsl.rawLua ''vim.fn.expand("~/.local/state/nvim/undo//")'';
|
||||
|
||||
# Required for nvim-cmp completion
|
||||
vim.opt.completeopt = [
|
||||
"menu"
|
||||
"menuone"
|
||||
"noselect"
|
||||
];
|
||||
|
||||
lua = lib.mkBefore ''
|
||||
vim.loader.enable()
|
||||
${builtins.readFile ../lua/keybinds.lua};
|
||||
${builtins.readFile ../lua/settings.lua};
|
||||
'';
|
||||
|
||||
vimscript = ''
|
||||
" Remember last position when reopening file
|
||||
au BufReadPost * if line("'\"") > 0 && line("'\"") <= line("$") | exe "normal! g`\"" | endif
|
||||
|
||||
" Flash highlight when yanking
|
||||
au TextYankPost * silent! lua vim.highlight.on_yank { timeout = 250 }
|
||||
'';
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
plugins = [ pkgs.vimPlugins.lualine-nvim ];
|
||||
setup.lualine = {
|
||||
options = {
|
||||
theme = "base16";
|
||||
icons_enabled = true;
|
||||
};
|
||||
};
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
{ pkgs, lib, ... }:
|
||||
{
|
||||
|
||||
plugins = [
|
||||
(pkgs.vimPlugins.nvim-treesitter.withPlugins (
|
||||
_plugins: with pkgs.tree-sitter-grammars; [
|
||||
tree-sitter-bash
|
||||
tree-sitter-c
|
||||
tree-sitter-fish
|
||||
tree-sitter-hcl
|
||||
tree-sitter-ini
|
||||
tree-sitter-json
|
||||
tree-sitter-lua
|
||||
tree-sitter-markdown
|
||||
tree-sitter-markdown-inline
|
||||
tree-sitter-nix
|
||||
tree-sitter-puppet
|
||||
tree-sitter-python
|
||||
tree-sitter-rasi
|
||||
tree-sitter-toml
|
||||
tree-sitter-vimdoc
|
||||
tree-sitter-yaml
|
||||
]
|
||||
))
|
||||
pkgs.vimPlugins.vim-matchup # Better % jumping in languages
|
||||
pkgs.vimPlugins.playground # Tree-sitter experimenting
|
||||
pkgs.vimPlugins.nginx-vim
|
||||
pkgs.vimPlugins.vim-helm
|
||||
# pkgs.vimPlugins.hmts-nvim # Tree-sitter injections for home-manager
|
||||
(pkgs.vimUtils.buildVimPlugin {
|
||||
pname = "nmasur";
|
||||
version = "0.1";
|
||||
src = ../plugin;
|
||||
})
|
||||
];
|
||||
|
||||
setup."nvim-treesitter.configs" = {
|
||||
highlight = {
|
||||
enable = true;
|
||||
};
|
||||
indent = {
|
||||
enable = true;
|
||||
};
|
||||
matchup = {
|
||||
enable = true;
|
||||
}; # Uses vim-matchup
|
||||
|
||||
textobjects = {
|
||||
select = {
|
||||
enable = true;
|
||||
lookahead = true; # Jump forward automatically
|
||||
|
||||
keymaps = {
|
||||
"['af']" = "@function.outer";
|
||||
"['if']" = "@function.inner";
|
||||
"['ac']" = "@class.outer";
|
||||
"['ic']" = "@class.inner";
|
||||
"['al']" = "@loop.outer";
|
||||
"['il']" = "@loop.inner";
|
||||
"['aa']" = "@call.outer";
|
||||
"['ia']" = "@call.inner";
|
||||
"['ar']" = "@parameter.outer";
|
||||
"['ir']" = "@parameter.inner";
|
||||
"['aC']" = "@comment.outer";
|
||||
"['iC']" = "@comment.outer";
|
||||
"['a/']" = "@comment.outer";
|
||||
"['i/']" = "@comment.outer";
|
||||
"['a;']" = "@statement.outer";
|
||||
"['i;']" = "@statement.outer";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Use mkAfter to ensure tree-sitter is already loaded
|
||||
lua = lib.mkAfter ''
|
||||
-- Use HCL parser with .tf files
|
||||
vim.treesitter.language.register('hcl', 'terraform')
|
||||
'';
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
local telescope = require("telescope.builtin")
|
||||
vim.keymap.set("n", "<Leader>k", telescope.keymaps)
|
||||
vim.keymap.set("n", "<Leader>/", telescope.live_grep)
|
||||
vim.keymap.set("n", "<Leader>ff", telescope.find_files)
|
||||
vim.keymap.set("n", "<Leader>fp", telescope.git_files)
|
||||
vim.keymap.set("n", "<Leader>fw", telescope.grep_string)
|
||||
vim.keymap.set("n", "<Leader>b", telescope.buffers)
|
||||
vim.keymap.set("n", "<Leader>hh", telescope.help_tags)
|
||||
vim.keymap.set("n", "<Leader>fr", telescope.oldfiles)
|
||||
vim.keymap.set("n", "<Leader>cc", telescope.commands)
|
||||
vim.keymap.set("n", "<Leader>gc", telescope.git_commits)
|
||||
vim.keymap.set("n", "<Leader>gf", telescope.git_bcommits)
|
||||
vim.keymap.set("n", "<Leader>gb", telescope.git_branches)
|
||||
vim.keymap.set("n", "<Leader>gs", telescope.git_status)
|
||||
vim.keymap.set("n", "<Leader>s", telescope.current_buffer_fuzzy_find)
|
||||
vim.keymap.set("n", "<Leader>rr", telescope.resume)
|
||||
|
||||
vim.keymap.set("n", "<Leader>N", function()
|
||||
local opts = {
|
||||
prompt_title = "Search Notes",
|
||||
cwd = "$NOTES_PATH",
|
||||
}
|
||||
telescope.live_grep(opts)
|
||||
end)
|
||||
|
||||
vim.keymap.set("n", "<Leader>fN", function()
|
||||
local opts = {
|
||||
prompt_title = "Find Notes",
|
||||
cwd = "$NOTES_PATH",
|
||||
}
|
||||
telescope.find_files(opts)
|
||||
end)
|
||||
|
||||
vim.keymap.set("n", "<Leader>cr", function()
|
||||
local opts = require("telescope.themes").get_ivy({
|
||||
layout_config = {
|
||||
bottom_pane = {
|
||||
height = 15,
|
||||
},
|
||||
},
|
||||
})
|
||||
telescope.command_history(opts)
|
||||
end)
|
||||
|
||||
-- Zoxide
|
||||
vim.keymap.set("n", "<Leader>fz", require("telescope").extensions.zoxide.list)
|
||||
|
||||
-- Project
|
||||
require("telescope").load_extension("projects")
|
||||
vim.keymap.set("n", "<C-p>", function()
|
||||
local opts = require("telescope.themes").get_ivy({
|
||||
layout_config = {
|
||||
bottom_pane = {
|
||||
height = 10,
|
||||
},
|
||||
},
|
||||
})
|
||||
require("telescope").extensions.projects.projects(opts)
|
||||
end)
|
||||
|
||||
-- File browser
|
||||
require("telescope").load_extension("file_browser")
|
||||
vim.keymap.set("n", "<Leader>fa", require("telescope").extensions.file_browser.file_browser)
|
||||
vim.keymap.set("n", "<Leader>fD", function()
|
||||
local opts = {
|
||||
prompt_title = "Find Downloads",
|
||||
cwd = "~/downloads",
|
||||
}
|
||||
require("telescope").extensions.file_browser.file_browser(opts)
|
||||
end)
|
@ -1,43 +0,0 @@
|
||||
{ pkgs, dsl, ... }:
|
||||
{
|
||||
|
||||
# Telescope is a fuzzy finder that can work with different sub-plugins
|
||||
|
||||
plugins = [
|
||||
pkgs.vimPlugins.telescope-nvim
|
||||
pkgs.vimPlugins.project-nvim
|
||||
pkgs.vimPlugins.telescope-fzy-native-nvim
|
||||
pkgs.vimPlugins.telescope-file-browser-nvim
|
||||
pkgs.vimPlugins.telescope-zoxide
|
||||
];
|
||||
|
||||
setup.telescope = {
|
||||
defaults = {
|
||||
mappings = {
|
||||
i = {
|
||||
"['<esc>']" = dsl.rawLua "require('telescope.actions').close";
|
||||
"['<C-h>']" = "which_key";
|
||||
};
|
||||
};
|
||||
};
|
||||
pickers = {
|
||||
find_files = {
|
||||
theme = "ivy";
|
||||
};
|
||||
oldfiles = {
|
||||
theme = "ivy";
|
||||
};
|
||||
buffers = {
|
||||
theme = "dropdown";
|
||||
};
|
||||
};
|
||||
extensions = {
|
||||
fzy_native = { };
|
||||
zoxide = { };
|
||||
};
|
||||
};
|
||||
|
||||
setup.project_nvim = { };
|
||||
|
||||
lua = builtins.readFile ./telescope.lua;
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
vim.keymap.set("t", "<A-CR>", "<C-\\><C-n>") --- Exit terminal mode
|
||||
|
||||
-- Only set these keymaps for toggleterm
|
||||
vim.api.nvim_create_autocmd("TermOpen", {
|
||||
pattern = "term://*toggleterm#*",
|
||||
callback = function()
|
||||
-- vim.keymap.set("t", "<Esc>", "<C-\\><C-n>") --- Exit terminal mode
|
||||
vim.keymap.set("t", "<C-h>", "<C-\\><C-n><C-w>h")
|
||||
vim.keymap.set("t", "<C-j>", "<C-\\><C-n><C-w>j")
|
||||
vim.keymap.set("t", "<C-k>", "<C-\\><C-n><C-w>k")
|
||||
vim.keymap.set("t", "<C-l>", "<C-\\><C-n><C-w>l")
|
||||
end,
|
||||
})
|
||||
|
||||
-- These are all the different types of terminals we can trigger
|
||||
|
||||
local terminal = require("toggleterm.terminal").Terminal
|
||||
|
||||
local basicterminal = terminal:new()
|
||||
function TERM_TOGGLE()
|
||||
basicterminal:toggle()
|
||||
end
|
||||
|
||||
local nixpkgs = terminal:new({ cmd = "nix repl --expr 'import <nixpkgs>{}'" })
|
||||
function NIXPKGS_TOGGLE()
|
||||
nixpkgs:toggle()
|
||||
end
|
||||
|
||||
vim.keymap.set("n", "<Leader>t", TERM_TOGGLE)
|
||||
vim.keymap.set("n", "<Leader>P", NIXPKGS_TOGGLE)
|
@ -1,24 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
dsl,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
{
|
||||
|
||||
# Toggleterm provides a floating terminal inside the editor for quick access
|
||||
|
||||
plugins = [ pkgs.vimPlugins.toggleterm-nvim ];
|
||||
|
||||
use.toggleterm.setup = dsl.callWith {
|
||||
open_mapping = dsl.rawLua "[[<c-\\>]]";
|
||||
hide_numbers = true;
|
||||
direction = "float";
|
||||
};
|
||||
|
||||
lua = ''
|
||||
${builtins.readFile ./toggleterm.lua}
|
||||
${if config.github then (builtins.readFile ./github.lua) else ""}
|
||||
${if config.kubernetes then (builtins.readFile ./kubernetes.lua) else ""}
|
||||
'';
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
{ pkgs, dsl, ... }:
|
||||
{
|
||||
|
||||
# This plugin creates a side drawer for navigating the current project
|
||||
|
||||
plugins = [
|
||||
pkgs.vimPlugins.nvim-tree-lua
|
||||
pkgs.vimPlugins.nvim-web-devicons
|
||||
];
|
||||
|
||||
# Disable netrw eagerly
|
||||
# https://github.com/kyazdani42/nvim-tree.lua/commit/fb8735e96cecf004fbefb086ce85371d003c5129
|
||||
vim.g = {
|
||||
loaded = 1;
|
||||
loaded_netrwPlugin = 1;
|
||||
};
|
||||
|
||||
setup.nvim-tree = {
|
||||
disable_netrw = true; # Disable the built-in file manager
|
||||
hijack_netrw = true; # Works as the file manager
|
||||
sync_root_with_cwd = true; # Change project whenever currend dir changes
|
||||
respect_buf_cwd = true; # Change to exact location of focused buffer
|
||||
update_focused_file = {
|
||||
# Change project based on the focused buffer
|
||||
enable = true;
|
||||
update_root = true;
|
||||
ignore_list = { };
|
||||
};
|
||||
diagnostics = {
|
||||
# Enable LSP and linter integration
|
||||
enable = true;
|
||||
icons = {
|
||||
hint = "";
|
||||
info = "";
|
||||
warning = "";
|
||||
error = "";
|
||||
};
|
||||
};
|
||||
renderer = {
|
||||
# Show files with changes vs. current commit
|
||||
icons = {
|
||||
glyphs = {
|
||||
git = {
|
||||
unstaged = "~";
|
||||
staged = "+";
|
||||
unmerged = "";
|
||||
renamed = "➜";
|
||||
deleted = "";
|
||||
untracked = "?";
|
||||
ignored = "◌";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
# Set keybinds and initialize program
|
||||
on_attach = dsl.rawLua ''
|
||||
function (bufnr)
|
||||
local api = require('nvim-tree.api')
|
||||
local function opts(desc)
|
||||
return { desc = 'nvim-tree: ' .. desc, buffer = bufnr, noremap = true, silent = true, nowait = true }
|
||||
end
|
||||
api.config.mappings.default_on_attach(bufnr)
|
||||
|
||||
vim.keymap.set('n', 'l', api.node.open.edit, opts('Open'))
|
||||
vim.keymap.set('n', '<CR>', api.node.open.edit, opts('Open'))
|
||||
vim.keymap.set('n', 'o', api.node.open.edit, opts('Open'))
|
||||
vim.keymap.set('n', 'h', api.node.navigate.parent_close, opts('Close Directory'))
|
||||
vim.keymap.set('n', 'v', api.node.open.vertical, opts('Open: Vertical Split'))
|
||||
end
|
||||
'';
|
||||
view = {
|
||||
# Set look and feel
|
||||
width = 30;
|
||||
side = "left";
|
||||
number = false;
|
||||
relativenumber = false;
|
||||
};
|
||||
};
|
||||
|
||||
# Toggle the sidebar
|
||||
lua = ''
|
||||
vim.keymap.set("n", "<Leader>e", ":NvimTreeFindFileToggle<CR>", { silent = true })
|
||||
'';
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
neovim = import ./package {
|
||||
inherit pkgs;
|
||||
colors = config.theme.colors;
|
||||
terraform = config.terraform.enable;
|
||||
github = true;
|
||||
kubernetes = config.kubernetes.enable;
|
||||
};
|
||||
in
|
||||
{
|
||||
|
||||
options.neovim.enable = lib.mkEnableOption "Neovim.";
|
||||
|
||||
config = lib.mkIf config.neovim.enable {
|
||||
home-manager.users.${config.user} =
|
||||
|
||||
{
|
||||
|
||||
home.packages = [ neovim ];
|
||||
|
||||
# Use Neovim as the editor for git commit messages
|
||||
programs.git.extraConfig.core.editor = "nvim";
|
||||
programs.jujutsu.settings.ui.editor = "nvim";
|
||||
|
||||
# Set Neovim as the default app for text editing and manual pages
|
||||
home.sessionVariables = {
|
||||
EDITOR = "nvim";
|
||||
MANPAGER = "nvim +Man!";
|
||||
};
|
||||
|
||||
# Create quick aliases for launching Neovim
|
||||
programs.fish = {
|
||||
shellAliases = {
|
||||
vim = "nvim";
|
||||
};
|
||||
shellAbbrs = {
|
||||
v = lib.mkForce "nvim";
|
||||
vl = lib.mkForce "nvim -c 'normal! `0' -c 'bdelete 1'";
|
||||
vll = "nvim -c 'Telescope oldfiles'";
|
||||
};
|
||||
};
|
||||
|
||||
# Create a desktop option for launching Neovim from a file manager
|
||||
# (Requires launching the terminal and then executing Neovim)
|
||||
xdg.desktopEntries.nvim = lib.mkIf (pkgs.stdenv.isLinux && config.gui.enable) {
|
||||
name = "Neovim wrapper";
|
||||
exec = "${config.home-manager.users.${config.user}.programs.rofi.terminal} nvim %F";
|
||||
mimeType = [
|
||||
"text/plain"
|
||||
"text/markdown"
|
||||
];
|
||||
};
|
||||
xdg.mimeApps.defaultApplications = lib.mkIf pkgs.stdenv.isLinux {
|
||||
"text/plain" = [ "nvim.desktop" ];
|
||||
"text/markdown" = [ "nvim.desktop" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
-- ===========================================================================
|
||||
-- Key Mapping
|
||||
-- ===========================================================================
|
||||
|
||||
-- Function to cut down config boilerplate
|
||||
local key = function(mode, key_sequence, action, params)
|
||||
params = params or {}
|
||||
vim.keymap.set(mode, key_sequence, action, params)
|
||||
end
|
||||
|
||||
-- Remap space as leader key
|
||||
key("", "<Space>", "<Nop>", { silent = true })
|
||||
vim.g.mapleader = " "
|
||||
vim.g.maplocalleader = " "
|
||||
|
||||
-- Keep selection when changing indentation
|
||||
key("v", "<", "<gv")
|
||||
key("v", ">", ">gv")
|
||||
|
||||
-- Clear search register
|
||||
key("n", "<CR>", ":noh<CR><CR>", { silent = true })
|
||||
|
||||
-- Shuffle lines around
|
||||
key("n", "<A-j>", ":m .+1<CR>==")
|
||||
key("n", "<A-k>", ":m .-2<CR>==")
|
||||
key("v", "<A-j>", ":m '>+1<CR>gv=gv")
|
||||
key("v", "<A-k>", ":m '<-2<CR>gv=gv")
|
||||
|
||||
-- Better window navigation
|
||||
key("n", "<C-h>", "<C-w>h")
|
||||
key("n", "<C-j>", "<C-w>j")
|
||||
key("n", "<C-k>", "<C-w>k")
|
||||
key("n", "<C-l>", "<C-w>l")
|
||||
|
||||
-- File commands
|
||||
key("n", "<Leader>q", ":quit<CR>")
|
||||
key("n", "<Leader>Q", ":quitall<CR>")
|
||||
key("n", "<Leader>fs", ":write<CR>")
|
||||
key("n", "<Leader>fd", ":lcd %:p:h<CR>", { silent = true })
|
||||
key("n", "<Leader>fu", ":lcd ..<CR>", { silent = true })
|
||||
key("n", "<Leader><Tab>", ":b#<CR>", { silent = true })
|
||||
key("n", "<Leader>tt", [[<Cmd>exe 'edit $NOTES_PATH/journal/'.strftime("%Y-%m-%d_%a").'.md'<CR>]])
|
||||
key("n", "<Leader>jj", ":!journal<CR>:e<CR>")
|
||||
|
||||
-- Window commands
|
||||
key("n", "<Leader>wv", ":vsplit<CR>")
|
||||
key("n", "<Leader>wh", ":split<CR>")
|
||||
key("n", "<Leader>wm", ":only<CR>")
|
||||
|
||||
-- Keep cursor in place
|
||||
key("n", "n", "nzz")
|
||||
key("n", "N", "Nzz")
|
||||
key("n", "J", "mzJ`z") --- Mark and jump back to it
|
||||
|
||||
-- Add undo breakpoints
|
||||
key("i", ",", ",<C-g>u")
|
||||
key("i", ".", ".<C-g>u")
|
||||
key("i", "!", "!<C-g>u")
|
||||
key("i", "?", "?<C-g>u")
|
||||
|
||||
-- Resize with arrows
|
||||
key("n", "<C-Up>", ":resize +2<CR>", { silent = true })
|
||||
key("n", "<C-Down>", ":resize -2<CR>", { silent = true })
|
||||
key("n", "<C-Left>", ":vertical resize -2<CR>", { silent = true })
|
||||
key("n", "<C-Right>", ":vertical resize +2<CR>", { silent = true })
|
||||
|
||||
-- Quickfix
|
||||
key("n", "]q", ":cnext<CR>")
|
||||
key("n", "[q", ":cprevious<CR>")
|
||||
key("n", "co", ":copen<CR>")
|
||||
key("n", "cq", ":cclose<CR>")
|
||||
|
||||
-- Other
|
||||
key("n", "<A-CR>", ":noh<CR>", { silent = true }) --- Clear search in VimWiki
|
||||
key("n", "Y", "y$") --- Copy to end of line
|
||||
key("v", "<C-r>", "y<Esc>:%s/<C-r>+//gc<left><left><left>") --- Substitute selected
|
||||
key("v", "D", "y'>gp") --- Duplicate selected
|
||||
key("x", "<Leader>p", '"_dP') --- Paste but keep register
|
@ -1,30 +0,0 @@
|
||||
-- ===========================================================================
|
||||
-- Settings
|
||||
-- ===========================================================================
|
||||
|
||||
vim.filetype.add({
|
||||
pattern = {
|
||||
[".*%.tfvars"] = "terraform",
|
||||
[".*%.tf"] = "terraform",
|
||||
[".*%.rasi"] = "rasi",
|
||||
},
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd("FileType", {
|
||||
pattern = "mail",
|
||||
callback = function()
|
||||
vim.o.wrapmargin = 79 -- Wrap text automatically
|
||||
end,
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd("FileType", {
|
||||
pattern = "markdown",
|
||||
command = "TableModeEnable",
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd("FileType", {
|
||||
pattern = "terraform",
|
||||
callback = function()
|
||||
vim.bo.commentstring = "# %s"
|
||||
end,
|
||||
})
|
@ -1,62 +0,0 @@
|
||||
# { inputs, globals, extraConfig ? [ ], ... }:
|
||||
#
|
||||
# let
|
||||
#
|
||||
# pkgs = import inputs.nixpkgs {
|
||||
# system = inputs.system;
|
||||
# overlays = [
|
||||
# (import ./modules/neovim/plugins-overlay.nix inputs)
|
||||
# inputs.nix2vim.overlay
|
||||
# ];
|
||||
# };
|
||||
#
|
||||
# in pkgs.neovimBuilder {
|
||||
# package = pkgs.neovim-unwrapped;
|
||||
# imports = [
|
||||
# ./modules/common/neovim/plugins/bufferline.nix
|
||||
# ./modules/common/neovim/plugins/completion.nix
|
||||
# ./modules/common/neovim/plugins/gitsigns.nix
|
||||
# ./modules/common/neovim/plugins/lsp.nix
|
||||
# ./modules/common/neovim/plugins/misc.nix
|
||||
# ./modules/common/neovim/plugins/statusline.nix
|
||||
# ./modules/common/neovim/plugins/syntax.nix
|
||||
# ./modules/common/neovim/plugins/telescope.nix
|
||||
# ./modules/common/neovim/plugins/toggleterm.nix
|
||||
# ./modules/common/neovim/plugins/tree.nix
|
||||
# ] ++ extraConfig;
|
||||
# }
|
||||
|
||||
{
|
||||
pkgs,
|
||||
colors,
|
||||
terraform ? false,
|
||||
github ? false,
|
||||
kubernetes ? false,
|
||||
...
|
||||
}:
|
||||
|
||||
# Comes from nix2vim overlay:
|
||||
# https://github.com/gytis-ivaskevicius/nix2vim/blob/master/lib/neovim-builder.nix
|
||||
pkgs.neovimBuilder {
|
||||
package = pkgs.neovim-unwrapped;
|
||||
inherit
|
||||
colors
|
||||
terraform
|
||||
github
|
||||
kubernetes
|
||||
;
|
||||
imports = [
|
||||
../config/align.nix
|
||||
../config/bufferline.nix
|
||||
../config/colors.nix
|
||||
../config/completion.nix
|
||||
../config/gitsigns.nix
|
||||
../config/lsp.nix
|
||||
../config/misc.nix
|
||||
../config/statusline.nix
|
||||
../config/syntax.nix
|
||||
../config/telescope.nix
|
||||
../config/toggleterm.nix
|
||||
../config/tree.nix
|
||||
];
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
expression: (apply_expression
|
||||
function: (apply_expression
|
||||
function: (select_expression
|
||||
attrpath: (attrpath) @writeshell (#match? @writeshell "^writeShell.*$")
|
||||
)
|
||||
)
|
||||
(indented_string_expression) @bash
|
||||
)
|
Reference in New Issue
Block a user