是否可以在文件中的某个行之后更改VIM背景颜色(Ruby类定义中的“私有”)



我很想能够在vim中看到我是否处于Ruby类定义的"私人"部分。班级定义看起来像这样:

class Foo
  def a_public_method
  end
  private
  def a_private_method
  end
end

是否有可能使VIM更改private行的背景颜色,以及之后的所有内容?

一个可能的解决方案是:

:call matchadd('Error', '^.*private_.{-}(^end)@=')

假设end关闭class始终从线的开头开始(不是非常优雅的解决方案)。您可以使用:hi而不是'Error'列出的另一个突出显示组。

我一直在尝试在Ruby中标记私人方法多年,但是我总是开始和停止,现在,由于您的问题,我终于有了一个合理的想法。所以,谢谢。

现在,首先, Ideal 解决方案将使用VIM的内置突出显示来扩展Ruby的语法文件。我认为这将有效的方式是定义以"私人"开头的语法区域(:help syn-region),并以"端"结尾。棘手的一点是,"私人"需要用特定的语法组rubyAccess标记,或者可能只是字符串中的任何"私有"或评论。end需要是rubyClass,或者可能关闭的不是类,而是方法的defdo

不幸的是,我不知道如何实现这一目标。我找不到一种从特定组到另一组定义语法区域的方法。如果您想研究语法突出显示,也许有一天想出解决问题的解决方案,这是Ruby的语法突出显示:https://github.com/vim-ruby/vim-ruby/vim-ruby/blob/blob/f792ee3b200556660da2e7303e7303e43721ef22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222太平洋流

现在,也就是说,在我在上面的术语中定义问题之后,我意识到我可以找到相关的"私有"one_answers" end"关键字,其中有正确的语法组,保存时。缓冲区之类的东西。考虑到您无论如何都在考虑明确的命令,这也可能是您的解决方案。

我在这里有要点,如果您发现更可读的话:https://gist.github.com/andrewradev/d848ad9621b47b4151bbbc61ab61ab6c5765f。它需要进入~/.vim/ftplugin/ruby.vim。在这里,有一些评论注释:

" Define what color the private area will be
hi rubyPrivateArea ctermbg=darkgray
function! s:MarkPrivateArea()
  " Clear out any previous matches
  call clearmatches()
  " Store the current view, in order to restore it later
  let saved_view = winsaveview()
  " start at the last char in the file and wrap for the
  " first search to find match at start of file
  normal! G$
  let flags = "w"
  while search('<private>', flags) > 0
    let flags = "W"
    if s:CurrentSyntaxName() !~# "rubyAccess"
      " it's not a real access modifier, keep going
      continue
    endif
    let start_line = line('.')
    " look for the matching "end"
    let saved_position = getpos('.')
    while search('<end>', 'W') > 0
      if s:CurrentSyntaxName() !~# "rubyClass"
        " it's not an end that closes a class, keep going
        continue
      endif
      let end_line = line('.') - 1
      call matchadd('rubyPrivateArea', '%'.start_line.'l_.*%'.end_line.'l')
      break
    endwhile
    " restore where we were before we started looking for the "end"
    call setpos('.', saved_position)
  endwhile
  " We're done highlighting, restore the view to what it was
  call winrestview(saved_view)
endfunction
function! s:CurrentSyntaxName()
  return synIDattr(synID(line("."), col("."), 0), "name")
endfunction
augroup rubyPrivateArea
  autocmd!
  " Initial marking
  autocmd BufEnter <buffer> call <SID>MarkPrivateArea()
  " Mark upon writing
  autocmd BufWrite <buffer> call <SID>MarkPrivateArea()
  " Mark when not moving the cursor for 'timeoutlen' time
  autocmd CursorHold <buffer> call <SID>MarkPrivateArea()
augroup END

高级别:它定义一个函数,即执行该区域的实际搜索和标记的 s:MarkPrivateAreas:表示其脚本本地,因此不会污染全局名称空间。后来在AutoComands中称为<SID>MarkPrivateArea-它是相同的功能。

该功能从文件的末尾开始,循环循环,然后禁止循环循环,让其仅覆盖整个文件,仅一次。它在正确的语法组中寻找"私有",找到关闭类的下一个"结束",并为该区域保存start_lineend_line。您可以在添加或删除- 1时进行访问,以确定您的"区域"是否应包括或排除"私有",以及它是否应包括或排除最终的"结束"。

(旁注:要为此,您需要具有"昂贵"的语法突出显示,但默认情况下应打开。相关文档:https://github.com/vim-ruby/vim-ruby/vim-ruby/blob/F792EE3B2D005660DA2E7303E43721EF222222227047/doc/ft-ruby-syntax.txt#l71)

最后,开始和端线组合成看起来像这样的模式:

'%<start-line>l_.*%<end-line>.'l'

尝试:help %l以获取更多信息,但这基本上是一种与文件的特定行中匹配的代码。_..的多行形式。因此,它匹配从起跑线到终点线的所有内容。

如果您想更改它,以便仅def S突出显示,则看起来像这样:

call matchadd('rubyPrivateArea', '%>'.start_line.'l<def>%<'.end_line.'l')

至少这就是我要做的,但是您确实说您想要标记的整个区域。

最终,在启动,编写文件以及持有光标的一段时间后,自动命令在启动时运行该功能。如果愿意,您可以删除其中的一些。例如,即使没有CursorHold,您也可以,如果您经常保存。

至于文件顶部的rubyPrivateArea突出显示组,关于如何使用:help highlight-args设置其颜色的完整说明。您也可以查看您喜欢的Colorscheme以获取一些示例。

最新更新