re-write sort function
This commit is contained in:
		
							parent
							
								
									0834c03385
								
							
						
					
					
						commit
						cba016ebfb
					
				@ -5,67 +5,117 @@
 | 
				
			|||||||
-- telescope window to search through all available module names, enter inserts, other key opens doc in split
 | 
					-- telescope window to search through all available module names, enter inserts, other key opens doc in split
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local ts_utils = require("nvim-treesitter.ts_utils")
 | 
					local ts = require('nvim-treesitter.parsers')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local M = {}
 | 
					local M = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
M.example = function()
 | 
					M.example = function()
 | 
				
			||||||
    local lines = {}
 | 
					    local bufnr = vim.api.nvim_get_current_buf()
 | 
				
			||||||
 | 
					    local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
 | 
				
			||||||
 | 
					    local parser = ts.get_parser(bufnr, 'yaml')
 | 
				
			||||||
 | 
					    local tree = parser:parse()[1]
 | 
				
			||||||
 | 
					    local root = tree:root()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    -- TOOD
 | 
					    local objects = {}
 | 
				
			||||||
    -- correctly handle comments
 | 
					 | 
				
			||||||
    -- removing all empty lines is back for raw blocks
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    -- remove all whitespace, we will create new blocks separated by empty lines after
 | 
					 | 
				
			||||||
    local last_search = vim.fn.getreg('/')
 | 
					 | 
				
			||||||
    vim.api.nvim_command('g/^$/d')
 | 
					 | 
				
			||||||
    vim.fn.setreg('/', last_search)
 | 
					 | 
				
			||||||
    local current_line_nr = 1
 | 
					    local current_line_nr = 1
 | 
				
			||||||
    local buf_handle = vim.api.nvim_win_get_buf(0)
 | 
					    while current_line_nr <= #lines do
 | 
				
			||||||
    local last_line_nr = vim.api.nvim_buf_line_count(buf_handle)
 | 
					        local line = lines[current_line_nr]
 | 
				
			||||||
    while (current_line_nr <= last_line_nr) do
 | 
					
 | 
				
			||||||
        vim.api.nvim_win_set_cursor(0, {current_line_nr, 1})
 | 
					        -- print('current_line_nr', current_line_nr)
 | 
				
			||||||
        local node = ts_utils.get_node_at_cursor(0)
 | 
					        -- print('line', line)
 | 
				
			||||||
        local parent = node:parent()
 | 
					
 | 
				
			||||||
        while (parent ~= nil and node:type() ~= 'block_mapping_pair') do
 | 
					        if not line or line:match("^%s*$") then
 | 
				
			||||||
            node = parent
 | 
					            -- print('empty line, continuing')
 | 
				
			||||||
            parent = node:parent()
 | 
					            current_line_nr = current_line_nr + 1
 | 
				
			||||||
 | 
					            goto continue
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
        local start_row, start_column, end_row, end_column = node:range()
 | 
					 | 
				
			||||||
        -- print('start_row=', start_row)
 | 
					 | 
				
			||||||
        -- print('end_row=', end_row)
 | 
					 | 
				
			||||||
        -- print('line:', vim.inspect(vim.fn.getline(start_row + 1, end_row + 1)))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        lines[current_line_nr] = vim.fn.getline(start_row + 1, end_row + 1)
 | 
					        -- if line:match("^%s*#") then
 | 
				
			||||||
 | 
					        --     -- print('comment, continuing')
 | 
				
			||||||
 | 
					        --     -- todo - how? they are currently part of the nodes, but the previous one - if anything i want them to stick to the next one
 | 
				
			||||||
 | 
					        --     current_line_nr = current_line_nr + 1
 | 
				
			||||||
 | 
					        --     goto continue
 | 
				
			||||||
 | 
					        -- end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        current_line_nr = current_line_nr + 1 + (end_row - start_row)
 | 
					        local node = root:named_descendant_for_range(current_line_nr-1, 0, current_line_nr-1, #line)
 | 
				
			||||||
 | 
					        if node and (node:type() == 'block_mapping_pair') then
 | 
				
			||||||
 | 
					            -- local node_lines = vim.treesitter.get_node_text(node, bufnr) -- not using, returns string, we want a table
 | 
				
			||||||
 | 
					            local start_row, _, end_row, _ = node:range()
 | 
				
			||||||
 | 
					            local node_lines = vim.api.nvim_buf_get_lines(bufnr, start_row, end_row + 1, false)
 | 
				
			||||||
 | 
					            -- print('line', line)
 | 
				
			||||||
 | 
					            -- print('node type', node:type())
 | 
				
			||||||
 | 
					            -- print('node range', node:range())
 | 
				
			||||||
 | 
					            -- print('node lines', node_lines)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            table.insert(objects, {
 | 
				
			||||||
 | 
					                sort_line = line,
 | 
				
			||||||
 | 
					                lines = node_lines,
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            -- set current line to the next line after the node's end, and accouting for 0-indexing
 | 
				
			||||||
 | 
					            current_line_nr = end_row + 2
 | 
				
			||||||
 | 
					            goto continue
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        -- do not get stuck on lines that do not match above
 | 
				
			||||||
 | 
					        print('did not match the line, node type: ', node:type(), ', line: ', line)
 | 
				
			||||||
 | 
					        -- insert it anyway, we do not want to loose lines
 | 
				
			||||||
 | 
					        table.insert(objects, {
 | 
				
			||||||
 | 
					            sort_line = line,
 | 
				
			||||||
 | 
					            lines = {line},
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        current_line_nr = current_line_nr + 1
 | 
				
			||||||
 | 
					        ::continue::
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    -- sort does not work if the index is not a continuous integer, so lets make sure it is. if we are sure that we dont need the original line number, we can do this from the start in `lines`
 | 
					    -- print(vim.inspect(objects))
 | 
				
			||||||
    a = {}
 | 
					 | 
				
			||||||
    for i,v in pairs(lines) do table.insert(a, v) end
 | 
					 | 
				
			||||||
    table.sort(
 | 
					    table.sort(
 | 
				
			||||||
        a,
 | 
					        objects,
 | 
				
			||||||
        function(k1, k2)
 | 
					        function(k1, k2)
 | 
				
			||||||
            return k1[1] < k2[1]
 | 
					            return k1.sort_line < k2.sort_line
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    -- print(vim.inspect(a))
 | 
					    -- print(vim.inspect(objects))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    insert_row = 1
 | 
					    -- clear the buffer
 | 
				
			||||||
    last_prefix = vim.split(a[1][1], '__')[1]
 | 
					    vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {})
 | 
				
			||||||
    for _, lines in ipairs(a) do
 | 
					
 | 
				
			||||||
        current_prefix = vim.split(lines[1], '__')[1]
 | 
					    -- flatten sorted objects into lines and insert back into the buffer
 | 
				
			||||||
        if current_prefix ~= last_prefix then
 | 
					    local sorted_lines = {}
 | 
				
			||||||
            vim.fn.setline(insert_row, '')
 | 
					    local last_prefix = nil
 | 
				
			||||||
            insert_row = insert_row + 1
 | 
					    for _, obj in ipairs(objects) do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        -- if the prefix switches, insert an empty line before the lines
 | 
				
			||||||
 | 
					        local split_line = vim.split(obj.sort_line, '__')
 | 
				
			||||||
 | 
					        -- if we only get one element back this means the line does not contain '__'
 | 
				
			||||||
 | 
					        -- lets try splitting on '_'
 | 
				
			||||||
 | 
					        -- else the fallback is the whole line
 | 
				
			||||||
 | 
					        if #split_line <= 1 then
 | 
				
			||||||
 | 
					            split_line = vim.split(obj.sort_line, '_')
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
        last_prefix = current_prefix
 | 
					        local current_prefix = split_line[1]
 | 
				
			||||||
        for i, line in ipairs(lines) do
 | 
					        -- print('current_prefix', current_prefix)
 | 
				
			||||||
            vim.fn.setline(insert_row, line)
 | 
					        -- print('last_prefix', last_prefix)
 | 
				
			||||||
            insert_row = insert_row + 1
 | 
					
 | 
				
			||||||
 | 
					        if last_prefix == nil then
 | 
				
			||||||
 | 
					            -- handle the first line
 | 
				
			||||||
 | 
					            last_prefix = current_prefix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        elseif current_prefix ~= last_prefix then
 | 
				
			||||||
 | 
					            -- print('inserting newline')
 | 
				
			||||||
 | 
					            table.insert(sorted_lines, "")
 | 
				
			||||||
 | 
					            last_prefix = current_prefix
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        -- print('obj', vim.inspect(obj))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for _, line in ipairs(obj.lines) do
 | 
				
			||||||
 | 
					            table.insert(sorted_lines, line)
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    -- print('sorted_lines', vim.inspect(sorted_lines))
 | 
				
			||||||
 | 
					    vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, sorted_lines)
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user