我希望能够在Vim中看到我是否在私人"是否有Ruby类定义的一部分。类定义如下所示:
class Foo
def a_public_method
end
private
def a_private_method
end
end
是否可以让Vim更改private
行的背景颜色以及之后的所有内容?
答案 0 :(得分:1)
可能的解决方案是:
:call matchadd('Error', '^.*private\_.\{-}\(^end\)\@=')
假设end
结束class
始终在一行开头(不是一个非常优雅的解决方案)。
您可以使用:hi
列出的其他突出显示组,而不是'Error'
。
答案 1 :(得分:1)
我多年来一直试图在红宝石中标记私人方法,但我总是开始和停止,现在,由于你的问题,我终于有了一个合理工作的想法。所以,谢谢你。
现在,首先,理想解决方案将使用Vim的内置突出显示来扩展ruby的语法文件。我想象这种方法的方法是定义一个以" private"开头的语法区域(:help syn-region
)。并以"结束"结束。棘手的一点是"私人"需要使用特定的语法组rubyAccess
进行标记,或者它可能只是任何"私有"在一个字符串或评论。 end
需要rubyClass
,或者它可能不是关闭课程,而是关闭方法def
或do
。
不幸的是,我无法弄清楚如何解决这个问题。我无法找到一种方法来定义从特定组到另一组的语法区域。如果你想学习语法高亮,也许有一天会想出问题的解决方案,这里有ruby的语法高亮:https://github.com/vim-ruby/vim-ruby/blob/f792ee3b2d005660da2e7303e43721ef222d7047/syntax/ruby.vim
现在,那就是说,在我用上面的术语定义问题之后,我意识到我可以找到相关的"私有"和"结束"具有正确语法组的关键字,在保存缓冲区或其他内容时。考虑到你无论如何都要考虑一个明确的命令,这对你来说也许是一个可行的解决方案。
如果您发现更具可读性,我在这里有一个要点:https://gist.github.com/AndrewRadev/d848ad9621b47b4151bbc61ab6c5765f。它需要进入~/.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:MarkPrivateArea
,用于执行区域的实际搜索和标记。 s:
表示它的脚本本地,因此它不会污染全局命名空间。它后来在自动命令中称为<SID>MarkPrivateArea
- 它的功能相同。
该函数从文件末尾开始,循环,然后禁止循环,让它覆盖整个文件,只有一次。它寻找&#34;私人&#34;使用正确的语法组,找到下一个&#34; end&#34;关闭一个类,并保存该区域的start_line
和end_line
。您可以添加或删除- 1
,以决定您的&#34;区域&#34;应包括或排除&#34;私人&#34;以及是否应该包含或排除最终的&#34;结束&#34;。
(旁注:为了实现这一目标,您需要进行&#34;昂贵的#34;语法突出显示,但默认情况下应该启用。相关文档:https://github.com/vim-ruby/vim-ruby/blob/f792ee3b2d005660da2e7303e43721ef222d7047/doc/ft-ruby-syntax.txt#L71)
最后,开始和结束行组合成一个如下所示的模式:
'\%<start-line>l\_.*\%<end-line>.'l'
请尝试使用:help \%l
获取更多信息,但这基本上是一个与文件特定行中的代码匹配的正则表达式模式。 \_.
是.
的多行形式。因此,它匹配从起始行到结束行的所有内容。
如果你想改变它,只有def
被突出显示,它将如下所示:
call matchadd('rubyPrivateArea', '\%>'.start_line.'l\<def\>\%<'.end_line.'l')
这至少是我要做的事情,但你确实说过你想要标记整个区域。
最后的自动命令在启动时,在写入文件时以及在保持光标一段时间后运行该函数。如果你愿意,你可以删除其中的一些。例如,如果您经常保存,即使没有CursorHold
,也可能没问题。
至于文件顶部的rubyPrivateArea
突出显示组,有关于如何使用:help highlight-args
设置颜色的完整说明。您还可以查看自己喜欢的colorscheme作为示例。