首页 > 其他分享 >neovim 插件管理

neovim 插件管理

时间:2022-12-25 15:33:59浏览次数:66  
标签:neovim 插件 set 管理 -- vim terminal lua nvim

起因是使用了很久vscode的插件,但是在前几天看到了一个neovim(以下简称 nvim)的视频。就看自己的vscode不是很顺眼,感觉界面不够简洁,所以尝试使用nvim。这期间尝试了别人的配置和spacevim,但是这会导致两个问题:

  1. 快捷键自己不熟悉,那么就相当于没有
  2. 插件不是自己配的,很多东西报错都不知道为什么。
    基于这些原因,就决定自己去尝试配置,同时由于nvim中文资料不是很多。特别是比较基础的,大多数只有一个操作的步骤,但是并没有原因或者为什么这样。自己通过阅读一下nvim官网,同时还有nvim用的比较多的包管理插件packer 以及拿来实操的一个插件toggletermj就是在nvim中创建内置的终端。

lua

nvim是通过lua来进行插件管理的,nvim实际运行的是Vimscript,通过提供一些api给lua,从而实现插件管理以及按键映射这些。具体可以看国内的菜鸟教程,主要明白函数就行了。

packer

这里主要讲一下packer的原理。
看一下安装语句

git clone --depth 1 https://github.com/wbthomason/packer.nvim\
 ~/.local/share/nvim/site/pack/packer/start/packer.nvim

我主要是用的是mac,这里可以看到使用的是一种比较原始的方法,在start目录下放置了一个插件,这里面的插件会在nvim启动时就运行(提醒一下,nvim是从vim中来的,虽然发展这么久很多不一样了,但是很多操作是兼容的,如果nvim查不到中文的,可以试试看vim的相关内容)。

这个插件会暴露出一个packer这么一个对象,通过对packer进行设置就可以安装插件啦。

那么如何给packer传递该管理哪些插件呢?创建一个~/.config/nvim/lua/plugins.lua然后在里面写上一个返回语句

return require('packer').startup(function(use)
  -- Packer can manage itself
        use 'wbthomason/packer.nvim'
        use {"akinsho/toggleterm.nvim", tag = '*', config = function()
                require("toggleterm").setup()
        end}
end)
~

这里面就是纯粹的lua语法,解析一下,require("<模块名>")就是调用一个模块,但是这个文件并没有关联其他文件呀,怎么调用的呢。原理下面会说。

然后看一下startup:the action or process of setting something in motion,意思就是开启的意思啦。这里返回一个匿名函数,具体使用的方法就是每个 use后面都接一个插件,接的方法有两种

  1. A list of plugin specifications (strings or tables)
  2. A table specifying a single plugin. It must have a plugin location string as its first element, and may additionally have a number of optional keyword elements, shown below:

大概意思就是一个插件的集合和单独一个插件,然后里面具体设定一些东西。然后具体使用就去插件官网看他们的readme就好了,都会有引导。

lua脚本的引入

nvim还是使用~/.config/nvim/init.vim中来管理(如果没有就创建一个),引入的话就是使用vimscript来调用lua脚本。

这里就是在vim运行时引入上面的lua脚本,在整个vim中就有packer这个模块,因为已经在刚才添加在start这个文件夹下了

-- vimscript脚本
-- ~/.config/nvim/init.vim
" 设置一个leader键,相当于一个自定义的键,我这里设置的空格,可以再接其它键一起设置成新的快捷键,以免出现快捷键的冲突。
let g:mapleader = " "

" 加载上面创建的文件,因为加载的路径会包括~/.config/nvim/lua
lua require('plugins')
" 加载指定lua脚本中指定的function
" command! Scratch lua require(tools).makeScratch()
" 设置快捷键,使用lua
lua require('mapkeyboard')


" 设置快捷键,使用vimscript
" insert terminal
" set
autocmd TermEnter term://*toggleterm#*
      \ tnoremap <silent><c-t> <Cmd>exe v:count1 . "ToggleTerm"<CR>
" By applying the mappings this way you can pass a count to your
" mapping to open a specific window.
" For example: 2<C-t> will open terminal 2
nnoremap <silent><c-t> <Cmd>exe v:count1 . "ToggleTerm"<CR>
inoremap <silent><c-t> <Esc><Cmd>exe v:count1 . "ToggleTerm"<CR>

这里vimscript没办法高亮,所以md设置的lua。

看上面的代码,具体的用法就已经在上面标注出来了。下面展示一下使用lua设置快捷键的文件。

-- ~/.config/nvim/lua/boardmapping.lua
-- 具体设置的方法
function _G.set_terminal_keymaps()
  local opts = {buffer = 0}
-- t表示的是terminal,也就是在使用终端的时候设置下面的快捷键。
-- <cmd> 和: 是相同的意思,表示的就是一个命令
  vim.keymap.set('t', '<esc>', [[<C-\><C-n>]], opts)
  vim.keymap.set('t', 'jk', [[<C-\><C-n>]], opts)
  vim.keymap.set('t', '<C-h>', [[<Cmd>wincmd h<CR>]], opts)
  vim.keymap.set('t', '<C-j>', [[<Cmd>wincmd j<CR>]], opts)
  vim.keymap.set('t', '<C-k>', [[<Cmd>wincmd k<CR>]], opts)
  vim.keymap.set('t', '<C-l>', [[<Cmd>wincmd l<CR>]], opts)
end

function _G.set_terminal_keymaps_insert()
  vim.keymap.set('n', '<C-h>', [[<Cmd>wincmd h<CR>]], opts)
  vim.keymap.set('n', '<C-j>', [[<Cmd>wincmd j<CR>]], opts)
  vim.keymap.set('n', '<C-k>', [[<Cmd>wincmd k<CR>]], opts)
  vim.keymap.set('n', '<C-l>', [[<Cmd>wincmd l<CR>]], opts)
end
-- 调用设置的方法
-- vim.cmd表示的是执行后面的内容
-- autocmd是表示vim中的自动调用,代表在碰到之后的内容时加载相应的方法.感叹号表示的是避免重复加载
vim.cmd('autocmd! TermOpen term://* lua set_terminal_keymaps()')
vim.cmd('lua set_terminal_keymaps_insert()')

-- 下面表示的是自定义一个terminal运行相应的命令,这里是在内部终端运行lazygit
local Terminal  = require('toggleterm.terminal').Terminal

local lazygit = Terminal:new({
  cmd = "lazygit",
  dir = "git_dir",
  direction = "float",
  float_opts = {
    border = "double",
  },
  -- function to run on opening the terminal
  on_open = function(term)
    vim.cmd("startinsert!")
    vim.api.nvim_buf_set_keymap(term.bufnr, "n", "q", "<cmd>close<CR>", {noremap = true, silent = true})
  end,
  -- function to run on closing the terminal
  on_close = function(term)
    vim.cmd("startinsert!")
  end,
})

function _lazygit_toggle()
  lazygit:toggle()
end

vim.api.nvim_set_keymap("n", "<leader>g", "<cmd>lua _lazygit_toggle()<CR>", {noremap = true, silent = true})

实际例子

这里使用的是toggleterm 来进行举例,首先看他的官网。里面说了
Using packer in lua

-- ~/.config/nvim/lua/mapkeyboard.lua
use {"akinsho/toggleterm.nvim", tag = '*', config = function()
  require("toggleterm").setup()
end}

直接在~/.config/nvim/lua/plugins.lua中加上这句话就可以了。具体怎么加,如果不明白就去看上面的,有这个文件的全部内容。

之后往下翻会有一些介绍,和目标什么的。然后就会有一个设置快捷键,这种设置方法一看就是vimscript,图方便就直接在init.vim中设置了,如果想要简洁,应该可以单独建一个文件夹然后在init.vim中引用就可以了。

-- vimscript脚本
-- ~/.config/nvim/init.vim
" set
" 在某些情况下,自动运行下面的内容。
autocmd TermEnter term://*toggleterm#*
      \ tnoremap <silent><c-t> <Cmd>exe v:count1 . "ToggleTerm"<CR>

" By applying the mappings this way you can pass a count to your
" mapping to open a specific window.
" For example: 2<C-t> will open terminal 2
nnoremap <silent><c-t> <Cmd>exe v:count1 . "ToggleTerm"<CR>
inoremap <silent><c-t> <Esc><Cmd>exe v:count1 . "ToggleTerm"<CR>

再往下就是一些在~/.config/nvim/lua/plugins.lua中进行设定的内容

require("toggleterm").setup{
  -- size can be a number or function which is passed the current terminal
  size = 20 | function(term)
    if term.direction == "horizontal" then
      return 15
    elseif term.direction == "vertical" then
      return vim.o.columns * 0.4
    end
  end,
  open_mapping = [[<c-\>]],
  on_create = fun(t: Terminal), -- function to run when the terminal is first created
  on_open = fun(t: Terminal), -- function to run when the terminal opens
  on_close = fun(t: Terminal), -- function to run when the terminal closes
  on_stdout = fun(t: Terminal, job: number, data: string[], name: string) -- callback for processing output on stdout
  on_stderr = fun(t: Terminal, job: number, data: string[], name: string) -- callback for processing output on stderr
  on_exit = fun(t: Terminal, job: number, exit_code: number, name: string) -- function to run when terminal process exits
  hide_numbers = true, -- hide the number column in toggleterm buffers
  shade_filetypes = {},
  autochdir = false, -- when neovim changes it current directory the terminal will change it's own when next it's opened
  highlights = {
    -- highlights which map to a highlight group name and a table of it's values
    -- NOTE: this is only a subset of values, any group placed here will be set for the terminal window split
    Normal = {
      guibg = "<VALUE-HERE>",
    },
    NormalFloat = {
      link = 'Normal'
    },
    FloatBorder = {
      guifg = "<VALUE-HERE>",
      guibg = "<VALUE-HERE>",
    },
  },
  shade_terminals = true, -- NOTE: this option takes priority over highlights specified so if you specify Normal highlights you should set this to false
  shading_factor = '<number>', -- the degree by which to darken to terminal colour, default: 1 for dark backgrounds, 3 for light
  start_in_insert = true,
  insert_mappings = true, -- whether or not the open mapping applies in insert mode
  terminal_mappings = true, -- whether or not the open mapping applies in the opened terminals
  persist_size = true,
  persist_mode = true, -- if set to true (default) the previous terminal mode will be remembered
  direction = 'vertical' | 'horizontal' | 'tab' | 'float',
  close_on_exit = true, -- close the terminal window when the process exits
  shell = vim.o.shell, -- change the default shell
  auto_scroll = true, -- automatically scroll to the bottom on terminal output
  -- This field is only relevant if direction is set to 'float'
  float_opts = {
    -- The border key is *almost* the same as 'nvim_open_win'
    -- see :h nvim_open_win for details on borders however
    -- the 'curved' border is a custom border type
    -- not natively supported but implemented in this plugin.
    border = 'single' | 'double' | 'shadow' | 'curved' | ... other options supported by win open
    -- like `size`, width and height can be a number or function which is passed the current terminal
    width = <value>,
    height = <value>,
    winblend = 3,
  },
  winbar = {
    enabled = false,
    name_formatter = function(term) --  term: Terminal
      return term.name
    end
  },
}

可以自己看需要进行设置

之后往下就是提供的方法的一些介绍,主要介绍一下通过lua进行快捷键设定。
这里因为是lua脚本,上面的plugins.lua上来就直接返回了。同时为了保证降低耦合,就没有尝试继续在里面加内容。就新建了一个lua脚本文件。~/.config/nvim/lua/mapkeyboard.lua这个文件,按照它给的内容

这里vim就是暴露出的一个全局变量,通过设置vim就可以对编辑器的特性进行设置

-- ~/.config/nvim/lua/mapkeyboard.lua
function _G.set_terminal_keymaps()
  local opts = {buffer = 0}
  vim.keymap.set('t', '<esc>', [[<C-\><C-n>]], opts)
  vim.keymap.set('t', 'jk', [[<C-\><C-n>]], opts)
  vim.keymap.set('t', '<C-h>', [[<Cmd>wincmd h<CR>]], opts)
  vim.keymap.set('t', '<C-j>', [[<Cmd>wincmd j<CR>]], opts)
  vim.keymap.set('t', '<C-k>', [[<Cmd>wincmd k<CR>]], opts)
  vim.keymap.set('t', '<C-l>', [[<Cmd>wincmd l<CR>]], opts)
end

-- if you only want these mappings for toggle term use term://*toggleterm#* instead
vim.cmd('autocmd! TermOpen term://* lua set_terminal_keymaps()')

创建好后再再init.vim这个文件中加上对这个文件的引用。

lua require('mapkeyboard')

这个同样也在上面init.vim中展示了全部的设置。

这个快捷键的大致意思就是:通过control加上h,j,k,l实现在terminal(内置终端)情况下也能跳文档编辑继续进行编辑。我觉得跳回文档编辑后不能再跳回去,就不太舒服又加了几个在normal(vim的编辑模式)中能运行的快捷键,其实实际含义就是输入:wincmd k/j/h/l 进行跳转。
所以最后就是下面这个样子

-- ~/.config/nvim/lua/boardmapping.lua
-- 具体设置的方法
function _G.set_terminal_keymaps()
  local opts = {buffer = 0}
-- t表示的是terminal,也就是在使用终端的时候设置下面的快捷键。
-- <cmd> 和: 是相同的意思,表示的就是一个命令
  vim.keymap.set('t', '<esc>', [[<C-\><C-n>]], opts)
  vim.keymap.set('t', 'jk', [[<C-\><C-n>]], opts)
  vim.keymap.set('t', '<C-h>', [[<Cmd>wincmd h<CR>]], opts)
  vim.keymap.set('t', '<C-j>', [[<Cmd>wincmd j<CR>]], opts)
  vim.keymap.set('t', '<C-k>', [[<Cmd>wincmd k<CR>]], opts)
  vim.keymap.set('t', '<C-l>', [[<Cmd>wincmd l<CR>]], opts)
end

function _G.set_terminal_keymaps_insert()
  vim.keymap.set('n', '<C-h>', [[<Cmd>wincmd h<CR>]], opts)
  vim.keymap.set('n', '<C-j>', [[<Cmd>wincmd j<CR>]], opts)
  vim.keymap.set('n', '<C-k>', [[<Cmd>wincmd k<CR>]], opts)
  vim.keymap.set('n', '<C-l>', [[<Cmd>wincmd l<CR>]], opts)
end
-- 调用设置的方法
-- vim.cmd表示的是执行后面的内容
-- autocmd是表示vim中的自动调用,代表在碰到之后的内容时加载相应的方法.感叹号表示的是避免重复加载
vim.cmd('autocmd! TermOpen term://* lua set_terminal_keymaps()')
vim.cmd('lua set_terminal_keymaps_insert()')

总结

原理

主要就是串了一下nvim的插件管理。

  1. nvim使用的还是vimscript脚本,只是兼容了lua。
  2. 可以通过在 ~/.local/share/nvim/site/pack/packer/start/中安装插件直接在运行时就导入插件
  3. ~/.config/nvim/init.vim是一个vimscript脚本,里面可以设置要执行的lua脚本,和对vim/nvim进行配置等
    基于上面的原理,首先通过在start中安装packer直接导入packer这个插件进行插件管理,之后通过init.vim给packer提供需要管理插件的各种信息,从而实现插件的管理。

实际操作步骤

  1. 去对应插件官网看如何在plugins.lua中加载包,复制粘贴过来
  2. 在对应插件官网看可以设置哪些,如果是直接对插件操作一般就是在plugins.lua包中对应插件的set()中进行设置
  3. 如果是快捷键
    1. 在init.vim中直接使用vimscript脚本进行设置
    2. 通过lua进行设置,然后在init.vim中导入lua脚本

问题

  1. 对于packer具体实现和vimscript的了解还是不深入,后面随着具体的使用再慢慢学习。

标签:neovim,插件,set,管理,--,vim,terminal,lua,nvim
From: https://www.cnblogs.com/yych0745/p/17004087.html

相关文章

  • C/C++通讯录管理系统
    C/C++通讯录管理系统通讯录管理系统设计题目:通讯录管理系统设计实现功能:1.创建一个通讯录(单链表的创建)。2.显示通讯录中所有联系人的信息和按组显示具体组的联系人信息......
  • make工程管理器
    工程管理器,顾名思义,是指管理较多的文件Make工程管理器也就是个“自动编译管理器”,这里的“自动”是指它能构根据文件时间戳自动发现更新过的文件而减少编译的工作量,同时,它......
  • “你帮我助”管理系统软件设计总结
    这次软件设计对我来说最大的难点就在于GUI,当然啦,之前的黑窗口缺乏直观的图形化交互界面,在我心中确实也不像是软件该有的形式。然而随着ddl日益临近,担心功能强大却复杂......
  • pytest用例管理框架
    先安装pipinstallpytestpytest用例管理框架默认规则:1.py文件必须以test_开头或者_test结尾2.类名必须以test开头3.测试用例必须以test_开头 get请求通过params......
  • 基于JSP的网上订餐管理系统的设计与实现(包调试成功)
    第1页毕业设计(论文)题目:基于​JSP的网上订餐管理系统​的设计与实现毕业设计(论文)要求及原始数据(资料):1.综述目前国内外网上订餐管理系统的现状;2.深入了解网上订餐系统的管理方式......
  • 面试官:你说说 Vue 中的组件和插件有什么区别?
    大家好,我是CoderBin前言面试官:“你说说Vue中的组件和插件有什么区别?”紧张的萌新:“vue组件是封装可复用的UI结构,插件好像是用vue.use()...”面试官:“...”······......
  • 预测型项目管理-1-项目的基本要素
    项目的基本要素★项目是为创造独特的产品、服务或成果而进行的临时性工作。★虽然项目是临时性工作,但其可交付成果可能会在项目的终止后依然存在。★项目的“临时性”是指......
  • 试卷审批管理信息系统--学生审核
      <%@pagecontentType="text/html;charset=UTF-8"language="java"isELIgnored="false"%><%@tagliburi="http://java.sun.com/jsp/jstl/core"prefix="c"%><......
  • 【玩转Docker容器 6】基于Docker构建GitLab管理代码
    @TOC推荐个人Docker文章,讲的非常详细【玩转Docker容器1】Dockerd的详解及安装【玩转Docker容器2】基于Docker一分钟搭建完Jdk、Mysql、Nginx、Redis、Tomcat环......
  • C++科研人员信息管理系统
    C++科研人员信息管理系统某科研团队主要有四类人员:科研主管、研究员、研究助理和实习研究员。现在,需要存储这些人员的姓名、编号、级别、当月薪水,计算月薪总额并显示全部......