如何在 Vim 中快速引用/取消引用单词并更改引用(例如从'
to )?"
我知道环绕.vim 插件,但我只想使用 Vim。
18 回答
环绕.vim 将是您最简单的答案。如果你真的反对使用它,这里有一些你可以做的例子。不一定是最有效的,但这就是编写环绕.vim 的原因。
- 引用一个单词,使用单引号
ciw'Ctrl+r"'
ciw
- 删除光标所在的单词,并以插入模式结束。'
- 添加第一个报价。Ctrl+r"
- 插入"
寄存器的内容,也就是最后的 yank/delete。'
- 添加结束语。
- 取消引用单引号中的单词
di'hPl2x
di'
- 删除单引号括起来的单词。hP
- 将光标向左移动一位(在开头引号的顶部)并将刚刚删除的文本放在引号之前。l
- 将光标向右移动一位(在开头引号的顶部)。2x
- 删除两个引号。
- 将单引号改为双引号
va':s/\%V'\%V/"/g
va'
- 直观地选择引用的单词和引号。:s/
- 开始更换。\%V'\%V
- 仅匹配视觉选择区域内的单引号。/"/g
- 将它们全部替换为双引号。
引用一个单词,使用单引号
ciw'Ctrl+r"'
这样做对我来说更容易
ciw '' Esc P
以下是一些可能有所帮助的映射:
:nnoremap <Leader>q" ciw""<Esc>P
:nnoremap <Leader>q' ciw''<Esc>P
:nnoremap <Leader>qd daW"=substitute(@@,"'\\\|\"","","g")<CR>P
如果您尚未更改 mapleader 变量,则使用\q"
\q'
或激活映射\qd
。他们在光标下的单词周围添加双引号,在光标下的单词周围添加单引号,分别删除光标下的单词周围的任何引号。
宏观方式!
按q和q录制到 q 寄存器(我们使用“q”作为记住“引号”的快捷方式)。
按shift+b将光标移动到当前单词的前面
按i类型'(单引号)
按esc然后按e移动到词尾
按a然后再按'以用引号括住单词。
按esc进入正常模式。
最后按q将其记录到
q
寄存器中。
如何使用
- 将光标移动到所需的单词。
- 按下@q以用引号将单词括起来。
- @@如果您想将它重复成另一个单词,请按。
您可以更改step 4
任何您喜欢的内容{一行、一个单词直到找到某个字符等}。
使录制的宏持久化
- 打开.vimrc
- 转到文件末尾
- 更改为插入模式。键入它以使其持久化:
让@q=' ctrl+ r ctrl+ rq'
保存并退出
打开你的文件,去一些词
现在按
@q
如果你做得对,神奇的东西应该会出现在你的话中。
您可以将此应用于您喜欢的其他宏。
除了其他命令之外,这会将所有单词用双引号括在一行中(根据您的评论)
:s/\(\S\+\)/"\1"/
或者如果你想减少反斜杠的数量,你可以\v
在模式的开头放置一个(非常神奇的)修饰符
:s/\v(\S+)/"\1"/
如果你使用 vim 插件https://github.com/tpope/vim-surround(或使用预装 vim-surround 的 VSCode Vim 插件),它非常方便!
添加
ysiw' // surround in word `'`
降低
ds' // drop surround `'`
改变
cs'" // change surround from `'` to `"`
它甚至适用于 html 标签!
cst<em> // change surround from current tag to `<em>`
查看 github 上的自述文件以获得更好的示例
用单引号括起来(例如)ciw'<C-r>"'<esc>
有效,但重复不起作用。尝试:
ciw'<C-r><C-o>"'<esc>
这会将默认寄存器的内容“按字面意思”放置。现在您可以按下.
任何单词以将其括在引号中。要了解:h[elp] i_ctrl-r
更多关于文本对象的信息,请访问:h text-objects
对于 VSCodeVim、Neovim 和 Macvim 的用户,你可以这样做
vwS"
- 你可以
"
用任何你想包装的东西来代替。 - 您可以
w
用任何其他选择运算符替换
我不知道任何内置的 vim 命令,但是如果你站在第一个 ' 或 " 上,使用r"f'r"
to change from ' to " and to change from " to ' 工作。该命令将光标下的任何字符替换为 ',并让您前进到下一个“。r'f"r'
r'
f"
添加报价
我开始在我的.vimrc
:
vnoremap q <esc>:call QuickWrap("'")<cr>
vnoremap Q <esc>:call QuickWrap('"')<cr>
function! QuickWrap(wrapper)
let l:w = a:wrapper
let l:inside_or_around = (&selection == 'exclusive') ? ('i') : ('a')
normal `>
execute "normal " . inside_or_around . escape(w, '\')
normal `<
execute "normal i" . escape(w, '\')
normal `<
endfunction
所以现在,我在引号中直观地选择我想要的任何内容(通常是通过viw
-在 word中视觉选择),然后按Q双引号,或按q单引号。
删除引号
vnoremap s <esc>:call StripWrap()<cr>
function! StripWrap()
normal `>x`<x
endfunction
我使用vim-textobj-quotes以便 vim 将引号视为文本对象。这意味着我可以vaq
(在引号周围进行视觉选择。这会找到最近的引号并在视觉上选择它们。(这是可选的,您可以执行类似的操作f"vww
)。然后我按下s
以从选择中删除引号。
更改报价
吻。我删除引号,然后添加引号。例如,要将单引号替换为双引号,我将执行以下步骤: 1. 删除单引号:vaqs
, 2. 添加新引号:vwQ
。
- http://vim.wikia.com/wiki/Wrap_a_visual_selection_in_an_HTML_tag这里的代码被修改并用作我的答案的一部分
- https://github.com/beloglazov/vim-textobj-quotes vim-text-obj-quotes
以下是一些可用于引用和取消引用单词的简单映射:
" 'quote' a word
nnoremap qw :silent! normal mpea'<Esc>bi'<Esc>`pl
" double "quote" a word
nnoremap qd :silent! normal mpea"<Esc>bi"<Esc>`pl
" remove quotes from a word
nnoremap wq :silent! normal mpeld bhd `ph<CR>
用于 vscode 的 VIM做得非常好。如果您不使用 vscode ,它基于一个vim-surround 。
一些例子:
“测试”,光标在引号内,类型 cs”” 以“测试”结尾
带有引号的“测试”类型 ds” 以测试结束
"test" 光标在引号内键入 cs"t 并输入 123> 以结束 <123>test
用光标在单词测试类型 ysaw 上进行测试以结束 (test)
用引号括起所有单词:
s/\(\w\+\)/"\1"/g
前:
aaa,bbb,ccc
后:
"aaa","bbb","ccc"
我正在使用vim-surround
命令,本质上几乎是 vim。
Surround.vim 是关于“环境”的:圆括号、方括号、引号、XML 标签等等。该插件提供映射以轻松地成对删除、更改和添加此类环境。
Plugin 'tpope/vim-surround'
例如,要完全删除分隔符,请按ds"
。更多细节在这里:
https ://github.com/tpope/vim-surround
我在我的 .vimrc 中使用了 nnoremap
单引号一个词:
nnoremap sq :silent! normal mpea'<Esc>bi'<Esc>`pl
要删除引号(也适用于双引号):
nnoremap qs :silent! normal mpeld bhd `ph<CR>
要记住的规则:'sq' = 单引号。
在选定的文本块周围添加单引号的可视模式映射示例:
:vnoremap qq <Esc>`>a'<Esc>`<i'<Esc>
这个怎么样?
:%s/\'/"/g
我写了一个脚本来做到这一点:
function! WrapSelect (front)
"puts characters around the selected text.
let l:front = a:front
if (a:front == '[')
let l:back = ']'
elseif (a:front == '(')
let l:back = ')'
elseif (a:front == '{')
let l:back = '}'
elseif (a:front == '<')
let l:back = '>'
elseif (a:front =~ " ")
let l:split = split(a:front)
let l:back = l:split[1]
let l:front = l:split[0]
else
let l:back = a:front
endif
"execute: concat all these strings. '.' means "concat without spaces"
"norm means "run in normal mode and also be able to use \<C-x> characters"
"gv means "get the previous visual selection back up"
"c means "cut visual selection and go to insert mode"
"\<C-R> means "insert the contents of a register. in this case, the
"default register"
execute 'norm! gvc' . l:front. "\<C-R>\"" . l:back
endfunction
vnoremap <C-l> :<C-u>call WrapSelect(input('Wrapping? Give both (space separated) or just the first one: '))<cr>
要使用,只需突出显示某些内容,点击 control l,然后键入一个字符。如果它是函数知道的字符之一,它将提供正确的终止字符。如果不是,它将使用相同的字符插入两侧。
Surround.vim 可以做的远不止这些,但这足以满足我的需要。