···1local M = {}
23local markers = require "vcmarkers.markers"
04local highlight = require "vcmarkers.highlight"
56---@param bufnr number Buffer number.
···109 end
110end
11100000112---@param bufnr integer The buffer number.
113-function M.select_section(bufnr)
114- local lnum = vim.fn.line "."
0115 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
125126- 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
000000135136- -- Could check that the section is actually a "plus" section,
137- -- but let's trust the user for now.
0000138 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 })
00000000000000000000000000000000000000000000146end
147148--- Convert markers to a different format.
···1local M = {}
23local markers = require "vcmarkers.markers"
4+local marker_format = require "vcmarkers.marker_format"
5local highlight = require "vcmarkers.highlight"
67---@param bufnr number Buffer number.
···110 end
111end
112113+---@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
132133+ 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
148149+--- 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)
207end
208209--- Convert markers to a different format.
···323 end
324end
325000000000000326--- Cycle the marker format.
327---@param jj_marker Marker
328---@return Marker
···323 end
324end
325326+---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
···2324---@param marker Marker
25---@param lnum integer
26----@return Section|nil
27function 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
36end
3738---@param section Section
···2324---@param marker Marker
25---@param lnum integer
26+---@return integer?, Section?
27function 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
36end
3738---@param section Section