• 从零开始配置vim(21)——会话管理


    很多代码编辑器都有这么一个功能,重新进入编辑器之后能恢复上次打开的所有文件,窗口布局,有的甚至是上次设置的一些配置。那么vim是否也可以实现这样的功能呢?答案是肯定的。使用vim自带的会话管理和 viminfo 可以实现恢复上次打开文件和布局以及重置上次的配置

    它们二者分别保存了不同的内容,一般会将它们联合起来使用。

    • 会话一般保留上次打开的文件、窗口布局、以及一些全局设置
    • viminfo 保留的是历史命令行记录、搜索替换模式记录、标签、非空寄存器的值、缓冲区列表、全局信息等等

    看起来很好像显的很杂一样,但是我觉得这些都不是需要记忆的,我们只需要知道使用使用 viminfosession可以恢复所有我们关心的内容即可,无需分辨哪些内容保存在哪个位置。我们使用自动命令来保存和加载它们,你甚至可能会忘记它们的存在。

    会话

    我们还是按照惯例,先来试试vim原生的内容
    我们可以使用 :mksession [file] 来保存一个当前的会话。再重新进入vim 的时候可以使用 :source session-file 来加载一个会话文件。

    在实际生成会话文件时,我们可以省略这个文件名,这个时候vim会自动生成一个采用默认文件名的会话文件。vim会默认在当前工作目录下生成一个 Session.vim的文件,我们打开这个文件发现它本质上就是一个vim的脚本,跟我们写的配置文件是一回事。各位小伙伴可以打开看看,试着读一下它里面具体在干嘛。

    我们来试着做一下这个实验,就以当前正在使用的 vim 配置这个工程。我们随机打开几个文件,然后执行 :mksession ,然后退出
    在这里插入图片描述
    关闭vim之后,我们发现在项目的根目录也就是 ~/.config/nvim 下,生成一个了一个 Session.vim 。有兴趣的小伙伴可以打开来看看里面的内容。它其实就是一个vim脚本,跟我们写的配置是一回事

    接着我们试着在终端输入 nvim 不带任何参数,直接打开我们的欢迎界面,在该界面中输入 :source Session.vim 。执行完成之后我们发现,它帮助我们将显示还原成了上次退出之前的样子
    在这里插入图片描述
    默认session要保存 哪些内容是由一个名为 sessionoption的变量决定的。不知道小伙伴还记不记得如何来查看一个变量现在的值?(:set sessionoption?) 。使用set在对应变量后面加上一个 ? 表示查询当前变量值。我们看到它目前保存这些内容 sessionoptions=blank,buffers,curdir,folds,help,tabpages,winsize。他们分别代表着空窗口、所有缓冲区、当前目录、折叠、帮助窗口、标签页、窗口大小。

    viminfo 文件

    vim每次在退出时会自动在用户的家目录保存一个名为 .viminfo 的文件,每次退出后都会发生覆盖行为。有时我们在编辑项目之后又重新打开vim编辑了另外一些内容,这个时候就有可能发生覆盖行为,把我们项目相关的内容给覆盖掉了,那这个时候该怎么办呢?

    好在vim提供了 :wviminfo命令来指定写入到哪个viminfo文件中。我们可以使用 :rviminfo来读入指定的viminfo文件。

    小伙伴可能有一个问题。既然Session.vim 是一个vim脚本,为什么不把所有设置都写在配置文件里面呢?我们可以这么做,但是提供一个额外的session功能可以根据项目来灵活的调整配置,我们将所有项目的通用配置保存在我们自己的配置文件里面,将某些项目特有的配置放到session中,由vim自己维护,这样vim能更好的适应不同的使用场合。

    viminfo 保存的是命令行,搜索记录这些,而且每次打开都会自动加载,所以就不像session 这样能很明显的看出效果。很明显的一个特征就是,即使我们这次打开仅仅只用了 :q 这一个命令,但是我们通过 q: 仍然可以看到之前几次打开时执行过的命令

    简单的配置

    为了防止小伙伴做无用功,我这里事先声明一下,针对会话管理我们是有专门的插件的。这里所做的配置在后面都会被我们弃用的,小伙伴可以不往自己的配置里面加了。但是想试试也可以,有些事只有自己亲手做了才能更好的理解

    首先我们希望它在退出的时候能自动保存Session和viminfo文件到对应的项目根目录下。在启动时能重新加载这些文件。自然要自动进行这些内容,我们想到的就是自动命令了。
    我们先来定义一个函数来保存这两个文件

    function save_session()
        local curdir = vim.api.nvim_eval([[getcwd()]])
        local session_file = curdir .. "/Session.vim"
        vim.cmd([[mksession ]] .. session_file)
        local viminfo = curdir .. "/.viminfo"
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在该函数中,我们使用 vimgetcwd 命令来获取当前vim所在的工作目录。工作目录的概念我们在之前介绍vim的时候已经介绍过了,忘记的小伙伴请自行折回去复习。然后我们拼接一个字符串,让vim保存sessionviminfo文件到当前工作目录中

    我们再来添加一个函数用来加载 session 内容。

    function load_session()
        local curdir = vim.api.nvim_eval([[getcwd()]])
        local session_file = curdir .. "/Session.vim"
        local viminfo = curdir .. "/.viminfo"
        file, err = io.open(session_file, "r")
        if err == nil then
            file:close()
            vim.cmd([[source ]] .. session_file)
        end
        file, err = io.open(viminfo, "r")
        if err == nil then
            file:close()
            vim.cmd([[rviminfo ]] .. viminfo)
        end
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    与保存函数不同的是,我这里加了一个判断文件是否存在的代码,因为我们无法得知用户会在哪个目录下打开vim,无法事先知道该目录是否有这些文件,所以这里先判断一下,如果没有文件就不进行任何操作。

    最后我们添加一个自动命令组来自动保存和加载 session 文件和 viminfo文件。

    local auto_save_session = vim.api.nvim_create_augroup("AUTO_SAVE_SESSION", {clear = true})
    vim.api.nvim_create_autocmd({"ExitPre"}, {
        pattern = "*",
        group = auto_save_session,
        callback = save_session
    })
    vim.api.nvim_create_autocmd({"VimEnter"}, {
        pattern = "*",                                                                       
        group = auto_save_session,
        callback = load_session
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    我们在终端直接输入 nvim 发现它自动恢复了上次打开的所有缓冲区。我们来试一下效果,先删除上一次生成的 Session.vim 文件,接着退出然后再次打开 vim ,我们发现它恢复到了打开之前的样子
    在这里插入图片描述

    到此我们已经有了一个简单的自动加载session 和上次配置的功能。如果希望有更多的定制可以考虑使用插件,但是如果只是简单的需要此功能的,可以就这么配置或者自己改改配置达到自己的需求。

    auto-session 插件

    上面我们已经定义了可以自动加载和保存上次会话的功能。有的小伙伴可能觉得这个功能太简单了,我希望能给我提供更方便、更加灵活的使用方式,而且我们上面的配置有一个很大的问题,我输入 nvim init.lua 已经指定了要打开的文件,它仍然会打开之前保存的 session ,这里我再介绍一个能够管理 session 的插件—— auto-session ,它能有效的避免上面的问题。

    我们使用如下的语句来安装 auto-session

    use {'rmagatti/auto-session'}
    
    • 1

    然后按照惯例,新建文件并且添加配置

    require("auto-session").setup({
        log_level = "error",
        -- 打开这些目录里面的内容时,不加载会话
        auto_session_suppress_dirs = {"~/", "~/Projects", "~/Downloads", "/", "/ect", "/usr"}
        auto_session_enable_last_session = false,
        -- 保存session文件到 ~/.local/share/nvim/sessions目录
        auto_session_root_dir = vim.fn.stdpath('data').."/sessions/",
        auto_session_enabled = true,
        auto_save_enabled = nil,
        auto_restore_enabled = nil,
        auto_session_use_git_branch = nil,
        -- the configs below are lua only
        bypass_session_save_file_types = nil
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    我们可以在 lualine 的配置文件中 sections 一节中添加 lualine_c = {require('auto-session-library').current_session_name} 来显示当前打开的会话名称

    最后根据官方的提示,我们可以给sessionoption 赋值,多保存两个内容

    vim.o.sessionoptions="blank,buffers,curdir,folds,help,tabpages,winsize,winpos,terminal"
    
    • 1

    这样我们如果打开了终端,下次进入时还可以恢复终端窗口

    最后我们再来补充一下之前 dashboard 的功能,之前定义的有一个恢复上次会话的功能

    {icon = "  ", desc = 'Recently lastest session    ', shortcut = "Leader s l", action = "RestoreSession"}
    
    • 1

    我们可以在 custom_center 中添加这么一行,具体的位置可以看我提交到github中的仓库

    到此为止,关于session的配置就结束了。

  • 相关阅读:
    基础1:JS的原型和原型链究竟
    (Clock Domain Crossing)跨时钟域信号的处理 (自我总结)
    【Command模式】C++设计模式——命令模式
    Kafka 基础概念及架构
    架构师系列-Nginx、OpenResty(三)- 负载均衡配置
    b和B的区别?大B与小b的区别(Bps与bps)以及b、B、KB、MB、TB、PB、EB的换算
    【雷神笔记本快捷键】雷神笔记本FN功能快捷键大全以及电脑CPU处于低功耗但电脑风扇高速转动噪音较大解决方案
    选择MobPush的三大理由
    【元胞自动机】基于元胞自动机模拟SEIR传播模型附matlab代码
    LeetCode 1588. Sum of All Odd Length Subarrays
  • 原文地址:https://blog.csdn.net/lanuage/article/details/126700431