用Vim写Markdown

博客文章: https://chengpengzhao.com/2019/11/30/2019-11-30-markdown-vim-shi-yong/


自从接触了Vim之后就成了它的脑残粉,无论些什么东西都想拿它来试试,每天还坚持练习盲打;前几天刚总结了写Markdown时可能用到的语法,马上想到如何利用mapping让在Vim写Markdown变得更简单。
当然现在那么多写markdown的工具,比如我之前一直用的Typora就感觉很不错,但毕竟是别人的软件,有一些你想要的功能它没有那就没办法,但Vim的话只要学几天Vimscript就能自己实现一些功能、自己定义觉得方便的快捷键,简直随心所欲为所欲为。
有些人总是喜欢折腾,我也不例外,连专业学习都能丢在一边,先把这边折腾完再说。
下面简单介绍我专门为写Markdown定义的Vim快捷键,刚开始是B站的一个大佬给我的启发,我在它的基础上改进了一下,为了方便我自己的使用。


最基础的语法

这个设置不设置快捷键区别不是很大,但感觉还是快了那么一点点,毕竟可以少按几次Enter
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nr5mZsFD-1575113262630)(https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20191130174945.gif “title”)]
相关.vimrc配置文件:

autocmd Filetype markdown inoremap <localLeader>f <Esc>/<++><CR>:nohlsearch<CR>i<Del><Del><Del><Del>
autocmd Filetype markdown inoremap <localLeader>1 <ESC>o#<Space><Enter><++><Esc>kA
autocmd Filetype markdown inoremap <localLeader>2 <ESC>o##<Space><Enter><++><Esc>kA
autocmd Filetype markdown inoremap <localLeader>3 <ESC>o###<Space><Enter><++><Esc>kA
autocmd Filetype markdown inoremap <localLeader>4 <ESC>o####<Space><Enter><++><Esc>kA
autocmd Filetype markdown inoremap <localLeader>5 <ESC>o#####<Space><Enter><++><Esc>kA

这里通过<++>这样一个比较特殊的标记来进行光标的快速移动,从而定位到下一输入处。我的localLeader定义为/符号,怎么按舒服怎么定义就行。
*<localLeader>f*的mapping定义中用了多个<Del>而没有用d、s之类的命令是为了防止把<++>符号复制到剪切板中。

代码、空格、段落

这几个用Vim就方便很多了,至少我用Typora时想多打几个空格每次都要先百度然后复制&emsp;,多空几行也得先打出一个<br>再复制,代码段插入的话Typora有快捷键,不过最后输入代码语言的时候还得鼠标点,感觉还是挺麻烦的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ThX538KU-1575113262631)(https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20191130175151.gif “code”)]
相关.vimrc配置文件:

autocmd Filetype markdown inoremap <localLeader>c ```<Enter><++><Enter>```<Enter><++><Enter><Esc>4kA
autocmd Filetype markdown inoremap <localLeader>s ``<++><Esc>F`i
autocmd Filetype markdown inoremap <localLeader>/ &emsp;<Esc>a
autocmd Filetype markdown inoremap <localLeader><CR> <br><Esc>a

autocmd Filetype markdown可以保证只在打开.md文件的时候启用这些快捷键,而别的时候则不用,防止没必要的冲突。

字体、分隔线

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wk7gemVb-1575113262632)(https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20191130175938.gif “字体”)]
这几个的实现方法都比较简单,先输入再移动光标到中间处;类似的还有删除线和下划线。

图片和链接

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DYnDzuGk-1575113262632)(https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20191130180444.gif “link”)]
这里首先展示了当前剪切板的内容,因为一般我们都是先通过PicGo等软件把图片传到图床上,再复制链接到markdown里这样一个流程。(只需要将图片往配制好的PicGo一拖,过几秒它会自动复制链接到剪切板)所以在Vim直接读取剪切板的内容连同相应格式粘贴出来就行了。
相关.vimrc配置文件:

autocmd Filetype markdown inoremap <localLeader>p ![](<C-R>+ "<++>")<++><Esc>F]i
autocmd Filetype markdown inoremap <localLeader>a [](<C-R>+ "<++>")<++><Esc>F]i
autocmd Filetype markdown inoremap <localLeader>l <ESC>o--------<Enter>

脚注引用(自动编号)

我想这个功能是一般markdown编辑器都不具备的吧,脚注是一个相对来说输入比较麻烦的东西,如果能通过一个键插入而且自动编号的话会方便许多。当然对那些文章里不怎么用脚注的人来说这个功能也没啥用。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TjZ0dInb-1575113262633)(https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20191130181356.gif “footnote”)]
一开始我使用普通的计数方式,即按一次相应快捷键计数器+1,但这样没法保证保存退出后下一次再打开文件时变量还保持那个数。最终实现是通过正则表达式对前文进行搜索匹配出现次数来实现自动编号的。由于Vimscript没学几天很多命令都不太熟,也可能有更简单的实现方式。

function! Count(pattern,startline)
  let l:cnt = 0
  silent! exe a:startline . ',.s/' . a:pattern . '/\=execute(''let l:cnt += 1'')/gn'
  return l:cnt
endfunction

autocmd Filetype markdown inoremap <expr> <localLeader><F12> eval(Count('\[\^\d\+\]',1)+1)
autocmd Filetype markdown imap <localLeader>n [^<localLeader><F12>]<Esc>ya[Go<C-O>p: <++><Esc><C-o>f]a

公式(自动编号)

有了前面的函数,这一部分也比较好实现了,只要把正则表达式改一下就行了;这两部分我多定义了两个几乎不会被按到的键的组合作为输出的过渡,单独计算出函数返回值,以免在复杂的字符串中调用函数使得输出位置不正确。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d3GZ5h9w-1575113262633)(https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20191130182420.gif “math”)]
可以从下面的gif看出,即使重新进入文件,仍能够按正常的顺序进行编号。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ukD1yPwv-1575113262634)(https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20191130182620.gif “math2”)]

function! Findtitle()
    for i in range(line('.'))
        if matchstr(getline(line('.')-i),'^# \+')!=#''
            let l:latesttitleline=line('.')-i
            break
        else
            let l:latesttitleline=line('.')
        endif
    endfor
    return l:latesttitleline
endfunction
autocmd Filetype markdown inoremap <expr> <localLeader><F11> Count('^# \+',1)
autocmd Filetype markdown inoremap <expr> <Leader><localLeader><F11> Count(' \\tag{\d\+-\d\+}',Findtitle())+1
autocmd Filetype markdown imap <localLeader>q <ESC>o$$<Enter><Enter> \tag{<localLeader><F11>-<Leader><localLeader><F11>}$$<Enter><BS><++><Esc>2iA

其他工具

平时用得到的基本上都写进去了,表格我尽量不用所以没放进去。我还加了一些小工具,比如说按<F2>会在下一行插入一个时间戳:

以下内容更新于2019-11-30 18:50:47

Markdown-Preview

忘了介绍写markdown用的这个工具了,能够实现实时的显示,对就像gif里看到的这样。github相关页面
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U7wZACSs-1575113262635)(https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20191130190437.gif “preview”)]

Ultisnips

接下来介绍一个非常强大的插件,叫做ultisnips,它也能自定义来实现许多复杂的命令,但它的原理不是mapping而是snippet,当你输入一段特定的字符串时它会用事先定义好的另一段字符串来代替它。
它也内置了许多命令,可以在安装的vim-snippets插件里找到相关文件,比如markdown里的一些命令:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ry4cZBPg-1575113262636)(https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20191130195703.gif “ultisnips”)]
第一次没按出来是因为screenkey这个小程序的原因- -,但相比自己定义的命令来说它自带的补全还是比较复杂的。

下一步计划

Markdown里面写LaTeX公式是最复杂的一个部分,因为公式里面包含的语法比所有Markdown本身的语法还要多,导致写公式的时候效率极低,导致最后要么是图片复制粘贴、要么是Mathpix snapping tool直接识别(能直接识别为什么要自己输入一遍)。
根据How I’m able to take notes in mathematics lectures using LaTeX and Vim这篇文章,如何结合自己的需要,让在Vim里输入公式变得简单?这便是下一步的计划。


  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值