Ubuntu 22.04 上配置 LunarVim 浏览linux kernel代码

article/2025/10/11 12:30:59

概述

微软的Visual Studio Code 无疑是目前最流行的代码IDE, 最丰富的插件,最容易上手,但缺点也是有的,比如还是有许多操作需要鼠标来完成,特别是使用laptop看代码,使用鼠标是很不方便的一件事,查看远程机器上的代码总没有ssh再去vim编辑来得方便.

之前使用基于vim的IDE exvim, 项目管理很好,比如我同时有多个linux源码目录,用于不同的branch和不同的issue.易用的全linux kernel代码内的搜索,建立索引的快捷键. 缺点是不能指定cscope ctags的代码范围, 因为大部分驱动开发只需要关注较少的相关代码目录,2020年的kernel已经拥有超过2700万行代码了,全部代码导致索引数据库太过庞大,搜索慢.同时vim不支持多线程任务(最新的似乎也支持多线程,但是绝大部分插件开发很早并没有做多线程方面的优化),导致现代CPU的多核性能并没有得到利用,因此操作越来越慢.

相较于vim,Neovim是从新开发的编辑器,天然没有历史包袱,支持多线程运行.

Lunarvim是一个基于neovim打造的IDE,已经集成了不少插件,即装即用. 但没有集成cscope ctags,跳转搜索功能缺失,需要根据个人习惯进行配置. 

1 安装Luarvim

jenkins@rico-fast:~$ sudo su
root@rico-fast:/home/jenkins# cd /etc/apt
# 备份apt源
root@rico-fast:/etc/apt# mv sources.list sources.list-orig
# 修改apt使用上海交通大学的源
root@rico-fast:/etc/apt# cat sources.list
deb http://ftp.sjtu.edu.cn/ubuntu/ jammy main restricted
deb http://ftp.sjtu.edu.cn/ubuntu/ jammy-updates main restricted
deb http://ftp.sjtu.edu.cn/ubuntu/ jammy universe
deb http://ftp.sjtu.edu.cn/ubuntu/ jammy-updates universe
deb http://ftp.sjtu.edu.cn/ubuntu/ jammy multiverse
deb http://ftp.sjtu.edu.cn/ubuntu/ jammy-updates multiverse
deb http://ftp.sjtu.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
deb http://ftp.sjtu.edu.cn/ubuntu/ jammy-security main restricted
deb http://ftp.sjtu.edu.cn/ubuntu/ jammy-security universe
deb http://ftp.sjtu.edu.cn/ubuntu/ jammy-security multiverse
# 更新源信息
root@rico-fast:/etc/apt# apt updatge
# 安装neovim
root@rico-fast:/etc/apt# apt install -y software-properties-common
root@rico-fast:/etc/apt# add-apt-repository ppa:neovim-ppa/unstable
root@rico-fast:/etc/apt# apt install -y neovim
root@rico-fast:/etc/apt# nvim -v
NVIM v0.10.0-dev
# 安装常用工具
root@rico-fast:/etc/apt# apt install -y htop file silversearcher-ag apt-file mlocate 
# 安装lvim依赖的工具库
root@rico-fast:/etc/apt# apt install -y git tig make pip python3-pip python3 python3-dev cargo curl npm fzf build-essential nodejs# 安装lunarvim和lunarvim内建的插件, 用时较长
# 注意需要用普通账户安装, 否则安装到了/root下,普通用户无法使用lunarvim
root@rico-fast:/etc/apt# exit
# 官方的安装方式: bash <(curl -s https://raw.githubusercontent.com/lunarvim/lunarvim/master/utils/installer/install.sh) 用时更久
jenkins@rico-fast:~$ wget https://raw.githubusercontent.com/lunarvim/lunarvim/master/utils/installer/install.sh
jenkins@rico-fast:~$ ./install.sh --no-install-dependencies# 准备代码
jenkins@rico-fast:~$ mkdir workspace
jenkins@rico-fast:~$ cd workspace
jenkins@rico-fast:~/workspace$ git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git --depth=1# 使用lunarvim 浏览代码
jenkins@rico-fast:~/workspace$ lvim .
# <space>f 输入:drm_ioctl.c 回车,打开需要浏览的代码文件
# <space>e 打开左侧nvim tree窗口,浏览代码目录,jk移动光标行,v打开选中文件

1.1 备份Lunarvim

jenkins@rico-fast:~$ cat ./backup-lvim.sh
#!/usr/bin/bashtar -czf ~/lunarvim-$(date "+%Y%m%d-%H%M%S")-${1}.tar.gz \
~/.local/share/lunarvim \
~/.local/share/lvim \
~/.local/bin/lvim \
~/.config/lvimjenkins@rico-fast:~$ ./backup-lvim.sh LvimInstallSuccess# plugins随时在更新,lazy-lock.jason保存了所有plugins的当前版本
# 用git进行版本管理,以便某些插件出bug时可以回退到之前的版本
jenkins@rico-fast:~$ cd .config/lvim/
jenkins@rico-fast:~/.config/lvim$ ll
-rw-rw-r--  1 jenkins jenkins  258  5月  8 14:30 config.lua
-rw-rw-r--  1 jenkins jenkins 4045  5月  8 14:31 lazy-lock.json
jenkins@rico-fast:~/.config/lvim$ git init
jenkins@rico-fast:~/.config/lvim$ git add .
jenkins@rico-fast:~/.config/lvim$ git commit

 2 修改 Lazy 使其不删除插件代码目录

Lazy是Lunarvim使用的插件管理器, 当<leader>pS进行插件管理时,可能会删除插件,导致后面我们对插件做的修改丢失, 为了防止丢失, 我将Lazy删除插件目录的代码屏蔽掉. 确实要删除插件目录时,可以手动去 ~/.local/share/lunarvim/site/pack/lazy/opt/ 删除对应目录.

# 在修改前,切换到自己的分支,这样修改后提交到自己的分支,当Lazy sync代码后,也可以快速切换回来
jenkins@rico-fast:~/.local/share/lunarvim/site/pack/lazy/opt/lazy.nvim$ git checkout -b MyBranchjenkins@rico-fast:~/.local/share/lunarvim/site/pack/lazy/opt/lazy.nvim$ cat 0001-Skip-removing-src-code-dir-of-plugin-when-uninstall-.patch
From 9ebef0d1e18dfd5826d4945f454f3412f31cd777 Mon Sep 17 00:00:00 2001
From: tiancyin <tianci.yin@amd.com>
Date: Tue, 9 May 2023 16:31:34 +0800
Subject: [PATCH] Skip removing src code dir of plugin when uninstall a plugin---lua/lazy/manage/task/fs.lua | 2 ++1 file changed, 2 insertions(+)diff --git a/lua/lazy/manage/task/fs.lua b/lua/lazy/manage/task/fs.lua
index 9386f76..0dda1ce 100644
--- a/lua/lazy/manage/task/fs.lua
+++ b/lua/lazy/manage/task/fs.lua
@@ -12,6 +12,8 @@ M.clean = {local dir = self.plugin.dir:gsub("/+$", "")assert(dir:find(Config.options.root, 1, true) == 1, self.plugin.dir .. " should be under packpath!")+    assert(false, "Skipping removing plugin directory when uninstall a plugin to prevent your changes lost" .. dir)
+local stat = vim.loop.fs_lstat(dir)assert(stat.type == "directory", self.plugin.dir .. " should be a directory!")-- 
2.34.1

3 添加cscope插件

3.1 安装依赖库

jenkins@rico-fast:~/.config/lvim$ sudo apt install -y universal-ctags cscope

3.2 修改config.lua添加cscope插件

在~/.config/lvim里加入下面的修改

jenkins@rico-fast:~/.config/lvim$ cat 0001-Add-cscope_maps.patch 
From c70b201bc030fd8ac3ced3dc9efedd2705b74623 Mon Sep 17 00:00:00 2001
From: Linux Jenkins <jenkins@rico-fast.amd.com>
Date: Mon, 8 May 2023 17:32:58 +0800
Subject: [PATCH] Add cscope_maps---config.lua | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++1 file changed, 70 insertions(+)diff --git a/config.lua b/config.lua
index 2a30f58..42115a5 100644
--- a/config.lua
+++ b/config.lua
@@ -2,3 +2,73 @@-- Video Tutorials: https://www.youtube.com/watch?v=sFA9kX-Ud_c&list=PLhoH5vyxr6QqGu0i7tt_XoVK9v-KvZ3m6-- Forum: https://www.reddit.com/r/lunarvim/-- Discord: https://discord.com/invite/Xb9B4Ny
+
+--------------------------------------------------------------------------------------------------------------------------------
+---Rico config begin
+
+lvim.plugins = {
+	{
+		-- ctags 被 neovim 内建支持, 当tags文件存在时可以
+		-- <C-]> 跳转到符号定义的地方
+		-- <C-o> 返回跳转前的代码处
+
+		-- ctags 只能建立了符号定义的索引,没有建立被调用的索引,因此用cscope来加速被引用的搜索
+		-- <leader>cc	搜索光标函数被调用的地方
+		-- <leader>ca	搜索光标符号被赋值的地方
+		-- <leader>cs	搜索光标符号出现的所有地方
+		-- <leader>cg	搜索光标符号的定义,等于ctags的<C+]>
+		-- <leader>cG	产生cscope.files文件
+		-- <leader>ct	搜索光标类型的实例
+		-- <leader>cT	生成索引文件cscope.out
+		-- <leader>ce	用egrep方式搜索光标符号, == grep -E 就是 把+ ? | 等当作逻辑符号,而不是一般异常符号来处理, ls | egrep "mp4|avi"
+		-- <leader>cf	打开光标文件
+		-- <leader>ci	搜索include了光标文件名的所有文件
+		-- <leader>cd	搜索被光标函数调用的函数
+		"dhananjaylatkar/cscope_maps.nvim",
+		dependencies = {
+			"folke/which-key.nvim",
+		},
+		config = function()
+			require("cscope_maps").setup({
+				disable_maps = false, -- true disables my keymaps, only :Cscope will be loaded
+			})
+		end,
+	},
+}
+
+--lvim --headless +'lua require("lvim.utils").generate_settings()' +qa && sort -o lv-settings.lua{,}  -- 在当前目前生成lvim的所有配置 lv-settings.lua
+
+lvim.keys.normal_mode["<C-s>"] = ":w<cr>"       -- Ctrl-s 保存文件
+lvim.keys.normal_mode["<S-q>"] = ":wqa<CR>"     -- 保存修改并退出 lvim
+
+-- lvim.leader = "space"                        -- leader键修改为space
+-- vim.opt.relativenumber = true                -- true则使用相对行号来标记代码行
+
+-- 配置Tab缩进为8个空格的宽度
+vim.opt.shiftwidth = 8                          -- the number of spaces inserted for each indentation
+vim.opt.tabstop = 8                             -- insert 8 spaces for a tab
+vim.opt.numberwidth = 8                         -- set number column width to 8 {default 4}
+
+vim.opt.fileencoding = "utf-8"                  -- 写文件时使用utf-8代码页
+vim.opt.ignorecase = true                       -- 搜索时忽略大小写
+vim.opt.mouse = "a"                             -- 允许lvim使用鼠标操作
+
+vim.opt.clipboard = "unnamedplus"               -- 使用OS 系统剪贴板
+
+lvim.keys.normal_mode["<C-d>"] = "<C-d>zz"      -- Ctrl-d 将光标下翻半页并将光标行在窗口上下居中
+
+-- cscope_maps 插件优先加载当前目录里的cscope.out, 然后加载与.git同级目录里的cscope.out,当只关注kernel的某个子模块目录时, 可以加速搜索
+-- <leader>cT 是先检查当前文件是否属于git仓库管理的代码,是则在.git同级目录里创建cscope.out, 不是则在当前目录里创建
+-- <S-t> 在当前目录里创建cscope.out, 且包含所有子目录和所有文件类型
+lvim.keys.normal_mode["<S-t>"] = ":!cscope -bR && ctags -R<CR>"
+
+
+lvim.keys.normal_mode["fs"] = ":Cscope find  s "        -- 手动输入要搜索的关键字, 查找此关键字所有出现的地方
+lvim.keys.normal_mode["ts"] = ":Cscope find  g "        -- 手动输入要搜索的关键字, 查找此关键字定义的地方
+
+
+-- ff 搜索光标关键字, gd被luarvim设置成LSP的goto definition,等同于vim的gd
+-- <C-w><C-r> 是交换窗口左右位置
+lvim.keys.normal_mode["ff"] = "/<C-r><C-w><CR>"
+
+---Rico config end
+--------------------------------------------------------------------------------------------------------------------------------
-- 
2.34.1

3.3 重新启动lvim自动安装cscope_maps

3.4 修改cscope_maps使其能自动加载cscope.out

cscope_maps默认使用一个统一的目录保存cscope.out, 但是我的linux目录有多个,比如linux-branch4-bug1, linux-branch3-bug2 ... , 一个统一的地方会导致多个项目的索引文件重名, 且当项目需要删除时还需要手动去删除索引文件. 并且当进入linux的深层目录在启动lvim,则找不到索引文件, 因此进行下面的修改, 这样cscope_maps会优先在当前目录里检查cscope.out是否存在, 存在则使用它, 如果不存在,再检查.git目录的上级目录.

# 在修改前,切换到自己的分支,这样修改后提交到自己的分支,当Lazy sync代码后,也可以快速切换回来
jenkins@rico-fast:~/.local/share/lunarvim/site/pack/lazy/opt/cscope_maps.nvim$ git checkout -b MyBranchjenkins@rico-fast:~/.local/share/lunarvim/site/pack/lazy/opt/cscope_maps.nvim$ cat 0001-search-and-load-cscope.out-automatically.patch
From 3514e67a413b63747dd61dd7c7b7e4e78449259a Mon Sep 17 00:00:00 2001
From: tiancyin <tianci.yin@amd.com>
Date: Thu, 4 May 2023 18:45:59 +0800
Subject: [PATCH 1/2] search and load cscope.out automatically[why]
If you 'cd to linux/drivers/gpu/drm/amd' and 'lvim amdgpu/amdgpu_drv.c',
lvim will not load cscope.out automatically, even linux/cscope.out exist.[how]
Search and add cscope.out automatically at lvim startup or 'cscope find',
two places to search:
'pwd', i.e. where you start lvim
.git's parent dir, e.g linux/.git exist, search linux/cscope.outAdd cscope.out automatically if it existsSigned-off-by: tiancyin <tianci.yin@amd.com>
---lua/cscope/cscope.lua | 68 ++++++++++++++++++++++++++++++++++++++++++-lua/cscope_maps.lua   | 54 ++++++++++++++++++++++++++++------2 files changed, 112 insertions(+), 10 deletions(-)diff --git a/lua/cscope/cscope.lua b/lua/cscope/cscope.lua
index a7a218f..c6f5a25 100644
--- a/lua/cscope/cscope.lua
+++ b/lua/cscope/cscope.lua
@@ -117,7 +117,38 @@ local cscope_find_helper = function(op_n, op_s, symbol)endend+M.load_db = function()
+	if vim.g.cscope_maps_db_file == nil then
+		local local_path = os.capture("pwd") .. "/cscope.out"
+		local git_path   = os.capture("git rev-parse --show-toplevel")
+		if git_path ~= "" then
+			-- print("[" .. FileName() .. ":" .. FunctionName() .. ":" .. LineNumber() .. "]"
+			-- 	.. git_path .. " is a git reprository")
+			git_path = git_path .. "/cscope.out"
+		else
+			-- print("[" .. FileName() .. ":" .. FunctionName() .. ":" .. LineNumber() .. "]"
+			-- 	.. git_path .. " is not a git reprository")
+		end
+
+		if vim.loop.fs_stat(local_path) ~= nil then
+			-- print("[" .. FileName() .. ":" .. FunctionName() .. ":" .. LineNumber() .. "]"
+			-- 	.. local_path .. " exist, use it, 'pwd'/cscope.out has high priority")
+			vim.g.cscope_maps_db_file = local_path
+		elseif vim.loop.fs_stat(git_path) ~= nil then
+			-- print("[" .. FileName() .. ":" .. FunctionName() .. ":" .. LineNumber() .. "]"
+			-- 	.. git_path .. " exist, use it")
+			vim.g.cscope_maps_db_file = git_path
+		else
+			-- print("[" .. FileName() .. ":" .. FunctionName() .. ":" .. LineNumber() .. "]"
+			-- 	.. "can't find cscope.out, set vim.g.cscope_maps_db_file to nil")
+			vim.g.cscope_maps_db_file = nil
+			-- assert(false, "assert false")
+		end
+	end
+end
+local cscope_find = function(op, symbol)
+	M.load_db()op = tostring(op)if #op ~= 1 thenprint("cscope: operation '" .. op .. "' is invalid")
@@ -132,6 +163,39 @@ local cscope_find = function(op, symbol)endend+local FileName = function()
+	local str = debug.getinfo(2, "S").source:sub(2)
+	return str:match("^.*/(.*).lua$") or str
+end
+
+local FunctionName = function()
+	local str = debug.getinfo(2, "n").name
+	return str
+end
+
+local LineNumber = function()
+	local line = debug.getinfo(2).currentline
+	return line
+end
+
+function os.capture(cmd, raw)
+	local f = assert(io.popen(cmd, 'r'))
+	local s = assert(f:read('*a'))
+	f:close()
+	if raw then return s end
+	s = string.gsub(s, '^%s+', '')
+	s = string.gsub(s, '%s+$', '')
+	s = string.gsub(s, '[\n\r]+', ' ')
+	return s
+end
+M.cscope = function(cmd, op, symbol)-- Parse top level output and call appropriate functionsif cmd == "find" then
@@ -168,12 +232,14 @@ local cscope_user_command = function()endM.setup = function(opts)
-	M.opts = vim.tbl_deep_extend("force", M.opts, opts)
+	M.opts                    = vim.tbl_deep_extend("force", M.opts, opts)-- This variable can be used by other plugins to change db_file-- e.g. vim-gutentags can use it for when--	vim.g.gutentags_cache_dir is enabled.vim.g.cscope_maps_db_file = nil+	M.load_db()
+if M.opts.use_telescope thencscope_telescope_picker = require("cscope.telescope_picker")end
diff --git a/lua/cscope_maps.lua b/lua/cscope_maps.lua
index 0bdf332..1901e9a 100644
--- a/lua/cscope_maps.lua
+++ b/lua/cscope_maps.lua
@@ -47,6 +47,32 @@ local sym_map = {}local keymap_opts = { noremap = true, silent = true }+local FileName = function()
+	local str = debug.getinfo(2, "S").source:sub(2)
+	return str:match("^.*/(.*).lua$") or str
+end
+
+local FunctionName = function()
+	local str = debug.getinfo(2, "n").name
+	return str
+end
+
+local LineNumber = function()
+	local line = debug.getinfo(2).currentline
+	return line
+end
+
+function os.capture(cmd, raw)
+	local f = assert(io.popen(cmd, 'r'))
+	local s = assert(f:read('*a'))
+	f:close()
+	if raw then return s end
+	s = string.gsub(s, '^%s+', '')
+	s = string.gsub(s, '%s+$', '')
+	s = string.gsub(s, '[\n\r]+', ' ')
+	return s
+end
+local keymap_wo_wk = function()-- Without which-keyvim.api.nvim_set_keymap(
@@ -142,6 +177,7 @@ M.setup = function(opts)-- function to print xcscpoe.el like promptsM.cscope_prompt = function(operation, default_symbol)
+		require("cscope.cscope").load_db()local prompt = sym_map[operation] .. " (default: '" .. default_symbol .. "'): "local cmd = cscope .. " find " .. operationvim.ui.input({ prompt = prompt }, function(new_symbol)
-- 
2.34.1

3.5 修改cscope_maps使其能自动生成cscope.out 和 tags

因为linux kernel的代码越来越庞大, 已经2000多万行了, 我们并不关注全部代码, 通常只需要关注一部分模块的代码即可, 因此在生成cscope.files时, 只添加我们关注的代码目录, 这样可以极大的减少索引的代码量并缩短搜索速度.

jenkins@rico-fast:~/.local/share/lunarvim/site/pack/lazy/opt/cscope_maps.nvim$ cat 0002-Generate-cscope.files-cscope.out-and-tags.patch 
From 15c13488e9151009c2a26a75f84fd3da852248c6 Mon Sep 17 00:00:00 2001
From: tiancyin <tianci.yin@amd.com>
Date: Thu, 4 May 2023 19:07:37 +0800
Subject: [PATCH 2/2] Generate cscope.files, cscope.out and tags[why]
For a new project, usually we should manually create cscope.out in
terminal, meantime maybe you want to skip most of the kernel code, just
focus on gpu driver related modules, since linux kernel code is huge,
build cscope.out and tags of ctags need much time, large database also
means more search time.[how]
Add lua code to generate database file, it's much convenious,
:cscope generate	to generate cscope.files in git's parent dir or 'pwd'
:cscope tag		to generate cscope.out and tags in git's parent dir or 'pwd'
<leader>cG		equivalent to ':cscope generate'
<leader>cT		equivalent to ':cscope tag'Signed-off-by: tiancyin <tianci.yin@amd.com>
---lua/cscope/cscope.lua | 120 ++++++++++++++++++++++++++++++++++++++++++lua/cscope_maps.lua   |  18 +++++++2 files changed, 138 insertions(+)diff --git a/lua/cscope/cscope.lua b/lua/cscope/cscope.lua
index c6f5a25..bf30025 100644
--- a/lua/cscope/cscope.lua
+++ b/lua/cscope/cscope.lua
@@ -196,12 +196,132 @@ function os.capture(cmd, raw)return send+-- function to generate cscope.files
+M.cscope_files_generate = function()
+	local linux_src_pathes = {
+		"include/acpi",
+		"include/drm",
+		"include/linux/sched",
+		"include/uapi",
+		"include/ufs",
+		"include/video",
+		"kernel",
+		"mm",
+		"drivers/acpi",
+		"drivers/dma-buf",
+		"drivers/gpu/drm/amd/acp",
+		"drivers/gpu/drm/amd/amdgpu",
+		"drivers/gpu/drm/amd/amdkfd",
+		"drivers/gpu/drm/amd/display",
+		"drivers/gpu/drm/amd/pm",
+		"drivers/gpu/drm/lib",
+		"drivers/gpu/drm/panel",
+		"drivers/gpu/drm/vkms",
+		"drivers/gpu/drm/bridge",
+		"drivers/gpu/drm/display",
+		"drivers/gpu/drm/ttm",
+		"drivers/gpu/drm/i2c",
+		"drivers/gpu/drm/scheduler",
+		"drivers/pci",
+	}
+
+	local linux_src_pathes_depth1 = {
+		"include/linux",
+		"drivers/gpu/drm",
+		"drivers/gpu/drm/amd/include",
+	}
+
+	local git_root = os.capture("git rev-parse --show-toplevel")
+	if git_root ~= "" then
+		print("[" .. FileName() .. ":" .. FunctionName() .. ":" .. LineNumber() .. "]"
+			.. git_root .. " is a git reprository")
+		local csc_files = git_root .. "/cscope.files"
+		if vim.loop.fs_stat(csc_files) == nil then
+			print("[" .. FileName() .. ":" .. FunctionName() .. ":" .. LineNumber() .. "]"
+				.. csc_files .. " does not exist, generate it")
+		else
+			print("[" .. FileName() .. ":" .. FunctionName() .. ":" .. LineNumber() .. "]"
+				.. csc_files .. " exist, regenerate it")
+		end
+		if vim.loop.fs_stat(git_root .. "/drivers/gpu/drm/amd") ~= nil then
+			print("[" .. FileName() .. ":" .. FunctionName() .. ":" .. LineNumber() .. "]"
+				.. git_root .. " is linux kernel src reprository, only involve a few gpu related pathes")
+			local i = 0
+			for _ in pairs(linux_src_pathes) do
+				i = i + 1
+				local find_cmd = "!find " .. git_root .. "/" .. linux_src_pathes[i]
+				    .. " -name \"*.[chS]\" -o -name \"*.m4\""
+				if i == 1 then
+					find_cmd = find_cmd .. " > "
+				else
+					find_cmd = find_cmd .. " >> "
+				end
+				find_cmd = find_cmd .. git_root .. "/cscope.files"
+				print("[" .. FileName() .. ":" .. FunctionName() .. ":" .. LineNumber() .. "]"
+					.. find_cmd)
+				vim.api.nvim_command(find_cmd)
+			end
+			i = 0
+			for _ in pairs(linux_src_pathes_depth1) do
+				i = i + 1
+				local find_cmd = "!find " .. git_root .. "/" .. linux_src_pathes_depth1[i]
+				    .. " -name \"*.[chS]\" -o -name \"*.m4\" -maxdepth 1 >> "
+				    .. git_root .. "/cscope.files"
+				print("[" .. FileName() .. ":" .. FunctionName() .. ":" .. LineNumber() .. "]"
+					.. find_cmd)
+				vim.api.nvim_command(find_cmd)
+			end
+		else
+			print("[" .. FileName() .. ":" .. FunctionName() .. ":" .. LineNumber() .. "]"
+				.. git_root .. " is not linux kernel src reprository, involve all pathes")
+			local find_cmd = "!find " .. git_root .. " > " .. git_root .. "/cscope.files"
+			print("[" .. FileName() .. ":" .. FunctionName() .. ":" .. LineNumber() .. "]"
+				.. find_cmd)
+			vim.api.nvim_command(find_cmd)
+		end
+	else
+		local local_path = os.capture("pwd")
+		print("[" .. FileName() .. ":" .. FunctionName() .. ":" .. LineNumber() .. "]"
+			.. local_path .. " is not a git reprository, directly output cscope.files here")
+		local find_cmd = "!find " .. local_path .. " > " .. local_path .. "/cscope.files"
+		print("[" .. FileName() .. ":" .. FunctionName() .. ":" .. LineNumber() .. "]"
+			.. find_cmd)
+		vim.api.nvim_command(find_cmd)
+	end
+end
+
+-- function to generate cscope.out
+M.cscope_out_generate = function()
+	local git_root = os.capture("git rev-parse --show-toplevel")
+	if git_root ~= "" then
+		print("[" .. FileName() .. ":" .. FunctionName() .. ":" .. LineNumber() .. "]"
+			.. git_root .. " is a git reprository")
+		local csc_files = git_root .. "/cscope.files"
+		if vim.loop.fs_stat(csc_files) == nil then
+			print("[" .. FileName() .. ":" .. FunctionName() .. ":" .. LineNumber() .. "]"
+				.. csc_files .. " does not exist")
+			M.cscope_files_generate()
+		end
+		local cmd = "!cd " .. git_root .. "/ && cscope -Rbq -i " .. git_root .. "/cscope.files"
+		vim.api.nvim_command(cmd)
+		vim.g.cscope_maps_db_file = git_root .. "/cscope.out"
+
+		cmd = "!cd " .. git_root .. "/ && ctags -L " .. git_root .. "/cscope.files"
+		vim.api.nvim_command(cmd)
+	end
+end
+
+-- command ':cscope generate' handlerM.cscope = function(cmd, op, symbol)-- Parse top level output and call appropriate functionsif cmd == "find" thencscope_find(op, symbol)elseif cmd == "help" or cmd == nil thencscope_help()
+	elseif cmd == "generate" then
+		M.cscope_files_generate()
+	elseif cmd == "tag" then
+		M.cscope_out_generate()elseprint("cscope: command '" .. cmd .. "' is invalid")end
diff --git a/lua/cscope_maps.lua b/lua/cscope_maps.lua
index 1901e9a..a7f9e6d 100644
--- a/lua/cscope_maps.lua
+++ b/lua/cscope_maps.lua
@@ -36,8 +36,10 @@ end-- define key table for input stringslocal sym_map = {["s"] = "Find this symbol",
+	["G"] = "Generate cscope.files",["g"] = "Find this global defination",["c"] = "Find functions calling this function",
+	["T"] = "Generate cscope.out",["t"] = "Find this text string",["e"] = "Find this egrep pattern",["f"] = "Find this file",
@@ -81,6 +83,12 @@ local keymap_wo_wk = function()[[<cmd>lua require('cscope_maps').cscope_prompt('s', vim.fn.expand("<cword>"))<cr>]],keymap_opts)
+	vim.api.nvim_set_keymap(
+		"n",
+		"<leader>cG",
+		[[<cmd>lua require('cscope.cscope').cscope_files_generate()<cr>]],
+		keymap_opts
+	)vim.api.nvim_set_keymap("n","<leader>cg",
@@ -93,6 +101,12 @@ local keymap_wo_wk = function()[[<cmd>lua require('cscope_maps').cscope_prompt('c', vim.fn.expand("<cword>"))<cr>]],keymap_opts)
+	vim.api.nvim_set_keymap(
+		"n",
+		"<leader>cT",
+		[[<cmd>lua require('cscope.cscope').cscope_out_generate()<cr>]],
+		keymap_opts
+	)vim.api.nvim_set_keymap("n","<leader>ct",
@@ -139,10 +153,14 @@ local keymap_w_wk = function(wk)name = "+code",s = { "<cmd>lua require('cscope_maps').cscope_prompt('s', vim.fn.expand('<cword>'))<cr>",sym_map["s"] },
+				G = { "<cmd>lua require('cscope.cscope').cscope_files_generate()<cr>",
+					sym_map["G"] },g = { "<cmd>lua require('cscope_maps').cscope_prompt('g', vim.fn.expand('<cword>'))<cr>",sym_map["g"] },c = { "<cmd>lua require('cscope_maps').cscope_prompt('c', vim.fn.expand('<cword>'))<cr>",sym_map["c"] },
+				T = { "<cmd>lua require('cscope.cscope').cscope_out_generate()<cr>",
+					sym_map["T"] },t = { "<cmd>lua require('cscope_maps').cscope_prompt('t', vim.fn.expand('<cword>'))<cr>",sym_map["t"] },e = { "<cmd>lua require('cscope_maps').cscope_prompt('e', vim.fn.expand('<cword>'))<cr>",
-- 
2.34.1

3.6 QuickFix 窗口遍历搜索结果

cscope的搜索结果会在QuickFix窗口里列出, jk选中某个搜索结果,回车就跳转到相应的代码处, active窗口从QuickFix改为源代码窗口,此时
]q                向下遍历QuickFix里的搜索结果
[q                向上遍历QuickFix里的搜索结果
<C-q>        开关QuickFix窗口

4 添加 auto-session 插件

通常我们会反复查看某个一个代码目录N多次, 本插件可以在lvim退出时保存窗口布局,下次打开时自动恢复之前的状态

4.1 修改config.lua添加cscope插件

在~/.config/lvim里加入下面的修改

jenkins@rico-fast:~/.config/lvim$ git show
commit e56d866edd916b8c77bfb73429b7db953e50de73 (HEAD -> master)
Author: Linux Jenkins <jenkins@rico-fast.amd.com>
Date:   Mon May 8 19:15:24 2023 +0800Add auto-sessiondiff --git a/config.lua b/config.lua
index 42115a5..6436a33 100644
--- a/config.lua
+++ b/config.lua
@@ -34,6 +34,32 @@ lvim.plugins = {})end,},
+
+       {
+               -- 还原窗口布局和打开的文件(利用的是nvim本身的会话功能)
+               --  ":mksession SessionName" -- ":source SessionName"   #创建文件SessionName保存当前的窗口layout状态, source则利用这些信息恢复窗口状态
+               --      ":wviminfo VimInfo" -- ":rviminfo VimInfo"              #创建文件VimInfo保存操作的历史记录,命令的历史记录等, 恢复那些记录
+                -- 只是存储的会话信息,不在代码目录里,默认统一放到 ~/.local/share/lvim/sessions 下了
+                -- 带参数启动lvim虽然不会自动还原, 但可以 :RestoreSession 手动还原, 与之对应 :SaveSession 手动保存
+                "rmagatti/auto-session",
+                config = function()
+                        require('lualine').setup {
+                                options = { theme = 'tokyonight', },
+                                sections = { lualine_c = { require('auto-session').current_session_name } }
+                        }
+                        require("auto-session").setup({
+                                log_level = "info",
+                                auto_session_enable_last_session = false,
+                                auto_session_root_dir = nil,
+                                auto_session_enabled = true,
+                                auto_save_enabled = true,
+                               auto_restore_enabled = true,
+                               -- auto_session_suppress_dirs = { "~/", "~/Projects" },
+                               auto_session_suppress_dirs = nil,
+                               auto_session_use_git_branch = false,
+                       })
+               end,
+       },}

4.2 重新启动lvim自动安装 auto-session

4.3 修改auto-session使其把会话文件保存到linux代码目录里

默认在~/.local/share/lvim/sessions 里保存会话文件, 会话文件可能会重名,改为保存到不同的源代码目录里

# 在修改前,切换到自己的分支,这样修改后提交到自己的分支,当Lazy sync代码后,也可以快速切换回来
jenkins@rico-fast:~/.local/share/lunarvim/site/pack/lazy/opt/auto-session$ git checkout -b MyBranchjenkins@rico-fast:~/.local/share/lunarvim/site/pack/lazy/opt/auto-session$ cat 0001-save-and-search-sessinfile-in-.git-parent-dir.patch
From 694b588d2de7aef07cc6e7c72a46d91d1d5cad64 Mon Sep 17 00:00:00 2001
From: Linux Jenkins <jenkins@rico-fast.amd.com>
Date: Mon, 8 May 2023 19:49:05 +0800
Subject: [PATCH] save and search sessinfile in .git parent dir---lua/auto-session/init.lua | 49 ++++++++++++++++++++++++++++++++++++++-1 file changed, 48 insertions(+), 1 deletion(-)diff --git a/lua/auto-session/init.lua b/lua/auto-session/init.lua
index a58c80f..5dd45d1 100644
--- a/lua/auto-session/init.lua
+++ b/lua/auto-session/init.lua
@@ -289,6 +289,8 @@ local function get_session_file_name(upcoming_session_dir)Lib.logger.debug { is_empty = is_empty, upcoming_session_dir = upcoming_session_dir }end+  upcoming_session_dir = vim.g["auto_session_root_dir"]
+ Lib.logger.debug("get_session_file_name", { session = session, upcoming_session_dir = upcoming_session_dir })if not vim.fn.isdirectory(Lib.expand(session or upcoming_session_dir)) then
@@ -371,6 +373,49 @@ function AutoSession.AutoSaveSession(sessions_dir)endend+local FileName = function()
+	local str = debug.getinfo(2, "S").source:sub(2)
+	return str:match("^.*/(.*).lua$") or str
+end
+
+local FunctionName = function()
+	local str = debug.getinfo(2, "n").name
+	return str
+end
+
+local LineNumber = function()
+	local line = debug.getinfo(2).currentline
+	return line
+end
+
+function os.capture(cmd, raw)
+	local f = assert(io.popen(cmd, 'r'))
+	local s = assert(f:read('*a'))
+	f:close()
+	if raw then return s end
+	s = string.gsub(s, '^%s+', '')
+	s = string.gsub(s, '%s+$', '')
+	s = string.gsub(s, '[\n\r]+', ' ')
+	return s
+end
+
+function AutoSession.load_db()
+	if vim.g["auto_session_root_dir"] == nil then
+		local git_path = os.capture("git rev-parse --show-toplevel")
+		if git_path ~= "" then
+			-- print("[" .. FileName() .. ":" .. FunctionName() .. ":" .. LineNumber() .. "]"
+			-- 	.. git_path .. " is a git reprository")
+			vim.g["auto_session_root_dir"] = git_path
+		else
+			-- print("[" .. FileName() .. ":" .. FunctionName() .. ":" .. LineNumber() .. "]"
+			-- 	.. git_path .. " is not a git reprository")
+			vim.g["auto_session_root_dir"] = os.capture("pwd")
+		end
+	end
+end
+
+
+---Gets the root directory of where to save the sessions.---By default this resolves to `vim.fn.stdpath "data" .. "/sessions/"`---@return string
@@ -379,6 +424,7 @@ function AutoSession.get_root_dir()return AutoSession.conf.auto_session_root_dirend+  AutoSession.load_db()local root_dir = vim.g["auto_session_root_dir"] or AutoSession.conf.auto_session_root_dirLib.init_dir(root_dir)@@ -608,7 +654,8 @@ local function extract_dir_or_file(session_dir_or_file)local session_file = nilif Lib.is_empty(session_dir_or_file) then
-    session_dir = vim.fn.getcwd()
+	  AutoSession.load_db()
+	  session_dir = vim.g["auto_session_root_dir"]elseif vim.fn.isdirectory(Lib.expand(session_dir_or_file)) == Lib._VIM_TRUE thenif not Lib.ends_with(session_dir_or_file, "/") thensession_dir = session_dir_or_file
-- 
2.34.1

4.4 不带参数启动lvim, 将自动恢复之前的窗口状态

5 添加其他插件

jenkins@rico-fast:~/.config/lvim$ cat 0001-Add-other-plugins-that-does-not-need-my-patches.patch
From 259d47f82a97c2a0eab9d3fb54a4a1d20f84608d Mon Sep 17 00:00:00 2001
From: Linux Jenkins <jenkins@rico-fast.amd.com>
Date: Mon, 8 May 2023 20:19:00 +0800
Subject: [PATCH] Add other plugins that does not need my patches---config.lua | 321 +++++++++++++++++++++++++++++++++++++++++++++++++++++1 file changed, 321 insertions(+)diff --git a/config.lua b/config.lua
index 6436a33..ca8e45c 100644
--- a/config.lua
+++ b/config.lua
@@ -60,6 +60,312 @@ lvim.plugins = {})end,},
+
+        {
+                -- 文件被编辑1秒后自动保存编辑的文件
+                "Pocco81/auto-save.nvim",
+                config = function()
+                        require("auto-save").setup {
+                                -- your config goes here
+                                -- or just leave it empty :)
+                                enabled = true, -- start auto-save when the plugin is loaded (i.e. when your package manager loads it)
+                                execution_message = {
+                                        message = function() -- message to print on save
+                                                return ("AutoSave: saved at " .. vim.fn.strftime("%H:%M:%S"))
+                                        end,
+                                        dim = 0.18,    -- dim the color of `message`
+                                        cleaning_interval = 1250, -- (milliseconds) automatically clean MsgArea after displaying `message`. See :h MsgArea
+                                },
+                                trigger_events = { "InsertLeave", "TextChanged" }, -- vim events that trigger auto-save. See :h events
+                                -- function that determines whether to save the current buffer or not
+                                -- return true: if buffer is ok to be saved
+                                -- return false: if it's not ok to be saved
+                                condition = function(buf)
+                                        local fn = vim.fn
+                                        local utils = require("auto-save.utils.data")
+
+                                        if
+                                                fn.getbufvar(buf, "&modifiable") == 1 and
+                                                utils.not_in(fn.getbufvar(buf, "&filetype"), {}) then
+                                                return true -- met condition(s), can save
+                                        end
+                                        return false -- can't save
+                                end,
+                                write_all_buffers = false, -- write all buffers when the current one meets `condition`
+                                debounce_delay = 135, -- saves the file at most every `debounce_delay` milliseconds
+                                callbacks = {
+                                        -- functions to be executed at different intervals
+                                        enabling = nil, -- ran when enabling auto-save
+                                        disabling = nil, -- ran when disabling auto-save
+                                        before_asserting_save = nil, -- ran before checking `condition`
+                                        before_saving = nil, -- ran before doing the actual save
+                                        after_saving = nil -- ran after doing the actual save
+                                }
+                        }
+                end,
+        },
+
+        {
+                -- 记住退出lvim时光标在文件的行号,重新打开此文件时自动跳转到上次光标行
+                "ethanholz/nvim-lastplace",
+                -- event = "BufRead",
+                config = function()
+                        require("nvim-lastplace").setup({
+                                lastplace_ignore_buftype = { "quickfix", "nofile", "help" },
+                                lastplace_ignore_filetype = { "gitcommit", "gitrebase", "svn", "hgcommit" },
+                                lastplace_open_folds = true,
+                        })
+                end,
+        },
+
+        {
+                -- 多关键字高亮
+                -- let HiSet   = 'f<CR>'
+                -- let HiErase = 'f<BS>'
+                -- let HiClear = 'f<C-L>'
+                -- let HiFind  = 'f<Tab>'
+                "azabiong/vim-highlighter",
+        },
+
+        {
+                -- 让代码滚动更顺滑, 当前要么jk一行一行的滚动, 要么<C-u/d> 直接半屏的跳(没有中间过程), 此插件可以显示半屏或整屏滚动的中间过程, 且中间过程丝滑快捷
+                "karb94/neoscroll.nvim",
+                event = "WinScrolled",
+                config = function()
+                        require('neoscroll').setup({
+                                -- All these keys will be mapped to their corresponding default scrolling animation
+                                mappings = { '<C-u>', '<C-d>', -- 半屏上下滚(光标行在屏上的位置不动)
+                                        '<C-b>', '<C-f>', -- 整屏上下滚(光标行在屏上的位置不动)
+                                        '<C-y>', '<C-e>', -- 逐行上下滚(光标行在屏上的位置跟着动)
+                                'zt', 'zz', 'zb' }, -- 光标行和代码行一起居3/4,居中,1/4
+                                hide_cursor = true, -- Hide cursor while scrolling
+                                stop_eof = true, -- Stop at <EOF> when scrolling downwards
+                                use_local_scrolloff = false, -- Use the local scope of scrolloff instead of the global scope
+                                respect_scrolloff = false, -- Stop scrolling when the cursor reaches the scrolloff margin of the file
+                                cursor_scrolls_alone = true, -- The cursor will keep on scrolling even if the window cannot scroll further
+                                easing_function = nil, -- Default easing function
+                                pre_hook = nil, -- Function to run before the scrolling animation starts
+                                post_hook = nil, -- Function to run after the scrolling animation ends
+                        })
+                end
+                -- 涉及三个物体的关系,
+                -- 一个相对人眼固定不动的窗口--屏幕;
+                -- 一条存储了N行代码的长纸带,纸带能相对窗口上下移动;
+                -- 一个光标所在行,能在屏幕内上下移动;
+
+                -- <C-u>	光标行与屏幕相对静止,纸带下滚半屏
+                -- <C-d>	光标行与屏幕相对静止,纸带上滚半屏
+                -- <C-b>	光标行与屏幕相对静止,纸带下滚全屏
+                -- <C-f>	光标行与屏幕相对静止,纸带上滚全屏
+
+                -- <C-y>	光标行与纸带相对静止,纸带逐行下滚
+                -- <C-e>	光标行与纸带相对静止,纸带逐行上滚
+                -- zt	        光标行与纸带相对静止,纸带上滚到区间顶
+                -- zz	        光标行与纸带相对静止,纸带滚到区间中
+                -- zb	        光标行与纸带相对静止,纸带下滚到区间底
+        },
+
+        {
+                -- 当代码块太长时, 本插件把函数名/switch 行等pin住, 滚动代码时知道光标在哪个代码块里
+                "romgrk/nvim-treesitter-context",
+                config = function()
+                        require("treesitter-context").setup {
+                                enable = true, -- Enable this plugin (Can be enabled/disabled later via commands)
+                                throttle = true, -- Throttles plugin updates (may improve performance)
+                                max_lines = 0, -- How many lines the window should span. Values <= 0 mean no limit.
+                                patterns = {
+					-- Match patterns for TS nodes. These get wrapped to match at word boundaries.
+					-- For all filetypes
+					-- Note that setting an entry here replaces all other patterns for this entry.
+					-- By setting the 'default' entry below, you can control which nodes you want to
+					-- appear in the context window.
+					default = {
+						'class',
+						'function',
+						'method',
+					},
+				},
+			}
+		end
+		-- :TSContextToggle
+		-- :TSContextEnable
+                -- :TSContextDisable
+        },
+
+        {
+                -- 彩色显示配对的() [] {}
+                "mrjones2014/nvim-ts-rainbow",
+	},
+
+        
+	{
+		-- 显示当前源文件的符号和函数列表
+		-- 下面定义F5为toggle "symbols outline" 窗口的快捷键
+		-- lvim.keys.normal_mode["<F5>"] = ":SymbolsOutline<CR>"
+		
+		-- Esc		Close outline
+		-- Enter	Go to symbol location in code
+		-- o		Go to symbol location in code without losing focus
+		-- Ctrl+Space	Hover current symbol
+		-- K		Toggles the current symbol preview
+		-- r		Rename symbol
+		-- a		Code actions
+		-- h		fold symbol
+		-- l		Unfold symbol
+		-- W		Fold all symbols
+		-- E		Unfold all symbols
+		-- R		Reset all folding
+		-- ?		Show help message
+
+		"simrat39/symbols-outline.nvim",
+		config = function()
+			require("symbols-outline").setup({
+				highlight_hovered_item = true,
+				show_guides = true,
+				auto_preview = false,
+				position = 'right',
+				relative_width = true,
+				width = 25,
+				auto_close = false,
+				show_numbers = false,
+				show_relative_numbers = false,
+				show_symbol_details = true,
+				preview_bg_highlight = 'Pmenu',
+				autofold_depth = nil,
+				auto_unfold_hover = true,
+				fold_markers = { '', '' },
+				wrap = false,
+				keymaps = {
+					-- These keymaps can be a string or a table for multiple keys
+					close = { "<Esc>", "q" },
+					goto_location = "<Cr>",
+					focus_location = "o",
+					hover_symbol = "<C-space>",
+					toggle_preview = "K",
+					rename_symbol = "r",
+					code_actions = "a",
+					fold = "h",
+					unfold = "l",
+					fold_all = "W",
+					unfold_all = "E",
+					fold_reset = "R",
+				},
+				lsp_blacklist = {},
+				symbol_blacklist = {},
+				symbols = {
+					File = { icon = "", hl = "@text.uri" },
+					Module = { icon = "", hl = "@namespace" },
+					Namespace = { icon = "", hl = "@namespace" },
+					Package = { icon = "", hl = "@namespace" },
+					Class = { icon = "𝓒", hl = "@type" },
+					Method = { icon = "ƒ", hl = "@method" },
+					Property = { icon = "", hl = "@method" },
+					Field = { icon = "", hl = "@field" },
+					Constructor = { icon = "", hl = "@constructor" },
+					Enum = { icon = "ℰ", hl = "@type" },
+					Interface = { icon = "ﰮ", hl = "@type" },
+					Function = { icon = "", hl = "@function" },
+					Variable = { icon = "", hl = "@constant" },
+					Constant = { icon = "", hl = "@constant" },
+					String = { icon = "𝓐", hl = "@string" },
+					Number = { icon = "#", hl = "@number" },
+					Boolean = { icon = "⊨", hl = "@boolean" },
+					Array = { icon = "", hl = "@constant" },
+					Object = { icon = "⦿", hl = "@type" },
+					Key = { icon = "🔐", hl = "@type" },
+					Null = { icon = "NULL", hl = "@type" },
+					EnumMember = { icon = "", hl = "@field" },
+					Struct = { icon = "𝓢", hl = "@type" },
+					Event = { icon = "🗲", hl = "@type" },
+					Operator = { icon = "+", hl = "@operator" },
+					TypeParameter = { icon = "𝙏", hl = "@parameter" },
+					Component = { icon = "", hl = "@function" },
+					Fragment = { icon = "", hl = "@constant" },
+				},
+			})
+		end,
+	},
+
+        {
+		-- vim最广泛使用的git插件
+		"tpope/vim-fugitive",
+		cmd = {
+			"G",
+			"Git",
+			"Gdiffsplit",
+			"Gread",
+			"Gwrite",
+			"Ggrep",
+			"GMove",
+			"GDelete",
+			"GBrowse",
+			"GRemove",
+			"GRename",
+			"Glgrep",
+			"Gedit"
+                        -- :Git <Tab>					能提示所有Git 命令
+                        -- :Git add
+                        -- :Git commit
+                        -- :Git rebase -i
+                        -- :Git diff
+                        -- :Git log
+                        -- :Git blame					新开窗口显示本源文件每行的最后提交
+                        -- :Git mergetool					合并 diffview 的命令
+                        -- :Gdiffsplit					以左右分屏方式对比当前文件未提交的修改
+                        -- :Ggrep 						Ggrep==git grep, 搜索git 关注的文件类型, ignore的不看
+                        -- :Ggrep ValidMode HEAD~1				在当前branch的某个历史版本里去搜索
+                        -- :Ggrep ValidMode specificBranch			在某个branch的最新状态上去搜索
+                        -- :Ggrep ValidMode HEAD HEAD~100 specificBranch	在某个branch的一段历史上去搜索
+                        -- :Ggrep ValidMode HEAD HEAD~100 			在当前branch的一段历史上去搜索
+                        -- :GMove						==git mv,
+                        -- :GRename					==git rename
+                        -- :GDelete					==git rm
+			-- $ git log --patch -G"release_vcpi_slots" .	命令行里搜索某个文件/目录的修改记录里包含关键字的commit␓
+		},
+		ft = { "fugitive" }
+	},
+
+	{
+		-- diffview.nvim 以vim diff的左右窗口对比的方式呈现每笔修改
+		"sindrets/diffview.nvim",
+		event = "BufRead",
+		-- bufferline/buffer/代码窗口(vs 或者 split产生的众多代码窗口) 之间的关系:
+		-- bufferline是一个状态条,里面有所有打开的buffer(i.e. 一个源代码文件名), 而一个代码窗口只代表一个矩形区域, 一个buffer可以出现在一个或者多个window里, 而一个window也可以对应多个buffer.
+		-- <leader>c关闭的是buffer, 如果此buffer被多个窗口打开, 那么所有窗口都将关闭此文件, 窗口切换为显示bufferline里的候补文件, 如果bufferline空了, 所有窗口将关闭, 并创建一个未命名buffer窗口
+		-- <leader>q关闭的是window, 此窗口将消失, 代码窗口区域还原成创建此窗口前的样子, 如果此window关联着多个buffer, buffer可能并没有被关闭, bufferline还存在, 点击 bufferline 还能打开代码窗口
+
+		-- lvim原有的nvimtree 和 代码窗口 共同组成了一个layer, 我把Diffview的窗口也定义为一层layer, 它比原layer在z-order上高一层, 会挡住原有layer
+		-- :[range]DiffviewFileHistory [paths] [options]	Opens a new file history view that lists all commits that affected the given paths.
+		-- :DiffviewFileHistory                                 倒品窗口查看当前branch的历史commit(底部窗口,同时缩进展示本commit修改了哪些文件),选中文件后回车将在上部左右窗口vimdiff形式直观展示修
+		-- :DiffviewFileHistory %                               倒品窗口查看当前文件的历史commit,同样以diff方式展示
+		-- :h DiffviewFileHistory                               help
+		-- :DiffviewFileHistory path/to/some/file.txt
+		-- :DiffviewFileHistory path/to/some/directory
+		-- :DiffviewFileHistory include/this and/this :!but/not/this
+		-- :DiffviewFileHistory --range=origin..HEAD
+		-- :DiffviewFileHistory --range=feat/example-branch
+		-- :'<,'>DiffviewFileHistory
+		-- Familiarize Yourself With :h diff-mode
+
+
+		-- :DiffviewOpen [git rev] [options] [ -- {paths...}]   比较版本间的差异,可以指定具体不同commit和文件, 左中右三窗口,左是版本间差异涉及哪些文件,中右是vimdiff.
+		-- 							左边文件列表窗口里,可以通过<tab> and <s-tab>遍历文件列表
+		-- Examples:
+		-- :DiffviewOpen					和 lvim原生git插件的 <leader>gd 效果一致, 和 "tpope/vim-fugitive"的 :Gdiffsplit 效果一致
+		-- :DiffviewOpen HEAD~2
+		-- :DiffviewOpen HEAD~4..HEAD~2
+		-- :DiffviewOpen d4a7b0d
+		-- :DiffviewOpen d4a7b0d^!
+		-- :DiffviewOpen d4a7b0d..519b30e
+		-- :DiffviewOpen origin/main...HEAD
+		-- :DiffviewOpen HEAD~2 -- lua/diffview plugin
+		-- :DiffviewClose                                       == :tabclose. 关闭diffview层
+		-- :DiffviewToggleFiles                                 Toggle 左边文件列表窗口
+		-- :DiffviewFocusFiles                                  光标移动到左边文件列表窗口
+		-- :DiffviewRefresh                                     刷新 Diffview
+
+	},
+}@@ -96,5 +402,13 @@ lvim.keys.normal_mode["ts"] = ":Cscope find  g "        -- 手动输入要搜索-- <C-w><C-r> 是交换窗口左右位置lvim.keys.normal_mode["ff"] = "/<C-r><C-w><CR>"+
+lvim.builtin.treesitter.rainbow.enable = true
+lvim.builtin.treesitter.rainbow.extended_mode = true
+lvim.builtin.treesitter.rainbow.max_file_lines = 10000
+lvim.builtin.treesitter.rainbow.disable = { "jsx", "js" }
+
+lvim.keys.normal_mode["<F5>"] = ":SymbolsOutline<CR>"
+
+-- ~/.config/lvim/lazy-lock.json stores all plugins version, end-user should store +this file, it will change time to time
+-- :Lazy restore -- will restore all plugins back to the specific version
+
+-- 插入模式时, 插入当前被编辑文件的路径.
+-- https://vim.fandom.com/wiki/Insert_current_filename
+lvim.keys.insert_mode["<leader>fp"] = "<C-r>=expand('%:p:h')<CR>"
+lvim.keys.insert_mode["<leader>fn"] = "<C-r>=expand('%:p')<CR>"---Rico config end--------------------------------------------------------------------------------------------------------------------------------
-- 
2.34.1

6 使能<leader>nn向后遍历bufferline

jenkins@rico-fast:~/.local/share/lunarvim/lvim$ cat 0001-Add-nn-to-next-bufferline-item.patch
From a2f5f7002bb4018329b25a2274246ecc8d21b1fc Mon Sep 17 00:00:00 2001
From: Linux Jenkins <jenkins@rico-fast.amd.com>
Date: Mon, 8 May 2023 20:24:20 +0800
Subject: [PATCH] Add nn to next bufferline item---lua/lvim/core/which-key.lua | 4 ++++1 file changed, 4 insertions(+)diff --git a/lua/lvim/core/which-key.lua b/lua/lvim/core/which-key.lua
index 2ab47b05..ed5f9b8f 100644
--- a/lua/lvim/core/which-key.lua
+++ b/lua/lvim/core/which-key.lua
@@ -278,6 +278,10 @@ M.config = function()r = { "<cmd>LvimReload<cr>", "Reload LunarVim's configuration" },u = { "<cmd>LvimUpdate<cr>", "Update LunarVim" },},
+                        n = {
+                                name = "Buffers",
+                                n = { "<cmd>BufferLineCycleNext<cr>", "Next" },
+                        },s = {name = "Search",b = { "<cmd>Telescope git_branches<cr>", "Checkout branch" },
-- 
2.34.1

7 Lunarvim的常用快捷键

-- 如下文件是lvim默认快捷键的配置的地方
-- ~/.local/share/lunarvim/lvim/lua/lvim/core/which-key.lua
--[[ mappings = {[";"] = { "<cmd>Alpha<CR>", "Dashboard" },							-- <leader>;	toggle lvim开始界面["e"] = { "<cmd>NvimTreeToggle<CR>", "Explorer" },						-- <leader>e	toggle 目录树侧窗["w"] = { "<cmd>w!<CR>", "Save" },								-- <leader>w	保存文件["c"] = { "<cmd>BufferKill<CR>", "Close Buffer" },						-- <leader>c	关闭buffer(一个打开的文件就是一个buffer)["q"] = { "<cmd>confirm q<CR>", "Quit" },								-- <leader>q	关闭窗口(一个窗口可以有多个打开的buffer)["/"] = { "<Plug>(comment_toggle_linewise_current)", "Comment toggle current line" },		-- <leader>/	toggle 注释掉光标行["f"] = {												-- <leader>f	文件查找function()require("lvim.core.telescope.custom-finders").find_project_files { previewer = false }end,"Find File",},["h"] = { "<cmd>nohlsearch<CR>", "No Highlight" },						-- <leader>h	normal下 gd 文件内查找光标关键字会高亮关键字, <leader>h 关闭高亮b = {name = "Buffers",j = { "<cmd>BufferLinePick<cr>", "Jump" },							-- <leader>bj	buffer跳转,标签化已打开的buffer,再按对应的字母就跳转到对应buffer,但如果buffer太多则bufferline里只能显示几个bufferf = { "<cmd>Telescope buffers previewer=false<cr>", "Find" },					-- <leader>bj	buffer跳转,以弹窗列出已打开buffers,jk移动光标回车打开bufferb = { "<cmd>BufferLineCyclePrev<cr>", "Previous" },						-- <leader>bb	buffer跳转,打开bufferline里前一个buffern = { "<cmd>BufferLineCycleNext<cr>", "Next" },							-- <leader>bn 	buffer跳转,打开bufferline里后一个bufferW = { "<cmd>noautocmd w<cr>", "Save without formatting (noautocmd)" },				-- w = { "<cmd>BufferWipeout<cr>", "Wipeout" }, -- TODO: implement this for bufferlinee = {												-- <leader>be	buffer关闭,标签化已打开的buffer,再按对应的字母就关闭对应buffer"<cmd>BufferLinePickClose<cr>","Pick which buffer to close",},h = { "<cmd>BufferLineCloseLeft<cr>", "Close all to the left" },				-- <leader>bh	buffer关闭,关闭激活buffer左边bufferl = { "<cmd>BufferLineCloseRight<cr>", "Close all to the right" },				-- <leader>bl	buffer关闭,关闭激活buffer右边bufferD = {												-- <leader>bD	根据目录排列已打开的buffer"<cmd>BufferLineSortByDirectory<cr>","Sort by directory",},L = {												-- <leader>bD	根据后缀排列已打开的buffer"<cmd>BufferLineSortByExtension<cr>","Sort by language",},},d = {name = "Debug",t = { "<cmd>lua require'dap'.toggle_breakpoint()<cr>", "Toggle Breakpoint" },b = { "<cmd>lua require'dap'.step_back()<cr>", "Step Back" },c = { "<cmd>lua require'dap'.continue()<cr>", "Continue" },C = { "<cmd>lua require'dap'.run_to_cursor()<cr>", "Run To Cursor" },d = { "<cmd>lua require'dap'.disconnect()<cr>", "Disconnect" },g = { "<cmd>lua require'dap'.session()<cr>", "Get Session" },i = { "<cmd>lua require'dap'.step_into()<cr>", "Step Into" },o = { "<cmd>lua require'dap'.step_over()<cr>", "Step Over" },u = { "<cmd>lua require'dap'.step_out()<cr>", "Step Out" },p = { "<cmd>lua require'dap'.pause()<cr>", "Pause" },r = { "<cmd>lua require'dap'.repl.toggle()<cr>", "Toggle Repl" },s = { "<cmd>lua require'dap'.continue()<cr>", "Start" },q = { "<cmd>lua require'dap'.close()<cr>", "Quit" },U = { "<cmd>lua require'dapui'.toggle({reset = true})<cr>", "Toggle UI" },},p = {name = "Plugins",i = { "<cmd>Lazy install<cr>", "Install" },s = { "<cmd>Lazy sync<cr>", "Sync" },								-- <leader>ps	lazy同步所有插件S = { "<cmd>Lazy clear<cr>", "Status" },							-- <leader>pS	lazy查看所有插件状态c = { "<cmd>Lazy clean<cr>", "Clean" },u = { "<cmd>Lazy update<cr>", "Update" },p = { "<cmd>Lazy profile<cr>", "Profile" },l = { "<cmd>Lazy log<cr>", "Log" },d = { "<cmd>Lazy debug<cr>", "Debug" },},-- " Available Debug Adapters:-- "   https://microsoft.github.io/debug-adapter-protocol/implementors/adapters/-- " Adapter configuration and installation instructions:-- "   https://github.com/mfussenegger/nvim-dap/wiki/Debug-Adapter-installation-- " Debug Adapter protocol:-- "   https://microsoft.github.io/debug-adapter-protocol/-- " Debuggingg = {name = "Git",g = { "<cmd>lua require 'lvim.core.terminal'.lazygit_toggle()<cr>", "Lazygit" },j = { "<cmd>lua require 'gitsigns'.next_hunk({navigation_message = false})<cr>", "Next Hunk" },	-- <leader>gj	跳转下一个修改的hunk代码段k = { "<cmd>lua require 'gitsigns'.prev_hunk({navigation_message = false})<cr>", "Prev Hunk" },	-- <leader>gk	跳转上一个修改的hunk代码段l = { "<cmd>lua require 'gitsigns'.blame_line()<cr>", "Blame" },				-- <leader>gl	弹窗显示光标行的最后修改记录, jk移动则弹窗自动关闭p = { "<cmd>lua require 'gitsigns'.preview_hunk()<cr>", "Preview Hunk" },			-- <leader>gp	光标行为未提交修改时,弹窗显示修改情况r = { "<cmd>lua require 'gitsigns'.reset_hunk()<cr>", "Reset Hunk" },				-- <leader>gr	光标行为未提交修改时,清除本hunk修改R = { "<cmd>lua require 'gitsigns'.reset_buffer()<cr>", "Reset Buffer" },			-- <leader>gR	清除本文件所有未提交的修改s = { "<cmd>lua require 'gitsigns'.stage_hunk()<cr>", "Stage Hunk" },				-- <leader>gs	光标行为未提交修改时,git add 本hunk修改u = {												-- <leader>gu	光标行为未提交修改时,git unadd 本hunk修改"<cmd>lua require 'gitsigns'.undo_stage_hunk()<cr>","Undo Stage Hunk",},o = { "<cmd>Telescope git_status<cr>", "Open changed file" },					-- <leader>go	查看当前仓库有哪些未提交的文件,选中回车打开文件b = { "<cmd>Telescope git_branches<cr>", "Checkout branch" },					-- <leader>gb	查看当前仓库有哪些branch并checkout到选中的branchc = { "<cmd>Telescope git_commits<cr>", "Checkout commit" },					-- <leader>gc	查看当前仓库修改记录,选中回车则checkout到选中的commitC = {"<cmd>Telescope git_bcommits<cr>","Checkout commit(for current file)",},d = {												-- <leader>gd	vimdiff查看当前buffer的修改记录, <leader>q 关闭 diff"<cmd>Gitsigns diffthis HEAD<cr>","Git Diff",},},l = {name = "LSP",a = { "<cmd>lua vim.lsp.buf.code_action()<cr>", "Code Action" },d = { "<cmd>Telescope diagnostics bufnr=0 theme=get_ivy<cr>", "Buffer Diagnostics" },w = { "<cmd>Telescope diagnostics<cr>", "Diagnostics" },f = { "<cmd>lua require('lvim.lsp.utils').format()<cr>", "Format" },i = { "<cmd>LspInfo<cr>", "Info" },I = { "<cmd>Mason<cr>", "Mason Info" },j = {"<cmd>lua vim.diagnostic.goto_next()<cr>","Next Diagnostic",},k = {"<cmd>lua vim.diagnostic.goto_prev()<cr>","Prev Diagnostic",},l = { "<cmd>lua vim.lsp.codelens.run()<cr>", "CodeLens Action" },q = { "<cmd>lua vim.diagnostic.setloclist()<cr>", "Quickfix" },r = { "<cmd>lua vim.lsp.buf.rename()<cr>", "Rename" },s = { "<cmd>Telescope lsp_document_symbols<cr>", "Document Symbols" },S = {"<cmd>Telescope lsp_dynamic_workspace_symbols<cr>","Workspace Symbols",},e = { "<cmd>Telescope quickfix<cr>", "Telescope Quickfix" },},L = {name = "+LunarVim",c = {												-- <leader>Lc	打开user配置文件 ~/.config/lvim/config.lua"<cmd>edit " .. get_config_dir() .. "/config.lua<cr>","Edit config.lua",},d = { "<cmd>LvimDocs<cr>", "View LunarVim's docs" },						f = {												-- <leader>Lf	.lua配置文件查找"<cmd>lua require('lvim.core.telescope.custom-finders').find_lunarvim_files()<cr>","Find LunarVim files",},g = {												-- <leader>Lg	.lua配置文件内容grep"<cmd>lua require('lvim.core.telescope.custom-finders').grep_lunarvim_files()<cr>","Grep LunarVim files",},k = { "<cmd>Telescope keymaps<cr>", "View LunarVim's keymappings" },				-- <leader>Lk	显示当前lvim的快捷键, 比如你想添加一个快捷键前先检查一下是否被占用, :mapi = {												-- <leader>Li	显示lvim的状态信息"<cmd>lua require('lvim.core.info').toggle_popup(vim.bo.filetype)<cr>","Toggle LunarVim Info",},I = {												-- <leader>LI	显示 ~/.local/share/lunarvim/lvim 的git status"<cmd>lua require('lvim.core.telescope.custom-finders').view_lunarvim_changelog()<cr>","View LunarVim's changelog",},l = {												-- <leader>Ll	显示lvim neovim LSP等的logname = "+logs",d = {"<cmd>lua require('lvim.core.terminal').toggle_log_view(require('lvim.core.log').get_path())<cr>","view default log",},D = {"<cmd>lua vim.fn.execute('edit ' .. require('lvim.core.log').get_path())<cr>","Open the default logfile",},l = {"<cmd>lua require('lvim.core.terminal').toggle_log_view(vim.lsp.get_log_path())<cr>","view lsp log",},L = { "<cmd>lua vim.fn.execute('edit ' .. vim.lsp.get_log_path())<cr>", "Open the LSP logfile" },n = {"<cmd>lua require('lvim.core.terminal').toggle_log_view(os.getenv('NVIM_LOG_FILE'))<cr>","view neovim log",},N = { "<cmd>edit $NVIM_LOG_FILE<cr>", "Open the Neovim logfile" },},r = { "<cmd>LvimReload<cr>", "Reload LunarVim's configuration" },				-- <leader>Lr	reload配置u = { "<cmd>LvimUpdate<cr>", "Update LunarVim" },						-- <leader>Lu	同步lvim和其他插件代码到最新},n = {												-- <leader>nn 	buffer跳转,打开bufferline里后一个buffer,lvim重新打开才生效(Rico)name = "Buffers",n = { "<cmd>BufferLineCycleNext<cr>", "Next" },},s = {name = "Search",b = { "<cmd>Telescope git_branches<cr>", "Checkout branch" },					-- <leader>sb == <leader>gb 查看当前仓库有哪些branch并checkout到选中的branchc = { "<cmd>Telescope colorscheme<cr>", "Colorscheme" },					-- <leader>sc	切换lvim的颜色主题f = { "<cmd>Telescope find_files<cr>", "Find File" },						-- <leader>sr	显示lvim最近打开过的文件,不包括lua文件h = { "<cmd>Telescope help_tags<cr>", "Find Help" },						-- <leader>sh	显示lvim所有命令的帮助H = { "<cmd>Telescope highlights<cr>", "Find highlight groups" },M = { "<cmd>Telescope man_pages<cr>", "Man Pages" },r = { "<cmd>Telescope oldfiles<cr>", "Open Recent File" },					-- <leader>sr	显示lvim最近打开过的文件R = { "<cmd>Telescope registers<cr>", "Registers" },						-- <leader>sR	显示所有剪贴板, lvim有很多剪贴板, 0~9A~Z等48个, "1yy-yank光标行到剪贴板1, "1p-paste剪贴板1到光标行下t = { "<cmd>Telescope live_grep<cr>", "Text" },k = { "<cmd>Telescope keymaps<cr>", "Keymaps" },						-- <leader>sk == <leader>Lk 显示当前lvim的快捷键C = { "<cmd>Telescope commands<cr>", "Commands" },						-- <leader>sh	遍历搜索lvim所有命令,选好命令后回车,对应命令出现在命令行里l = { "<cmd>Telescope resume<cr>", "Resume last search" },p = {												-- <leader>sp	切换lvim的颜色主题"<cmd>lua require('telescope.builtin').colorscheme({enable_preview = true})<cr>","Colorscheme with Preview",},},T = {name = "Treesitter",i = { ":TSConfigInfo<cr>", "Info" },},},
]]
-- ~/.local/share/lunarvim/lvim/lua/lvim/core/nvimtree.lua
--[[ lvim.builtin.nvimtree.setup.view.mappings.list = {{ key = { "l", "<CR>", "o" }, action = "edit", mode = "n" },		-- 在nvimtree文件列表窗里, l/o/<CR>打开光标文件{ key = "h", action = "close_node" },					-- 在nvimtree文件列表窗里, h跳转到上级目录{ key = "v", action = "vsplit" },						-- 在nvimtree文件列表窗里, v左右分屏打开光标文件{ key = "C", action = "cd" },{ key = "gtf", action = "telescope_find_files", action_cb = telescope_find_files },	-- 在nvimtree文件列表窗里, gtf搜索本目录下的文件名{ key = "gtg", action = "telescope_live_grep", action_cb = telescope_live_grep },		-- 在nvimtree文件列表窗里, gtg搜索本目录下的文件内容} ]]
-- ~/.local/share/lunarvim/lvim/lua/lvim/core/comment.lua
--[[ ---LHS of line and block comment toggle mapping in NORMAL/VISUAL mode---@type tabletoggler = {---line-comment toggle			-- NORMAL 模式时, gcc 注释掉光标行line = "gcc",---block-comment toggle			-- VISUAL 模式时, gbc 注释掉代码块block = "gbc",},---LHS of extra mappings---@type tableextra = {---Add comment on the line above		-- NORMAL 模式时, gcO 在光标行前插入注释行above = "gcO",---Add comment on the line below		-- NORMAL 模式时, gco 在光标行后插入注释行below = "gco",---Add comment at the end of line		-- NORMAL 模式时, gcA 在光标行尾插入注释eol = "gcA",}, ]]
-- ~/.local/share/lunarvim/lvim/lua/lvim/keymappings.lua
--[[ local defaults = {insert_mode = {-- Move current line / block with Alt-j/k ala vscode.["<A-j>"] = "<Esc>:m .+1<CR>==gi",		-- Insert模式时, <Alt-j> <Alt-k> 上下移动光标行["<A-k>"] = "<Esc>:m .-2<CR>==gi",},normal_mode = {-- Better window movement["<C-h>"] = "<C-w>h",			-- Normal模式时, <Ctrl-j> <Ctrl-k> active 窗口["<C-j>"] = "<C-w>j",["<C-k>"] = "<C-w>k",["<C-l>"] = "<C-w>l",-- Resize with arrows["<C-Up>"] = ":resize -2<CR>",		-- Normal模式时, <Ctrl-Up> <Ctrl-Down> 调整窗口宽高["<C-Down>"] = ":resize +2<CR>",["<C-Left>"] = ":vertical resize -2<CR>",["<C-Right>"] = ":vertical resize +2<CR>",-- Move current line / block with Alt-j/k a la vscode.["<A-j>"] = ":m .+1<CR>==",			-- Normal模式时, <Alt-j> <Alt-k> 上下移动光标行["<A-k>"] = ":m .-2<CR>==",-- QuickFix["]q"] = ":cnext<CR>",			-- Normal模式时, 很多插件的结果会显示在QuickFix窗口里, ]q能够遍历cscope搜索的result list["[q"] = ":cprev<CR>",["<C-q>"] = ":call QuickFixToggle()<CR>",	-- toggle QuickFix 窗口},term_mode = {-- Terminal window navigationQ["<C-h>"] = "<C-\\><C-N><C-w>h",["<C-j>"] = "<C-\\><C-N><C-w>j",["<C-k>"] = "<C-\\><C-N><C-w>k",["<C-l>"] = "<C-\\><C-N><C-w>l",},visual_mode = {-- Better indenting["<"] = "<gv",				-- VISUAL 模式时, < > 左右移动代码块 缩进[">"] = ">gv",-- ["p"] = '"0p',-- ["P"] = '"0P',},visual_block_mode = {-- Move current line / block with Alt-j/k ala vscode.["<A-j>"] = ":m '>+1<CR>gv-gv",		-- VISUAL 模式时, <Alt-j> <Alt-k> 上下移动代码块["<A-k>"] = ":m '<-2<CR>gv-gv",},command_mode = {-- navigate tab completion with <c-j> and <c-k>-- runs conditionally["<C-j>"] = { 'pumvisible() ? "\\<C-n>" : "\\<C-j>"', { expr = true, noremap = true } },["<C-k>"] = { 'pumvisible() ? "\\<C-p>" : "\\<C-k>"', { expr = true, noremap = true } },},
}
]]

8 使用vim宏功能

有一个文件列表,想把这些文件压缩备份,需要在每行末尾添加 " \", 但是行很多,手动修改太麻烦,可以使用vim的宏来完成
参考: Use Vim macros to automate frequent tasks | Enable Sysadmin

Normal mode时,移动光标到需要修改的行,然后
qa        q是启动宏录制 a是把宏记录到寄存器a(vim的寄存器相当于剪贴板,有40多个带名字的剪贴板,你也可以使用其他寄存器,比如h)
A          跳转到行尾插入
space\  输入空格和斜线
Esc      退出insert mode
q          结束宏录制
@a      在一个需要进行宏调用的行调用寄存器a里的宏
@@     重复调用上一次的宏
200@a 重复调用a里的宏200次

 

参考

Keybindings | LunarVim


http://chatgpt.dhexx.cn/article/fdkd4ODL.shtml

相关文章

linux虚拟机向上滚动,能当主力,能入虚拟机,还能随时打包带走,Linux 就是这么强大...

原标题&#xff1a;能当主力&#xff0c;能入虚拟机&#xff0c;还能随时打包带走&#xff0c;Linux 就是这么强大 来源&#xff1a;zasdfgbnm zasdfgbnm.github.io/2017/06/29/能当主力&#xff0c;能入虚拟机&#xff0c;还能随时打包带走&#xff0c;Linux就是这么强大/ 这里…

Kubernetes(九)Deployment滚动更新

小知识点 kubectl get pods podA -n NAMEAPSCE -o yaml --export如果不带上--export 生成文件会有很多无用的内容备注&#xff1a; 可以换成其它系列的资源注意&#xff1a; 新版本已经废弃-->1.18.4有&#xff0c;1.19.3已经废弃了 一 Deployment理解 Deployment 是…

【腾讯Bugly干货分享】Android Patch 方案与持续交付

本文来自于腾讯bugly开发者社区&#xff0c;非经作者同意&#xff0c;请勿转载&#xff0c;原文地址&#xff1a;http://dev.qq.com/topic/57a31921ac3a1fb613dd40f3 Android 不仅系统版本众多&#xff0c;机型众多&#xff0c;而且各个市场都各有各的政策和审核速度&#xff…

160多个android开源代码汇总

第一部分 个性化控件(View) 主要介绍那些不错个性化的View&#xff0c;包括ListView、ActionBar、Menu、ViewPager、Gallery、GridView、ImageView、ProgressBar、TextView、ScrollView、TimeView、TipView、FlipView、ColorPickView、GraphView、UI Style等等。 、其他 一、Li…

chenyuntc/simple-faster-r-cnn的代码详细讲解

chenyuntc/simple-faster-r-cnn的代码详细讲解 datadata/voc_dataset.pydata/util.pydata/dataset.py micsconvet_caffe_pretraintrain_fast.py utilsarray_tool.py_config.pyeval_tool.pyvis_tool.py modelutilsnmsbuild_.py_nms_gpu_post_py.pynon_maximum_suppression.py_nm…

android开源代码

Android开源项目--分类汇总 转自&#xff1a;https://github.com/Trinea/android-open-project Android开源项目第一篇——个性化控件(View)篇 包括ListView、ActionBar、Menu、ViewPager、Gallery、GridView、ImageView、ProgressBar、TextView、其他 Android开源项目第二篇—…

Android Studio Flamingo | 2022.2.1 Patch 1(火烈鸟版本)

版本概况 Android Studio Flamingo | 2022.2.1 Patch 1 Build #AI-222.4459.24.2221.9971841, built on April 20, 2023 Runtime version: 17.0.60-b2043.56-9586694 amd64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. Windows 11 10.0 GC: G1 Young Generation, G1 Old…

代码审查 本地测试经验汇总

软件测试虽然辛苦&#xff0c;但是掌握了一定的技巧之后将使你事半功倍。 &#xff08;1&#xff09; 边界测试&#xff0c;测试用户输入框中的数值的最大数和最小数&#xff0c;以及为空时的情况。 &#xff08;2&#xff09; 非法测试&#xff0c;例如在输入数字的地方输入字…

【Unity】优化UGUI 滚动条ScrollRect(高效复用)

最近忙于性能优化&#xff0c;深切体会到二八法则真是指导高(tou)效(lan)工作的有力武器。这个礼拜花了几天解决了一个实际问题&#xff1a;UGUI的ScrollRect加载太多物体的时候&#xff0c;第一次弹出界面会非常卡顿&#xff0c;而且不在界面里的内容依然会参与绘制(毫无意义的…

vue 切换页面没有改变滚动条_Vue真是太好了 壹万多字的Vue知识点 超详细!

1⃣️、Vue和其他两大框架的区别 Angular 学习成本太高React 代码可读性差Vue 学习成本较低 很容易上手VUE官方: https://cn.vuejs.org/v2/guide/comparison.html ️2⃣️、Vue是什么 Vue是一套用于构建用户界面的渐进式框架 "前端框架"让程序员脱离自己操作DOM 专注…

前端低代码平台腾讯云微搭使用文档

腾讯云微搭 调研报告 之前作者有写过一个同类低代码平台调研报告 H5-Dooring 点击查看&#xff0c;这次我们去尝试使用腾讯系低代码平台&#xff0c;文中也会增加两者之间的差异对比和使用体验上的区别。 1. 简介 1.1 概述 腾讯云微搭低代码是一个高性能的低代码开发平台&a…

Android Patch方案与持续交付

Android 不仅系统版本众多&#xff0c;机型众多&#xff0c;而且各个市场都各有各的政策和审核速度&#xff0c;每次发布一个版本对于开发同学来讲都是一种漫长的煎熬。相比于 iOS 两三天就能达到 80% 的覆盖速度而言&#xff0c;Android 应用版本升级至少需要两周才能达到 80%…

element-ui el-table组件添加height属性后滚动条被顶下去一截

el-table 组件添加了height属性&#xff0c;数据行数超标&#xff0c;出现滚动条&#xff1b; 同时给table中的一列添加了 fixed“right” 这个属性&#xff0c;然后又在项目里自定义了滚动条样式&#xff0c;这个滚动条跟固定列会被挤下去&#xff0c;造成错位的bug。建议去掉…

已解决:element Table 滚动条首次进入不显示、偶尔切换页面后不显示,刷新当前页或改变窗口才显示

记录一下在项目中遇到的问题&#xff0c;困扰了几天最终解决了。 一、问题&#xff1a;element Table 滚动条首次进入不显示、偶尔切换页面后不显示&#xff0c;刷新当前页或改变窗口才显示。 1、首次进入的效果 可以看到滚动条并没有渲染出来&#xff0c;但是刷新页面或者改…

Android Patch 方案与持续交付

Android 不仅系统版本众多&#xff0c;机型众多&#xff0c;而且各个市场都各有各的政策和审核速度&#xff0c;每次发布一个版本对于开发同学来讲都是一种漫长的煎熬。相比于 iOS 两三天就能达到 80% 的覆盖速度而言&#xff0c;Android 应用版本升级至少需要两周才能达到 80%…

js表格冻结列滚动条同步滚动

用div css写的table表格怎么实现冻结某列&#xff0c;同时实现数据滚动条滚动的时候&#xff0c;表头也跟着滚动呢&#xff1f; 效果图&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html> <head><meta charset"utf-8"><style>.f…

损失函数分类

损失函数 机器学习模型关于单个样本的预测值与真实值的差称为损失。损失越小&#xff0c;模型越好&#xff0c;如果预测值与真实值相等&#xff0c;就是没有损失。 损失函数&#xff08;Loss function&#xff09;是用来估量模型的预测值 f(x) 与真实值 Y 的不一致程度&#x…

损失函数总结

1. 概况 损失函数一般分为&#xff1a;0-1 损失函数&#xff0c;HingeLoss&#xff0c;绝对值损失函数&#xff0c;Huber Loss, 平方损失函数&#xff0c;对数损失函数&#xff0c;指数损失。 1. 0-1损失函数(zero-one loss) 0-1损失是指预测值和目标值不相等为1&#xff0…

matlab的损失函数mse,MSELoss损失函数

MSELoss损失函数中文名字就是&#xff1a;均方损失函数&#xff0c;公式如下所示&#xff1a; 这里 loss, x, y 的维度是一样的&#xff0c;可以是向量或者矩阵&#xff0c;i 是下标。 很多的 loss 函数都有 size_average 和 reduce 两个布尔类型的参数。因为一般损失函数都是直…