Vim-vim如何快速实现“粘贴并替换”功能

Vim-vim如何快速实现“粘贴并替换”功能

泛泛之交 发布于 2016-12-24 字数 447 浏览 1435 回复 2

经常会遇到这样的场景,需要将同一句话替换一段文本中若干个不同的地方,被替换的内容都不一样,所有没有办法使用替换功能。

我的vim操作如下:

  1. yy要复制的行
  2. 移动到要替换的位置,p进行粘贴
  3. 光标下移至被替换行,dd删除被替换行
  4. 由于剪切板被dd操作重置,需要yy重新复制
  5. 重复1-4

总觉得这个操作效率不高,请问vim中能否实现一个快捷的“粘贴并替换”功能,并且保持剪切板的内容不变?

如果你对这篇文章有疑问,欢迎到本站 社区 发帖提问或使用手Q扫描下方二维码加群参与讨论,获取更多帮助。

扫码加入群聊

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

归属感 2017-06-13 2 楼

可以在配置文件里加入如下代码:

" replace text with unnamed register (in all modes)
function! ReplaceWithUnamed(type)
let paste_save=&paste
let &paste=1
if a:type == 'line'
silent exe "normal! '[V']"
elseif a:type == 'block'
silent exe "normal! `[<C-V>`]"
elseif a:type == 'char'
silent exe "normal! `[v`]"
else
silent exe "normal! `<" . a:type . "`>"
endif
silent exe "normal! "_c<C-R>"<ESC>"
let &paste=paste_save
endfunction
nmap <silent> S :set opfunc=ReplaceWithUnamed<CR>g@
vmap <silent> S :<C-U>call ReplaceWithUnamed(visualmode())<CR>

先声明一下,这不是我写的代码。
通过快捷键S即可对选中的文本替换
1. 你这个问题可以这样解决:
先yy复制,到要粘贴的位置,V选中行,S即可,会直接将选中的行替换成复制的内容,同时"寄存器里的内容不会改变,可用同样的方法改变别的地方,而不用再yy。
2. 支持光标移动操作
如下代码:

1 VIM
2 This is vim;

在第一行复制VIM,再到第2行fv,再Sfm,即可将vim替换为VIM。
注意:可能vim会替换成VIMm,这需要在配置文件里加入

set selection=inclusive

修改后代码,修复用yy复制一行后,用大写VS替换其他行,会自动换行的bug

" replace text with unnamed register (in all modes)
function! ReplaceWithUnamed(type)
let paste_save=&paste
let &paste=1
if a:type == 'line'
silent exe "normal! '[V']"
elseif a:type == 'block'
silent exe "normal! `[<C-V>`]"
elseif a:type == 'char'
silent exe "normal! `[v`]"
else
silent exe "normal! `<" . a:type . "`>"
endif
"---------------------------------------------------------------------
"去掉"寄存器中恰好在最后的换行符,即该换行符后面不能再有文字,同时去掉空白符
let str_tmp=substitute(@",'s*n(_.+)@!','','')
silent exe "normal! "_c<C-R>=str_tmp<ESC>"
"----------------------------------------------------------------------
let &paste=paste_save
endfunction
nmap <silent> S :set opfunc=ReplaceWithUnamed<CR>g@
vmap <silent> S :<C-U>call ReplaceWithUnamed(visualmode())<CR>

夜无邪 2017-02-11 1 楼

如果只是单纯的替换操作的话,推荐 Allo 用 :s/Old/New/[g] 的方式,支持正则哦~

例如:替换文本中所有的中文 “ 和 ” 为半角英文的 "
在命令模式下键入 :%s/“/"/g 回车,然后 :%s/”/"/g 回车
特殊的文本内容就看你的需求了,如果会点正则,替换会变的异常简单
前面的 % 用来标识全文的匹配,最后的 g 标识确认替换

如果有很多跨行的操作,有个不常用的招数

比如:想复制 第五行到第十行的内容到 第三十五行行尾
同样是在命令模式下键入 :5,10 co 35
如果是剪切操作,使用 :5,10 m 35
很好用的说

说到剪切板,vim 其实很为程序员考虑的哦
在使用 y 复制的时候,可以指定为公共寄存器,与局部寄存器并存的说

例如:需要复制当前三行为公共寄存器的值
使用 "y3y 就可以啦,然后在需要粘贴的地方 "p 就粘出来
这个时候使用 yy 以及单纯的 p 的话,不会影响公共寄存器的哦

2012/9/25 add:
首先,我阐述一下个人观点,Vim 是一个追求完美的编辑工具
它的完美源自于它允许用户做自己最需要的事情,高度的定制化,显然是我们所期望的;
另外一个方面,这种定制化等多是指根据特定的需求来自己琢磨和编写,相信这也是很多 Vim 迷最享受的事情。

下面,我拿以下文字作为输入源:

根据提问者需求
1. 替换多句不同的内容为相同的内容;
2. 待替换的内容可通过 dd 删除,也就是说是按句换行的;
3. 需要有一个公共存储寄存器作为结果粘贴出来。

我们拿第一行的 “WHAT IS VIM” 作为公共的内容,稍候替换时备用,使用一下命令

<esc>gg"*yy

然后定制一个快捷键,斑驳不常使用 W 作为移动使用,习惯上都是那这个键作为绑定使用,如果提问者对这方面挑剔的话,推荐使用 w 之类的字符,避免替换掉默认的按键功能
定制如下:

:map W dd"*P<cr>

接下来就想提问者要求的那样,移动光标到你需要替换文字的地方,然后

<esc>W

例如以上文字,我们想改变第六行、第九,十行、以及第十三行的内容,可以使用命令

6GW
9G2W
12GW

注:<esc> 表示键盘的 Esc 按键,<cr> 表示回车,都是录入时候按键盘上的按键,不需要输入文本内容。使用快捷键时,要在命名模式下使用,所以前面加了个 <esc> 提醒,只要保证在命名模式下,<esc> 就完全不需要了。
另外,当需要替换多行时,像第九、十行要替换为 WHAT IS VIM 一样,在 W 之前加上对应的数字即可。存放到公共寄存器的话,也可以多行,"* + 行数 + yy 即可。
还需要额外解释的是:虽然实例中想要替换 第十三行 的内容,但是由于第九、十行被替换成为了一行,所以原来的十三行成为了第十二行。

以下是截图中的那段文字:

WHAT IS VIM

Vim is an almost compatible version of the UNIX editor Vi.
Many new features have been added: multi-level undo, syntax highlighting, etc.
There is also a Graphical User Interface (GUI) available.
See "runtime/doc/vi_diff.txt" for differences with Vi.

This editor is very useful for editing programs and other plain text files.
All commands are given with normal keyboard characters,
so those who can type with ten fingers can work very fast.
Additionally, function keys can be defined by the user, and the mouse can be used.

Vim runs under MS-Windows, Macintosh, and almost all flavours of UNIX.
Porting to other systems should not be very difficult.

希望有所帮助,祝好
斑驳敬上