i3wm,Neovim与Alacritty的使用与配置

常用的窗口管理器,编辑器与终端模拟器等等

这些工具都有相对的优劣,我个人觉得生态,稳定性是两个非常重要的因素. 生态好就会有不断的更新和维护,稳定性会让用户更好的长期适应.

i3wm

i3wm是个基于x11的窗口管理器,生态很强fz-wu/i3_user_guide_Chinese: i3wm官方指南,方便同学们学习i3wm. i3是一个平铺式的窗口管理器 (github.com)

Container modes

类似的还有awesome wm,dwm,也有基于wayland的compositor hyprland(没有使用hyprland也是因为感觉还不太稳定,等过段时间再看看).详情看Comparison of tiling window managers - ArchWiki (archlinux.org)Wayland - ArchWiki (archlinux.org)

具体配置文档i3: i3 User’s Guide (i3wm.org)

一个例子i3wm-config/i3/config at master · levinit/i3wm-config (github.com)

i3本身不支持透明等功能,还需要安装其他工具ArchLinux系统i3wm配置及体验记录 – ZocoXX,i3wm-config | my i3wm config (levinit.github.io)

awesomewm

使用lua配置,相对i3的文本配置,个人认为更友好,上手门槛更低.atsepkov/awesome-awesome-wm: A curated list of awesome tools/scripts/configs for Awesome Window Manager. (github.com),除了本身窗口管理外,还有查看CPU资源,图片等工具需要额外安装.

所以比较方便的做法就是clone其他人的配置😅

i3

awesome

hyprlandConfiguring – Hyprland Wiki

个人感觉还是hyprland的配置和文档好,但是使用上bug可能不少.

Neovim

基于vim的编辑器,更好地进行配置、安装插件.

主要是需要了解neovim的一些配置语法,如果为了方便直接使用lazyvim等配置即可.

Lua-guide - Neovim docs neovim使用vim.*等变量替代了原本的vimscript,不过你依然可以使用vim.cmd执行vimscript,使用vim.fn执行函数

1
2
3
4
5
6
7
8
9
vim.cmd("colorscheme habamax")
vim.cmd.highlight({ "Error", "guibg=red" })
print(vim.fn.printf('Hello from %s', 'Lua'))
local reversed_list = vim.fn.reverse({ 'a', 'b', 'c' })
vim.print(reversed_list) -- { "c", "b", "a" }
local function print_stdout(chan_id, data, name)
print(data[1])
end
vim.fn.jobstart('ls', { on_stdout = print_stdout })

vim.*变量

vim.g: global variables (g:)

vim.b: variables for the current buffer (b:)

vim.w: variables for the current window (w:)

vim.t: variables for the current tabpage (t:)

vim.v: predefined Vim variables (v:)

vim.env: environment variables defined in the editor session

设置options

options就是vim中的表现比如set smarttab

设置全局和本地选项(例如在 init.lua 中)最方便的方法是通过 vim.opt.
设置全局和本地选项最方便的方法是通过 vim.opt 和它的朋友们:
vim.opt: 行为类似于 :set
vim.opt_global: 行为类似于 :setglobal
vim.opt_local:行为类似于 :setlocal

vim.opt
1
2
vim.opt.smarttab = true
vim.opt.smarttab = false

代价是不能直接访问选项值,而必须
使用 vim.opt:get():

vim.o

有一种更直接的类似变量的访问方式,使用 vim.o
vim.o:行为类似于 :set
vim.go:行为类似于 :setglobal
vim.bo:用于缓冲区选项
vim.wo:用于窗口的选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
vim.o.smarttab = false -- :set nosmarttab
print(vim.o.smarttab)
--> false
vim.o.listchars = 'space:_,tab:>~' -- :set listchars='space:_,tab:>~'
print(vim.o.listchars)
--> 'space:_,tab:>~'
vim.o.isfname = vim.o.isfname .. ',@-@' -- :set isfname+=@-@
print(vim.o.isfname)
--> '@,48-57,/,.,-,_,+,,,#,$,%,~,=,@-@'
vim.bo.shiftwidth = 4 -- :setlocal shiftwidth=4
print(vim.bo.shiftwidth)
--> 4
vim.bo[4].expandtab = true -- sets expandtab to true in buffer 4
vim.wo.number = true -- sets number to true in current window
vim.wo[0].number = true -- same as above
vim.wo[0][0].number = true -- sets number to true in current buffer
-- in current window only
print(vim.wo[0].number) --> true

Mappings

设置执行命令的快捷键.

可以使用 vim.keymap.set() 创建映射。该函数需要三个参数:
{mode} 是一个字符串或字符串表,包含映射生效的模式前缀。前缀是 :map-modes 中列出的前缀,或 :map! 中的”!”,或 :map 中的空字符串。
{lhs} 是一个字符串,包含应触发映射的键序列。
{rhs} 是包含 Vim 命令或 Lua 函数的字符串,当输入 {lhs} 时应执行该命令或函数。空字符串等同于 ,表示禁用按键。

1
2
3
4
5
6
7
8
-- Normal mode mapping for Vim command
vim.keymap.set('n', '<Leader>ex1', '<cmd>echo "Example 1"<cr>')
-- Normal and Command-line mode mapping for Vim command
vim.keymap.set({'n', 'c'}, '<Leader>ex2', '<cmd>echo "Example 2"<cr>')
-- Normal mode mapping for Lua function
vim.keymap.set('n', '<Leader>ex3', vim.treesitter.start)
-- Normal mode mapping for Lua function with arguments
vim.keymap.set('n', '<Leader>ex4', function() print('Example 4') end)

Autocommands

自动命令是一个 Vim 命令或一个 Lua 函数,每当触发一个或多个事件(如文件被打开)时就会自动执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
vim.api.nvim_create_autocmd({"BufEnter", "BufWinEnter"}, {
pattern = {"*.c", "*.h"},
command = "echo 'Entering a C or C++ file'",
})
-- Same autocommand written with a Lua function instead
vim.api.nvim_create_autocmd({"BufEnter", "BufWinEnter"}, {
pattern = {"*.c", "*.h"},
callback = function() print("Entering a C or C++ file") end,
})
-- User event triggered by MyPlugin
vim.api.nvim_create_autocmd("User", {
pattern = "MyPlugin",
callback = function() print("My Plugin Works!") end,
})

User commands

用户命令可通过 nvim_create_user_command() 创建。该函数须要三个参数:
命令名称字符串(必须以大写字母开头,以区别于内置命令);
一个包含 Vim 命令或 Lua 函数的字符串,命令调用时执行该字符串;
包含命令属性的表格;此外,它还可以包含关键字 desc(描述命令的字符串)、force(设置为 false 以避免替换已存在的同名命令)和 preview(用于 :command-preview 的 Lua 函数)。

1
2
3
vim.api.nvim_create_user_command('Test', 'echo "It works!"', {})
vim.cmd.Test()
--> It works!

可以使用lazyvim,lunarvim,Astrovim或者nvchad等配置文件,已经为我们配置好了很多东西.

LazyVim

lazyvim规定了每个lazyvim的库应该怎么编写,编写方式按照文档规定.nvchad,astrovim都是按照这种方式的.

默认keymaps⌨️ Keymaps | LazyVim

Plugins | LazyVim

拿Lazyvim举例,相当于packer.nvim等插件管理器的替代,lazy.vim中默认设置如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
{
root = vim.fn.stdpath("data") .. "/lazy", -- directory where plugins will be installed
defaults = {
-- Set this to `true` to have all your plugins lazy-loaded by default.
-- Only do this if you know what you are doing, as it can lead to unexpected behavior.
lazy = false, -- should plugins be lazy-loaded?
-- It's recommended to leave version=false for now, since a lot the plugin that support versioning,
-- have outdated releases, which may break your Neovim install.
version = nil, -- always use the latest git commit
-- version = "*", -- try installing the latest stable version for plugins that support semver
-- default `cond` you can use to globally disable a lot of plugins
-- when running inside vscode for example
cond = nil, ---@type boolean|fun(self:LazyPlugin):boolean|nil
},
-- leave nil when passing the spec as the first argument to setup()
spec = nil, ---@type LazySpec
local_spec = true, -- load project specific .lazy.lua spec files. They will be added at the end of the spec.
lockfile = vim.fn.stdpath("config") .. "/lazy-lock.json", -- lockfile generated after running update.
---@type number? limit the maximum amount of concurrent tasks
concurrency = jit.os:find("Windows") and (vim.uv.available_parallelism() * 2) or nil,
git = {
-- defaults for the `Lazy log` command
-- log = { "--since=3 days ago" }, -- show commits from the last 3 days
log = { "-8" }, -- show the last 8 commits
timeout = 120, -- kill processes that take more than 2 minutes
url_format = "https://github.com/%s.git",
-- lazy.nvim requires git >=2.19.0. If you really want to use lazy with an older version,
-- then set the below to false. This should work, but is NOT supported and will
-- increase downloads a lot.
filter = true,
},
pkg = {
enabled = true,
cache = vim.fn.stdpath("state") .. "/lazy/pkg-cache.lua",
versions = true, -- Honor versions in pkg sources
-- the first package source that is found for a plugin will be used.
sources = {
"lazy",
"rockspec",
"packspec",
},
},
rocks = {
root = vim.fn.stdpath("data") .. "/lazy-rocks",
server = "https://nvim-neorocks.github.io/rocks-binaries/",
},
dev = {
---@type string | fun(plugin: LazyPlugin): string directory where you store your local plugin projects
path = "~/projects",
---@type string[] plugins that match these patterns will use your local versions instead of being fetched from GitHub
patterns = {}, -- For example {"folke"}
fallback = false, -- Fallback to git when local plugin doesn't exist
},
install = {
-- install missing plugins on startup. This doesn't increase startup time.
missing = true,
-- try to load one of these colorschemes when starting an installation during startup
colorscheme = { "habamax" },
},
ui = {
-- a number <1 is a percentage., >1 is a fixed size
size = { width = 0.8, height = 0.8 },
wrap = true, -- wrap the lines in the ui
-- The border to use for the UI window. Accepts same border values as |nvim_open_win()|.
border = "none",
-- The backdrop opacity. 0 is fully opaque, 100 is fully transparent.
backdrop = 60,
title = nil, ---@type string only works when border is not "none"
title_pos = "center", ---@type "center" | "left" | "right"
-- Show pills on top of the Lazy window
pills = true, ---@type boolean
icons = {
cmd = " ",
config = "",
event = " ",
favorite = " ",
ft = " ",
init = " ",
import = " ",
keys = " ",
lazy = "󰒲 ",
loaded = "●",
not_loaded = "○",
plugin = " ",
runtime = " ",
require = "󰢱 ",
source = " ",
start = " ",
task = "✔ ",
list = {
"●",
"➜",
"★",
"‒",
},
},
-- leave nil, to automatically select a browser depending on your OS.
-- If you want to use a specific browser, you can define it here
browser = nil, ---@type string?
throttle = 20, -- how frequently should the ui process render events
custom_keys = {
-- You can define custom key maps here. If present, the description will
-- be shown in the help menu.
-- To disable one of the defaults, set it to false.

["<localleader>l"] = {
function(plugin)
require("lazy.util").float_term({ "lazygit", "log" }, {
cwd = plugin.dir,
})
end,
desc = "Open lazygit log",
},

["<localleader>t"] = {
function(plugin)
require("lazy.util").float_term(nil, {
cwd = plugin.dir,
})
end,
desc = "Open terminal in plugin dir",
},
},
},
diff = {
-- diff command <d> can be one of:
-- * browser: opens the github compare view. Note that this is always mapped to <K> as well,
-- so you can have a different command for diff <d>
-- * git: will run git diff and open a buffer with filetype git
-- * terminal_git: will open a pseudo terminal with git diff
-- * diffview.nvim: will open Diffview to show the diff
cmd = "git",
},
checker = {
-- automatically check for plugin updates
enabled = false,
concurrency = nil, ---@type number? set to 1 to check for updates very slowly
notify = true, -- get a notification when new updates are found
frequency = 3600, -- check for updates every hour
check_pinned = false, -- check for pinned packages that can't be updated
},
change_detection = {
-- automatically check for config file changes and reload the ui
enabled = true,
notify = true, -- get a notification when changes are found
},
performance = {
cache = {
enabled = true,
},
reset_packpath = true, -- reset the package path to improve startup time
rtp = {
reset = true, -- reset the runtime path to $VIMRUNTIME and your config directory
---@type string[]
paths = {}, -- add any custom paths here that you want to includes in the rtp
---@type string[] list any plugins you want to disable here
disabled_plugins = {
-- "gzip",
-- "matchit",
-- "matchparen",
-- "netrwPlugin",
-- "tarPlugin",
-- "tohtml",
-- "tutor",
-- "zipPlugin",
},
},
},
-- lazy can generate helptags from the headings in markdown readme files,
-- so :help works even for plugins that don't have vim docs.
-- when the readme opens with :help it will be correctly displayed as markdown
readme = {
enabled = true,
root = vim.fn.stdpath("state") .. "/lazy/readme",
files = { "README.md", "lua/**/README.md" },
-- only generate markdown helptags for plugins that dont have docs
skip_if_doc_exists = true,
},
state = vim.fn.stdpath("state") .. "/lazy/state.json", -- state info for checker and other things
-- Enable profiling of lazy.nvim. This will add some overhead,
-- so only enable this when you are debugging lazy.nvim
profiling = {
-- Enables extra stats on the debug tab related to the loader cache.
-- Additionally gathers stats about all package.loaders
loader = false,
-- Track each new require in the Lazy profiling tab
require = false,
},
}

options.lua中配置了一些全局变量以及vim许多属性.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
-- This file is automatically loaded by plugins.core
vim.g.mapleader = " "
vim.g.maplocalleader = "\\"

-- LazyVim auto format
vim.g.autoformat = true

-- LazyVim picker to use.
-- Can be one of: telescope, fzf
-- Leave it to "auto" to automatically use the picker
-- enabled with `:LazyExtras`
vim.g.lazyvim_picker = "auto"

-- LazyVim root dir detection
-- Each entry can be:
-- * the name of a detector function like `lsp` or `cwd`
-- * a pattern or array of patterns like `.git` or `lua`.
-- * a function with signature `function(buf) -> string|string[]`
vim.g.root_spec = { "lsp", { ".git", "lua" }, "cwd" }

-- LazyVim automatically configures lazygit:
-- * theme, based on the active colorscheme.
-- * editorPreset to nvim-remote
-- * enables nerd font icons
-- Set to false to disable.
vim.g.lazygit_config = true

-- Options for the LazyVim statuscolumn
vim.g.lazyvim_statuscolumn = {
folds_open = false, -- show fold sign when fold is open
folds_githl = false, -- highlight fold sign with git sign color
}

-- Optionally setup the terminal to use
-- This sets `vim.o.shell` and does some additional configuration for:
-- * pwsh
-- * powershell
-- LazyVim.terminal.setup("pwsh")

-- Hide deprecation warnings
vim.g.deprecation_warnings = false

-- Set filetype to `bigfile` for files larger than 1.5 MB
-- Only vim syntax will be enabled (with the correct filetype)
-- LSP, treesitter and other ft plugins will be disabled.
-- mini.animate will also be disabled.
vim.g.bigfile_size = 1024 * 1024 * 1.5 -- 1.5 MB

-- Show the current document symbols location from Trouble in lualine
vim.g.trouble_lualine = true

local opt = vim.opt

opt.autowrite = true -- Enable auto write
-- only set clipboard if not in ssh, to make sure the OSC 52
-- integration works automatically. Requires Neovim >= 0.10.0
opt.clipboard = vim.env.SSH_TTY and "" or "unnamedplus" -- Sync with system clipboard
opt.completeopt = "menu,menuone,noselect"
opt.conceallevel = 2 -- Hide * markup for bold and italic, but not markers with substitutions
opt.confirm = true -- Confirm to save changes before exiting modified buffer
opt.cursorline = true -- Enable highlighting of the current line
opt.expandtab = true -- Use spaces instead of tabs
opt.fillchars = {
foldopen = "",
foldclose = "",
fold = " ",
foldsep = " ",
diff = "╱",
eob = " ",
}
opt.foldlevel = 99
opt.formatexpr = "v:lua.require'lazyvim.util'.format.formatexpr()"
opt.formatoptions = "jcroqlnt" -- tcqj
opt.grepformat = "%f:%l:%c:%m"
opt.grepprg = "rg --vimgrep"
opt.ignorecase = true -- Ignore case
opt.inccommand = "nosplit" -- preview incremental substitute
opt.jumpoptions = "view"
opt.laststatus = 3 -- global statusline
opt.linebreak = true -- Wrap lines at convenient points
opt.list = true -- Show some invisible characters (tabs...
opt.mouse = "a" -- Enable mouse mode
opt.number = true -- Print line number
opt.pumblend = 10 -- Popup blend
opt.pumheight = 10 -- Maximum number of entries in a popup
opt.relativenumber = true -- Relative line numbers
opt.scrolloff = 4 -- Lines of context
opt.sessionoptions = { "buffers", "curdir", "tabpages", "winsize", "help", "globals", "skiprtp", "folds" }
opt.shiftround = true -- Round indent
opt.shiftwidth = 2 -- Size of an indent
opt.shortmess:append({ W = true, I = true, c = true, C = true })
opt.showmode = false -- Dont show mode since we have a statusline
opt.sidescrolloff = 8 -- Columns of context
opt.signcolumn = "yes" -- Always show the signcolumn, otherwise it would shift the text each time
opt.smartcase = true -- Don't ignore case with capitals
opt.smartindent = true -- Insert indents automatically
opt.spelllang = { "en" }
opt.spelloptions:append("noplainbuffer")
opt.splitbelow = true -- Put new windows below current
opt.splitkeep = "screen"
opt.splitright = true -- Put new windows right of current
opt.statuscolumn = [[%!v:lua.require'lazyvim.util'.ui.statuscolumn()]]
opt.tabstop = 2 -- Number of spaces tabs count for
opt.termguicolors = true -- True color support
opt.timeoutlen = vim.g.vscode and 1000 or 300 -- Lower than default (1000) to quickly trigger which-key
opt.undofile = true
opt.undolevels = 10000
opt.updatetime = 200 -- Save swap file and trigger CursorHold
opt.virtualedit = "block" -- Allow cursor to move where there is no text in visual block mode
opt.wildmode = "longest:full,full" -- Command-line completion mode
opt.winminwidth = 5 -- Minimum window width
opt.wrap = false -- Disable line wrap

if vim.fn.has("nvim-0.10") == 1 then
opt.smoothscroll = true
opt.foldexpr = "v:lua.require'lazyvim.util'.ui.foldexpr()"
opt.foldmethod = "expr"
opt.foldtext = ""
else
opt.foldmethod = "indent"
opt.foldtext = "v:lua.require'lazyvim.util'.ui.foldtext()"
end

-- Fix markdown indentation settings
vim.g.markdown_recommended_style = 0

自定义的一些keymap如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
-- This file is automatically loaded by lazyvim.config.init

-- DO NOT USE `LazyVim.safe_keymap_set` IN YOUR OWN CONFIG!!
-- use `vim.keymap.set` instead
local map = LazyVim.safe_keymap_set

-- better up/down
map({ "n", "x" }, "j", "v:count == 0 ? 'gj' : 'j'", { desc = "Down", expr = true, silent = true })
map({ "n", "x" }, "<Down>", "v:count == 0 ? 'gj' : 'j'", { desc = "Down", expr = true, silent = true })
map({ "n", "x" }, "k", "v:count == 0 ? 'gk' : 'k'", { desc = "Up", expr = true, silent = true })
map({ "n", "x" }, "<Up>", "v:count == 0 ? 'gk' : 'k'", { desc = "Up", expr = true, silent = true })

-- Move to window using the <ctrl> hjkl keys
map("n", "<C-h>", "<C-w>h", { desc = "Go to Left Window", remap = true })
map("n", "<C-j>", "<C-w>j", { desc = "Go to Lower Window", remap = true })
map("n", "<C-k>", "<C-w>k", { desc = "Go to Upper Window", remap = true })
map("n", "<C-l>", "<C-w>l", { desc = "Go to Right Window", remap = true })

-- Resize window using <ctrl> arrow keys
map("n", "<C-Up>", "<cmd>resize +2<cr>", { desc = "Increase Window Height" })
map("n", "<C-Down>", "<cmd>resize -2<cr>", { desc = "Decrease Window Height" })
map("n", "<C-Left>", "<cmd>vertical resize -2<cr>", { desc = "Decrease Window Width" })
map("n", "<C-Right>", "<cmd>vertical resize +2<cr>", { desc = "Increase Window Width" })

-- Move Lines
map("n", "<A-j>", "<cmd>m .+1<cr>==", { desc = "Move Down" })
map("n", "<A-k>", "<cmd>m .-2<cr>==", { desc = "Move Up" })
map("i", "<A-j>", "<esc><cmd>m .+1<cr>==gi", { desc = "Move Down" })
map("i", "<A-k>", "<esc><cmd>m .-2<cr>==gi", { desc = "Move Up" })
map("v", "<A-j>", ":m '>+1<cr>gv=gv", { desc = "Move Down" })
map("v", "<A-k>", ":m '<-2<cr>gv=gv", { desc = "Move Up" })

-- buffers
map("n", "<S-h>", "<cmd>bprevious<cr>", { desc = "Prev Buffer" })
map("n", "<S-l>", "<cmd>bnext<cr>", { desc = "Next Buffer" })
map("n", "[b", "<cmd>bprevious<cr>", { desc = "Prev Buffer" })
map("n", "]b", "<cmd>bnext<cr>", { desc = "Next Buffer" })
map("n", "<leader>bb", "<cmd>e #<cr>", { desc = "Switch to Other Buffer" })
map("n", "<leader>`", "<cmd>e #<cr>", { desc = "Switch to Other Buffer" })
map("n", "<leader>bd", LazyVim.ui.bufremove, { desc = "Delete Buffer" })
map("n", "<leader>bD", "<cmd>:bd<cr>", { desc = "Delete Buffer and Window" })
....

autocmd.lua如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
-- This file is automatically loaded by lazyvim.config.init.

local function augroup(name)
return vim.api.nvim_create_augroup("lazyvim_" .. name, { clear = true })
end

-- Check if we need to reload the file when it changed
vim.api.nvim_create_autocmd({ "FocusGained", "TermClose", "TermLeave" }, {
group = augroup("checktime"),
callback = function()
if vim.o.buftype ~= "nofile" then
vim.cmd("checktime")
end
end,
})

-- Highlight on yank
vim.api.nvim_create_autocmd("TextYankPost", {
group = augroup("highlight_yank"),
callback = function()
vim.highlight.on_yank()
end,
})

-- resize splits if window got resized
vim.api.nvim_create_autocmd({ "VimResized" }, {
group = augroup("resize_splits"),
callback = function()
local current_tab = vim.fn.tabpagenr()
vim.cmd("tabdo wincmd =")
vim.cmd("tabnext " .. current_tab)
end,
})

-- go to last loc when opening a buffer
vim.api.nvim_create_autocmd("BufReadPost", {
group = augroup("last_loc"),
callback = function(event)
local exclude = { "gitcommit" }
local buf = event.buf
if vim.tbl_contains(exclude, vim.bo[buf].filetype) or vim.b[buf].lazyvim_last_loc then
return
end
vim.b[buf].lazyvim_last_loc = true
local mark = vim.api.nvim_buf_get_mark(buf, '"')
local lcount = vim.api.nvim_buf_line_count(buf)
if mark[1] > 0 and mark[1] <= lcount then
pcall(vim.api.nvim_win_set_cursor, 0, mark)
end
end,
})

-- close some filetypes with <q>
vim.api.nvim_create_autocmd("FileType", {
group = augroup("close_with_q"),
pattern = {
"PlenaryTestPopup",
"help",
"lspinfo",
"notify",
"qf",
"spectre_panel",
"startuptime",
"tsplayground",
"neotest-output",
"checkhealth",
"neotest-summary",
"neotest-output-panel",
"dbout",
"gitsigns.blame",
},
callback = function(event)
vim.bo[event.buf].buflisted = false
vim.keymap.set("n", "q", "<cmd>close<cr>", { buffer = event.buf, silent = true })
end,
})

-- make it easier to close man-files when opened inline
vim.api.nvim_create_autocmd("FileType", {
group = augroup("man_unlisted"),
pattern = { "man" },
callback = function(event)
vim.bo[event.buf].buflisted = false
end,
})

-- wrap and check for spell in text filetypes
vim.api.nvim_create_autocmd("FileType", {
group = augroup("wrap_spell"),
pattern = { "*.txt", "*.tex", "*.typ", "gitcommit", "markdown" },
callback = function()
vim.opt_local.wrap = true
vim.opt_local.spell = true
end,
})

-- Fix conceallevel for json files
vim.api.nvim_create_autocmd({ "FileType" }, {
group = augroup("json_conceal"),
pattern = { "json", "jsonc", "json5" },
callback = function()
vim.opt_local.conceallevel = 0
end,
})

-- Auto create dir when saving a file, in case some intermediate directory does not exist
vim.api.nvim_create_autocmd({ "BufWritePre" }, {
group = augroup("auto_create_dir"),
callback = function(event)
if event.match:match("^%w%w+:[\\/][\\/]") then
return
end
local file = vim.uv.fs_realpath(event.match) or event.match
vim.fn.mkdir(vim.fn.fnamemodify(file, ":p:h"), "p")
end,
})

vim.filetype.add({
pattern = {
[".*"] = {
function(path, buf)
return vim.bo[buf]
and vim.bo[buf].filetype ~= "bigfile"
and path
and vim.fn.getfsize(path) > vim.g.bigfile_size
and "bigfile"
or nil
end,
},
},
})

vim.api.nvim_create_autocmd({ "FileType" }, {
group = augroup("bigfile"),
pattern = "bigfile",
callback = function(ev)
vim.b.minianimate_disable = true
vim.schedule(function()
vim.bo[ev.buf].syntax = vim.filetype.match({ buf = ev.buf }) or ""
end)
end,
})
如何配置Lazyvim

lazyvim的官方建议:

  1. 文件结构如下,可以在plugins文件夹中设置
1
2
3
4
5
6
7
8
9
~/.config/nvim
├── lua
│ ├── config
│ │ └── lazy.lua
│ └── plugins
│ ├── spec1.lua
│ ├── **
│ └── spec2.lua
└── init.lua

默认的lazy.lua大概长下面这样,通过lazy.lua修改一些简单配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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("lazy").setup({
spec = {
-- add LazyVim and import its plugins
{ "LazyVim/LazyVim", import = "lazyvim.plugins" },
-- import/override with your plugins
{ import = "plugins" },
},
defaults = {
-- By default, only LazyVim plugins will be lazy-loaded. Your custom plugins will load during startup.
-- If you know what you're doing, you can set this to `true` to have all your custom plugins lazy-loaded by default.
lazy = false,
-- It's recommended to leave version=false for now, since a lot the plugin that support versioning,
-- have outdated releases, which may break your Neovim install.
version = false, -- always use the latest git commit
-- version = "*", -- try installing the latest stable version for plugins that support semver
},
install = { colorscheme = { "tokyonight", "habamax" } },
checker = { enabled = true }, -- automatically check for plugin updates
performance = {
rtp = {
-- disable some rtp plugins
disabled_plugins = {
"gzip",
-- "matchit",
-- "matchparen",
-- "netrwPlugin",
"tarPlugin",
"tohtml",
"tutor",
"zipPlugin",
},
},
},
})
pugin spec

可以这样修改插件的一些选项🔌 Plugin Spec | lazy.nvim (folke.io)

此外通过plugin spec下载或者更改插件的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
return {
-- the colorscheme should be available when starting Neovim
{
"folke/tokyonight.nvim",
lazy = false, -- make sure we load this during startup if it is your main colorscheme
priority = 1000, -- make sure to load this before all the other start plugins
config = function()
-- load the colorscheme here
vim.cmd([[colorscheme tokyonight]])
end,
},

-- I have a separate config.mappings file where I require which-key.
-- With lazy the plugin will be automatically loaded when it is required somewhere
{ "folke/which-key.nvim", lazy = true },

{
"nvim-neorg/neorg",
-- lazy-load on filetype
ft = "norg",
-- options for neorg. This will automatically call `require("neorg").setup(opts)`
opts = {
load = {
["core.defaults"] = {},
},
},
},

{
"dstein64/vim-startuptime",
-- lazy-load on a command
cmd = "StartupTime",
-- init is called during startup. Configuration for vim plugins typically should be set in an init function
init = function()
vim.g.startuptime_tries = 10
end,
},

{
"hrsh7th/nvim-cmp",
-- load cmp on InsertEnter
event = "InsertEnter",
-- these dependencies will only be loaded when cmp loads
-- dependencies are always lazy-loaded unless specified otherwise
dependencies = {
"hrsh7th/cmp-nvim-lsp",
"hrsh7th/cmp-buffer",
},
config = function()
-- ...
end,
},

-- if some code requires a module from an unloaded plugin, it will be automatically loaded.
-- So for api plugins like devicons, we can always set lazy=true
{ "nvim-tree/nvim-web-devicons", lazy = true },

-- you can use the VeryLazy event for things that can
-- load later and are not important for the initial UI
{ "stevearc/dressing.nvim", event = "VeryLazy" },

{
"Wansmer/treesj",
keys = {
{ "J", "<cmd>TSJToggle<cr>", desc = "Join Toggle" },
},
opts = { use_default_keymaps = false, max_join_length = 150 },
},

{
"monaqa/dial.nvim",
-- lazy-load on keys
-- mode is `n` by default. For more advanced options, check the section on key mappings
keys = { "<C-a>", { "<C-x>", mode = "n" } },
},

-- local plugins need to be explicitly configured with dir
{ dir = "~/projects/secret.nvim" },

-- you can use a custom url to fetch a plugin
{ url = "git@github.com:folke/noice.nvim.git" },

-- local plugins can also be configured with the dev option.
-- This will use {config.dev.path}/noice.nvim/ instead of fetching it from GitHub
-- With the dev option, you can easily switch between the local and installed version of a plugin
{ "folke/noice.nvim", dev = true },
}
PropertyTypeDescription
[1]string?Short plugin url. Will be expanded using config.git.url_format. Can also be a url or dir.
dependenciesLazySpec[]A list of plugin names or plugin specs that should be loaded when the plugin loads. Dependencies are always lazy-loaded unless specified otherwise. When specifying a name, make sure the plugin spec has been defined somewhere else.
enabledboolean? or fun():booleanWhen false, or if the function returns false, then this plugin will not be included in the spec
condboolean? or fun(LazyPlugin):booleanBehaves the same as enabled, but won’t uninstall the plugin when the condition is false. Useful to disable some plugins in vscode, or firenvim for example.
prioritynumber?Only useful for start plugins (lazy=false) to force loading certain plugins first. Default priority is 50. It’s recommended to set this to a high number for colorschemes
initfun(LazyPlugin)init functions are always executed during. Mostly useful for setting vim.g.* configuration used by Vim plugins startup
optstable or fun(LazyPlugin, opts:table)opts should be a table (will be merged with parent specs), return a table (replaces parent specs) or should change a table. The table will be passed to the Plugin.config() function. Setting this value will imply Plugin.config()
configfun(LazyPlugin, opts:table) or trueconfig is executed when the plugin loads. The default implementation will automatically run require(MAIN).setup(opts) if opts or config = true is set. Lazy uses several heuristics to determine the plugin’s MAIN module automatically based on the plugin’s name. (opts is the recommended way to configure plugins).
mainstring?You can specify the main module to use for config() and opts(), in case it can not be determined automatically. See config()
buildfun(LazyPlugin) or string or false or a list of build commandsbuild is executed when a plugin is installed or updated. See Building for more information.
添加插件

添加插件非常简单,只需将插件规格添加到 lua/plugins/*.lua 下的某个文件中即可。可以在其中创建任意数量的文件。允许缓存所有插件spec。
规格更改更新时将自动重新加载,因此 :Lazy UI 始终是最新的。

可以在 lua/plugins 文件夹中为每个插件创建一个文件,也可以为某些功能创建一个包含所有插件规格的独立文件.

1
2
3
4
5
6
7
8
9
10
11
12
return {
-- add symbols-outline
{
"simrat39/symbols-outline.nvim",
cmd = "SymbolsOutline", # 根据命令进行懒惰加载
keys = { { "<leader>cs", "<cmd>SymbolsOutline<cr>", desc = "Symbols Outline" } }, #Lazy-load on key mapping
opts = {
-- add your options that should be passed to the setup() function here
position = "right",
},
},
}

懒加载规则

lazy.nvim 可自动懒加载 Lua 模块. 这意味着,如果你有一个懒加载的插件 A 和一个需要插件 A 的模块的插件 B,那么插件 A 将按照预期按需加载。

此外,还可以对事件(events)、命令(cmd)、文件类型(filetype)和按键映射(key mappings)进行懒加载.

当以下情况之一为真时,插件将被懒加载:

  • 该插件仅作为依赖项(dependency)存在于plugin spec中
  • 它有一个事件、cmd、ft 或keys关键字
  • config.defaults.lazy == true

自定义Plugin Specs

默认合并规则:

cmd:将使用自定义命令扩展命令列表
event:事件列表,将使用自定义事件进行扩展
ft:文件类型列表将使用自定义文件类型进行扩展
keys:键映射列表,将使用自定义键映射进行扩展
opts:自定义选项将与默认选项合并
dependencies:依赖项列表将使用自定义依赖项进行扩展
任何其他属性都将覆盖默认值,比如spec

也就是说如果lazyvim中有了你想下载的插件,你可通过在plugins目录下添加一个lua文件修改,如果你想添加一个没有的插件,操作是一样的,无非是少了一些默认的配置.

在可能的情况下,始终使用 opts 而不是 config。

增加或者禁用插件keymap

添加 keys= 的规则。

也可以通过设置默认 keymap 为 false 来禁用.要覆盖一个关键映射,只需添加一个具有相同 lhs 和新 rhs 的关键映射(也就是按键相同,操作不同)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
return {
"nvim-telescope/telescope.nvim",
keys = {
-- disable the keymap to grep files
{"<leader>/", false},
-- change a keymap
{ "<leader>ff", "<cmd>Telescope find_files<cr>", desc = "Find Files" },
-- add a keymap to browse plugin files
{
"<leader>fp",
function() require("telescope.builtin").find_files({ cwd = require("lazy.core.config").options.root }) end,
desc = "Find Plugin File",
},
},
},
tips
  • 如果想去的缓冲区离您所在的位置很近,请使用 H 和 L。
  • 否则,如果缓冲区已打开,请使用 \
  • 对于其他文件,使用
  • 使用 \bd 关闭不再需要的缓冲区
  • 使用 \ss 快速跳转到所处缓冲区中的函数
  • 使用 \、\ 和 gd 浏览代码

  • 使用 \bp 可以固定缓冲区,使用 \bP 可以删除所有未固定的缓冲区

  • 在你将来想做但现在不需要的文件中添加 TODO,并删除它们的缓冲区,git 会跟踪它们
  • 如果要禁用某个缓冲区的自动格式化,则为该缓冲区设置 vim.b.autoformat = false
  • 1
    2
    3
    4
    5
    6
    7
    -- Disable autoformat for lua files
    vim.api.nvim_create_autocmd({ "FileType" }, {
    pattern = { "lua" },
    callback = function()
    vim.b.autoformat = false
    end,
    })

    可以使用 <leader>uf来启用该缓冲区的自动格式化。

    除了layvim的配置,neotree等使用的插件的配置也应该看看

    如果你想学习vim,可以通过vim tutor或者在线的vim adventure练习.

    Alacritty

    GPU加速的终端模拟器,保持了最小的核心功能,没有窗口分割等(如果想要更多功能,考虑使用wezterm(基本不需要什么配置),配置使用lua).

    Alacritty的配置非常轻松,使用.tomlAlacritty,结构比较清晰

    下面是一个例子

    Default-Alacritty-TOML-Config/alacritty.toml at main · TwiggieSmallz/Default-Alacritty-TOML-Config (github.com)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    [GENERAL]

    [ENV]

    [WINDOW]

    [SCROLLING]

    [FONT]

    [SELECTION]

    [TERMINAL]

    [CURSOR]

    [font]

    [HINTS]

    size = 12.0

    [font.bold]
    family = "monospace"
    style = "Bold"

    [font.bold_italic]
    family = "monospace"
    style = "Bold Italic"

    [font.italic]
    family = "monospace"
    style = "Italic"

    [font.normal]
    family = "monospace"
    style = "Regular"

    后言

    有许多操作具体我也在学习,欢迎交流.感觉目前使用neovim写点小demo还是不错的,大项目可以使用jetbrains的IDE.

    如果你想geek一点,使用arch的文档以及常用的软件ArchWiki (archlinux.org)ihchiz/Awesome-Linux-Software-zh_CN: 🐧 一个 Linux 上超赞的应用,软件,工具以及其它资源的集中地。 (github.com),下载和使用这类软件非常全面和方便. 可以考虑使用Archcraft (github.com)试试,自带许多配置文件.

    也可以看看我介绍的一些日常开发setupprotools (protool-ten.vercel.app)

    -------------本文结束感谢您的阅读-------------
    感谢阅读.

    欢迎关注我的其它发布渠道