【问题标题】:In nixos, how to get vim syntax highlighting for the nix language?在nixos中,如何获得nix语言的vim语法高亮?
【发布时间】:2019-07-30 00:46:44
【问题描述】:

我正在尝试为 nix 语言添加 vim 语法突出显示,并且一直在尝试使用 this github repo 来做到这一点。

在该仓库中,我找到了nix.vim file。我已经尝试按照存储库的“手动安装”说明将其放置在 ~/.vim 中,但这并不能使颜色出现。

自那次尝试以来,我一直在尝试通过更改我的/etc/nixos/configuration.nix 文件来获得语法着色,并且一直试图从this documentation 中理解。因此我在我的配置文件中添加了这个programs.vim 代码块,

programs.vim = {
  enable = true;
  extraConfig = ''
  '';
};

并将整个nix.vim 文件的内容粘贴到该programs.vim.extraConfig 部分的字符串中。因此添加到我的configuration.nix 的块是:

programs.vim = {
  enable = true;
  extraConfig = ''
" Vim syntax file
" Language:    Nix
" Maintainer:  Daiderd Jordan <daiderd@gmail.com>
" URL:         https://github.com/LnL7/vim-nix

if exists("b:current_syntax")
  finish
endif

syn keyword nixBoolean     true false
syn keyword nixNull        null
syn keyword nixRecKeyword  rec

syn keyword nixOperator or
syn match   nixOperator '!=\|!'
syn match   nixOperator '<=\?'
syn match   nixOperator '>=\?'
syn match   nixOperator '&&'
syn match   nixOperator '//\='
syn match   nixOperator '=='
syn match   nixOperator '?'
syn match   nixOperator '||'
syn match   nixOperator '++\='
syn match   nixOperator '-'
syn match   nixOperator '\*'
syn match   nixOperator '->'

syn match nixParen '[()]'
syn match nixInteger '\d\+'

syn keyword nixTodo FIXME NOTE TODO OPTIMIZE XXX HACK contained
syn match   nixComment '#.*' contains=nixTodo,@Spell
syn region  nixComment start=+/\*+ end=+\*/+ contains=nixTodo,@Spell

syn region nixInterpolation matchgroup=nixInterpolationDelimiter start="\${" end="}" contained contains=@nixExpr,nixInterpolationParam

syn match nixSimpleStringSpecial /\\\%([nrt"\\$]\|$\)/ contained
syn match nixStringSpecial /''['$]/ contained
syn match nixStringSpecial /\$\$/ contained
syn match nixStringSpecial /''\\[nrt]/ contained

syn match nixInvalidSimpleStringEscape /\\[^nrt"\\$]/ contained
syn match nixInvalidStringEscape /''\\[^nrt]/ contained

syn region nixSimpleString matchgroup=nixStringDelimiter start=+"+ skip=+\\"+ end=+"+ contains=nixInterpolation,nixSimpleStringSpecial,nixInvalidSimpleStringEscape
syn region nixString matchgroup=nixStringDelimiter start=+''+ skip=+''['$\\]+ end=+''+ contains=nixInterpolation,nixStringSpecial,nixInvalidStringEscape

syn match nixFunctionCall "[a-zA-Z_][a-zA-Z0-9_'-]*"

syn match nixPath "[a-zA-Z0-9._+-]*\%(/[a-zA-Z0-9._+-]\+\)\+"
syn match nixHomePath "\~\%(/[a-zA-Z0-9._+-]\+\)\+"
syn match nixSearchPath "[a-zA-Z0-9._+-]\+\%(\/[a-zA-Z0-9._+-]\+\)*" contained
syn match nixPathDelimiter "[<>]" contained
syn match nixSearchPathRef "<[a-zA-Z0-9._+-]\+\%(\/[a-zA-Z0-9._+-]\+\)*>" contains=nixSearchPath,nixPathDelimiter
syn match nixURI "[a-zA-Z][a-zA-Z0-9.+-]*:[a-zA-Z0-9%/?:@&=$,_.!~*'+-]\+"

syn match nixAttributeDot "\." contained
syn match nixAttribute "[a-zA-Z_][a-zA-Z0-9_'-]*\ze\%([^a-zA-Z0-9_'.-]\|$\)" contained
syn region nixAttributeAssignment start="=" end="\ze;" contained contains=@nixExpr
syn region nixAttributeDefinition start=/\ze[a-zA-Z_"$]/ end=";" contained contains=nixComment,nixAttribute,nixInterpolation,nixSimpleString,nixAttributeDot,nixAttributeAssignment

syn region nixInheritAttributeScope start="(" end=")" contained contains=nixComment,nixAttributeDot
syn region nixAttributeDefinition matchgroup=nixInherit start="\<inherit\>" end=";" contained contains=nixComment,nixInheritAttributeScope,nixAttribute

syn region nixAttributeSet start="{" end="}" contains=nixComment,nixAttributeDefinition

"                                                                                                              vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
syn region nixArgumentDefinitionWithDefault matchgroup=nixArgumentDefinition start="[a-zA-Z_][a-zA-Z0-9_'-]*\ze\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*?\@=" matchgroup=NONE end="[,}]\@=" transparent contained contains=@nixExpr
"                                                           vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
syn match nixArgumentDefinition "[a-zA-Z_][a-zA-Z0-9_'-]*\ze\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*[,}]\@=" contained
syn match nixArgumentEllipsis "\.\.\." contained
syn match nixArgumentSeparator "," contained

"                          vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv                        vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
syn match nixArgOperator '@\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*[a-zA-Z_][a-zA-Z0-9_'-]*\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*:'he=s+1 contained contains=nixAttribute

"                                                 vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
syn match nixArgOperator '[a-zA-Z_][a-zA-Z0-9_'-]*\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*@'hs=e-1 contains=nixAttribute nextgroup=nixFunctionArgument

" This is a bit more complicated, because function arguments can be passed in a
" very similar form on how attribute sets are defined and two regions with the
" same start patterns will shadow each other. Instead of a region we could use a
" match on {\_.\{-\}}, which unfortunately doesn't take nesting into account.
"
" So what we do instead is that we look forward until we are sure that it's a
" function argument. Unfortunately, we need to catch comments and both vertical
" and horizontal white space, which the following regex should hopefully do:
"
" "\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*"
"
" It is also used throught the whole file and is marked with 'v's as well.
"
" Fortunately the matching rules for function arguments are much simpler than
" for real attribute sets, because we can stop when we hit the first ellipsis or
" default value operator, but we also need to paste the "whitespace & comments
" eating" regex all over the place (marked with 'v's):
"
" Region match 1: { foo ? ... } or { foo, ... } or { ... } (ellipsis)
"                                         vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv   {----- identifier -----}vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
syn region nixFunctionArgument start="{\ze\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*\%([a-zA-Z_][a-zA-Z0-9_'-]*\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*[,?}]\|\.\.\.\)" end="}" contains=nixComment,nixArgumentDefinitionWithDefault,nixArgumentDefinition,nixArgumentEllipsis,nixArgumentSeparator nextgroup=nixArgOperator

" Now it gets more tricky, because we need to look forward for the colon, but
" there could be something like "{}@foo:", even though it's highly unlikely.
"
" Region match 2: {}
"                                         vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv    vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv@vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv{----- identifier -----}  vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
syn region nixFunctionArgument start="{\ze\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*}\%(\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*@\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*[a-zA-Z_][a-zA-Z0-9_'-]*\)\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*:" end="}" contains=nixComment nextgroup=nixArgOperator

"                                                               vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
syn match nixSimpleFunctionArgument "[a-zA-Z_][a-zA-Z0-9_'-]*\ze\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*:/\@!"

syn region nixList matchgroup=nixListBracket start="\[" end="\]" contains=@nixExpr

syn region nixLetExpr matchgroup=nixLetExprKeyword start="\<let\>" end="\<in\>" contains=nixComment,nixAttributeDefinition

syn keyword nixIfExprKeyword then contained
syn region nixIfExpr matchgroup=nixIfExprKeyword start="\<if\>" end="\<else\>" contains=@nixExpr,nixIfExprKeyword

syn region nixWithExpr matchgroup=nixWithExprKeyword start="\<with\>" matchgroup=NONE end=";" contains=@nixExpr

syn region nixAssertExpr matchgroup=nixAssertKeyword start="\<assert\>" matchgroup=NONE end=";" contains=@nixExpr

syn cluster nixExpr contains=nixBoolean,nixNull,nixOperator,nixParen,nixInteger,nixRecKeyword,nixConditional,nixBuiltin,nixSimpleBuiltin,nixComment,nixFunctionCall,nixFunctionArgument,nixSimpleFunctionArgument,nixPath,nixHomePath,nixSearchPathRef,nixURI,nixAttributeSet,nixList,nixSimpleString,nixString,nixLetExpr,nixIfExpr,nixWithExpr,nixAssertExpr,nixInterpolation

" These definitions override @nixExpr and have to come afterwards:

syn match nixInterpolationParam "[a-zA-Z_][a-zA-Z0-9_'-]*\%(\.[a-zA-Z_][a-zA-Z0-9_'-]*\)*" contained

" Non-namespaced Nix builtins as of version 2.0:
syn keyword nixSimpleBuiltin
      \ abort baseNameOf derivation derivationStrict dirOf fetchGit
      \ fetchMercurial fetchTarball import isNull map placeholder removeAttrs
      \ scopedImport throw toString


" Namespaced and non-namespaced Nix builtins as of version 2.0:
syn keyword nixNamespacedBuiltin contained
      \ abort add addErrorContext all any attrNames attrValues baseNameOf
      \ catAttrs compareVersions concatLists concatStringsSep currentSystem
      \ currentTime deepSeq derivation derivationStrict dirOf div elem elemAt
      \ fetchGit fetchMercurial fetchTarball fetchurl filter \ filterSource
      \ findFile foldl' fromJSON functionArgs genList \ genericClosure getAttr
      \ getEnv hasAttr hasContext hashString head import intersectAttrs isAttrs
      \ isBool isFloat isFunction isInt isList isNull isString langVersion
      \ length lessThan listToAttrs map match mul nixPath nixVersion
      \ parseDrvName partition path pathExists placeholder readDir readFile
      \ removeAttrs replaceStrings scopedImport seq sort split splitVersion
      \ storeDir storePath stringLength sub substring tail throw toFile toJSON
      \ toPath toString toXML trace tryEval typeOf unsafeDiscardOutputDependency
      \ unsafeDiscardStringContext unsafeGetAttrPos valueSize

syn match nixBuiltin "builtins\.[a-zA-Z']\+"he=s+9 contains=nixComment,nixNamespacedBuiltin

hi def link nixArgOperator               Operator
hi def link nixArgumentDefinition        Identifier
hi def link nixArgumentEllipsis          Operator
hi def link nixAssertKeyword             Keyword
hi def link nixAttribute                 Identifier
hi def link nixAttributeDot              Operator
hi def link nixBoolean                   Boolean
hi def link nixBuiltin                   Special
hi def link nixComment                   Comment
hi def link nixConditional               Conditional
hi def link nixHomePath                  Include
hi def link nixIfExprKeyword             Keyword
hi def link nixInherit                   Keyword
hi def link nixInteger                   Integer
hi def link nixInterpolation             Macro
hi def link nixInterpolationDelimiter    Delimiter
hi def link nixInterpolationParam        Macro
hi def link nixInvalidSimpleStringEscape Error
hi def link nixInvalidStringEscape       Error
hi def link nixLetExprKeyword            Keyword
hi def link nixNamespacedBuiltin         Special
hi def link nixNull                      Constant
hi def link nixOperator                  Operator
hi def link nixPath                      Include
hi def link nixPathDelimiter             Delimiter
hi def link nixRecKeyword                Keyword
hi def link nixSearchPath                Include
hi def link nixSimpleBuiltin             Keyword
hi def link nixSimpleFunctionArgument    Identifier
hi def link nixSimpleString              String
hi def link nixSimpleStringSpecial       SpecialChar
hi def link nixString                    String
hi def link nixStringDelimiter           Delimiter
hi def link nixStringSpecial             Special
hi def link nixTodo                      Todo
hi def link nixURI                       Include
hi def link nixWithExprKeyword           Keyword

" This could lead up to slow syntax highlighting for large files, but usually
" large files such as all-packages.nix are one large attribute set, so if we'd
" use sync patterns we'd have to go back to the start of the file anyway
syn sync fromstart

let b:current_syntax = "nix"
  '';
};

这给我在syn match nixStringSpecial /''['$]/ contained 行带来了问题,因为双引号'' 过早地结束了nix 字符串。

此时我不确定是否应该尝试解决此处的字符串定界问题,或者尝试其他方法。这是否正朝着让 vim 突出显示在我的 nixos 机器上运行的 nix 语言的正确方向前进?

【问题讨论】:

  • 您将nix.vim 文件复制到了哪里?它需要在~/.vim/syntax 内,并且您需要将以下行添加到您的.vimrcau BufRead,BufNewFile *.nix set filetype=nix
  • @GiftZwergrapper 我已将nix.vim 正确放置在~/.vim/syntax,只是您建议将au BufRead,BufNewFile *.nix set filetype=nix 添加到.vimrc 使其正常工作。谢谢!

标签: vim nix nixos


【解决方案1】:

正如上面评论中已经提到的,让它工作的解决方案如下:

nix.vim 语法文件需要放在~/.vim/syntax 目录中,并且需要在您的.vimrc 中添加以下行:

au BufRead,BufNewFile *.nix set filetype=nix

此行确保 vim 识别 .nix 文件的文件类型并激活正确的语法突出显示。

【讨论】:

    【解决方案2】:

    TL;DR

    将插件文件放在正确的运行时路径目录中。

    包的一个解决方案是

    # git clone https://github.com/LnL7/vim-nix ~/.vim/pack/nix-stuff/start/vim-nix
    

    如果您使用 git 版本 .vim 并想使用子模块,请进行相应调整。


    总结 Plugin layout in the dark ages:h runtimepath,vim 在运行时路径的以下位置查找插件脚本:

          filetype.vim  filetypes by file name |new-filetype|
          scripts.vim   filetypes by file contents |new-filetype-scripts|
          autoload/ automatically loaded scripts |autoload-functions|
          colors/   color scheme files |:colorscheme|
          compiler/ compiler files |:compiler|
          doc/      documentation |write-local-help|
          ftplugin/ filetype plugins |write-filetype-plugin|
          indent/   indent scripts |indent-expression|
          keymap/   key mapping files |mbyte-keymap|
          lang/     menu translations |:menutrans|
          menu.vim  GUI menus |menu.vim|
          pack/     packages |:packadd|
          plugin/   plugin scripts |write-plugin|
          print/    files for printing |postscript-print-encoding|
          spell/    spell checking files |spell|
          syntax/   syntax files |mysyntaxfile|
          tutor/    files for vimtutor |tutor|
    

    注意某些位置如何具有语义含义:语法与文件类型与通用“始终加载”插件。

    现在,将所有插件文件放到正确的位置是很棘手的:

    过去,当您想使用别人编写的插件时,您会下载文件并将它们一个一个地放置到适当的目录中。您也可以使用ziptar 为您放置。

    这种方法存在一些重大问题:

    当您想要更新插件时会发生什么?你可以覆盖旧文件,但你怎么知道作者是否删除了你现在需要手动删除的文件?

    如果两个插件碰巧有一个同名的文件(如 utils.vim 或类似的通用文件)怎么办?有时您可以简单地重命名它,但如果它位于 autoload/ 或其他名称重要的目录中,您必须自己编辑插件。不好玩。

    人们想出了几个技巧来让事情变得更简单,比如 Vimballs。幸运的是,我们不再需要遭受这些丑陋的黑客攻击。 (A New Hope, Steve Losh)

    结果是 github 上的大多数 vim 插件都是在 'runtimepath' 条目之后构建的。根据需要,它们具有语法、ftplugin 或编译器目录。

    在 vim-8 之前,标准解决方案是众多插件管理器之一(给它一个谷歌;有很多)。我最喜欢的是 Tim Pope 的病原体,因为它与子模块一起工作得非常优雅。

    从 vim-8 开始,我开始使用包,您可以在 :h packages 阅读相关内容。

    【讨论】:

      猜你喜欢
      • 2012-08-16
      • 2014-11-14
      • 2020-01-11
      • 2011-01-19
      • 2015-08-08
      • 2014-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多