Closed uwla closed 1 month ago
Hey @uwla glad you liked the project! Yes that workflow you explained is a great example of tssorters use case, and reducing keystrokes in (n)vim is always great 😄
To answer your question: Yes I do plan on continuing to support the plugin, specially since I use it in my day to day as well! A few things of the things I'm working on:
I also created the plugin as a proof of concept and wanted to let the plugin "simmer" to see how people were using it and also seeing if there were any crazy bugs I didn't take into account. Once I get these things out of the way it should make things much smoother, so I do appreciate the patience!
I saw you posted the issue in the other thread which I pushed a fix for. I'm closing this issue for now but feel free to reopen it or create another issue in case something else comes up, thanks!
The third point is great!
Is it possible to make the plugin accept a lua function to compare the nodes to be sorted? The function would take two treesitter nodes, have read access to all their properties/attributes, and then return -1,0,1 (-1 means less, 0 equality, 1 greater).
Something like:
cmp_fn = function(nodeA, nodeB)
return calcVal(nodeA.attrX) - calcVal(nodeB.attrX)
end
That would allow, for example
id
-> classes
-> name
-> ...
-> placeholder
-> data-
,display
-> position
-> margin
-> padding
-> ...
-> text-decoration
-> ...
package.json
: name
-> author
-> url
-> ...
docker-compose
: services
-> volumes
-> networks
-> ...
The possibilities are endless... Basically, it would be possible to create rules to sort not based on a number or string, but upon relevant rules from some coding standard agreed upon developers within a team
I took a brief look into the source code and found out exactly what I was looking for.
You use the function in opts
or a default one as the order_by
sorting function:
--- Returns the retrieved lines in a sorted order
---@param nodes TSNode[]
---@param opts SorterOpts | SortableOpts
---@return string[]
local function get_sorted_lines(nodes, opts)
local order_by = opts.order_by or default_sort
The format of the function is as I expected:
--- Default sort function simply sorts the text alphabetically
---@param node1 TSNode
---@param node2 TSNode
---@return boolean # Return true if the node1 comes before node2
local function default_sort(node1, node2)
local line1 = tshelper.get_text(node1)
local line2 = tshelper.get_text(node2)
return line1 < line2
end
So, @mtrajano , I would suggest add some option like cmp_fn
to be passed to setup({})
:
require("tssorter").setup({
---@param node1 TSNode
---@param node2 TSNode
---@param tshelper TSHelper
cmp_fn = function(a, b, tshelper)
val_1 = tshelper.get_someval(a)
val_2 = tshelper.get_someval(b)
return val_1 < val_2
-- or maybe
return val_1 - val_2
end
})
The tshelper
is passed as third argument in order for the plugin
user to be able to get relevant information from the nodes without importing tshelper
in their lua config.
I could make a PR but I would instructions because I have no clue about how to develop lua
plugins or how they work... and I only code in lua
to rice nvim
and yazi
@uwla You should already be able to do this with the current implementation. The opts for a sortable does take in an order_by
key with 2 params (node1, node2) as you mentioned: https://github.com/mtrajano/tssorter.nvim/blob/main/lua/tssorter/sorter.lua#L42. It's possible the docs around this feature aren't super clear so if you have an idea on how to improve that I'm open to it.
So your config for a sortable could be something like:
{
node = 'some_int_node',
order_by = function(node1, node2)
local num1 = tshelper.get_text(node1)
local num1 = tshelper.get_text(node2)
-- randomly sort number nodes
return tonumber(num1) * math.random() < tonumber(num2) * math.random()
end
}
Let me know if that's what you meant or if you had something else in mind. node1
and node2
are just TSNodes so you could theoretically do anything with it, including looking for nested nodes and sorting based on that. The ordinal stuff I'm working on will hopefully make that a lot easier though through configuration.
@uwla Just pushed some changes adding the ability to sort by inner nodes, here's a more complex example making use of that order by function to sort norg tasks by a specific order: https://github.com/mtrajano/tssorter.nvim/blob/main/lua/tssorter/config.lua#L73
Hi, thanks for the answer and sorry for the delay.
Your example was very helpful and it is clear now what can be done and how.
I want to write custom sorters, I just hadn't the time yet, but with your examples it will be easy I guess!
This plugin can be very powerful since we can use custom sorters for any treesitter nodes!
This project looks awesome! I've been looking for something like this for a while.
In order to keep files organized I usually sort HTML attributes, CSS properties, JSON keys, etc, by splitting them into multiple lines (using
splitjoin.vim
) them sort them applyvim_sort_motion
usinginner indentation
textobj, them join them again. But this is too much manual work... So, I loved this project!I saw there is a project roadmap. Do you plan to keep improving the project?