最近,我在 Reddit 上面分享了一个新的代码格式化的插件 format.nvim, 回复大多是是在问为什么要做这个插件以及跟现有插件的区别。
在 SpaceVim v2.3.0 之前,一直使用的代码格式化插件是 neoformat, 这个插件是使用 Vim 脚本写的,同时支持 Neovim 和 Vim。
但是美中不足的地方是这个插件执行格式化命令是调用 Vim 的 system()
函数,当命令执行消耗时间很长时,就会卡住界面无法进行下一步操作。
我也尝试过给 neoformat 增加异步支持,但是考虑到其他几个原因,还是决定重新写一个插件。
其实 neoformat 的插件代码实现逻辑还是非常好的,因此我也是参考了 neoformat 的实现逻辑, 使用 Lua 来实现了这个异步代码格式化的插件 format.nvim。 这个插件使用了 SpaceVim 的 job api 可以异步执行格式化命令,使得 Neovim 的操作更加顺畅。
对于 SpaceVim 用户来说,只需要在启用 format 模块的时候,指定格式化方法为 format.nvim 即可,配置如下:
[[layers]]
name = 'format'
format_method = 'format.nvim'
虽然 format.nvim 是基于 SpaceVim 的 Job API 实现的,但是该插件已经包含的改 API 的必须文件, 因此可以任意插件管理器独立安装,例如使用 vim-plug:
Plug 'wsdjeg/format.nvim'
以 Lua 语言为例,设置使用 stylua 命令进行格式化:
require('format').setup({
custom_formatters = {
lua = {
exe = 'stylua',
args = { '-' },
stdin = true,
},
},
})
1、格式化整个 Buffer
format.nvim 只提供了一个命令 :Fromat
, 执行该命令时就可以根据当前文件的文件类型选择对应的 formatter 对整个 Buffer 进行格式化。
2、选中区域进行格式化
:Format
命令支持指定区域进行格式化,因此可以在 Neovim 中选中几行代码进行格式化。
3、指定文件类型
通常执行 :Format
命令时,会读取当前 Buffer 的 &filetype 选项,但是如果需要指定其他文件类型,比如 java,可以使用如下格式执行命令:
:Format! java
4、指定 formatter
如果一个文件类型有多个 formatters,可以在执行改命令时指定一个 formatter 的名字,比如 :Format prettier
前面提到 :Format
命令支持指定区域格式,这里需要借助一个插件 context_filetype.vim。
通过这个插件获取到代码块的区域和文件类型,传给 Format 命令。
以下示例使用 <Leader>f
格式化光标所在的代码块:
function! s:format_code_block() abort
let cf = context_filetype#get()
if cf.filetype !=# 'markdown'
let command = printf('%s,%sFormat! %s', cf.range[0][0], cf.range[1][0], cf.filetype)
exe command
endif
endfunction
nnoremap <silent> <Leader>f <cmd><sid>format_code_block()<cr>
前段时间整理自己的个人维基发现笔记太零散,很难快速定位到自己需要的笔记。 以往借助自己的 flygrep 插件根据记忆的关键字倒是可以找到相关的内容, 但是随着笔记越来越多,关键字筛选已经不足以快速定位了。 于是就想找一个更好的方式来组织管理日常的笔记,后来就了解到了《卢曼卡片盒笔记法》
最开始,我是想找一个三端(手机、电脑、网页)同步的笔记软件,但是似乎没有合适的。因为都是文本编辑,而且如果要使用卡片盒笔记法的话, 那么笔记就需要遵循一定的格式。日常使用 Neovim 也非常多,几乎文本的编辑都是在 Neovim 内完成的,索性就不再舍近求远去找笔记软件了, 就直接在 Neovim 内完成。检索了下 Github 发现还是有不少现成的插件实现,但是功能似乎都不是很完善。
因此自己 Fork 了一个插件,在这个插件的基础上做了一些功能的改进和增加,有兴趣的话欢迎尝试:vim-zettelkasten。
浏览笔记列表时,展示笔记的引用数量以及被引用数量,同时列出笔记包含的 Tags 列表,如下图所示:
同时,在 ZkBrowser 窗口内支持的快捷键包括:
快捷键 | 功能描述 |
---|---|
q |
退出 ZkBrowser 窗口 |
<LeftRelease> |
鼠标左键点击 Tag,筛选包含该 Tag 的笔记 |
gf |
打开光标 ID 下的笔记 |
Ctrl-l |
清除 Tags 筛选,列出所有笔记 |
Ctrl-] |
使用 preview-window 窗口预览笔记 |
[I |
使用 quickfix-window 列出 References |
F2 |
打开 Tags 列表侧栏 |
侧栏的效果图如下,可以在侧栏窗口中使用回车键或者鼠标左键点击 Tag 实现筛选:
侧栏中,标签按照首字母归类,鼠标左键点击归类的字母,可以折叠这些标签。
当笔记 Tags 非常多的时候,可以使用 telescope.nvim 进行检索,检索后默认的回车键行为是列出包含该 Tag 的所有笔记。
默认的快捷键为 SPC m z g
。
笔记的标题(Title)也可以使用 telescope.nvim 进行检索,默认的快捷键是 SPC m z f
。
在编辑笔记过程中,可以使用快捷键 ctrl-x ctrl-u
来打开补全窗口,补全引用的笔记 ID。
如果是使用 SpaceVim,可以通过 zettelkasten 模块选项设置笔记模板的文件夹,新建一些常用的笔记模板,比如:
[[layers]]
name = 'zettelkasten'
zettel_dir = 'D:\me\zettelkasten'
zettel_template_dir = 'D:\me\zettelkasten_template'
通常基于默认新建笔记直接使用 SPC m z n
快捷键即可,如果需要基于其他模板来新建,可以使用快捷键 SPC m z t
调用 Telescope 检索常用模板。
因为 SpaceVim 默认是兼容 Neovim 和 Vim 的,因此后面是有计划让这个插件也支持 Vim 的,但是为了减少重复实现的一些代码,可能是需要 Vim 有 +lua
特性。
新的工作环境感觉不是想象中那么理想,但是也在努力去适应。 最近感觉也比较压抑,本来周末想去看的一部电影,因为一些事情耽搁了,今晚抽空一个人去电影院看了。
正如电影的名字一样,即便是生活很多时候不是很如意,但是有些人还是很善于发现身边的一些“好东西”。
可能是因为自己工作的原因,很多时候太过追求结果,而忽略了过程中一些美好的事情。
曾今的我一直固执的认为谎言就是谎言,没有善恶之分,因为总有方式更好地呈现事实。 但很多时候,一些善意的谎言其实可以让事情变得更加简单。
其实,说实在的,电影不是特别的好看,很多情节、对话太过于刻意。 就感觉正常的两个人对话,不该是这样,很多时候刻意的制造一些“鸡汤”类的说教, 或者刻意的制造一些搞笑的对话。
但是,其中确实有很多“鸡汤”值得去好好想想,比如:
1、小女孩上台表演前的那段对话,有时候因为害怕别人的眼光、说辞、看法, 而退缩,其实,这个社会上,在意你的人,真的没有你想象的那么多。 可能明天,他就会忘记你所做的事。
2、又比如小孩的作文,我最喜欢的、以及出现了两次的跟幻想相关的话题。 我觉得小孩子还没有这样的思想,更多的是电影呈现给观众的一些观点。 是的,即便是现在,后面的生活,还有很多年,你永远不会知道自己最喜欢的将会是什么,还是要保留一些幻想。
周末跟家人们去看了一部电影,小朋友们选了柯南,我就去看了张家辉主演的《重生》。
剧中角色:
安渡(阮经天 饰)
安渡缉毒组小队长,被其舅舅安佩长期长期压抑不得势再加上自幼经历悲惨,造成了阴暗的性格,被权力、金钱迷失倒也正常。 人性这种东西其实很奇怪,不能去深究其好坏。
张耀(张家辉 饰)
张耀的剧情也算还能理解,想要在监狱里替换掉沙旺,并且通过各种检查,没有安渡他们的安排跟支持几乎不可能。
巴莱(马浴柯 饰)
完全没有想到的是南茜和巴莱也是也是提前安排好的碟中谍角色。
前不久,删除了用了很久的 Telegram 账号 @wsdjeg
。
为了避免非本人使用该用户名带来不必要的麻烦,原来的用户名转移给了一个无管理员的公共的 Channel。
个人是非常抵触使用手机号注册和登录的软件,因为手机号实际上运营商是可以二次销售的。 大学期间至今,前面大概有三个手机号已经停机不用了,但是现在搜了下,居然有别人已经用它来注册了微信。
此外,如果提供足够的材料或者“特殊情况”下,运营商可以重新制作一张 SIM 卡,原 SIM 会废弃。 那么新卡就可以接受验证信息,这就意味着,对于账号的所有权,你没有绝对的控制权。
对于 Vim Script 的语法的认知似乎还停留在 《笨方法学 Vim Script》的年代, 在接触 Neovim 以及使用 Lua 写插件之前一直都是使用 Vim Script。 即使是现在部分插件为了兼容 Vim,任然会使用 Vim 脚本实现一个兼容版本。 随着 Vim 版本的更新,实际上以及引入了很多新的语法格式。
查看了下自己以往写的 Vim 脚本,string 的连接符仍然是使用单个点,实际上 Vim 早就支持使用 ..
符号来连接字符串。
let s:foo = 'abc' . 'def'
" 可以改成
let s:foo = 'abc' .. 'def'
在函数内部调用传入的参数,过往最常用的无外乎 a:0
、 a:000
或者 a:foo
等等。
a:
实际上是一个 dict
变量, 可以看下具体包含哪些 key
:
function! s:foo(x, y, ...)
echom a:
endfunction
1,2call s:foo(1, 2, 3)
执行 so %
输出如下:
{'0': 1, '000': [3], '1': 3, 'y': 2, 'firstline': 1, 'x': 1, 'lastline': 2}
{'0': 1, '000': [3], '1': 3, 'y': 2, 'firstline': 1, 'x': 1, 'lastline': 2}
从上面的输出不难看出 a:
字典变量中 key
包括:
0
: 可变参数数量, 可变参数是 1 个 3000
: 可变参数组成的列表x
或者 y
: 特定名称的参数此外还有两个特殊 key
值,firstline
和 lastline
, 这个是传入的 range, 同时这意味着在定义函数时,参数名称不可以是 firstline
和 lastline
。
否则会有如下错误:
E125: Illegal argument: firstline
在 Vim 8.1.1310 中,增加了 optional-function-argument
, 具体写法如下:
function! s:foo(x, y = 3, ...)
echom a:
endfunction
call s:foo(1)
{'0': 0, '000': [], 'y': 3, 'firstline': 1, 'x': 1, 'lastline': 1}
上面的输出可以看出,在调用 s:foo
函数时,虽然只传入了一个参数,但是在函数内部 a:
任然有一个 y
key,其值为默认值 3
。
闭包在其他很多编程语言里面都有类似的写法,可以理解为一个函数工厂,根据“环境变量”返回一个特定环境下的函数。
在 Vim 7.4.2120 中给 :function
定义增加了 closure 属性。示例如下:
function! s:foo(x)
function! s:xy(y) closure
return pow(a:y, a:x)
endfunction
return funcref('s:xy')
endfunction
let s:a = s:foo(2)
let s:b = s:foo(3)
echo s:a(2)
echo s:b(2)
若不使用 closure
关键字,在函数 s:xy
内部是无法调用 a:x
的。
其实,在 Lua 中也可以实现类似的功能:
local function foo(x)
return function(y)
return y^x
end
end
local a = foo(2)
local b = foo(3)
print(a(2))
print(b(2))
以上两种输出结果都是:
4.0
8.0