Closed andrewferrier closed 2 years ago
Agreed I can't think of a good usecase right now either (!), but it seems very interesting in principle and could open up some creativity. Maybe some cleverness with treesitter, if the object surrounded is known to be of a particular type, that could affect the surrounding.
I think this issue is definitely less essential though, from my personal perspective at least.
@andrewferrier I've implemented it in the latest commit. The argument that's passed into the function is going to be an array of strings, where each string represents a line. For example, if |
demarcates the selection, then
ab|cde
fghi|j
would be represented as { "cde", "fghi" }
. I tested it out with a basic buffer-local option:
-- ftplugin/cpp.lua
require("nvim-surround").buffer_setup({
delimiters = {
pairs = {
["c"] = function(text)
-- If the surrounded text is one line consisting of all digits
if #text == 1 and text[1]:match("^%d+$") then
return { "to_string(", ")" }
end
return { "stoi(", ")" }
end,
}
}
})
Surrounding numbers using c
will wrap the number in to_string(text)
, while anything else will be wrapped in stoi(text)
.
I've updated the README video with some of the new features, let me know if there's anything you feel I'm missing that should be emphasized more
Nice! That change looks really good. Might be good to show your stoi()
example in the README to show people one way that feature could be used. Otherwise looks pretty good right now!
@kylechui I might be polishing the nosecone here a little, but in terms of providing a complete "API" for someone implementing this custom function, I wonder if it would be worth providing the start and end positions (row and col) too, as well as the buffer number? That enables the person implementing the pair to use other vim functions to look stuff up, check for treesitter objects, etc. if they wanted.
@andrewferrier This has been amended in the latest commit. The new API is that a table args
is now passed to the function, which has the following keys:
text
: table of strings, contains a string per line of the buffer that is selectedbufnr
: number, contains the buffer number where the surround is calledselection
: table with two keys first_pos
and last_pos
, each of which is a pair representing a row, col pair for the beginning and end of the selectionI documented this a little bit in :h nvim-surround
Edit: Merging this into main, as using an args
table should mean that the API is stable, and all of the current tests are passing.
Nice! I'm still struggling to think of some good use cases right now but I'm sure there will be some... this is a really nice generalized capability that hopefully folks can use creatively.
@andrewferrier This doesn't use the args
table, but I think is pretty cool for C++ files. It basically just adds std::
if you aren't using the standard namespace for printing:
["p"] = function()
for _, line in ipairs(vim.api.nvim_buf_get_lines(0, 0, -1, false)) do
print(line)
if line == "using namespace std;" then
return { "cout << ", " << endl;" }
end
end
return { "std::cout << ", " << std::endl;" }
end,
That way you can quickly surround a line in a print statement with yssp
.
I still don't know enough about TreeSitter nor LSP to meaningfully "hook into them", but yeah hopefully some smarter people can come along and figure that out haha.
Edit: Honestly at this point this is almost reminding me of a snippet engine, perhaps we can borrow a few ideas from there... :eyes:
Nice! I don't write C++ but I understand the basic principle. Great plugability... worth highlighting this when you advertise the plugin, I would suggest.
@andrewferrier Hi again! I am now one day older, and one day wiser, and have learned how to use TreeSitter (somewhat). Here's an example of using different surrounds for different fenced code blocks in a markdown file:
However, this still doesn't actually make use of the args
table that this feature provides; I might consider removing it after a while if there aren't any applications of it. If you're curious, here's the corresponding configuration code (it's a bit much):
Yeah, that's really interesting! It's get_node_at_cursor()
that really unlocks the magic here, I guess. What I like about this is that even though the surrounds are still fairly simple, you are able to make them language dependent.
Understand about the args
table. Personally I think it probably still allows for some magic, but I'm not the one who has to maintain it. I would still leave it a while and see if anyone does anything with it.
It might be worth another post on reddit etc. highlighting some of the "customizability" you've added to get folks' creative juices flowing...
Yep, I was planning on making another post soon-ish to really show off all of the new features/configuration that I've added since 2 weeks ago, I'll also maybe open a discussion post about it to see if people have any ideas there.
@andrewferrier Probably going to remove this feature with the advent of pattern-based surrounds since to my knowledge nobody has found any use for it whatsoever, and the extra bloat was annoying me haha (commit).
All good :)
As per the idea here: https://github.com/kylechui/nvim-surround/issues/27#issuecomment-1178793314.