Vim and Neovim pair single quotes ('
) in several useful ways. In particular:
'
vim generates another '
and places your cursor between the pair.'
s is treated as a text object that vim can operate on.The same behavior holds for back ticks (`) which vim pairs with a second back tick.
This is great; however, in some contexts a back tick should pair with a single quote rather than with a second back tick. My questions are:
In Latex opening double quotes are written using two backticks (``) rather than a double quote (") and are closed with two single quotes (''). In this case here the desired pairing would be two backticks and two single quotes with the cursor in the middle. Additionally, the text object should be the text between the set of backticks and the set of single quotes.
The csquotes package helpfully suggested below by Friedrich helps with the Latex case, but I'm interested in something that would address this more generally.
In Stata local macros and strings that include double quotes both use this pattern. A simple example:
local foo bar
di "`foo'"
generate one_dbl_quote = `"""'
This puts the string bar
into a local macro named foo
then prints the contents of foo
to the console, then creates a string variable holding a single double quote.
As it turns out, several answers of How can I treat LaTeX quotes as a text object? on Vi and Vim SE apply to this question as well.
I'll not try to replicate all of the answers here but the answer by user
superjer defines new mappings
for aq
and iq
text-objects (see :help text-objects
for more information). The answer is lightweight and
can easily be adapted to this question. It does have the caveat that it only works for single quotes and
only if the string is in one line which seems acceptable for Stata macros (not for LaTeX though).
To enable the mappings only for the stata
filetype (if the filetype is not
known, consider adding it using the instructions from :help new-filetype
), and create a ~/.vim/after/ftplugin/stata.vim
file like this:
vnoremap <buffer><silent> iq t'oT`
onoremap <buffer> iq <Cmd>normal viq<CR>
vnoremap <buffer><silent> aq f'oF`
onoremap <buffer> aq <Cmd>normal vaq<CR>
Or - a little bit less tidy - you could take a shortcut and just enable them via autocmd
based on file extension in your vimrc
:
augroup quotes-text-objects
autocmd!
autocmd BufNew,BufEnter *.dta vnoremap <buffer><silent> iq t'oT`
autocmd BufNew,BufEnter *.dta onoremap <buffer> iq <Cmd>normal viq<CR>
autocmd BufNew,BufEnter *.dta vnoremap <buffer><silent> aq f'oF`
autocmd BufNew,BufEnter *.dta onoremap <buffer> aq <Cmd>normal vaq<CR>
augroup END
Note that this uses <buffer>
mappings so they don't leak out to non-Stata
files.
Instead of using iq
and aq
, you might even decide to go crazy and overwrite the default operators i`
and a`
.
For strings spanning multiple lines, things get tricky fast. In that case, I'd suggest using a plugin such as the two mentioned in the linked question's answers: vim-sandwich or - for LaTeX specifically - textobj-latex.
If you like any of these suggestions, visit Vi and Vim SE and give the respective authors your upvote!