nvim-surround
nvim-surround copied to clipboard
Multi-character string delimiters
Checklist
- [x] Have you read through
:h nvim-surroundto 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.