How can I quickly quote/unquote words and change quoting (e.g. from ' to ") in Vim? I know about the surround.vim plugin, but I would like to use just Vim.
How can I quickly quote/unquote words and change quoting (e.g. from ' to ") in Vim? I know about the surround.vim plugin, but I would like to use just Vim.
surround.vim is going to be your easiest answer. If you are truly set against using it, here are some examples for what you can do. Not necessarily the most efficient, but that's why surround.vim was written.
ciw'Ctrl+r"'
ciw - Delete the word the cursor is on, and end up in insert mode.' - add the first quote.Ctrl+r" - Insert the contents of the " register, aka the last yank/delete.' - add the closing quote.
di'hPl2x
di' - Delete the word enclosed by single quotes.hP - Move the cursor left one place (on top of the opening quote) and put the just deleted text before the quote.l - Move the cursor right one place (on top of the opening quote).2x - Delete the two quotes.
va':s/\%V'\%V/"/g
va' - Visually select the quoted word and the quotes.:s/ - Start a replacement.\%V'\%V - Only match single quotes that are within the visually selected region./"/g - Replace them all with double quotes.Here's some mapping that could help:
:nnoremap <Leader>q" ciw""<Esc>P
:nnoremap <Leader>q' ciw''<Esc>P
:nnoremap <Leader>qd daW"=substitute(@@,"'\\\|\"","","g")<CR>P
If you haven't changed the mapleader variable, then activate the mapping with \q" \q' or \qd. They add double quote around the word under the cursor, single quote around the word under the cursor, delete any quotes around the word under the cursor respectively.
In addition to the other commands, this will enclose all words in a line in double quotes (as per your comment)
:s/\(\S\+\)/"\1"/
or if you want to reduce the number of backslashes, you can put a \v (very-magic) modifier at the start of the pattern
:s/\v(\S+)/"\1"/
If you use the vim plugin https://github.com/tpope/vim-surround (or use VSCode Vim plugin, which comes with vim-surround pre-installed), its pretty convinient!
add
ysiw' // surround in word `'`
drop
ds' // drop surround `'`
change
cs'" // change surround from `'` to `"`
It even works for html tags!
cst<em> // change surround from current tag to `<em>`
check out the readme on github for better examples
For users of VSCodeVim, Neovim and Macvim, you can do
vwS"
" with whatever you would like to wrap by.w with any other selection operatorI don't know any builtin vim command for this, but using r"f'r" to change from ' to " and r'f"r' to change from " to ' works if you stand on the first ' or ". The command r' replaces whatever character is under your cursor with ', and f" moves you forward to the next ".
VIM for vscode does it awsomely. It's based one vim-surround if you don't use vscode.
Some examples:
"test" with cursor inside quotes type cs"' to end up with 'test'
"test" with cursor inside quotes type ds" to end up with test
"test" with cursor inside quotes type cs"t and enter 123> to end up with <123>test
test with cursor on word test type ysaw) to end up with (test)
wrap all words with quotes:
s/\(\w\+\)/"\1"/g
before:
aaa,bbb,ccc
after:
"aaa","bbb","ccc"
I am using the vim-surround command, almost vim in nature.
Surround.vim is all about "surroundings": parentheses, brackets, quotes, XML tags, and more. The plugin provides mappings to easily delete, change and add such surroundings in pairs.
Plugin 'tpope/vim-surround'
for example, To remove the delimiters entirely, press ds".
More details are here:
https://github.com/tpope/vim-surround
Visual mode map example to add single quotes around a selected block of text:
:vnoremap qq <Esc>`>a'<Esc>`<i'<Esc>
I wrote a script that does this:
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>
To use, just highlight something, hit control l, and then type a character. If it's one of the characters the function knows about, it'll provide the correct terminating character. If it's not, it'll use the same character to insert on both sides.
Surround.vim can do more than just this, but this was sufficient for my needs.