this repo has no description

Revamp selection, split into `select`, `select_verbatim`, `select_all`.

The first and last one takes plus sections, rather than the legacy
behavior of taking the section as is, even if it is a diff section.

+150 -15
+70 -9
lua/vcmarkers/actions.lua
··· 1 local M = {} 2 3 local markers = require "vcmarkers.markers" 4 local highlight = require "vcmarkers.highlight" 5 6 ---@param bufnr number Buffer number. ··· 109 end 110 end 111 112 ---@param bufnr integer The buffer number. 113 - function M.select_section(bufnr) 114 - local lnum = vim.fn.line "." 115 local diff_markers = vim.b[bufnr].vcmarkers_markers 116 local marker = markers.cur_marker(lnum, diff_markers) 117 if not marker then ··· 120 vim.log.levels.WARN, 121 { title = "VCMarkers" } 122 ) 123 - return 124 end 125 126 - local section = markers.current_section(marker, lnum) 127 if not section then 128 vim.notify( 129 "No section under cursor", 130 vim.log.levels.WARN, 131 { title = "VCMarkers" } 132 ) 133 - return 134 end 135 136 - -- Could check that the section is actually a "plus" section, 137 - -- but let's trust the user for now. 138 vim.api.nvim_buf_set_lines( 139 bufnr, 140 marker.start_line, 141 marker.end_line, 142 true, 143 - section.lines 144 ) 145 - vim.api.nvim_win_set_cursor(0, { marker.start_line + 1, 0 }) 146 end 147 148 --- Convert markers to a different format.
··· 1 local M = {} 2 3 local markers = require "vcmarkers.markers" 4 + local marker_format = require "vcmarkers.marker_format" 5 local highlight = require "vcmarkers.highlight" 6 7 ---@param bufnr number Buffer number. ··· 110 end 111 end 112 113 + ---@class MarkerContext 114 + ---@field marker? Marker The marker under the cursor, if any. 115 + ---@field section? Section The section under the cursor, if any. 116 + ---@field section_index? integer The index of the section under the cursor, if any. 117 + 118 ---@param bufnr integer The buffer number. 119 + ---@param lnum integer The line number. 120 + ---@return MarkerContext 121 + local function _get_marker_context(bufnr, lnum) 122 local diff_markers = vim.b[bufnr].vcmarkers_markers 123 local marker = markers.cur_marker(lnum, diff_markers) 124 if not marker then ··· 127 vim.log.levels.WARN, 128 { title = "VCMarkers" } 129 ) 130 + return {} 131 end 132 133 + local index, section = markers.current_section(marker, lnum) 134 if not section then 135 vim.notify( 136 "No section under cursor", 137 vim.log.levels.WARN, 138 { title = "VCMarkers" } 139 ) 140 + return { marker = marker } 141 end 142 + return { 143 + marker = marker, 144 + section = section, 145 + section_index = index, 146 + } 147 + end 148 149 + --- Replace the lines of a marker with the given lines. 150 + --- @param bufnr integer The buffer number. 151 + --- @param marker Marker The marker to replace. 152 + --- @param lines string[] The lines to replace with. 153 + --- @param move_cursor boolean Whether to move the cursor to the start of the marker after replacing. 154 + local function _replace_marker(bufnr, marker, lines, move_cursor) 155 vim.api.nvim_buf_set_lines( 156 bufnr, 157 marker.start_line, 158 marker.end_line, 159 true, 160 + lines 161 ) 162 + if move_cursor then 163 + -- Put cursor at a predictable place, at the start line of marker. 164 + vim.api.nvim_win_set_cursor(0, { marker.start_line + 1, 0 }) 165 + end 166 + end 167 + 168 + ---@param bufnr integer The buffer number. 169 + function M.select_section_verbatim(bufnr) 170 + local lnum = vim.fn.line "." 171 + local ctx = _get_marker_context(bufnr, lnum) 172 + if not ctx.marker or not ctx.section then 173 + return 174 + end 175 + _replace_marker(bufnr, ctx.marker, ctx.section.lines, true) 176 + end 177 + 178 + ---@param bufnr integer The buffer number. 179 + function M.select_section_plus(bufnr) 180 + local lnum = vim.fn.line "." 181 + local ctx = _get_marker_context(bufnr, lnum) 182 + if not ctx.marker or not ctx.section_index then 183 + return 184 + end 185 + 186 + local plus_sections = marker_format.plus_sections(ctx.marker) 187 + local section = plus_sections[ctx.section_index] 188 + _replace_marker(bufnr, ctx.marker, section.lines, true) 189 + end 190 + 191 + -- For backward compatibility. 192 + M.select_section = M.select_section_verbatim 193 + 194 + ---@param bufnr integer The buffer number. 195 + function M.select_all(bufnr) 196 + local lnum = vim.fn.line "." 197 + local ctx = _get_marker_context(bufnr, lnum) 198 + if not ctx.marker then 199 + return 200 + end 201 + local plus_sections = marker_format.plus_sections(ctx.marker) 202 + local all_lines = {} 203 + for _, section in ipairs(plus_sections) do 204 + vim.list_extend(all_lines, section.lines) 205 + end 206 + _replace_marker(bufnr, ctx.marker, all_lines, true) 207 end 208 209 --- Convert markers to a different format.
+3 -1
lua/vcmarkers/init.lua
··· 30 stop = _no_args(M.actions.stop), 31 prev_marker = _with_count(M.actions.prev_marker), 32 next_marker = _with_count(M.actions.next_marker), 33 - select = _no_args(M.actions.select_section), 34 fold = _no_args(M.fold.toggle), 35 cycle = _no_args(M.actions.cycle_marker), 36 }
··· 30 stop = _no_args(M.actions.stop), 31 prev_marker = _with_count(M.actions.prev_marker), 32 next_marker = _with_count(M.actions.next_marker), 33 + select = _no_args(M.actions.select_section_plus), 34 + select_all = _no_args(M.actions.select_all), 35 + select_verbatim = _no_args(M.actions.select_section_verbatim), 36 fold = _no_args(M.fold.toggle), 37 cycle = _no_args(M.actions.cycle_marker), 38 }
+12
lua/vcmarkers/marker_format.lua
··· 323 end 324 end 325 326 --- Cycle the marker format. 327 ---@param jj_marker Marker 328 ---@return Marker
··· 323 end 324 end 325 326 + ---Return only the plus sections of a marker. 327 + ---@param marker Marker 328 + ---@return Side[] 329 + function M.plus_sections(marker) 330 + local sides, _ = _deconstruct_marker(marker) 331 + local plus_sides = {} 332 + for i = 1, #sides, 2 do 333 + plus_sides[#plus_sides + 1] = sides[i] 334 + end 335 + return plus_sides 336 + end 337 + 338 --- Cycle the marker format. 339 ---@param jj_marker Marker 340 ---@return Marker
+4 -4
lua/vcmarkers/markers.lua
··· 23 24 ---@param marker Marker 25 ---@param lnum integer 26 - ---@return Section|nil 27 function M.current_section(marker, lnum) 28 lnum = lnum - 1 -- Convert to zero-based line number. 29 - for _, section in ipairs(marker.sections) do 30 local start = section.header_line or section.content_line 31 if start <= lnum and lnum < section.content_line + #section.lines then 32 - return section 33 end 34 end 35 - return nil 36 end 37 38 ---@param section Section
··· 23 24 ---@param marker Marker 25 ---@param lnum integer 26 + ---@return integer?, Section? 27 function M.current_section(marker, lnum) 28 lnum = lnum - 1 -- Convert to zero-based line number. 29 + for i, section in ipairs(marker.sections) do 30 local start = section.header_line or section.content_line 31 if start <= lnum and lnum < section.content_line + #section.lines then 32 + return i, section 33 end 34 end 35 + return nil, nil 36 end 37 38 ---@param section Section
+61 -1
lua/vcmarkers_tests/functional/test_selection_actions.lua
··· 27 +first conflict new 1 28 after 29 ]], 30 }, 31 select_second_section = { 32 line = 6, ··· 35 first conflict new 2 36 after 37 ]], 38 }, 39 }, 40 test = function(case) ··· 45 helpers.wait_update() 46 47 helpers.set_cursor(case.line, 0) 48 - actions.select_section(bufnr) 49 50 testing.assert_list_eq( 51 helpers.get_lines(bufnr),
··· 27 +first conflict new 1 28 after 29 ]], 30 + action = actions.select_section, 31 }, 32 select_second_section = { 33 line = 6, ··· 36 first conflict new 2 37 after 38 ]], 39 + action = actions.select_section, 40 + }, 41 + -- select_section_verbatim is an alias for select_section 42 + select_verbatim_first_section = { 43 + line = 5, 44 + expected = [[ 45 + before 46 + -first conflict old 47 + +first conflict new 1 48 + after 49 + ]], 50 + action = actions.select_section_verbatim, 51 + }, 52 + select_verbatim_second_section = { 53 + line = 6, 54 + expected = [[ 55 + before 56 + first conflict new 2 57 + after 58 + ]], 59 + action = actions.select_section_verbatim, 60 + }, 61 + select_plus_first_section = { 62 + line = 5, 63 + expected = [[ 64 + before 65 + first conflict new 1 66 + after 67 + ]], 68 + action = actions.select_section_plus, 69 + }, 70 + select_plus_second_section = { 71 + line = 6, 72 + expected = [[ 73 + before 74 + first conflict new 2 75 + after 76 + ]], 77 + action = actions.select_section_verbatim, 78 + }, 79 + select_all_first_section = { 80 + line = 5, 81 + expected = [[ 82 + before 83 + first conflict new 1 84 + first conflict new 2 85 + after 86 + ]], 87 + action = actions.select_all, 88 + }, 89 + select_all_second_section = { 90 + line = 6, 91 + expected = [[ 92 + before 93 + first conflict new 1 94 + first conflict new 2 95 + after 96 + ]], 97 + action = actions.select_all, 98 }, 99 }, 100 test = function(case) ··· 105 helpers.wait_update() 106 107 helpers.set_cursor(case.line, 0) 108 + case.action(bufnr) 109 110 testing.assert_list_eq( 111 helpers.get_lines(bufnr),