LSP document : https://neovim.io/doc/user/lsp.html
Bolck fold document : https://neovim.io/doc/user/fold.html
Regular expression pattern : https://neovim.io/doc/user/pattern.html
Lazyvim : https://www.lazyvim.org/configuration/lazy.nvim
1. init.lua
if not use init.lua but use init.vim, try add
lua require("init")
in init.vim file
2. Install font
https://www.nerdfonts.com/font-downloads
After download, install, and select font with "mono"
3. Change window size
Use ctrl + <-, ->
There are several window commands that allow you to do this:
- Ctrl+W +/-: increase/decrease height (ex.
20<C-w>+) - Ctrl+W >/<: increase/decrease width (ex.
30<C-w><) - Ctrl+W _: set height (ex.
50<C-w>_) - Ctrl+W |: set width (ex.
50<C-w>|) - Ctrl+W =: equalize width and height of all windows
See also: :help CTRL-W
https://vi.stackexchange.com/questions/514/how-do-i-change-the-current-splits-width-and-height
3.a. Block collapse/fold/open
https://neovim.io/doc/user/fold.html
Fold : zc
Open : zo
...
4. Change window
User
ctrl + h,j,k,l
or
c + ww
5. Show hidden file in tree
H ( shift + h )
6. switch tab ( edit buffer ) in edit view
H, L (shift + h / shift + l)
7. handle buffer
space + b + ...
8. install lsp
:LazyExtras
press 'x' to enable plugin lsp
one can use '/' to search, for example : /lang.go search for golang
9. Nevigate
g : show go to menu
gd : goto definition
gD : goto declaration
gc : comment lines
^o : back
9: #j : go to relative j line , #k : go to k relative line above
10 : >> : ident right, << : ident left
11 : " ff" find in files , " fF" find in file of pwd
12 : ":Telescope live_grep" life grep
13 : check plugin function : :checkhealth telescope
14 : check keymap : :verbose map <leader>fg
15 : add live grep keyp map
15.a : reference to lazy/telescope.nvim/README.md, here we can use
Normal :
nnoremap <leader>fg <cmd>Telescope live_grep<cr>
Lua :
nnoremap <leader>fg <cmd>lua require('telescope.builtin').live_grep()<cr>
15.b : modify lazy/LazyVim/lua/lazyvim/plugins/extras/editor/telescope.lua, add a line
{ "<leader>fG", "<cmd>Telescope live_grep<cr>", desc = "Telescope live_grep" },
15.c : ^q : you will leave the find result in the split buffer below
15.d : multiple file replace : :cdo %s/xxx/yyy/gc
15.e : map "current cursor text" to search
{ "<leader>fs", "<cmd>Telescope grep_string<cr>", desc = "Telescope grep_string" },
16. Debug golang
To use nvim debug golang, we need
1. delve
2. dap related modules
2.1 dap-core, nvim-dap, nvim-dap-ui, nvim-dap-go
2.2 after install, use <leader>d will enter debug mode
17. Grep string under cursor
{ "<leader>sw", LazyVim.pick("grep_string", { word_match = "-w" }), desc = "Word (Root Dir)" },
{ "<leader>sW", LazyVim.pick("grep_string", { root = false, word_match = "-w" }), desc = "Word (cwd)" },
{ "<leader>sw", LazyVim.pick("grep_string"), mode = "v", desc = "Selection (Root Dir)" },
{ "<leader>sW", LazyVim.pick("grep_string", { root = false }), mode = "v", desc = "Selection (cwd)" },
{ "<leader>uC", LazyVim.pick("colorscheme", { enable_preview = true }), desc = "Colorscheme with Preview" },
diff --git a/lua/lazyvim/plugins/extras/editor/telescope.lua b/lua/lazyvim/plugins/extras/editor/telescope.lua
index 55ccace..0806788 100644
--- a/lua/lazyvim/plugins/extras/editor/telescope.lua
+++ b/lua/lazyvim/plugins/extras/editor/telescope.lua
@@ -108,6 +108,8 @@ return {
{ "<leader>ff", LazyVim.pick("files"), desc = "Find Files (Root Dir)" },
{ "<leader>fF", LazyVim.pick("files", { root = false }), desc = "Find Files (cwd)" },
{ "<leader>fg", "<cmd>Telescope git_files<cr>", desc = "Find Files (git-files)" },
+ { "<leader>fG", "<cmd>Telescope live_grep<cr>", desc = "Telescope live_grep" },
+ { "<leader>fs", "<cmd>Telescope grep_string<cr>", desc = "Telescope grep_string" },
{ "<leader>fr", "<cmd>Telescope oldfiles<cr>", desc = "Recent" },
{ "<leader>fR", LazyVim.pick("oldfiles", { cwd = vim.uv.cwd() }), desc = "Recent (cwd)" },
-- git
17. Formating
Json : :%!jq '.' , https://codegoalie.com/posts/format-json-nvim-jq/
18. Use ctags : golang
ctags -R --languages=Go .
19. Add a plugin
a. path is ~/.config/nvim/lua/plugins
b. put xxx.lua under it
c. example
-- since this is just an example spec, don't actually load anything here and return an empty spec
-- stylua: ignore
if true then return {} end
-- every spec file under the "plugins" directory will be loaded automatically by lazy.nvim
--
-- In your plugin files, you can:
-- * add extra plugins
-- * disable/enabled LazyVim plugins
-- * override the configuration of LazyVim plugins
return {
-- add gruvbox
{ "ellisonleao/gruvbox.nvim" },
-- Configure LazyVim to load gruvbox
{
"LazyVim/LazyVim",
opts = {
colorscheme = "gruvbox",
},
},
-- change trouble config
{
"folke/trouble.nvim",
-- opts will be merged with the parent spec
opts = { use_diagnostic_signs = true },
},
-- disable trouble
{ "folke/trouble.nvim", enabled = false },
-- override nvim-cmp and add cmp-emoji
{
"hrsh7th/nvim-cmp",
dependencies = { "hrsh7th/cmp-emoji" },
---@param opts cmp.ConfigSchema
opts = function(_, opts)
table.insert(opts.sources, { name = "emoji" })
end,
},
-- change some telescope options and a keymap to browse plugin files
{
"nvim-telescope/telescope.nvim",
keys = {
-- add a keymap to browse plugin files
-- stylua: ignore
{
"<leader>fp",
function() require("telescope.builtin").find_files({ cwd = require("lazy.core.config").options.root }) end,
desc = "Find Plugin File",
},
},
-- change some options
opts = {
defaults = {
layout_strategy = "horizontal",
layout_config = { prompt_position = "top" },
sorting_strategy = "ascending",
winblend = 0,
},
},
},
-- add pyright to lspconfig
{
"neovim/nvim-lspconfig",
---@class PluginLspOpts
opts = {
---@type lspconfig.options
servers = {
-- pyright will be automatically installed with mason and loaded with lspconfig
pyright = {},
},
},
},
-- add tsserver and setup with typescript.nvim instead of lspconfig
{
"neovim/nvim-lspconfig",
dependencies = {
"jose-elias-alvarez/typescript.nvim",
init = function()
require("lazyvim.util").lsp.on_attach(function(_, buffer)
-- stylua: ignore
vim.keymap.set( "n", "<leader>co", "TypescriptOrganizeImports", { buffer = buffer, desc = "Organize Imports" })
vim.keymap.set("n", "<leader>cR", "TypescriptRenameFile", { desc = "Rename File", buffer = buffer })
end)
end,
},
---@class PluginLspOpts
opts = {
---@type lspconfig.options
servers = {
-- tsserver will be automatically installed with mason and loaded with lspconfig
tsserver = {},
},
-- you can do any additional lsp server setup here
-- return true if you don't want this server to be setup with lspconfig
---@type table<string, fun(server:string, opts:_.lspconfig.options):boolean?>
setup = {
-- example to setup with typescript.nvim
tsserver = function(_, opts)
require("typescript").setup({ server = opts })
return true
end,
-- Specify * to use this function as a fallback for any server
-- ["*"] = function(server, opts) end,
},
},
},
-- for typescript, LazyVim also includes extra specs to properly setup lspconfig,
-- treesitter, mason and typescript.nvim. So instead of the above, you can use:
{ import = "lazyvim.plugins.extras.lang.typescript" },
-- add more treesitter parsers
{
"nvim-treesitter/nvim-treesitter",
opts = {
ensure_installed = {
"bash",
"html",
"javascript",
"json",
"lua",
"markdown",
"markdown_inline",
"python",
"query",
"regex",
"tsx",
"typescript",
"vim",
"yaml",
},
},
},
-- since `vim.tbl_deep_extend`, can only merge tables and not lists, the code above
-- would overwrite `ensure_installed` with the new value.
-- If you'd rather extend the default config, use the code below instead:
{
"nvim-treesitter/nvim-treesitter",
opts = function(_, opts)
-- add tsx and treesitter
vim.list_extend(opts.ensure_installed, {
"tsx",
"typescript",
})
end,
},
-- the opts function can also be used to change the default opts:
{
"nvim-lualine/lualine.nvim",
event = "VeryLazy",
opts = function(_, opts)
table.insert(opts.sections.lualine_x, {
function()
return "😄"
end,
})
end,
},
-- or you can return new options to override all the defaults
{
"nvim-lualine/lualine.nvim",
event = "VeryLazy",
opts = function()
return {
--[[add your custom lualine config here]]
}
end,
},
-- use mini.starter instead of alpha
{ import = "lazyvim.plugins.extras.ui.mini-starter" },
-- add jsonls and schemastore packages, and setup treesitter for json, json5 and jsonc
{ import = "lazyvim.plugins.extras.lang.json" },
-- add any tools you want to have installed below
{
"williamboman/mason.nvim",
opts = {
ensure_installed = {
"stylua",
"shellcheck",
"shfmt",
"flake8",
},
},
},
}
d. to disable a plugin, add the following
if true then
return {}
end
20 : After update nvim packages
a. Example : Lazy with U or LazyExtras
b. Example : update node version
c. Example : update golang version
What will happen : some package need update
1. gopls : go install golang.org/x/tools/gopls@latest
2. mason update : :MasonUpdate
3. :MasonInstall gopls
21 : Code trace for search function : <leader>-/
I'll help you find how `<leader>-/` is defined in your Neovim configuration and which function it calls. Let me search through your configuration files.
Searched codebase for "leader / keymap mapping toggle comment", 16 results
Let me search more specifically for the `<leader>/` keymap pattern:
Searched for text `<leader>/`, 12 results
Great! Now let me look at the LazyVim core configuration files to understand which picker is being used by default:
Read [](file:///Users/holmaschen/.local/share/nvim/lazy/LazyVim/lua/lazyvim/plugins/extras/editor/snacks_picker.lua)
Now let me check the LazyVim configuration to see which picker is being used and examine the `LazyVim.pick()` function:
Searched for text `LazyVim.pick` (`**/lazy/LazyVim/lua/**`), 20 results
Let me examine the core LazyVim pick utility module:
Searched for text `LazyVim.pick` (`**/lazy/LazyVim/lua/lazyvim/util/**`), 4 results
Read [](file:///Users/holmaschen/.local/share/nvim/lazy/LazyVim/lua/lazyvim/util/pick.lua)
Now let me check which picker is currently active in your LazyVim setup. Let me look for plugin configuration files that might define which picker is loaded:
Searched for files matching `**/init.lua`, 10 matches
Let me look for your Neovim configuration outside the lazy plugin directory:
Read [](file:///Users/holmaschen/.local/share/nvim)
Let me check your Neovim config directory (typically in `~/.config/nvim`):
Searched for files matching `**/~/.config/nvim/**`, no matches
Ran terminal command: find ~ -name "nvim" -type d 2>/dev/null | head -5
Let me check your actual Neovim configuration:
Read [](file:///Users/holmaschen/.config/nvim)
Let me check what picker is currently active by looking for any loaded configurations or running a Neovim command:
Ran terminal command: nvim --headless -c "lua if LazyVim and LazyVim.pick and LazyVim.pick.picker then print(LazyVim.pick.picker.name) else print('LazyVim not loaded') end" +q 2>/dev/null || echo "Could not determine picker"
Let me check what is likely configured by looking at your loaded plugins:
Searched codebase for "telescope installed configured keymap picker settings", 26 results
Based on my search through your Neovim configuration, I can now explain how `<leader>/` is defined and which function it calls.
## How `<leader>/` is defined
The `<leader>/` keymap is defined in different ways depending on which picker plugin is active in your LazyVim configuration. Looking at your setup, there are three possible picker plugins that could be active:
1. **Snacks Picker** (most likely)
2. **Telescope**
3. **FZF-lua**
## Current Implementation
Based on the search results, your configuration appears to be using **Snacks Picker** (the default for LazyVim). Here's how `<leader>/` is defined:
In snacks_picker.lua, line 60:
```lua
{ "<leader>/", LazyVim.pick("grep"), desc = "Grep (Root Dir)" },
```
## Function Call Chain
When you press `<leader>/`, the following function chain is executed:
1. **`LazyVim.pick("grep")`** - This is a wrapper function from pick.lua
2. **`LazyVim.pick.wrap("grep", opts)`** - Returns a function that calls:
3. **`LazyVim.pick.open("grep", opts)`** - Which translates the command and calls:
4. **`M.picker.open(command, opts)`** - Where `M.picker` is the registered picker (Snacks)
5. **`Snacks.picker.pick("grep", opts)`** - The final function that opens the grep interface
## Specific Function Called
The ultimate function that gets called is:
```lua
Snacks.picker.pick("grep", opts)
```
This opens the Snacks picker in grep mode, allowing you to search for text across all files in your project's root directory.
## Alternative Implementations
If you were using different pickers, the keymap would resolve to:
- **Telescope**: `require("telescope.builtin").live_grep(opts)`
- **FZF-lua**: `require("fzf-lua").live_grep(opts)`
The beauty of LazyVim's picker abstraction is that `<leader>/` always provides the same functionality (project-wide text search) regardless of which picker backend you're using, but the underlying implementation changes based on your configuration.
Let me examine how `Snacks.picker.pick("grep", opts)` actually works by looking into the Snacks.nvim source code.
Read [](file:///Users/holmaschen/.local/share/nvim/lazy/snacks.nvim/lua/snacks/picker/init.lua)
Now let me look at the grep source implementation:
Searched codebase for "grep source snacks picker implementation command rg ag ripgrep", 22 results
Now let me look at the actual grep source file to understand the command it uses:
Read [](file:///Users/holmaschen/.local/share/nvim/lazy/snacks.nvim/lua/snacks/picker/source/grep.lua)
Now let me also check the proc source to understand how the command execution works:
Read [](file:///Users/holmaschen/.local/share/nvim/lazy/snacks.nvim/lua/snacks/picker/source/proc.lua)
Perfect! Now I have a complete understanding of how `Snacks.picker.pick("grep", opts)` works. Let me provide you with the detailed explanation.
## How `Snacks.picker.pick("grep", opts)` Actually Works
### 1. Command Used: **Ripgrep (`rg`)**
When you call `Snacks.picker.pick("grep", opts)`, it **uses `rg` (ripgrep)** as the underlying command, NOT `ag`, `grep`, or other tools. This is hardcoded in the source file:
```lua
local function get_cmd(opts, filter)
local cmd = "rg" -- Hardcoded to use ripgrep
-- ... rest of the function
end
```
### 2. Command Arguments
The default `rg` command that gets executed looks like this:
```bash
rg --color=never --no-heading --with-filename --line-number --column --smart-case --max-columns=500 --max-columns-preview -g !.git -- "search_pattern"
```
### 3. How It Works Internally
Here's the complete flow:
1. **`LazyVim.pick("grep")`** → calls **`Snacks.picker.pick("grep", opts)`**
2. **Snacks picker** loads the **grep source** from `/snacks/picker/source/grep.lua`
3. **`get_cmd()` function** builds the ripgrep command with these default arguments:
```lua
local args = {
"--color=never", -- No colored output
"--no-heading", -- Don't group matches by file
"--with-filename", -- Include filename in output
"--line-number", -- Include line numbers
"--column", -- Include column numbers
"--smart-case", -- Smart case matching
"--max-columns=500", -- Limit column width
"--max-columns-preview",
"-g", "!.git", -- Exclude .git directory
}
```
4. **Additional options** are dynamically added based on your configuration:
- `--hidden` or `--no-hidden` (show hidden files)
- `--no-ignore` (show ignored files)
- `-L` (follow symlinks)
- `-t <filetype>` (filter by file type)
- `--fixed-strings` (literal search instead of regex)
- `-g <glob>` (glob patterns)
5. **Process execution**: The command is executed via proc.lua using Neovim's `uv.spawn()` (libuv process spawning)
6. **Real-time output processing**: Results are streamed live as ripgrep finds matches, parsed, and displayed in the picker interface
### 4. Output Processing
The ripgrep output is parsed in real-time:
```lua
-- Example ripgrep output: "file.lua:123:45:some matching text"
local file, line, col, text = item.text:match("^(.+):(%d+):(%d+):(.*)$")
```
Each result is transformed into a structured item with:
- `file`: The file path
- `pos`: Line and column position `[line, col]`
- `line`: The matching text content
### 5. Why Ripgrep?
Snacks picker uses `rg` because it's:
- **Extremely fast** - faster than `ag` and traditional `grep`
- **Feature-rich** - supports smart case, file type filtering, glob patterns
- **Modern** - handles Unicode, respects `.gitignore` by default
- **Reliable** - well-maintained and widely adopted
### 6. No Fallback
Unlike some other tools, Snacks picker **only** uses ripgrep for grep functionality. There's no fallback to `ag`, `grep`, or other search tools. If `rg` is not available, the grep function would fail.
So to directly answer your question: **`Snacks.picker.pick("grep", opts)` calls the `rg` (ripgrep) command**, not `ag`, `grep`, or any other search tool.
沒有留言:
張貼留言