init
This commit is contained in:
commit
b8cad0f750
1
.luacheckrc
Normal file
1
.luacheckrc
Normal file
@ -0,0 +1 @@
|
||||
return { globals = { 'vim' } }
|
||||
14
.luarc.json
Normal file
14
.luarc.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json",
|
||||
"runtime": {
|
||||
"version": "LuaJIT"
|
||||
},
|
||||
"workspace": {
|
||||
"library": [
|
||||
"lua",
|
||||
"$VIMRUNTIME",
|
||||
"${3rd}/luv/library"
|
||||
],
|
||||
"checkThirdParty": false
|
||||
}
|
||||
}
|
||||
7
.stylua.toml
Normal file
7
.stylua.toml
Normal file
@ -0,0 +1,7 @@
|
||||
column_width = 100
|
||||
indent_type = "Spaces"
|
||||
indent_width = 2
|
||||
quote_style = "AutoPreferSingle"
|
||||
call_parentheses = "Always"
|
||||
line_endings = "Unix"
|
||||
|
||||
109
docs/commands.md
Normal file
109
docs/commands.md
Normal file
@ -0,0 +1,109 @@
|
||||
#============================================================
|
||||
# Neovim Command Reference (Core Commands)
|
||||
#============================================================
|
||||
|
||||
|
||||
#============================================================
|
||||
# FILE & SESSION MANAGEMENT
|
||||
#============================================================
|
||||
:w (write) Save current buffer
|
||||
:w <file> Write to <file> (does NOT rename buffer)
|
||||
:sav (saveas) <file> Save to <file> and rename current buffer
|
||||
:q (quit) Quit current window if no unsaved changes
|
||||
:q! Force quit (discard changes)
|
||||
:wq Write and quit current buffer
|
||||
:wqa Write and quit all buffers
|
||||
:qa Quit all windows
|
||||
:qa! Quit all without saving
|
||||
:e (edit) <file> Edit <file> in current window (new buffer)
|
||||
:e! Revert buffer to last saved version (discard changes)
|
||||
:enew Create new empty buffer
|
||||
:r (read) <file> Read <file> into current buffer after cursor
|
||||
:ter (terminal) Open terminal buffer
|
||||
:clo (close) Close current window
|
||||
|
||||
|
||||
#============================================================
|
||||
# BUFFERS
|
||||
#============================================================
|
||||
:ls (buffers) List open buffers
|
||||
:bn (bnext) Go to next buffer
|
||||
:bp (bprev) Go to previous buffer
|
||||
:b<num> Go to buffer by number
|
||||
:b <file> Go to buffer by (partial) name
|
||||
:bd (bdelete) [<num>] Delete current (or given) buffer
|
||||
:bw (bwipeout) [<num>] Delete buffer and remove from memory
|
||||
:bo (only) Close all windows except current
|
||||
:e # Edit alternate (previous) buffer
|
||||
:b# Switch to alternate buffer
|
||||
:b% Re-edit current buffer (no-op)
|
||||
:b$ Go to last buffer
|
||||
|
||||
|
||||
#============================================================
|
||||
# WINDOWS (SPLITS)
|
||||
#============================================================
|
||||
:sp (split) [<file>] Split horizontally (optionally open <file>)
|
||||
:vsp (vsplit) [<file>] Split vertically (optionally open <file>)
|
||||
:new Split with new empty buffer
|
||||
:vnew Vertical split with new empty buffer
|
||||
:close Close current window
|
||||
:only Keep only current window open
|
||||
|
||||
|
||||
#============================================================
|
||||
# TABS
|
||||
#============================================================
|
||||
:tabnew [<file>] Open new tab (optionally edit <file>)
|
||||
:tabn (tabnext) Go to next tab
|
||||
:tabp (tabprev) Go to previous tab
|
||||
:tabm (tabmove) <num> Move current tab to position <num>
|
||||
:tabfirst Jump to first tab
|
||||
:tablast Jump to last tab
|
||||
:tabc (tabclose) Close current tab
|
||||
:tabo (tabonly) Close all other tabs
|
||||
:tabdo <cmd> Execute <cmd> in all tabs (e.g. :tabdo q)
|
||||
|
||||
|
||||
#============================================================
|
||||
# REGISTERS, MARKS & HISTORY
|
||||
#============================================================
|
||||
:reg (registers) Show register contents
|
||||
:marks Show all marks
|
||||
:ju (jumps) Show jump list
|
||||
:changes Show change list
|
||||
|
||||
|
||||
#============================================================
|
||||
# SEARCH / GREP / QUICKFIX
|
||||
#============================================================
|
||||
:g/{pattern}/d Delete all lines matching {pattern}
|
||||
:g!/{pattern}/d Delete all lines NOT matching {pattern}
|
||||
:vim /{pattern}/ **/* Search for {pattern} recursively in all files
|
||||
:cn (cnext) Jump to next quickfix entry
|
||||
:cp (cprevious) Jump to previous quickfix entry
|
||||
:cope (copen) Open quickfix window
|
||||
:ccl (cclose) Close quickfix window
|
||||
:cl (clist) List quickfix entries
|
||||
|
||||
|
||||
#============================================================
|
||||
# DIFF MODE
|
||||
#============================================================
|
||||
:diffthis Start diff mode for current window
|
||||
:diffo (diffoff) Turn off diff mode
|
||||
:diffu (diffupdate) Recalculate diff
|
||||
:diffg (diffget) Get changes from other window
|
||||
:diffpu (diffput) Send changes to other window
|
||||
|
||||
|
||||
#============================================================
|
||||
# NOTES & SYMBOLS
|
||||
#============================================================
|
||||
% Current buffer
|
||||
# Alternate (last visited) buffer
|
||||
$ Last buffer in list
|
||||
+ Next buffer
|
||||
- Previous buffer
|
||||
" Most recently edited buffer (context dependent)
|
||||
|
||||
217
docs/docs.md
Normal file
217
docs/docs.md
Normal file
@ -0,0 +1,217 @@
|
||||
TODO:
|
||||
- wrap up invero theme in separate repo and proper colors?
|
||||
- check plugins logins
|
||||
- cache / create final result
|
||||
- simplify coding: ts, lsp, lint, format (check other repos)
|
||||
- how to download parsers and plugins alternative
|
||||
- telescope alternative
|
||||
- keymaps
|
||||
- wrap up everything
|
||||
|
||||
```lua
|
||||
--[[
|
||||
Neovim Lua config: ways to set things
|
||||
|
||||
- vim.opt : preferred modern API for options (handles lists, cleaner syntax)
|
||||
- vim.g : global variables (leader key, plugin settings, disable builtins, etc.)
|
||||
- vim.o : global-only option (rarely needed directly)
|
||||
- vim.wo : window-local option (applies to current window only, use in autocmds)
|
||||
- vim.bo : buffer-local option (applies to current buffer only, use in autocmds)
|
||||
- vim.env : set environment variables (like PATH, LANG)
|
||||
- vim.fn : call Vimscript functions (e.g. vim.fn.getcwd())
|
||||
- vim.cmd : run raw Vimscript/Ex commands (e.g. vim.cmd("colorscheme desert"))
|
||||
- vim.api : low-level Neovim API (create autocmds, keymaps, buffer/window ops, etc.)
|
||||
|
||||
TL;DR -> use vim.opt + vim.g in options.lua for defaults.
|
||||
Use vim.wo/vim.bo only in context-specific tweaks (autocmds).
|
||||
Use vim.env, vim.fn, vim.cmd, vim.api as needed for scripting.
|
||||
--]]
|
||||
```
|
||||
|
||||
## check macos fileS: https://github.com/dsully/dotfiles/blob/main/.data/macos-defaults/globals.yaml
|
||||
|
||||
# Used pacakges:
|
||||
- rockspaces Metadata files describing how to build and install a Lua package.
|
||||
- luarocks Package manager for Lua modules. (optional)
|
||||
- tree-sitter Parser generator. Not needed except for using CLI. (optional)
|
||||
|
||||
- fd-find (fd) Alternative to `find`. (optional)
|
||||
- ripgrep (rg) Line-oriented search tool. (recommended)
|
||||
|
||||
- git Revision control system. (requirement)
|
||||
- lazygit Terminal UI for git commands. (optional)
|
||||
|
||||
- fzf Command-line fuzzy finder.
|
||||
- bat "cat" but with colors
|
||||
- curl Command-line for transferring data specified with URL syntax.
|
||||
- wget Utility for downloading files from the Web.
|
||||
- make
|
||||
- cc Collection of compilers.
|
||||
- build-essential Meta-package that installs standard C/C++ libraries and headers.
|
||||
These are needed to compile tree-sitter parsers. Run only on the first time.
|
||||
cc (gcc, clang) C compiler. Usually it points to `clang` (on macos) or `gcc` (on linux).
|
||||
g++ C++ compiler.
|
||||
make Build automation tool from source code.
|
||||
|
||||
- unzip Extraction utility for archives compressed in .zip.
|
||||
- ca-certificates Provides a set of trusted Certificate Authority (CA) certificates.
|
||||
- openssh-client Tools for connecting to remote servers securely over SSH.
|
||||
- libssl-dev Development libraries and headers for OpenSSL.
|
||||
- sudo
|
||||
- tree
|
||||
- jq
|
||||
- man-db
|
||||
- python3
|
||||
- volta Node manager
|
||||
- ncurses ncurses-dev ncurses-libs ncurses-terminfo \
|
||||
- check: https://github.com/glepnir/nvim/blob/main/Dockerfile
|
||||
|
||||
|
||||
# Currently installed
|
||||
- plenary.nvim
|
||||
- lazy.nvim
|
||||
|
||||
- nvim-treesitter
|
||||
- neovim/nvim-lspconfig
|
||||
- williamboman/mason.nvim
|
||||
- williamboman/mason-lspconfig.nvim
|
||||
- j-hui/fidget.nvim
|
||||
- hrsh7th/cmp-nvim-lsp
|
||||
- b0o/schemastore.nvim
|
||||
|
||||
- windwp/nvim-ts-autotag # auto close,rename tags
|
||||
- nvim-autopairs # auto pair chars
|
||||
- stevearc/conform.nvim # formatter
|
||||
- nvim-cmp # completion
|
||||
- cmp-path
|
||||
- cmp-nvim-lsp
|
||||
|
||||
- nvim-tree.lua # file explorer
|
||||
- telescope.nvim
|
||||
- telescope-fzf-native.nvim
|
||||
- telescope-ui-select.nvim
|
||||
- plenary.nvim
|
||||
- harpoon # tags
|
||||
|
||||
|
||||
# Notes:
|
||||
- in lsp change tsserver to vtsls
|
||||
|
||||
# New package definition
|
||||
- Plugin and Package managers
|
||||
- folke/lazy.nvim
|
||||
- mason-org/mason.nvim
|
||||
- TS
|
||||
- nvim-treesitter
|
||||
- nvim-treesitter-textobjects
|
||||
- LSP
|
||||
- neovim/nvim-lspconfig
|
||||
|
||||
- nvim-ts-autotag tag elements (`</>`)
|
||||
- windwp/nvim-autopairs auto pairs
|
||||
- blink.cmp autocompletion
|
||||
- stevearc/conform.nvim autoformat
|
||||
- mini.ai `a/i` motions
|
||||
- mini.pairs
|
||||
- mini.surround
|
||||
- mfussenegger/nvim-lint
|
||||
- nvim-lspconfig
|
||||
- fzf-lua (replace telescope)
|
||||
- ? indent guides
|
||||
- lukas-reineke/indent-blankline.nvim
|
||||
- snacks.indent
|
||||
- mini.indentscope
|
||||
|
||||
## Deps:
|
||||
- SchemaStore.nvim
|
||||
- mason-lspconfig.nvim
|
||||
- mason.nvim
|
||||
|
||||
## Maybe:
|
||||
- folke/ts-comments.nvim better comments
|
||||
- grug-far.nvim find and replace
|
||||
- markdown-preview.nvim side by side md (disabled in folke)
|
||||
- toppair/peek.nvim another markdown preview?
|
||||
- render-markdown.nvim inline viewer
|
||||
- markview.nvim
|
||||
- diffview.nvim
|
||||
- octo.nvim edit and review GH issues and pr
|
||||
- yanky.nvim better yank+put. has history
|
||||
- inc-rename.nvim LSP renaming with visual feedback
|
||||
- mini.basics defaults options
|
||||
- mini.test run tests under cursor
|
||||
- mini.diff inline diff
|
||||
- mini.hipatters hilight patters and hex colors
|
||||
- mini.move move chunks (like vscode)
|
||||
- undo tree (find a plugin)
|
||||
|
||||
## AI help
|
||||
- jackMort/ChatGPT.nvim
|
||||
- MunifTanjim/nui.nvim (dep)
|
||||
- nvim-lua/plenary.nvim (dep)
|
||||
- nvim-telescope/telescope.nvim (dep)
|
||||
- robitx/gp.nvim
|
||||
- zbirenbaum/copilot.lua (folke)
|
||||
- milanglacier/minuet-ai.nvim (folke)
|
||||
|
||||
## Options
|
||||
```
|
||||
|
||||
opt.backup = true
|
||||
opt.backupdir = vim.fn(stdpath("state") .. "/backup"
|
||||
opt.mousescroll = "vert:1,hor:4"
|
||||
opt.winborder = "rounded"
|
||||
opt.undofile = true
|
||||
-- lazy
|
||||
rtp = {
|
||||
disabled_plugins = { "gzip", "tarPlugin", "zipPlugin", "tohtml", "tutor" },
|
||||
},
|
||||
|
||||
vim.keymap.set("n", "<C-c>", "ciw")
|
||||
|
||||
-- ts lsp
|
||||
includeCompletionsWithSnippetText = true,
|
||||
jsxAttributeCompletionStyle = "auto",
|
||||
|
||||
-- tree-sitter parsers naming:
|
||||
https://github.com/nvim-treesitter/nvim-treesitter/blob/master/lua/nvim-treesitter/parsers.lua
|
||||
```
|
||||
|
||||
folke cmd
|
||||
```lua
|
||||
-- show cursor line only in active window
|
||||
vim.api.nvim_create_autocmd({ "InsertLeave", "WinEnter" }, {
|
||||
callback = function()
|
||||
if vim.w.auto_cursorline then
|
||||
vim.wo.cursorline = true
|
||||
vim.w.auto_cursorline = nil
|
||||
end
|
||||
end,
|
||||
})
|
||||
vim.api.nvim_create_autocmd({ "InsertEnter", "WinLeave" }, {
|
||||
callback = function()
|
||||
if vim.wo.cursorline then
|
||||
vim.w.auto_cursorline = true
|
||||
vim.wo.cursorline = false
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
-- backups
|
||||
vim.api.nvim_create_autocmd("BufWritePre", {
|
||||
group = vim.api.nvim_create_augroup("better_backup", { clear = true }),
|
||||
callback = function(event)
|
||||
local file = vim.uv.fs_realpath(event.match) or event.match
|
||||
local backup = vim.fn.fnamemodify(file, ":p:~:h")
|
||||
backup = backup:gsub("[/\\]", "%%")
|
||||
vim.go.backupext = backup
|
||||
end,
|
||||
})
|
||||
```
|
||||
|
||||
Enable folding with TS:
|
||||
```
|
||||
vim.opt.foldmethod = "expr"
|
||||
vim.opt.foldexpr = "nvim_treesitter#foldexpr()"
|
||||
vim.opt.foldenable = false -- start with all folds open
|
||||
```
|
||||
119
docs/keymaps.md
Normal file
119
docs/keymaps.md
Normal file
@ -0,0 +1,119 @@
|
||||
#============================================================
|
||||
# NEOVIM KEYMAP REFERENCE (CORE & USEFUL)
|
||||
#============================================================
|
||||
|
||||
|
||||
#============================================================
|
||||
# INSERT MODE (Ctrl + ...)
|
||||
#============================================================
|
||||
Ctrl + h Delete character before cursor
|
||||
Ctrl + w Delete word before cursor
|
||||
Ctrl + j Insert line break (newline) at cursor
|
||||
Ctrl + t Indent current line one 'shiftwidth' to the right
|
||||
Ctrl + d De-indent current line one 'shiftwidth' to the left
|
||||
Ctrl + n Insert next auto-completion match
|
||||
Ctrl + p Insert previous auto-completion match
|
||||
Ctrl + r x Insert contents of register x
|
||||
Ctrl + o {cmd} Temporarily enter Normal mode to execute {cmd}
|
||||
Esc / Ctrl + c Exit insert mode and return to Normal mode
|
||||
|
||||
|
||||
#============================================================
|
||||
# NORMAL MODE — WINDOW & TAB MANAGEMENT
|
||||
#============================================================
|
||||
C-w s Split current window horizontally
|
||||
C-w v Split current window vertically
|
||||
C-w c Close current window
|
||||
C-w q Quit current window (same as close but exit if last)
|
||||
C-w w Cycle through open windows
|
||||
C-w x Exchange window with next one
|
||||
|
||||
C-w = Equalize window sizes
|
||||
C-w _ Maximize height of current window
|
||||
C-w | Maximize width of current window
|
||||
|
||||
C-w h Move to window left
|
||||
C-w j Move to window below
|
||||
C-w k Move to window above
|
||||
C-w l Move to window right
|
||||
|
||||
C-w H Move current window far left
|
||||
C-w J Move current window to bottom
|
||||
C-w K Move current window to top
|
||||
C-w L Move current window far right
|
||||
|
||||
C-w t Move current split into a new tab
|
||||
|
||||
gt Go to next tab
|
||||
gT Go to previous tab
|
||||
<n>gt Go to tab number <n>
|
||||
|
||||
|
||||
#============================================================
|
||||
# NORMAL MODE — TAGS, JUMPS & MOTIONS
|
||||
#============================================================
|
||||
Ctrl + ] Jump to tag under cursor
|
||||
gd Go to local declaration
|
||||
gD Go to global declaration
|
||||
{ Jump backward one paragraph/block
|
||||
} Jump forward one paragraph/block
|
||||
; Repeat last motion forward
|
||||
, Repeat last motion backward
|
||||
Ctrl + e Scroll window down (cursor stays put)
|
||||
Ctrl + y Scroll window up (cursor stays put)
|
||||
H Move cursor to top of screen
|
||||
M Move cursor to middle of screen
|
||||
L Move cursor to bottom of screen
|
||||
|
||||
|
||||
#============================================================
|
||||
# NORMAL MODE — TEXT OBJECTS
|
||||
#============================================================
|
||||
aw "A word" — select word + following space
|
||||
ab "A block" — select around ()
|
||||
aB "A Block" — select around {}
|
||||
at "A tag" — select around XML/HTML tag
|
||||
|
||||
ib "Inner block" — inside ()
|
||||
iB "Inner Block" — inside {}
|
||||
it "Inner tag" — inside tag (no delimiters)
|
||||
|
||||
|
||||
#============================================================
|
||||
# NORMAL MODE — DIFF / CHANGES
|
||||
#============================================================
|
||||
do Obtain (get) changes from other window
|
||||
dp Put (send) changes to other window
|
||||
|
||||
|
||||
#============================================================
|
||||
# REGISTERS & CLIPBOARD
|
||||
#============================================================
|
||||
"xy Yank into register x
|
||||
"xp Paste contents of register x
|
||||
"+y Yank into system clipboard
|
||||
"+p Paste from system clipboard
|
||||
|
||||
#--- Common Registers ---
|
||||
"0 Last yank
|
||||
" Unnamed register (last delete or yank)
|
||||
"% Current file name
|
||||
"# Alternate file name
|
||||
"* X11 primary selection clipboard
|
||||
"+ X11 clipboard register
|
||||
"/ Last search pattern
|
||||
": Last command-line command
|
||||
". Last inserted text
|
||||
"- Last small (less than a line) delete
|
||||
"= Expression register (evaluate expression)
|
||||
"_ Black hole register (discard output)
|
||||
|
||||
|
||||
#============================================================
|
||||
# TIPS & NOTES
|
||||
#============================================================
|
||||
- Ctrl + o in Insert mode is a powerful way to run one Normal-mode command temporarily.
|
||||
- Use “aw”, “iw”, “ab”, “ib”, etc. with operators (e.g., ‘daw’, ‘yib’) for precise text manipulation.
|
||||
- The system clipboard is “+” (Windows/macOS/Linux), but some X11 systems also use “*”.
|
||||
- When in diff mode, ‘do’ and ‘dp’ are complementary: “get” vs. “put” changes.
|
||||
|
||||
94
docs/neovim-actions.md
Normal file
94
docs/neovim-actions.md
Normal file
@ -0,0 +1,94 @@
|
||||
-- Window Creation/Closing
|
||||
Ctrl-w s - Split window horizontally
|
||||
Ctrl-w v - Split window vertically
|
||||
Ctrl-w n - Create new window horizontally with empty buffer
|
||||
Ctrl-w c - Close current window
|
||||
Ctrl-w o - Close all windows except current one
|
||||
|
||||
-- Window Navigation
|
||||
Ctrl-h - Move to window on the left
|
||||
Ctrl-j - Move to window below
|
||||
Ctrl-k - Move to window above
|
||||
Ctrl-l - Move to window on the right
|
||||
|
||||
-- Window Moving/Rearranging
|
||||
Ctrl-w H - Move current window to far left
|
||||
Ctrl-w J - Move current window to bottom
|
||||
Ctrl-w K - Move current window to top
|
||||
Ctrl-w L - Move current window to far right
|
||||
|
||||
-- Window Resizing
|
||||
Ctrl-w = - Make all windows equal size
|
||||
Ctrl-w _ - Maximize height of current window
|
||||
Ctrl-w | - Maximize width of current window
|
||||
Ctrl-w > - Increase width by 5 column
|
||||
Ctrl-w < - Decrease width by 5 column
|
||||
Ctrl-w + - Increase height by 5 row
|
||||
Ctrl-w - - Decrease height by 5 row
|
||||
|
||||
-- Window Special Commands
|
||||
Ctrl-w T - Move current window to new tab
|
||||
Ctrl-w } - Preview definition in new window
|
||||
Ctrl-w z - Close preview window
|
||||
|
||||
-- Tab
|
||||
<Leader>t] :tabnext - Go to next tab
|
||||
<Leader>t[ :tabprevious - Go to previous tab
|
||||
<Leader>tn :tabnew - Create a new tab
|
||||
<Leader>tc :tabclose - Close current tab
|
||||
<Leader>to :tabonly - Close all other tabs
|
||||
<Leader>{n} :{n}gt - Go to tab {n}
|
||||
|
||||
-- Buffer
|
||||
-- note: mainly using the telescope one
|
||||
<Leader>space telescope.buffers - open buffers with telescope. there can navigate and delete
|
||||
<Leader>bl :ls - List all buffers
|
||||
<Leader>bd :bdelete - Delete current buffer
|
||||
<Leader>bn :bnext - Go to next buffer
|
||||
<Leader>bp :bprevious - Go to previous buffer
|
||||
<Leader>b{n} :buffer {n} - Go to buffer {n}
|
||||
<Leader>bb :b<Space> - Start buffer selection
|
||||
<Leader>bo :bufdo bd|1bd - Delete all other buffers
|
||||
|
||||
-- Telescope
|
||||
<Leader>ff telescope.find_files - Search Files
|
||||
<Leader>fg telescope.live_grep - Search by Grep
|
||||
<Leader>fb telescope.buffers - Search Buffers
|
||||
<Leader>fh telescope.help_tags - Search Help
|
||||
<Leader>fp telescope.projects - Search Projects
|
||||
<Leader>fm telescope.marks - Search Marks
|
||||
<Leader>fc telescope.commands - Search Commands
|
||||
<Leader>fk telescope.keymaps - Search Keymaps
|
||||
<Leader>fs telescope.git_status - Search Git Status
|
||||
<Leader>fw telescope.grep_string - Search current Word
|
||||
<Leader>fd telescope.diagnostics - Search Diagnostics
|
||||
<Leader>fr telescope.lsp_references - Search References
|
||||
|
||||
-- Neo-tree
|
||||
<Leader>e :NvimTree toggle - Explorer Toggle
|
||||
<Leader>E :NvimTree focus - Explorer Focus
|
||||
|
||||
-- Harpoon
|
||||
<Leader>h harpoon_ui.toggle_menu - Harpoon Menu
|
||||
<Leader>m harpoon_mark.add_file - Mark File
|
||||
<Leader>1 harpoon_ui.nav_file(1) - Harpoon File 1
|
||||
<Leader>2 harpoon_ui.nav_file(2) - Harpoon File 2
|
||||
<Leader>3 harpoon_ui.nav_file(3) - Harpoon File 3
|
||||
<Leader>4 harpoon_ui.nav_file(4) - Harpoon File 4
|
||||
<Leader>hn harpoon_ui.nav_next - Harpoon Next
|
||||
<Leader>hp harpoon_ui.nav_prev - Harpoon Previous
|
||||
|
||||
-- Terminal
|
||||
<Leader>tet :terminal cd %:h - Terminal in This dir
|
||||
<Leader>ter :terminal - Terminal Regular
|
||||
<Leader>tec :!cd %:h && - Terminal Command
|
||||
<Esc> <C-\><C-n> - Terminal Normal Mode
|
||||
<C-w> <C-\><C-n><C-w> - Terminal Window Command
|
||||
|
||||
-- LSP
|
||||
gd vim.lsp.buf.definition - Goto Definition
|
||||
gr vim.lsp.buf.references - Goto References
|
||||
K vim.lsp.buf.hover - Hover Documentation
|
||||
<Leader>rn vim.lsp.buf.rename - Rename
|
||||
<Leader>ca vim.lsp.buf.code_action - Code Action
|
||||
<Leader>f vim.lsp.buf.format - Format
|
||||
29
init.lua
Normal file
29
init.lua
Normal file
@ -0,0 +1,29 @@
|
||||
local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim'
|
||||
if not (vim.uv or vim.loop).fs_stat(lazypath) then
|
||||
local lazyrepo = 'https://github.com/folke/lazy.nvim.git'
|
||||
local out =
|
||||
vim.fn.system({ 'git', 'clone', '--filter=blob:none', '--branch=stable', lazyrepo, lazypath })
|
||||
if vim.v.shell_error ~= 0 then
|
||||
vim.api.nvim_echo({
|
||||
{ 'Failed to clone lazy.nvim:\n', 'ErrorMsg' },
|
||||
{ out, 'WarningMsg' },
|
||||
{ '\nPress any key to exit...' },
|
||||
}, true, {})
|
||||
vim.fn.getchar()
|
||||
os.exit(1)
|
||||
end
|
||||
end
|
||||
vim.opt.rtp:prepend(lazypath)
|
||||
|
||||
require('config.options')
|
||||
require('config.keymaps')
|
||||
require('config.autocmds')
|
||||
require('config.clipboard')
|
||||
require('config.terminal')
|
||||
require('custom.navigation')
|
||||
require('lazy').setup({
|
||||
spec = { { import = 'plugins' } },
|
||||
install = { missing = false },
|
||||
change_detection = { notify = false },
|
||||
rocks = { enabled = false },
|
||||
})
|
||||
12
lazy-lock.json
Normal file
12
lazy-lock.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"conform.nvim": { "branch": "master", "commit": "fbcb4fa7f34bfea9be702ffff481a8e336ebf6ed" },
|
||||
"fzf-lua": { "branch": "main", "commit": "58ebb27333bd12cb497f27b7da07a677116bc0ef" },
|
||||
"lazy.nvim": { "branch": "main", "commit": "1ea3c4085785f460fb0e46d2fe1ee895f5f9e7c1" },
|
||||
"mason.nvim": { "branch": "main", "commit": "ad7146aa61dcaeb54fa900144d768f040090bff0" },
|
||||
"nvim-autopairs": { "branch": "master", "commit": "7a2c97cccd60abc559344042fefb1d5a85b3e33b" },
|
||||
"nvim-lint": { "branch": "master", "commit": "9da1fb942dd0668d5182f9c8dee801b9c190e2bb" },
|
||||
"nvim-tree.lua": { "branch": "master", "commit": "321bc61580fd066b76861c32de3319c3a6d089e7" },
|
||||
"nvim-treesitter": { "branch": "master", "commit": "42fc28ba918343ebfd5565147a42a26580579482" },
|
||||
"nvim-ts-autotag": { "branch": "main", "commit": "c4ca798ab95b316a768d51eaaaee48f64a4a46bc" },
|
||||
"rose-pine": { "branch": "main", "commit": "72a04c4065345b51b56aed4859ea1d884f734097" }
|
||||
}
|
||||
6
lsp/json_ls.lua
Normal file
6
lsp/json_ls.lua
Normal file
@ -0,0 +1,6 @@
|
||||
return {
|
||||
cmd = { 'vscode-json-language-server', '--stdio' },
|
||||
filetypes = { 'json', 'jsonc' },
|
||||
init_options = { provideFormatter = true },
|
||||
root_markers = { '.git' },
|
||||
}
|
||||
14
lsp/lua_ls.lua
Normal file
14
lsp/lua_ls.lua
Normal file
@ -0,0 +1,14 @@
|
||||
return {
|
||||
cmd = { "lua-language-server" },
|
||||
filetypes = { "lua" },
|
||||
root_markers = {
|
||||
".luarc.json",
|
||||
".luarc.jsonc",
|
||||
".luacheckrc",
|
||||
".stylua.toml",
|
||||
"stylua.toml",
|
||||
"selene.toml",
|
||||
"selene.yml",
|
||||
".git",
|
||||
},
|
||||
}
|
||||
49
lua/config/autocmds.lua
Normal file
49
lua/config/autocmds.lua
Normal file
@ -0,0 +1,49 @@
|
||||
-- Automatically create a scratch buffer if Neovim starts with no files
|
||||
vim.api.nvim_create_autocmd('VimEnter', {
|
||||
callback = function()
|
||||
-- Only trigger if no file arguments are passed
|
||||
if vim.fn.argc() == 0 then
|
||||
vim.cmd('enew')
|
||||
vim.bo.buftype = 'nofile'
|
||||
vim.bo.bufhidden = 'wipe'
|
||||
vim.bo.swapfile = false
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
-- Highlight when yanking (copying) text
|
||||
vim.api.nvim_create_autocmd('TextYankPost', {
|
||||
callback = function()
|
||||
vim.highlight.on_yank()
|
||||
end,
|
||||
})
|
||||
|
||||
-- Disable comment continuation only when using 'o'/'O', but keep it for <Enter>
|
||||
vim.api.nvim_create_autocmd('FileType', {
|
||||
pattern = '*',
|
||||
callback = function()
|
||||
vim.opt_local.formatoptions:remove('o')
|
||||
end,
|
||||
})
|
||||
|
||||
-- Show cursor line only in active window
|
||||
vim.api.nvim_create_autocmd({ 'WinEnter', 'InsertLeave' }, {
|
||||
callback = function()
|
||||
if vim.w.auto_cursorline then
|
||||
vim.wo.cursorline = true
|
||||
vim.w.auto_cursorline = nil
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd({ 'WinLeave', 'InsertEnter' }, {
|
||||
callback = function()
|
||||
if vim.bo.filetype == 'NvimTree' then
|
||||
return
|
||||
end
|
||||
if vim.wo.cursorline then
|
||||
vim.w.auto_cursorline = true
|
||||
vim.wo.cursorline = false
|
||||
end
|
||||
end,
|
||||
})
|
||||
25
lua/config/clipboard.lua
Normal file
25
lua/config/clipboard.lua
Normal file
@ -0,0 +1,25 @@
|
||||
if vim.env.CONTAINER then
|
||||
vim.g.clipboard = {
|
||||
name = 'osc52',
|
||||
copy = {
|
||||
['+'] = require('vim.ui.clipboard.osc52').copy('+'),
|
||||
['*'] = require('vim.ui.clipboard.osc52').copy('*'),
|
||||
},
|
||||
paste = {
|
||||
['+'] = require('vim.ui.clipboard.osc52').paste('+'),
|
||||
['*'] = require('vim.ui.clipboard.osc52').paste('*'),
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
vim.schedule(function()
|
||||
vim.opt.clipboard = 'unnamedplus'
|
||||
end)
|
||||
|
||||
-- TEMP: Check if it helps with edge cases
|
||||
vim.api.nvim_create_user_command('FixClipboard', function()
|
||||
vim.cmd('lua require("vim.ui.clipboard.osc52")')
|
||||
vim.schedule(function()
|
||||
vim.notify('Clipboard provider reloaded (OSC52)')
|
||||
end)
|
||||
end, {})
|
||||
54
lua/config/keymaps.lua
Normal file
54
lua/config/keymaps.lua
Normal file
@ -0,0 +1,54 @@
|
||||
local map = vim.keymap.set
|
||||
|
||||
map('n', '<leader>q', vim.diagnostic.setloclist)
|
||||
|
||||
map({ 'i', 'c' }, 'jk', '<Esc>')
|
||||
map('n', '<Esc>', '<cmd>nohlsearch<CR>')
|
||||
|
||||
-- Prevent overriding the register
|
||||
map('n', 'x', '"_x')
|
||||
|
||||
-- Window Navigation
|
||||
map('n', '<C-h>', '<C-w>h')
|
||||
map('n', '<C-l>', '<C-w>l')
|
||||
map('n', '<C-j>', '<C-w>j')
|
||||
map('n', '<C-k>', '<C-w>k')
|
||||
|
||||
-- Tab management
|
||||
map('n', '<Leader>tn', ':tabnew<CR>')
|
||||
map('n', '<Leader>tc', ':tabclose<CR>')
|
||||
map('n', '<Leader>tl', ':tabnext<CR>')
|
||||
map('n', '<Leader>th', ':tabprevious<CR>')
|
||||
map('n', '<Leader>tm.', ':tabmove +1<CR>')
|
||||
map('n', '<Leader>tm,', ':tabmove -1<CR>')
|
||||
for i = 1, 9 do
|
||||
map('n', string.format('<Leader>%d', i), string.format('%dgt', i))
|
||||
end
|
||||
|
||||
-- Buffer Management
|
||||
-- map('n', '<Leader>bl', ':ls<CR>')
|
||||
-- map('n', '<Leader>bd', ':bdelete<CR>')
|
||||
-- map('n', ']b', ':bnext<CR>')
|
||||
-- map('n', '[b', ':bprevious<CR>')
|
||||
-- map('n', '<Leader>bb', ':b<Space>')
|
||||
-- map('n', '<Leader>bo', ':bufdo bd|1bd<CR>')
|
||||
|
||||
-- Terminal
|
||||
map('n', '<leader>tt', ':TermDefault<CR>')
|
||||
map('n', '<leader>tr', ':TermRelative<CR>')
|
||||
map('n', '<leader>ts', ':TermSplit<CR>')
|
||||
map('n', '<leader>tv', ':TermVSplit<CR>')
|
||||
|
||||
-- Terminal mode mappings
|
||||
local tn = '<C-\\><C-n>'
|
||||
map('t', '<Esc>', tn)
|
||||
map('t', 'jk', tn)
|
||||
map('t', '<C-w>', tn .. '<C-w>')
|
||||
map('t', '<C-h>', '<cmd>wincmd h<CR>')
|
||||
map('t', '<C-j>', '<cmd>wincmd j<CR>')
|
||||
map('t', '<C-k>', '<cmd>wincmd k<CR>')
|
||||
map('t', '<C-l>', '<cmd>wincmd l<CR>')
|
||||
|
||||
-- File explorer
|
||||
vim.keymap.set('n', '<leader>e', '<cmd>NvimTreeToggle<CR>')
|
||||
vim.keymap.set('n', '<leader>E', '<cmd>NvimTreeOpen<CR>')
|
||||
89
lua/config/options.lua
Normal file
89
lua/config/options.lua
Normal file
@ -0,0 +1,89 @@
|
||||
-- Map Leader
|
||||
vim.g.mapleader = ' '
|
||||
vim.g.maplocalleader = ' '
|
||||
|
||||
-- Disable built-in plugins
|
||||
vim.loader.enable()
|
||||
vim.g.loaded_gzip = 1
|
||||
vim.g.loaded_tar = 1
|
||||
vim.g.loaded_tarPlugin = 1
|
||||
vim.g.loaded_zip = 1
|
||||
vim.g.loaded_zipPlugin = 1
|
||||
vim.g.loaded_getscript = 1
|
||||
vim.g.loaded_getscriptPlugin = 1
|
||||
vim.g.loaded_vimball = 1
|
||||
vim.g.loaded_vimballPlugin = 1
|
||||
vim.g.loaded_matchit = 1
|
||||
vim.g.loaded_2html_plugin = 1
|
||||
vim.g.loaded_rrhelper = 1
|
||||
vim.g.loaded_netrw = 1 -- use nvim-tree instead
|
||||
vim.g.loaded_netrwPlugin = 1
|
||||
|
||||
-- UI
|
||||
vim.g.health = { style = 'float' }
|
||||
vim.g.have_nerd_font = true
|
||||
vim.opt.termguicolors = false
|
||||
|
||||
vim.opt.textwidth = 100
|
||||
vim.opt.colorcolumn = '+0'
|
||||
|
||||
vim.opt.signcolumn = 'no'
|
||||
vim.opt.number = true
|
||||
vim.opt.relativenumber = true
|
||||
vim.opt.cursorline = true
|
||||
vim.opt.winborder = 'rounded'
|
||||
vim.opt.guicursor = 'n-v-i-c:block'
|
||||
vim.opt.ruler = false
|
||||
vim.opt.laststatus = 3
|
||||
vim.opt.statusline = '── %f %h%w%m%r %= [%l,%c-%L] ──'
|
||||
vim.opt.fillchars = {
|
||||
stl = '─',
|
||||
stlnc = '─',
|
||||
horiz = '─',
|
||||
horizdown = '─',
|
||||
horizup = '─',
|
||||
vert = '│',
|
||||
vertleft = '│',
|
||||
vertright = '│',
|
||||
verthoriz = '│',
|
||||
}
|
||||
|
||||
-- Wrap
|
||||
vim.opt.wrap = false
|
||||
vim.opt.linebreak = true
|
||||
vim.opt.breakindent = true
|
||||
|
||||
-- Indent
|
||||
vim.opt.shiftwidth = 2 -- Number of spaces to use for (auto)indent
|
||||
vim.opt.tabstop = 2 -- Number of spaces that a <Tab> in file counts for
|
||||
vim.opt.softtabstop = 2 -- Number of spaces when pressing <Tab> in insert mode
|
||||
vim.opt.expandtab = true -- Use spaces instead of literal tab characters
|
||||
vim.opt.autoindent = true -- Copy indent from the current line when starting a new one
|
||||
vim.opt.smartindent = true -- Automatically inserts indents in code blocks (for C-like languages)
|
||||
|
||||
-- Scroll and mouse
|
||||
vim.opt.scrolloff = 10
|
||||
vim.opt.sidescrolloff = 5
|
||||
vim.opt.mousescroll = 'hor:1,ver:5'
|
||||
vim.opt.mouse = 'a' -- Enable mouse support
|
||||
|
||||
-- Search
|
||||
vim.opt.ignorecase = true
|
||||
vim.opt.smartcase = true -- Override ignorecase if search contains upper case chars
|
||||
vim.opt.inccommand = 'split' -- Live substitution preview
|
||||
vim.opt.completeopt = { 'menu,menuone,noselect' }
|
||||
|
||||
-- Splits
|
||||
vim.opt.splitright = true
|
||||
vim.opt.splitbelow = true
|
||||
|
||||
-- Persistence
|
||||
vim.opt.undofile = true
|
||||
vim.opt.swapfile = false
|
||||
|
||||
-- Tweaks
|
||||
vim.opt.updatetime = 1000
|
||||
vim.opt.timeout = true
|
||||
vim.opt.ttimeout = true
|
||||
vim.opt.timeoutlen = 500
|
||||
vim.opt.ttimeoutlen = 10
|
||||
62
lua/config/terminal.lua
Normal file
62
lua/config/terminal.lua
Normal file
@ -0,0 +1,62 @@
|
||||
local term_group = vim.api.nvim_create_augroup('custom-term-open', { clear = true })
|
||||
vim.api.nvim_create_autocmd('TermOpen', {
|
||||
group = term_group,
|
||||
callback = function()
|
||||
vim.opt_local.number = false
|
||||
vim.opt_local.relativenumber = false
|
||||
vim.opt_local.scrolloff = 0
|
||||
vim.bo.filetype = 'terminal'
|
||||
vim.cmd.startinsert()
|
||||
end,
|
||||
})
|
||||
|
||||
-- Close all terminal buffers before quitting
|
||||
vim.api.nvim_create_autocmd('QuitPre', {
|
||||
group = vim.api.nvim_create_augroup('shoutoff_terminals', { clear = true }),
|
||||
callback = function()
|
||||
for _, buf in ipairs(vim.api.nvim_list_bufs()) do
|
||||
if vim.api.nvim_buf_is_loaded(buf) and vim.bo[buf].buftype == 'terminal' then
|
||||
vim.api.nvim_buf_delete(buf, { force = true })
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
-- Insert when re-entering a terminal window (after switching back)
|
||||
vim.api.nvim_create_autocmd('BufEnter', {
|
||||
group = term_group,
|
||||
pattern = 'term://*',
|
||||
callback = function()
|
||||
if vim.bo.buftype == 'terminal' and vim.fn.mode() ~= 'i' then
|
||||
vim.cmd.startinsert()
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
local function open_default()
|
||||
vim.cmd('terminal')
|
||||
end
|
||||
|
||||
local function open_relative()
|
||||
local shell = vim.o.shell or 'zsh'
|
||||
local dir = vim.fn.expand('%:p:h')
|
||||
vim.cmd(string.format('edit term://%s//%s', dir, shell))
|
||||
end
|
||||
|
||||
local function open_split()
|
||||
vim.cmd('new')
|
||||
vim.cmd('wincmd J')
|
||||
vim.api.nvim_win_set_height(0, 12)
|
||||
vim.wo.winfixheight = true
|
||||
vim.cmd('term')
|
||||
end
|
||||
|
||||
local function open_vertical()
|
||||
vim.cmd('vsplit')
|
||||
vim.cmd('term')
|
||||
end
|
||||
|
||||
vim.api.nvim_create_user_command('TermDefault', open_default, {})
|
||||
vim.api.nvim_create_user_command('TermRelative', open_relative, {})
|
||||
vim.api.nvim_create_user_command('TermSplit', open_split, {})
|
||||
vim.api.nvim_create_user_command('TermVSplit', open_vertical, {})
|
||||
323
lua/custom/navigation.lua
Normal file
323
lua/custom/navigation.lua
Normal file
@ -0,0 +1,323 @@
|
||||
-- Minimal fuzzy finder + content search for Neovim 0.11+
|
||||
-- Optional: `fdfind` or `fd` for file listing, and `rg` (ripgrep) for text search.
|
||||
|
||||
local Fuzzy = {}
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-- 🧩 Helpers
|
||||
--------------------------------------------------------------------
|
||||
|
||||
-- Collect all files (try fdfind/fd first, then globpath)
|
||||
local function get_file_list()
|
||||
local handle = io.popen('fdfind --type f 2>/dev/null || fd --type f 2>/dev/null')
|
||||
if handle then
|
||||
local result = handle:read('*a')
|
||||
handle:close()
|
||||
if result and result ~= '' then
|
||||
return vim.split(result, '\n', { trimempty = true })
|
||||
end
|
||||
end
|
||||
return vim.fn.globpath('.', '**/*', false, true)
|
||||
end
|
||||
|
||||
-- Create floating input + result windows
|
||||
local function open_float(prompt)
|
||||
local input_buf = vim.api.nvim_create_buf(false, true)
|
||||
local result_buf = vim.api.nvim_create_buf(false, true)
|
||||
|
||||
-- mark both buffers as scratch/unlisted
|
||||
for _, b in ipairs({ input_buf, result_buf }) do
|
||||
vim.bo[b].bufhidden = 'wipe'
|
||||
vim.bo[b].buflisted = false
|
||||
vim.bo[b].swapfile = false
|
||||
end
|
||||
vim.bo[input_buf].buftype = 'prompt'
|
||||
vim.bo[result_buf].buftype = 'nofile'
|
||||
|
||||
local width = math.floor(vim.o.columns * 0.7)
|
||||
local height = 20
|
||||
local row = math.floor((vim.o.lines - height) / 2)
|
||||
local col = math.floor((vim.o.columns - width) / 2)
|
||||
|
||||
local input_win = vim.api.nvim_open_win(input_buf, true, {
|
||||
relative = 'editor',
|
||||
row = row,
|
||||
col = col,
|
||||
width = width,
|
||||
height = 1,
|
||||
style = 'minimal',
|
||||
border = 'rounded',
|
||||
})
|
||||
vim.fn.prompt_setprompt(input_buf, prompt)
|
||||
|
||||
local result_win = vim.api.nvim_open_win(result_buf, false, {
|
||||
relative = 'editor',
|
||||
row = row + 2,
|
||||
col = col,
|
||||
width = width,
|
||||
height = height - 2,
|
||||
style = 'minimal',
|
||||
border = 'single',
|
||||
})
|
||||
|
||||
return input_buf, result_buf, input_win, result_win
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-- 🔵 Highlight current selection
|
||||
--------------------------------------------------------------------
|
||||
function Fuzzy:highlight_selection()
|
||||
if not self.result_buf then
|
||||
return
|
||||
end
|
||||
if not self.ns_id then
|
||||
self.ns_id = vim.api.nvim_create_namespace('FuzzyHighlight')
|
||||
end
|
||||
vim.api.nvim_buf_clear_namespace(self.result_buf, self.ns_id, 0, -1)
|
||||
if self.matches and self.matches[self.cursor] then
|
||||
local rel_cursor = self.cursor - (self.scroll or 0)
|
||||
if rel_cursor >= 1 and rel_cursor <= self.page_size then
|
||||
vim.api.nvim_buf_set_extmark(self.result_buf, self.ns_id, rel_cursor - 1, 0, {
|
||||
end_line = rel_cursor,
|
||||
hl_group = 'Visual',
|
||||
hl_eol = true,
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-- 🔴 Close all floating windows
|
||||
--------------------------------------------------------------------
|
||||
function Fuzzy.close()
|
||||
local wins = { Fuzzy.input_win, Fuzzy.result_win }
|
||||
for _, win in ipairs(wins) do
|
||||
if win and vim.api.nvim_win_is_valid(win) then
|
||||
vim.api.nvim_win_close(win, true)
|
||||
end
|
||||
end
|
||||
Fuzzy.active = false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-- 🟢 File finder
|
||||
--------------------------------------------------------------------
|
||||
function Fuzzy.open()
|
||||
if Fuzzy.active then
|
||||
Fuzzy.close()
|
||||
end
|
||||
Fuzzy.active = true
|
||||
|
||||
Fuzzy.files = get_file_list()
|
||||
Fuzzy.matches = Fuzzy.files
|
||||
Fuzzy.cursor = 1
|
||||
Fuzzy.scroll = 0
|
||||
Fuzzy.page_size = 50
|
||||
|
||||
Fuzzy.input_buf, Fuzzy.result_buf, Fuzzy.input_win, Fuzzy.result_win = open_float('Search: ')
|
||||
|
||||
local function render_results()
|
||||
local total = #Fuzzy.matches
|
||||
if total == 0 then
|
||||
vim.api.nvim_buf_set_lines(Fuzzy.result_buf, 0, -1, false, { '-- no matches --' })
|
||||
return
|
||||
end
|
||||
local start_idx = Fuzzy.scroll + 1
|
||||
local end_idx = math.min(start_idx + Fuzzy.page_size - 1, total)
|
||||
local display = {}
|
||||
for i = start_idx, end_idx do
|
||||
display[#display + 1] = Fuzzy.matches[i]
|
||||
end
|
||||
vim.api.nvim_buf_set_lines(Fuzzy.result_buf, 0, -1, false, display)
|
||||
Fuzzy:highlight_selection()
|
||||
end
|
||||
|
||||
local function update_results(text)
|
||||
if text == '' then
|
||||
Fuzzy.matches = Fuzzy.files
|
||||
else
|
||||
Fuzzy.matches = vim.fn.matchfuzzy(Fuzzy.files, text)
|
||||
end
|
||||
Fuzzy.cursor, Fuzzy.scroll = 1, 0
|
||||
render_results()
|
||||
end
|
||||
|
||||
vim.api.nvim_create_autocmd({ 'TextChangedI', 'TextChangedP' }, {
|
||||
buffer = Fuzzy.input_buf,
|
||||
callback = function()
|
||||
local text = vim.fn.getline('.'):gsub('^Search:%s*', '')
|
||||
update_results(text)
|
||||
end,
|
||||
})
|
||||
|
||||
vim.keymap.set('i', '<C-n>', function()
|
||||
if Fuzzy.cursor < #Fuzzy.matches then
|
||||
Fuzzy.cursor = Fuzzy.cursor + 1
|
||||
if Fuzzy.cursor > Fuzzy.scroll + Fuzzy.page_size then
|
||||
Fuzzy.scroll = Fuzzy.scroll + 1
|
||||
end
|
||||
render_results()
|
||||
end
|
||||
end, { buffer = Fuzzy.input_buf })
|
||||
|
||||
vim.keymap.set('i', '<C-p>', function()
|
||||
if Fuzzy.cursor > 1 then
|
||||
Fuzzy.cursor = Fuzzy.cursor - 1
|
||||
if Fuzzy.cursor <= Fuzzy.scroll then
|
||||
Fuzzy.scroll = math.max(Fuzzy.scroll - 1, 0)
|
||||
end
|
||||
render_results()
|
||||
end
|
||||
end, { buffer = Fuzzy.input_buf })
|
||||
|
||||
vim.keymap.set('i', '<CR>', function()
|
||||
local choice = Fuzzy.matches[Fuzzy.cursor]
|
||||
if choice then
|
||||
Fuzzy.close()
|
||||
vim.cmd.edit(vim.fn.fnameescape(choice))
|
||||
end
|
||||
end, { buffer = Fuzzy.input_buf })
|
||||
|
||||
vim.keymap.set('i', '<Esc>', Fuzzy.close, { buffer = Fuzzy.input_buf })
|
||||
vim.keymap.set('i', '<C-c>', Fuzzy.close, { buffer = Fuzzy.input_buf })
|
||||
vim.keymap.set('n', '<Esc>', Fuzzy.close, { buffer = Fuzzy.input_buf })
|
||||
vim.keymap.set('n', 'q', Fuzzy.close, { buffer = Fuzzy.input_buf })
|
||||
|
||||
vim.cmd.startinsert()
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-- 🟣 Ripgrep-based content search (scrolling + match highlighting)
|
||||
--------------------------------------------------------------------
|
||||
function Fuzzy.open_grep()
|
||||
if Fuzzy.active then
|
||||
Fuzzy.close()
|
||||
end
|
||||
Fuzzy.active = true
|
||||
|
||||
Fuzzy.input_buf, Fuzzy.result_buf, Fuzzy.input_win, Fuzzy.result_win = open_float('Grep: ')
|
||||
Fuzzy.matches, Fuzzy.cursor, Fuzzy.scroll = {}, 1, 0
|
||||
Fuzzy.page_size = 50
|
||||
Fuzzy.ns_id = vim.api.nvim_create_namespace('FuzzyHighlight')
|
||||
|
||||
local function render_results(query)
|
||||
local total = #Fuzzy.matches
|
||||
if total == 0 then
|
||||
vim.api.nvim_buf_set_lines(Fuzzy.result_buf, 0, -1, false, { '-- no matches --' })
|
||||
return
|
||||
end
|
||||
|
||||
local start_idx = Fuzzy.scroll + 1
|
||||
local end_idx = math.min(start_idx + Fuzzy.page_size - 1, total)
|
||||
local display = {}
|
||||
for i = start_idx, end_idx do
|
||||
display[#display + 1] = Fuzzy.matches[i]
|
||||
end
|
||||
|
||||
vim.api.nvim_buf_set_lines(Fuzzy.result_buf, 0, -1, false, display)
|
||||
vim.api.nvim_buf_clear_namespace(Fuzzy.result_buf, Fuzzy.ns_id, 0, -1)
|
||||
|
||||
-- highlight selection
|
||||
local rel_cursor = math.min(Fuzzy.cursor - Fuzzy.scroll, #display)
|
||||
vim.api.nvim_buf_set_extmark(Fuzzy.result_buf, Fuzzy.ns_id, rel_cursor - 1, 0, {
|
||||
end_line = rel_cursor,
|
||||
hl_group = 'Visual',
|
||||
hl_eol = true,
|
||||
})
|
||||
|
||||
-- highlight query matches
|
||||
if query and query ~= '' then
|
||||
local pattern = vim.pesc(query)
|
||||
for i, line in ipairs(display) do
|
||||
for s, e in line:gmatch('()' .. pattern .. '()') do
|
||||
vim.api.nvim_buf_set_extmark(Fuzzy.result_buf, Fuzzy.ns_id, i - 1, s - 1, {
|
||||
end_col = e - 1,
|
||||
hl_group = 'Search',
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function run_grep(query)
|
||||
if query == '' then
|
||||
vim.api.nvim_buf_set_lines(Fuzzy.result_buf, 0, -1, false, { '-- type to search --' })
|
||||
return
|
||||
end
|
||||
local handle = io.popen('rg --vimgrep --hidden --smart-case ' .. vim.fn.shellescape(query))
|
||||
if not handle then
|
||||
return
|
||||
end
|
||||
local result = handle:read('*a')
|
||||
handle:close()
|
||||
Fuzzy.matches = vim.split(result, '\n', { trimempty = true })
|
||||
Fuzzy.cursor, Fuzzy.scroll = 1, 0
|
||||
render_results(query)
|
||||
end
|
||||
|
||||
vim.api.nvim_create_autocmd({ 'TextChangedI', 'TextChangedP' }, {
|
||||
buffer = Fuzzy.input_buf,
|
||||
callback = function()
|
||||
local text = vim.fn.getline('.'):gsub('^Grep:%s*', '')
|
||||
run_grep(text)
|
||||
end,
|
||||
})
|
||||
|
||||
vim.keymap.set('i', '<C-n>', function()
|
||||
if Fuzzy.cursor < #Fuzzy.matches then
|
||||
Fuzzy.cursor = Fuzzy.cursor + 1
|
||||
if Fuzzy.cursor > Fuzzy.scroll + Fuzzy.page_size then
|
||||
Fuzzy.scroll = Fuzzy.scroll + 1
|
||||
end
|
||||
local query = vim.fn.getline('.'):gsub('^Grep:%s*', '')
|
||||
render_results(query)
|
||||
end
|
||||
end, { buffer = Fuzzy.input_buf })
|
||||
|
||||
vim.keymap.set('i', '<C-p>', function()
|
||||
if Fuzzy.cursor > 1 then
|
||||
Fuzzy.cursor = Fuzzy.cursor - 1
|
||||
if Fuzzy.cursor <= Fuzzy.scroll then
|
||||
Fuzzy.scroll = math.max(Fuzzy.scroll - 1, 0)
|
||||
end
|
||||
local query = vim.fn.getline('.'):gsub('^Grep:%s*', '')
|
||||
render_results(query)
|
||||
end
|
||||
end, { buffer = Fuzzy.input_buf })
|
||||
|
||||
vim.keymap.set('i', '<CR>', function()
|
||||
local line = Fuzzy.matches[Fuzzy.cursor]
|
||||
if line then
|
||||
local parts = vim.split(line, ':')
|
||||
local file, lnum = parts[1], tonumber(parts[2]) or 1
|
||||
Fuzzy.close()
|
||||
vim.cmd.edit(vim.fn.fnameescape(file))
|
||||
vim.api.nvim_win_set_cursor(0, { lnum, 0 })
|
||||
end
|
||||
end, { buffer = Fuzzy.input_buf })
|
||||
|
||||
vim.keymap.set('i', '<Esc>', function()
|
||||
Fuzzy.close()
|
||||
end, { buffer = Fuzzy.input_buf })
|
||||
|
||||
vim.cmd.startinsert()
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-- 🧩 Commands & Keymaps
|
||||
--------------------------------------------------------------------
|
||||
vim.api.nvim_create_user_command('FuzzyLive', function()
|
||||
Fuzzy.open()
|
||||
end, {})
|
||||
vim.api.nvim_create_user_command('FuzzyGrep', function()
|
||||
Fuzzy.open_grep()
|
||||
end, {})
|
||||
|
||||
vim.keymap.set('n', '<leader>f', function()
|
||||
vim.cmd.FuzzyLive()
|
||||
end, { desc = 'Open fuzzy file finder' })
|
||||
vim.keymap.set('n', '<leader>g', function()
|
||||
vim.cmd.FuzzyGrep()
|
||||
end, { desc = 'Search file contents with ripgrep' })
|
||||
|
||||
return Fuzzy
|
||||
26
lua/plugins/colorscheme.lua
Normal file
26
lua/plugins/colorscheme.lua
Normal file
@ -0,0 +1,26 @@
|
||||
return {
|
||||
'triimdev/invero.nvim',
|
||||
lazy = false,
|
||||
priority = 1000,
|
||||
dev = true,
|
||||
config = function()
|
||||
vim.api.nvim_create_user_command('ReloadInvero', function()
|
||||
require('invero').invalidate_cache()
|
||||
vim.cmd('Lazy reload invero.nvim')
|
||||
end, {})
|
||||
|
||||
require('invero').setup({
|
||||
highlights = function(c, tool)
|
||||
c.bg_float = tool(152)
|
||||
return {
|
||||
WinSeparator = { fg = c.outline, bg = c.base },
|
||||
StatusLine = { fg = c.outline, bg = c.base },
|
||||
StatusLineNC = { fg = c.text, bg = c.base, bold = true },
|
||||
}
|
||||
end,
|
||||
})
|
||||
|
||||
vim.o.background = 'light'
|
||||
vim.cmd.colorscheme('invero')
|
||||
end,
|
||||
}
|
||||
148
lua/plugins/filetree.lua
Normal file
148
lua/plugins/filetree.lua
Normal file
@ -0,0 +1,148 @@
|
||||
local function my_on_attach(bufnr)
|
||||
local api = require('nvim-tree.api')
|
||||
local opts = { buffer = bufnr }
|
||||
|
||||
-- basics: copy/cut/paste/create/rename/remove
|
||||
vim.keymap.set('n', 'c', api.fs.copy.node, opts)
|
||||
vim.keymap.set('n', 'x', api.fs.cut, opts)
|
||||
vim.keymap.set('n', 'p', api.fs.paste, opts)
|
||||
vim.keymap.set('n', 'a', api.fs.create, opts)
|
||||
vim.keymap.set('n', 'r', api.fs.rename, opts)
|
||||
vim.keymap.set('n', 'R', api.fs.rename_basename, opts)
|
||||
vim.keymap.set('n', 'd', api.fs.remove, opts)
|
||||
|
||||
-- bulk mark and delete/move
|
||||
vim.keymap.set('n', 's', api.marks.toggle, opts)
|
||||
vim.keymap.set('n', 'S', api.marks.clear, opts)
|
||||
vim.keymap.set('n', 'bd', api.marks.bulk.delete, opts)
|
||||
vim.keymap.set('n', 'bm', api.marks.bulk.move, opts)
|
||||
|
||||
-- copy filename/path
|
||||
vim.keymap.set('n', 'y', api.fs.copy.filename, opts)
|
||||
vim.keymap.set('n', 'Y', api.fs.copy.relative_path, opts)
|
||||
vim.keymap.set('n', 'gy', api.fs.copy.absolute_path, opts)
|
||||
vim.keymap.set('n', 'ge', api.fs.copy.basename, opts)
|
||||
|
||||
-- expand/collapse
|
||||
vim.keymap.set('n', 'e', api.tree.expand_all, opts)
|
||||
vim.keymap.set('n', 'E', api.tree.collapse_all, opts)
|
||||
|
||||
-- filter
|
||||
vim.keymap.set('n', 'f', api.live_filter.start, opts)
|
||||
vim.keymap.set('n', 'F', api.live_filter.clear, opts)
|
||||
|
||||
-- navigate
|
||||
vim.keymap.set('n', 'J', api.node.navigate.sibling.last, opts)
|
||||
vim.keymap.set('n', 'K', api.node.navigate.sibling.first, opts)
|
||||
vim.keymap.set('n', 'P', api.node.navigate.parent, opts)
|
||||
|
||||
-- open
|
||||
vim.keymap.set('n', '<CR>', api.node.open.edit, opts)
|
||||
vim.keymap.set('n', 'o', api.node.open.edit, opts)
|
||||
vim.keymap.set('n', 'O', api.node.open.no_window_picker, opts)
|
||||
|
||||
-- miscellaneous
|
||||
vim.keymap.set('n', 'K', api.node.show_info_popup, opts)
|
||||
vim.keymap.set('n', 'U', api.tree.reload, opts)
|
||||
end
|
||||
|
||||
return {
|
||||
'nvim-tree/nvim-tree.lua',
|
||||
version = '*',
|
||||
dev = true,
|
||||
opts = {
|
||||
on_attach = my_on_attach,
|
||||
view = { signcolumn = 'no' },
|
||||
actions = { file_popup = { open_win_config = { border = 'rounded' } } },
|
||||
renderer = {
|
||||
root_folder_label = false,
|
||||
-- root_folder_label = function(path)
|
||||
-- return '-- ' .. vim.fn.fnamemodify(path, ':t') .. ' --'
|
||||
-- end,
|
||||
special_files = {},
|
||||
|
||||
highlight_hidden = 'all',
|
||||
highlight_clipboard = 'all',
|
||||
|
||||
indent_markers = {
|
||||
enable = true,
|
||||
inline_arrows = false,
|
||||
icons = { corner = '│', none = '│', bottom = ' ' },
|
||||
},
|
||||
icons = {
|
||||
bookmarks_placement = 'after',
|
||||
git_placement = 'after',
|
||||
show = {
|
||||
file = false,
|
||||
folder = false,
|
||||
folder_arrow = false, -- KEEP FALSE
|
||||
git = true,
|
||||
modified = false,
|
||||
hidden = false,
|
||||
diagnostics = false,
|
||||
bookmarks = true,
|
||||
},
|
||||
glyphs = {
|
||||
-- default = '•',
|
||||
default = ' ',
|
||||
symlink = '',
|
||||
bookmark = '',
|
||||
modified = '●',
|
||||
hidden = '',
|
||||
folder = {
|
||||
arrow_closed = '',
|
||||
arrow_open = '',
|
||||
default = '▸',
|
||||
open = '▾',
|
||||
empty = '',
|
||||
empty_open = '',
|
||||
symlink = '',
|
||||
symlink_open = '',
|
||||
},
|
||||
|
||||
git = {
|
||||
unstaged = '◇', -- '✗',
|
||||
staged = '',
|
||||
unmerged = '',
|
||||
renamed = '',
|
||||
untracked = '',
|
||||
deleted = '', -- '',
|
||||
ignored = '',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
hijack_cursor = true,
|
||||
prefer_startup_root = true,
|
||||
update_focused_file = {
|
||||
enable = true,
|
||||
update_root = { enable = true, ignore_list = {} },
|
||||
exclude = false,
|
||||
},
|
||||
modified = { enable = true, show_on_dirs = true, show_on_open_dirs = true },
|
||||
filters = {
|
||||
enable = true,
|
||||
git_ignored = true,
|
||||
dotfiles = false,
|
||||
git_clean = false,
|
||||
no_buffer = false,
|
||||
no_bookmark = false,
|
||||
custom = {},
|
||||
exclude = {},
|
||||
},
|
||||
filesystem_watchers = {
|
||||
enable = true,
|
||||
debounce_delay = 50,
|
||||
ignore_dirs = {
|
||||
'/.git',
|
||||
'/.DS_Store',
|
||||
'/build',
|
||||
'/dist',
|
||||
'/public',
|
||||
'/node_modules',
|
||||
'/target',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
128
lua/plugins/syntax.lua
Normal file
128
lua/plugins/syntax.lua
Normal file
@ -0,0 +1,128 @@
|
||||
vim.keymap.set('n', '<leader>d', vim.diagnostic.open_float, { noremap = true, silent = true })
|
||||
|
||||
vim.diagnostic.config({
|
||||
update_in_insert = false,
|
||||
virtual_text = {
|
||||
prefix = '', -- remove annoying ▎ etc
|
||||
format = function(diagnostic)
|
||||
if diagnostic.source then
|
||||
return string.format('[%s] %s', diagnostic.source, diagnostic.message)
|
||||
end
|
||||
return diagnostic.message
|
||||
end,
|
||||
},
|
||||
float = {
|
||||
border = 'rounded',
|
||||
source = true, -- show source in floating window too
|
||||
},
|
||||
severity_sort = true,
|
||||
})
|
||||
|
||||
vim.lsp.enable({ 'lua_ls' })
|
||||
vim.lsp.enable({ 'json_ls' })
|
||||
|
||||
return {
|
||||
{ 'mason-org/mason.nvim', config = true },
|
||||
{ 'windwp/nvim-ts-autotag', config = true },
|
||||
{ 'windwp/nvim-autopairs', event = 'InsertEnter', config = true },
|
||||
|
||||
-- { 'saghen/blink.cmp', version = '1.*' },
|
||||
{
|
||||
'nvim-treesitter/nvim-treesitter',
|
||||
build = ':TSUpdate',
|
||||
main = 'nvim-treesitter.configs',
|
||||
opts = {
|
||||
highlight = { enable = true },
|
||||
incremental_selection = { enable = true },
|
||||
textobjects = { enable = true },
|
||||
ensure_installed = {
|
||||
-- Documentation
|
||||
'vim',
|
||||
'vimdoc',
|
||||
'markdown',
|
||||
'markdown_inline',
|
||||
-- Data
|
||||
'gitcommit',
|
||||
'gitignore',
|
||||
'dockerfile',
|
||||
'diff',
|
||||
'json',
|
||||
'jsonc',
|
||||
-- Scripting
|
||||
'bash',
|
||||
'lua',
|
||||
'sql',
|
||||
-- Programming
|
||||
'c',
|
||||
'cpp',
|
||||
'go',
|
||||
'rust',
|
||||
'python',
|
||||
-- Web
|
||||
'html',
|
||||
'css',
|
||||
'javascript',
|
||||
'typescript',
|
||||
'tsx',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
'mfussenegger/nvim-lint',
|
||||
event = { 'BufReadPre', 'BufNewFile' },
|
||||
opts = {
|
||||
linters_by_ft = {
|
||||
lua = { 'luacheck' },
|
||||
python = { 'ruff' },
|
||||
javascript = { 'eslint_d' },
|
||||
},
|
||||
},
|
||||
config = function(_, opts)
|
||||
local lint = require('lint')
|
||||
lint.linters_by_ft = opts.linters_by_ft
|
||||
vim.api.nvim_create_autocmd({ 'BufEnter', 'BufWritePost', 'InsertLeave' }, {
|
||||
group = vim.api.nvim_create_augroup('lint_autocmd', { clear = true }),
|
||||
callback = function()
|
||||
lint.try_lint()
|
||||
end,
|
||||
})
|
||||
end,
|
||||
},
|
||||
{
|
||||
'stevearc/conform.nvim',
|
||||
event = { 'BufWritePre' },
|
||||
opts = {
|
||||
-- Automatically format on save
|
||||
format_on_save = {
|
||||
timeout_ms = 500,
|
||||
lsp_format = 'fallback', -- Use LSP when no formatter is configured
|
||||
},
|
||||
|
||||
-- Formatters per filetype
|
||||
default_format_opts = { stop_after_first = true },
|
||||
formatters_by_ft = {
|
||||
lua = { 'stylua' },
|
||||
sh = { 'shfmt' },
|
||||
swift = { 'swift_format' },
|
||||
python = { 'isort', 'black' },
|
||||
json = { 'jq' },
|
||||
javascript = { 'prettierd', 'prettier' },
|
||||
javascriptreact = { 'prettierd', 'prettier' },
|
||||
typescript = { 'prettierd', 'prettier' },
|
||||
typescriptreact = { 'prettierd', 'prettier' },
|
||||
},
|
||||
},
|
||||
|
||||
config = function(_, opts)
|
||||
require('conform').setup(opts)
|
||||
|
||||
-- Create a command to format manually
|
||||
vim.api.nvim_create_user_command('Format', function()
|
||||
require('conform').format({
|
||||
async = true,
|
||||
lsp_format = 'fallback',
|
||||
})
|
||||
end, { desc = 'Format current buffer' })
|
||||
end,
|
||||
},
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user