[译] Vimscript 有路勤为径 —— 开关

目录: vim | 标签: | 发布时间:

开关

在最早的某个章节中,我们讨论过在 Vim 中如何设置选项。 针对布尔值的选项,我们可以用 set someoption! 来“开关”选项。 这对于我们创建映射是特别有用的。

运行以下命令:

:nnoremap <leader>N :setlocal number!<cr>

试试在普通模式下按下 <leader>N。Vim 会开关当前窗口的的行号。 创建这样的“开关”映射确实很方便,因为我们不需要分别用两个按键来开和关了。

遗憾的是这只对布尔值选项有效。如果我们想开关一个非布尔值选项,那就要更复杂一些了。

开关选项

让我们从创建一个可以开关选项的函数开始,并且创建一个映射来调用它。 把以下代码放进你的 ~/.vimrc 文件(或者也可以是 ~/.vim/plugin 中的一个独立文件):

nnoremap <leader>f :call FoldColumnToggle()<cr>

function! FoldColumnToggle()
    echom &foldcolumn
endfunction

保存并载入执行文件,然后试试按下 <leader>f,Vim 会显示 foldcolumn 选项当前的值。 如果你不熟悉这个选项,就去阅读 :help foldcolumn

阅读更多>>


[译] Vimscript 有路勤为径 —— 字典

目录: vim | 标签: | 发布时间:

字典

我们要讲的最后一种 Vimscript 变量类型是字典。 Vimscript 字典类似于 Python 的字典、Ruby 的哈希、以及 Javascript 的对象。

字典可以用花括号来创建。值可以是各种类型,但是键总是会被强转为字符串。 你不会期待凡事都是完全一样的,对吧?

运行以下命令:

:echo {'a': 1, 100: 'foo'}

Vim 显示 {'a': 1, '100': 'foo'},这表示 Vimscript 确实把键强转为了字符串,而保留值的类型不动。

Vimscript 不像 Javascript 标准那么愚钝,它允许在字典的最后一个元素后面添加逗号。 运行以下命令:

:echo {'a': 1, 100: 'foo',}

Vim 还是显示 {'a': 1, '100': 'foo'}。你应该总是在字典末尾添加逗号, 特别是使用多行定义的时候,这让你在添加新条目时不容易出错。

索引

你可以像大多数语言那样在字典中检索某个键。运行命令:

:echo {'a': 1, 100: 'foo',}['a']

Vim 显示 1。试试使用一个非字符串索引:

:echo {'a': 1, 100: 'foo',}[100]

Vim 在检索之前会先把索引强转为字符串,这很有必要,因为键也只能是字符串。

Vimscript 也支持 Javascript 风格的 “.” ,但是键只能由字母、数字、以及下划线组成。 试试以下命令:

:echo {'a': 1, 100: 'foo',}.a
:echo {'a': 1, 100: 'foo',}.100

Vim 都会显示正确的元素。你可以根据自己的喜好和风格来选择使用哪种方式。

阅读更多>>


[译] Vimscript 有路勤为径 —— 循环

目录: vim | 标签: | 发布时间:

循环

你可能会惊讶的发现,虽然我们已经完成了这本编程语言书籍的35个章节,但是还没有涉及到循环! Vimscript 提供了如此多其他的选项来实现文本上的操作(例如 normal!),所以循环不如其他语言中显得那么重要。

虽然如此,可能某一天你确实需要用到,所以,我们现在来看看 Vim 支持的两种主要循环。

for 循环

第一种循环是 for 循环。如果你使用过 Java、C、或是 Javascript 的 for 循环, 可能会觉得有点奇怪,但是也足够优雅。运行以下命令:

:let c = 0

:for i in [1, 2, 3, 4]
:  let c += i
:endfor

:echom c

Vim 显示 10,这是把列表中的元素加起来的结果。 Vimscript 的 for 循环会遍历列表(或者字典,我们会在后面讲到)。

在 Vimscript 中,没有等效于 C 风格 for (int i = 0; i < foo; i++) 的循环形式。 乍看起来可能很糟,但是实际上,你不会想念它的。

阅读更多>>


[译] Vimscript 有路勤为径 —— 列表

目录: vim | 标签: | 发布时间:

列表

到目前为止,我们用过很多次变量了,但还没有讨论过聚合! Vim 主要有两种聚合类型,我们现在就来看看第一种:列表。

Vimscript 列表是有序的、多类型的元素集合。运行以下命令:

:echo ['foo', 3, 'bar']

Vim 显示了这个列表。当然,列表是可以嵌套的。运行以下命令:

:echo ['foo', [3, 'bar']]

Vim 正确的显示了这个列表。

索引

Vimscript 列表的索引是从0开始的,你可以像平常一样获取元素。运行命令:

:echo [0, [1, 2]][1]

Vimscript 显示 [1, 2]。你也可以反方向使用索引,就如 Python 一样。试试命令:

:echo [0, [1, 2]][-2]

Vim 显示 0。索引 -1 表示列表的最后一个元素,-2 表示倒数第二个元素,以此类推。

阅读更多>>


[译] Vimscript 有路勤为径 —— 案例分析:grep操作符,第三部分

目录: vim | 标签: | 发布时间:

案例分析:grep操作符,第三部分

我们新的“grep操作符”运行的很好,但还是要想办法让你的用户在编写 Vimscript 时感觉轻松惬意。 我们可以再优化两点,使这操作符可以更好的在 Vim 生态中发挥作用。

保存寄存器

如果复制文本到无名寄存器,那我们就把之前寄存在那的内容给清除了。 更进一步的,使用我们的操作符并移动,再可视化选择文本并复制,这样也会清除上次可视化选择的文本。

这对我们的用户不是很友好,所以在这种情况下需要避免使用可视化选择,并且在任何需要复制文本的时候, 把无名寄存器中的内容保存起来,这样在处理完成之后,就可以恢复了。 修改代码成如下:

nnoremap <leader>g :set operatorfunc=GrepOperator<cr>g@
vnoremap <leader>g :<c-u>call GrepOperator(visualmode())<cr>

function! GrepOperator(type)
    let saved_unnamed_register = @@

    if a:type ==# 'v'
        normal! `<v`>y
    elseif a:type ==# 'char'
        normal! `[y`]
    else
        return
    endif

    silent execute "grep! -R " . shellescape(@@) . " ."
    copen

    let @@ = saved_unnamed_register
endfunction

我们在函数的顶部和底部分别添加了两行 let 语句。 第一行,把 @@ 的内容保存到一个变量中,然后第二行恢复它。 此外,在我们的操作符应用到一个移动命令时,我们用复制替换可视化选择。

保存并载入执行文件。为了确保它能正常运行,我们先试着复制一些问文本,然后按下 <leader>giw 来运行我们的操作符, 然后按下 p 粘贴出来,并检查是不是之前复制的文本。

当编写 Vim 插件是,你应该总是力求保存和恢复任何代码会修改的设置或寄存器,这样才能不让你的用户感到诧异和困惑。

阅读更多>>


[译] Vimscript 有路勤为径 —— 案例分析:grep操作符,第二部分

目录: vim | 标签: | 发布时间:

案例分析:grep操作符,第二部分

现在我们已经得到了一个解决方案的初步框架,是时候给它填充更多能量了。

记住:我们最初的目标是创建一个“grep操作符”。为了实现这个,还有一大堆的新东西要讲。 但是像上一章节里一样:我们先从一些简单的内容开始,然后不停的改造,直到成为你想要的。

在我们开始之前,先把 ~/.vimrc 文件中上一章节刚创建的映射注释掉 —— 我们会为新建的操作符绑定同样的按键。

创建一个文件

创建一个操作符需要若干命令,徒手键入这些很快就会令人乏味。 你可以添加到 ~/.vimrc 文件中,但我们还是为这个操作符单独新建一个文件。 它已经足够丰富来独自支撑一个文件了。

首先,找到你 Vim 的 plugin 目录。Linux 或者 OS X 系统里,是在 ~/.vim/plugin。 如果是 Windows 系统,会在用户目录下的 vimrfiles 目录里。 (如果你不确认用户目录在哪,在 Vim 中使用 :echo $HOME 命令查看)。 如果这个目录不存在,那创建一个。

plugin/ 中创建一个名为 grep-operator.vim 的文件。你将在这里编写新的操作符代码。 在编辑文件的同时,你可以随时运行 :source % 来重载代码。 这个文件也会和 ~/.vimrc 一样,在每次打开 Vim 时载入。

记住,你必须先保存文件,再载入执行,这样才能看到更改!

阅读更多>>


[译] Vimscript 有路勤为径 —— 案例分析:grep操作符,第一部分

目录: vim | 标签: | 发布时间:

案例分析:grep操作符,第一部分

在本章节和后面的章节中,我们会完整地创建一段足够复杂的 Vimscript 代码。 我们会讨论几种之前没看过的东西,以及如何把之前学过的东西在实战中组合在一起。

在你完成本次案例分析的过程中,碰到了任何不熟悉的,都应该用 :help 查阅。 如果似懂非懂地完成了所有的东西,你将学不到多少东西。

grep 命令

如果从来没用过 :grep,你现在就应该花上一分钟来阅读 :help :grep:help :make。 如果之前从来没有用过 quickfix 窗口,那就阅读 :help quickfix-window

简而言之::grep ... 会运行一个外部grep程序来处理输入的任何参数,解析结果, 然后填充到quickfix列表,这样你就可以在 Vim 中跳到那些结果上了。

我们的例子就是要让 :grep 更容易使用,通过添加一个“grep操作符”,可以用任何 Vim 内置(或自定义)的移动来选择想要搜索的文本。

阅读更多>>


[译] Vimscript 有路勤为径 —— 基本正则表达式

目录: vim | 标签: | 发布时间:

基本正则表达式

Vim 是个文本编辑器,这就意味着你大部分的Vimscript代码都应该专注于处理文本。 Vim 支持强大的正则表达式,但依旧有些诡异的地方。

在缓冲中键入以下文本:

max = 10

print "Starting"

for i in range(max):
    print "Counter:", i

print "Done"

我们就用这段文本来验证 Vimscript 支持的正则表达式。 这刚好是一段Python代码,但是如果你不了解Python也不用担心。这只是个例子。

我假设你知道基本的正则表达式。如果不知道,那应该停止阅读本书,并且阅读Zed Shaw写的 Learn Regex the Hard Way。等完成了之后再回来。

阅读更多>>


最新整理的git自定义log格式

目录: git | 标签: | 发布时间:

从使用git以来,很长一段是用从书上看来的git log --graph --decorate --oneline来查看历史提交记录。

效果如图:

但是这样是有些关键信息没有显示出来的,比如提交者是谁,提交时间等。 想要在一行中看到更多的信息,那就需要用--pretty=<format>参数了。

阅读更多>>


[译] Vimscript 有路勤为径 —— execute normal!命令

目录: vim | 标签: | 发布时间:

execute normal!命令

既然我们已经学习了 executenormal!,那就进一步的讨论一个常用的 Vimscript 习惯. 运行以下命令:

:execute "normal! gg/foo\<cr>dd"

这会移动到文件顶部,搜索第一次出现 foo 的地方,然后删除这一行。

之前我们已经尝试了在搜索命令中使用 normal!,但是没办法按下回车来真正执行搜索。 结合 normalexecute 就能解决这个问题。

execute 让你以编程的方式构建命令,这样就可以用普通的 Vim 字符串转义序列来生成需要的非打印字符。 试试以下命令:

:execute "normal! mqA;\<esc>`q"

这个命令做了什么?让我们拆分开来看:

这看起来有点吓人,但是实际上是非常有用的:它在当前行的末尾添加一个分号,而把保留光标在原处。 如果你在写Javascript,C,或任何其他用分号作为语句终止符的语言时,忘记了写分号, 那么为这个命令创建一个映射肯定能派上用场。

阅读更多>>

加载更多