nvim-surround
nvim-surround copied to clipboard
Multi-character string delimiters
Checklist
- [x] Have you read through
:h nvim-surround
to see if there might be any relevant information there?
Is your feature request related to a problem? Please describe.
Several languages support strings that use multiple characters as delimiters.
- C#:
"""string"""
- Kotlin:
"""string"""
- Python:
"""string"""
or'''string'''
- Groovy:
"""string"""
or'''string'''
or$/string/$
- Lua:
[[string]]
or[=[string]=]
(any number of=
) - Rust:
##string##
(any number of#
) - Java
``string``
(any number of`
)
Describe the solution you'd like
It'd be nice if we could change single-character delimited strings to multi-character and vice versa.
Additional context
Some languages also support prefixes but that would probably be too complicated.
- C#:
@"string"
or$"string"
(any supported delimiter, can be mixed, any number of$
) - Python:
b"string"
orr"string"
orf"string"
(any supported delimiter, can be mixed) - Rust:
b"string"
orr"string"
(any supported delimiter, can be mixed) - Bash:
$'string'
(any supported delimiter) - JavaScript:
String.raw`string`
(prefix can be any function)
To my knowledge (if I'm understanding correctly) this should already be possible in the plugin. It's certainly not the most elegant, but here's a code sample for Lua strings:
require("nvim-surround").setup({
surrounds = {
["s"] = {
add = function()
local count = require("nvim-surround.config").get_input("Enter a count: ")
return { { "[" .. ("="):rep(count) .. "[" }, { "]" .. ("="):rep(count) .. "]" } }
end,
find = "%[(=*)%[.-%]%1%]",
delete = "^(%[=*%[)().-(%]=*%])()$",
},
},
aliases = {
["s"] = false,
},
})
The other ones that you mentioned should also be possible, through a mix of using config.get_input()
and good Lua pattern-matching.
I guess this could also be implemented using counts like #147. It would have to support two counts, one for selecting and one for replacing.
For example:
-
cs"2] would change
"string"
to[[string]]
. -
2cs#" would change
##string##
to"string"
-
3cs'3" would change
'''string'''
to"""string"""
.
(The first count could come either before or after cs
, whichever you think makes more sense.)
Workarounds for $/string/$
and [=[string]=]
which can't be implemented that way:
-- add this to init.lua because it's not built-in
vim.keymap.set({'o', 'x'}, 'a/', ':<C-U>normal F/vf/<CR>', {silent = true})
-
cs'/ysa/$ would change
'string'
to$/string/$
-
cs'2]ysa]= would change
'string'
to[=[string]=]
-
cs"2]ysa]2= would change
"string"
to[==[string]==]
Going to close this issue in favor of #147, which seems to be a good implementation strategy for this idea.