IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发工具 -> vim学习经验 09 -> 正文阅读

[开发工具]vim学习经验 09

我想补充gu,gUg~,gt(w,iw,$,t,i(,等等).
两个目录:doc/(文档)plugin/(插件)
开始:

if !exists("g:totitle_default_keys") 
  let g:totitle_default_keys = 1 
endif
//文件底部,加上映射
if g:totitle_default_keys
  nnoremap <expr> gt ToTitle()
  xnoremap <expr> gt ToTitle()
//视觉模式
  nnoremap <expr> gtt ToTitle() .. "_"
endif

nnoremap <expr> gt ToTitle ()映射普通模式*操作符*.这样,可操作符+动作/文本块.
nnoremap<expr>gtt ToTitle() .. "_"映射普通模式的逐行操作符(类似guugUU)...Vim的串插值操作符._用作带操作符的动作.
_表示向下计数1行.gU_d_gUUdd意思一样.
<expr>参数允许指定计数.
vimrcplugin/前运行,如果不想用gt(因为已有),而用gz.
let g:totitle_default_keys = 0放在你的vimrc中,这样,可在vimrc自定义映射.因为!exists ("g:totitle_default_keys")if g:totitle_default_keys都返回假.

let g:totitle_default_keys = 0

nnoremap <expr> gz ToTitle()
xnoremap <expr> gz ToTitle()
nnoremap <expr> gzz ToTitle() .. "_"

然后这样,就可以了.

 function! ToTitle(type = "")
  if a:type ==# ""
    set opfunc=ToTitle
    return "g@"
  endif

  "细节"
  if a:type != "block" && a:type != "line" && a:type != "char"
    let l:words = a:type
    let l:wordsArr = trim(l:words)->split("\s\+")
    call map(l:wordsArr, "s:capitalize(v:val)")
    return l:wordsArr->join(" ")
  endif

  "保存当前配置"
  let l:sel_save = &selection
  let l:reg_save = getreginfo('"')
  let l:cb_save = &clipboard
  let l:visual_marks_save = [getpos("'<"), getpos("'>")]

  try
    set clipboard= selection=inclusive
    let l:commands = #{line: "'[V']y", char: "`[v`]y", block: "`[\<c-v>`]y"}

    silent exe "noautocmd keepjumps normal! " .. get(l:commands, a:type, "")
    let l:selected_phrase = getreg('"')
    let l:WORD_PATTERN = "\<\k*\>"
    let l:UPCASE_REPLACEMENT = "\=s:capitalize(submatch(0))"

    let l:startLine = line("'<")
    let l:startCol = virtcol(".")

    "用户调用块操作"
    if a:type ==# "block"
      sil! keepj norm! gv"ad
"
      keepj $
      keepj pu_

      let l:lastLine = line("$")

      sil! keepj norm "ap
"

      let l:curLine = line(".")

      sil! keepj norm! VGg@
      exe "keepj norm! 0\<c-v>G$h\"ad"
      exe "keepj " . l:startLine
      exe "sil! keepj norm! " . l:startCol . "\<bar>\"aP"
      exe "keepj " . l:lastLine
      sil! keepj norm! "_dG
      exe "keepj " . l:startLine
      exe "sil! keepj norm! " . l:startCol . "\<bar>"

    "用户调用`符/行`操作
    else
      let l:titlecased = substitute(@@, l:WORD_PATTERN, l:UPCASE_REPLACEMENT, "g")
      let l:titlecased = s:capitalizeFirstWord(l:titlecased)
      call setreg('"', l:titlecased)
      let l:subcommands = #{line: "'[V']p", char: "`[v`]p", block: "`[\<c-v>`]p"}
      silent execute "noautocmd keepjumps normal! " .. get(l:subcommands, a:type, "")
      exe "keepj " . l:startLine
      exe "sil! keepj norm! " . l:startCol . "\<bar>"
    endif
  finally

    "恢复设置"
    call setreg('"', l:reg_save)
    call setpos("'<", l:visual_marks_save[0])
    call setpos("'>", l:visual_marks_save[1])
    let &clipboard = l:cb_save
    let &selection = l:sel_save
  endtry
  return
endfunction

opfunc是什么?为什么它返回g@?
Vim有个特殊操作符,g@操作符函数.允许函数分配给opfunc选项.如果把Foo()函数赋值给opfunc,运行g@w时,会在下个单词上运行Foo().如果运行g@i(,则我在内圆括号中运行Foo().该操作符函数对创建你自己的Vim操作符至关重要.

set opfunc=ToTitle
return g@

工作原理:假设有如下映射:

nnoremap <expr> gt ToTitle()`

通过按gtw,Vim会检查opfunc是否为空.如果为,则Vim会给它分配ToTitle.然后它返回g@,本质上又一次调用ToTitle,即可工作了.
最开始时,opfunc为空,因而a:type'',这样第1段为真.再调用,赋值,并返回.

  set opfunc=ToTitle
  return "g@"

刚按下gtw后,gt完成上述操作,并返回g@.返回g@后,变成g@w.g@为函数符号,因而把w传递给g@执行.就调用了ToTitle.

三种动作类型,符/行/块.g@w操作符,g@j操作行,列前后,则是操作块.作为类型参数传递给函数.
可用

function! Test(some_arg)
  echom a:some_arg 
endfunction
//再

:set opfunc=Test

来测试.
接着:

if a:type != "block" && a:type != "line" && a:type != "char"
  let l:words = a:type
  let l:wordsArr = trim(l:words)->split("\s\+")
//分开空格
  call map(l:wordsArr, "s:capitalize(v:val)")
  return l:wordsArr->join(" ")
//元素大写并合并.
endif
//虽然违反了单一职责原则

你可这样:

:echo ToTitle("once on a time")
//输出Once Upon a Time

接着,

let l:sel_save = &selection
let l:reg_save = getreginfo('"')
let l:cb_save = &clipboard
let l:visual_marks_save = [getpos(""<"), getpos("">")]

临时变量,保存当前状态.

set clipboard= selection=inclusive
//`selection`为包含,`clipboard`为空

默认为包含,见:h'clipboard':h'selection'
然后是,

    let l:commands = #{line: "'[V']y", char: "`[v`]y", block: "`[\<c-v>`]y"}
    silent exe "noautocmd keepjumps normal! " .. get(l:commands, a:type, "")
//安静,为静转执行,否则在屏幕底部显示通知.

#{}为字典.
"l:commands"局部变量为以"lines","char""block"为键的哈希.
noautocmd,执行后续命令而不触发自动命令.
keepjumps,在移动时不记录光标移动.
Vim中,某些动作会在更改,跳转和标记列表中自动记录.这可以避免.使用noautocmdkeepjumps目的是防止副作用.normal按普通命令执行命令串,..Vim串插值语法.get()是接受列表,blob或字典的getter方法.这里,传递给它的是l:commands字典.
关键是a:type.a:type是:符行块之一.因此,如果a:type'line',你执行"noautocmd keepjumps normal! '[V']y".更多信息,见:h silent,:h:exe,:h:noautocmd,:h:keepjumps,:h:normal:hget().
'[']记住g@命令的开始和结束动作位置.

'[会移动光标到第一行,这是运行g@时开始地方.V逐行可视模式命令.最后,']移动光标到先前更改或复制出的文本末尾,但此时,它移动光标到最后一次g@操作末尾.最后y复制出选定文本.
上段,就是复制要执行文本.其他命令类似,

let l:commands = #{line: "'[V']y", char: "`[v`]y", block: "`[\<c-v>`]y"}
//类似操作.

接着:

let l:selected_phrase = getreg('"')

无名寄存器内容.然后是正则:

let l:WORD_PATTERN = "\<\k*\>"

\<\>是单词边界,\k是关键字模式.这是匹配模式.最后有

let l:UPCASE_REPLACEMENT = "\=s:capitalize(submatch(0))"

模式.用\=.submatch(0)为整个匹配.

let l:startLine = line("'<")
//返回行号
let l:startCol = virtcol(".")
//光标列.先保存

处理块操作:

    if a:type ==# "block"
      sil! keepj norm! gv"ad
"
      keepj $
      keepj pu_

      let l:lastLine = line("$")

      sil! keepj norm "ap
"

      let l:curLine = line(".")

      sil! keepj norm! VGg@
      exe "keepj norm! 0\<c-v>G$h\"ad"
      exe "keepj " . l:startLine
      exe "sil! keepj norm! " . l:startCol . "\<bar>\"aP"
      exe "keepj " . l:lastLine
      sil! keepj norm! "_dG
      exe "keepj " . l:startLine
      exe "sil! keepj norm! " . l:startCol . "\<bar>"

sil!静默运行,keepj移动时保留跳转历史.然后执行普通gv"ad命令.gv选择最后一个可视高亮显示文本(在pancakes例中,它将重新高亮显示所有三个'cakes')."ad删除他们,并在a寄存器存储.结果,现在,a中存储了3个块.然后

keepj $ 
keepj pu _

$移动到文件最后一行.pu_光标位置下方插入一行,keepj不会改变跳转历史.

let l:lastLine = line("$")
//行号存储在`lastLine`变量中

再复制进尾行:

sil! keepj norm "ap

然后,存储光标所在当前行位置:

let l:curLine = line(".")

然后是:

sil! keepj norm! VGg@
exe "keepj norm! 0\<c-v>G$h\"ad"
exe "keepj " . l:startLine
exe "sil! keepj norm! " . l:startCol . "\<bar>\"aP"
exe "keepj " . l:lastLine
sil! keepj norm! "_dG
exe "keepj " . l:startLine
exe "sil! keepj norm! " . l:startCol . "\<bar>"

这里:

sil! keepj norm! VGg@

递归调用VGg@,VG可视块,g@递归调用函数.这样都大写了.

exe "keepj norm! 0\<c-v>G$h\"ad"

删除高亮,并存储在a寄存器中.h为右移,c-v为可视,G为尾.

exe "keepj " . l:startLine

光标移回起始行.再粘贴:

exe "sil! keepj norm! " . l:startCol . "\<bar>\"aP"

<bar>|动作,为跳至多少列的意思.再粘贴.

exe "keepj " . l:lastLine
sil! keepj norm! "_dG
exe "keepj " . l:startLine
exe "sil! keepj norm! " . l:startCol . "\<bar>"

最后,删除.清理,回到原位.
然后是行/符代码.

      let l:titlecased = substitute(@@, l:WORD_PATTERN, l:UPCASE_REPLACEMENT, "g")
//关键.
      let l:titlecased = s:capitalizeFirstWord(l:titlecased)
      call setreg('"', l:titlecased)
      let l:subcommands = #{line: "'[V']p", char: "`[v`]p", block: "`[\<c-v>`]p"}
      silent execute "noautocmd keepjumps normal! " .. get(l:subcommands, a:type, "")
      exe "keepj " . l:startLine
      exe "sil! keepj norm! " . l:startCol . "\<bar>"

@@包含无名寄存器文本.l:WORD_PATTERN是单个关键字匹配.l:UPCASE_REPLACEMENT调用capitalize()命令,g替换所有.

let l:titlecased = s:capitalizeFirstWord(l:titlecased)
//保证首字母总大写.如an不会大写时.

接着

call setreg('"', l:titlecased)

放入无名寄存器.

let l:subcommands = #{line: "'[V']p", char: "`[v`]p", block: "`[\<c-v>`]p"}
silent execute "noautocmd keepjumps normal! " .. get(l:subcommands, a:type, "")

这里用p粘贴.

exe "keepj " . l:startLine
exe "sil! keepj norm! " . l:startCol . "\<bar>"

移回来.恢复设置:

call setreg('"', l:reg_save)
call setpos("'<", l:visual_marks_save[0])
call setpos("'>", l:visual_marks_save[1])
let &clipboard = l:cb_save
let &selection = l:sel_save

无名,位置,剪切板及选区.
:set ft=help设置文档类型.
关键字,*totitle*这样写.也可用|包围关键字.这是vim的内部链接.C-]跳进,C-[跳出.
:helptags ~/.vim/doc创建新的标签文件,这样就可搜索了.

  开发工具 最新文章
Postman接口测试之Mock快速入门
ASCII码空格替换查表_最全ASCII码对照表0-2
如何使用 ssh 建立 socks 代理
Typora配合PicGo阿里云图床配置
SoapUI、Jmeter、Postman三种接口测试工具的
github用相对路径显示图片_GitHub 中 readm
Windows编译g2o及其g2o viewer
解决jupyter notebook无法连接/ jupyter连接
Git恢复到之前版本
VScode常用快捷键
上一篇文章      下一篇文章      查看所有文章
加:2022-07-17 16:44:21  更:2022-07-17 16:47:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 14:31:06-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码