分享 解决粘贴到终端 Vim 缩进错乱

vincent178 · 2013年08月13日 · 最后由 nightire 回复于 2017年04月23日 · 30363 次阅读
本帖已被管理员设置为精华贴

当 Vim 的自动缩进打开的时候,你粘贴到终端 Vim 的 code 会出现缩进错乱的情况。当然这个问题只是出现在从其他应用里面复制内容,并且不是用的 MacVim 或者 Gui Vim 的时候。

原因是在终端的 vim 中没有相应的程序来处理这个从其他应用复制粘贴的过程,所以 Vim 通过插入键盘输入的 buffer 来模拟这个粘贴的过程,这个时候 Vim 会以为这是用户输入的。

问题就是出在这:当上一行结束,光标进入下一行时 Vim 会自动以上一行的的缩进为初始位置。这样就会破坏原始文件的缩进。

好在 Vim 提供了 past 和 pastetoggle 选项,你只要把这一行加入你的 vimrc 文件。

set pastetoggle=

还有更高级的

nnoremap  :set invpaste paste? imap :set invpaste paste? set pastetoggle=

这样可以在状态栏中显示 paste,不赖吧。。。

最后广告时间:我的 vimrc 文件 https://github.com/vincent178/dotfiles/blob/master/vim/.vimrc

谢谢@Rei 的 writings.io,很好用。这篇 blog 就是在上面写的。 http://vincent178.writings.io/articles/9

感谢楼主!!!这问题困扰我很久了

anyway 我的 vimrc

nice,vincent,我偶尔会遇到,但是忘记了怎样重现

原来如此啊,我每次都是用 emacs 打开了再粘贴的

3ks,我每次都 set paste,set nopaste , 看样子需要设一下了

涨知识了,不知道 set paste 跟 set noautoindent 有什么区别

使用"+p 可以避免这个问题,参见 practial vim

very nice !

#4 楼 @stc 同样的手敲 set paste

暴力点,paste 完就格式化保存

:map ggVG=:w!

赞,郁闷好久了。

我来锦上添花好了,放个给极度懒人用的大招:

autocmd InsertEnter * setlocal paste
autocmd InsertLeave * setlocal nopaste

这个的效果呢,就是当你进入 Insert 模式的时候自动开启 paste,此时你从外面复制粘贴进来的东西就会保持原有队形了。之后你回到 Normal 模式的时候,Vim 会自动关闭 paste

这个比较适合不喜欢按快捷键的纯粹懒人,不过请小心,一直处于 paste 开启的状态下虽然不影响基本的功能,但是可能会影响其他的插件正常工作哦!

最好的办法还是使用键位映射在你需要粘贴的时候手动开启 paste,不过可以保留离开时自动 nopaste 的功能,省点事儿,因为有时候你开启 paste 复制完,然后退出 Insert 时忘记了 nopaste,那么下次再进入 Insert 的时候还是 paste 的。

不过实际使用中最好把 autocmd 的命令用一个自定义的 augroup 包起来,并在最开始用 autocmd! 重置一下,以避免重复修改 .vimrc 造成的 autocmd 重载多次。

具体的作法我放个图:

截图里还给了一个有用的设置,让从 Insert 模式下离开的时候没有延迟,Vim 默认的设置会有点迟钝的感觉。

#14 楼 @nightire 赞,每回都能从你的文字中学到好东西。

#16 楼 @guyanbiao 截图里的字体?Source Code Pro

#14 楼 @nightire 确实会导致其他插件失效,还是用"*p方便点

19 楼 已删除

#18 楼 @lovejoy 嗯,是的,这是因为 paste 会导致 formatoptions 被清空,所以所有的格式化选项都没有了(所以才能不影响外部复制进来的文字)。

因此 "*p 是终极选项。在实际中,我也是用了 nnoremap <D-v> "*p 的。

简单实在空格 p

let mapleader=" "
map <leader>p "*p

赞一个,我也被困扰很久,每次都是粘贴以后自己再格式化一下

顶!!!我的x键有救了

楼主,可不可以解释一下这两行的作用

nnoremap <F2> :set invpaste paste?<CR>
imap <F2> <C-O>:set invpaste paste?<CR>

#24 楼 @JohnLu 第一行的作用是在命令模式下,按 F2 会在状态栏显示 paste 第二行的作用是在 insert 模式下,按 F2 会在状态栏显示 paste

http://vimdoc.sourceforge.net/htmldoc/options.html :se[t] inv{option} Toggle option: Invert value. {not in Vi}

gg=G 不是最简单调整缩进的么

赞!学习新知识!

#21 楼 "*p +1 另外map <leader>y "*y 也挺方便的

mac 中的 vim 怎么使用系统剪切板啊?现在无法复制和粘贴 vim 以外的文字啊。

#12 楼 @lostleaf 特地打开电脑验证了以下,+是 clipboard 用于复制粘贴; *是 primary,用于选择

#14 楼 @nightire 这样 autoindent 就彻底废了阿

#24 楼 @JohnLu 明白了,谢谢!

#29 楼 @simlegate 如果你使用 terminal 中的 vim,可以加这一句到配置文件

" Use System Clipboard
if $TMUX == ''
  set clipboard+=unnamed
endif

#31 楼 @ensonmj 这个方法是用来大量复制外部内容时用的,本来就不需要 autoindent 捣乱,你可以把我的方法映射一个键来切换,于是当你需要不停地复制粘贴时就很管用了,并不是要一直使用它,特别是在编辑的时候肯定还是需要 autoindent 的。

终于解决了拷贝带来的副作用

👍 ,默默地感谢

我能说我基本没用 vim 吗?看到这个,感觉大家都用这个样,,伤心了。。

#38 楼 @small_fish__ 我也是,没用 vim。。。但是大家回复都说好。。。我也伤心了。。。

之前都是手动用 = 调整的笨孩子感谢 lz 分享。。

#11 楼 @i5ting 直接插入模式下 粘贴 的问题是,如果插件里有能自动补全引号括号这样的功能的话,粘贴之后整段文本就混乱了,gg=G 也没用了

感谢 lz 啊,解决困扰好久的问题。

好东西啊。。谢谢。。

第一次回复,感谢楼主。

@Vincent178 问个弱弱的问题。。假如我复制的时候。源文件都是 tab 空格的。但是复制到另外的文件中的时候为啥变成 space 空格了。。有没有好的办法解决啊。。复制到另外的文件的时候还是 tab 空格。。

#46 楼 @sven 你需要把你的 vim 调整成 tab 空格,具体设置可以参考这样

set autoindent
set noexpandtab
set tabstop=4
set shiftwidth=4

@Vincent178 嗯我试试。。thks

@Vincent178 貌似不行~~

#49 楼 @sven 你复制的时候需要在 insert 模式下

@Vincent178 是的已经在 insert 模式下。。但是复制带有 tab 空格的行。粘贴后仍变成 space 空格了。。

#51 楼 @sven 把你的配置文件贴一下

53 楼 已删除

@Vincent178 别见笑。所有的配置。。感觉跟你们比弱爆了。。 filetype plugin on syntax enable syntax on colorscheme desert nnoremap :set invpaste paste? imap :set invpaste paste? set pastetoggle= set autoindent set noexpandtab set tabstop=4 set shiftwidth=4

@Vincent178 不知道。我复制过去的时候仍是 space。。。。而不是 tab。。。我再看看

vim7.4 发布了,升级一下吧。看一下你编辑后的版本 (vim --version),如果包含+clipboard(其它都请当作背景):

+clipboard       +iconv           +path_extra      -toolbar
+cmdline_compl   +insert_expand   -perl            +user_commands

然后在.vimrc 里设置

set clipboard=unnamed

就可以正常写入读取 cliboard 了。

不错哦,解决了困扰我好长时间的问题。

59 楼 已删除
nightire 回复

求 vim 主题

akai76 回复

抱歉,年代太久远了,我记不得了,如果我眼神不错,这个应该是 Tomorrow 里的一款。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号