Skip to content

Project Root

Linwei edited this page Feb 22, 2019 · 10 revisions

https://github.com/vim/vim/issues/3573#issuecomment-433705924

It would be great to have a standardized APIs for project-related information (e.g. file lists, root directory, VCS type, a way to set project-specific buffer-local options / variables etc.). Much of this can be implemented in vim plugins but it would be preferable if vim provided a standard way to do this.

方案1:修改 Vim

  • 默认配置目录:默认名字为 .vimprj (vim project) 短一点,命令行下面少打些字。

  • 配置目录的名称用户可以通过 rootmarker 配置项目修改:

    set rootmarker=.vimprj
    set rootmarker=.vscode
    set rootmarker=.git
    set rootmarker=.project
  • 项目根目录:

    从当前文件所在目录往上搜索,直到碰到存在 rootmarker 定义的目录名称,比如 .vimprj

    let v:projectroot = fnamemodify(find(&rootmarker, '.;'), ':h')

    每个文件再打开的时候由 vim 用上述方法自动搜索它所属的根目录,并且写到 v:projectroot 变量中(该变量每个 buffer 都不相同),如果找不到,就为空字符串。如果文件打开的时候没有找到 .vimprj 但是用户后来在文件所在目录创建了 .vimprj 文件夹,那么关闭再打开的时候这个值就有了。

    插件可以根据这个值,来做一些和项目相关的事情,比如在同一个项目内 grep,或者搜索文件,生成 tag。

    let v:projectname = (has('win32)' || has('win64'))? tolower(v:projectroot) : v:projectroot

    这是项目的名称,项目的唯一标识。

  • 文件修饰符:

    %:j    - same as v:projectroot, project root directory of current buffer
    %:i    - file path relative to current project root
    

    可以再命令行直接使用这些修饰符,也可以用 expand('xxx') 来展开他们。

  • 本地设置:

    如果一个项目的 .vimprj 目录中存在 settings.json,内容类似:

    {
        "shiftwidth": 2,
        "tabstop": 2,
        "expandtab": false
    }

    那么打开任何该目录下面的文件,都会自动去加载一下该 settings.json,并用 setlocal 的方式设置成本地配置。

  • 老版本 Vim 的支持:

    对于一个独立插件,并不需要最新版本的 vim 才能工作,如果是老版本的 vim,可以通过下面几句:

    if !exists('g:rootmarker')
        let g:rootmarker = exists('+rootmarker')? &rootmarker : ".vimprj"
    endif
    if !exists('v:projectroot')
        let b:_project_root = fnamemodify(find(g:rootmarker, '.;'), ':h')
    else
        let b:_project_root = v:projectroot
    endif

    进行初始化,进而在新老版本 vim 中支持同样一种约定,插件涉及到和项目相关的配置或者数据,应该放到 .vimprj 下面

  • 文件列表:

    项目的 .vimprj 目录中可以存在一个名为 filelist 的文件,用来描述该项目里有哪些文件,每个文件一行,使用相对路径(相对于根目录):

    src/hello.py
    src/world.py
    src/module/xp.py
    

    该文件不是必须的,如果不存在的话,相当于项目目录下面所有文件都属于 “项目文件”,但是有些情况下项目目录内有很多无关的文件,但是用户常常希望对仅属于该项目的文件进行 grep ,其他文件不进行,那么该文件列表就可以控制各种搜索范围。

    该文件不支持通配符(便于当作参数传给其他工具),但是可以由一些命令帮助快速添加,比如快速从 git 仓库导出文件列表,或者按通配符添加文件列表

    对于插件作者而言,并不一定强制使用该文件,但是知晓该文件的话,能够同其他同样知晓该文件的插件协同,比如一些插件负责维护和展示项目文件列表,而另外一些插件负责读取和搜索。

Clone this wiki locally