Skip to content

Commit 7de7334

Browse files
committed
feat(actions): Return context data from the conflict nav actions
The conflict navigation actions now return relevant data, like: - The total number of conflicts - The index of the current conflict - The content of the current conflict - A list of all conflicts For more info, see |diffview-actions-jumpto_conflict|. (fixes #265)
1 parent 5bbcf16 commit 7de7334

File tree

2 files changed

+86
-33
lines changed

2 files changed

+86
-33
lines changed

doc/diffview.txt

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,23 @@ goto_file_tab *diffview-actions-goto_file_tab*
859859
|diffview-file-inference| for details on how the file target is
860860
determined.
861861

862+
jumpto_conflict({num}, {use_delta}) *diffview-actions-jumpto_conflict*
863+
Contexts: `diff_view`, `file_panel`
864+
865+
Jump to a conflict marker in the current file.
866+
867+
Parameters: ~
868+
{num} (integer)
869+
The 1-based index of the conflict to jump to.
870+
{use_delta} (boolean)
871+
If true: treat {num} like a relative offset from the current
872+
cursor position. I.e. `1` would jump one conflict forward, `-2`
873+
would jump 2 conflicts backwards.
874+
875+
Return: ~
876+
If the current file contains any conflicts, the action returns a
877+
|diffview.ConflictCount| table.
878+
862879
listing_style *diffview-actions-listing_style*
863880
Contexts: `file_panel`
864881

@@ -870,6 +887,10 @@ next_conflict *diffview-actions-next_conflict*
870887

871888
Moves the cursor to the next conflict marker in the current file.
872889

890+
Return: ~
891+
If the current file contains any conflicts, the action returns a
892+
|diffview.ConflictCount| table.
893+
873894
next_entry *diffview-actions-next_entry*
874895
Contexts: `view`, `panel`
875896

@@ -902,6 +923,10 @@ prev_conflict *diffview-actions-prev_conflict*
902923

903924
Moves the cursor to the previous conflict marker in the current file.
904925

926+
Return: ~
927+
If the current file contains any conflicts, the action returns a
928+
|diffview.ConflictCount| table.
929+
905930
prev_entry *diffview-actions-prev_entry*
906931
Contexts: `view`, `panel`
907932

@@ -1007,6 +1032,7 @@ actions:
10071032

10081033
|diffview-actions-focus_entry|
10091034
|diffview-actions-goto_file_edit|
1035+
|diffview-actions-jumpto_conflict|
10101036
|diffview-actions-view_windo|
10111037

10121038
USER AUTOCOMMANDS *diffview-user-autocmds*
@@ -1257,7 +1283,7 @@ CDiffView *diffview.api.views.diff.diff_vi
12571283

12581284
FileDict *diffview.git.FileDict*
12591285

1260-
Fields:~
1286+
Fields: ~
12611287
{working} (FileData[])
12621288
{staged} (FileData[])
12631289
{conflicting} (FileData[])
@@ -1310,7 +1336,7 @@ LogOptions *diffview.git.LogOptions*
13101336

13111337
Table controlling the options passed to git-log.
13121338

1313-
Fields:~
1339+
Fields: ~
13141340
NOTE: All these options are described in far more detail in the
13151341
man page for git-log. See `:Man git-log(1)` for more information.
13161342

@@ -1389,5 +1415,20 @@ LogOptions *diffview.git.LogOptions*
13891415
the specified pattern (extended regular expression) in a
13901416
file.
13911417

1418+
ConflictCount *diffview.ConflictCount*
1419+
1420+
Fields: ~
1421+
{total} (integer)
1422+
The total number of conflicts in the current file.
1423+
1424+
{current} (integer)
1425+
The index of the current conflict.
1426+
1427+
{cur_conflict} (table?)
1428+
The current conflict, if the cursor is currently in a conflict
1429+
region.
1430+
1431+
{conflicts} (table[])
1432+
List of all conflicts in the current file.
13921433

13931434
vim:tw=78:ts=8:ft=help:norl:

lua/diffview/actions.lua

Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,16 @@ function M.goto_file_tab()
157157
end
158158
end
159159

160-
---Jump to the next merge conflict marker.
161-
function M.next_conflict()
160+
---@class diffview.ConflictCount
161+
---@field total integer
162+
---@field current integer
163+
---@field cur_conflict? ConflictRegion
164+
---@field conflicts ConflictRegion[]
165+
166+
---@param num integer
167+
---@param use_delta? boolean
168+
---@return diffview.ConflictCount?
169+
function M.jumpto_conflict(num, use_delta)
162170
local view = lib.get_current_view()
163171

164172
if view and view:instanceof(StandardView.__get()) then
@@ -167,13 +175,29 @@ function M.next_conflict()
167175
local curfile = main.file
168176

169177
if main:is_valid() and curfile:is_valid() then
170-
local conflicts, _, cur_idx = vcs_utils.parse_conflicts(
178+
local next_idx
179+
local conflicts, cur, cur_idx = vcs_utils.parse_conflicts(
171180
api.nvim_buf_get_lines(curfile.bufnr, 0, -1, false),
172181
main.id
173182
)
174183

175184
if #conflicts > 0 then
176-
local next_idx = math.min(cur_idx, #conflicts) % #conflicts + 1
185+
if not use_delta then
186+
next_idx = utils.clamp(num, 1, #conflicts)
187+
else
188+
local delta = num
189+
190+
if not cur and delta < 0 and cur_idx <= #conflicts then
191+
delta = delta + 1
192+
end
193+
194+
if (delta < 0 and cur_idx < 1) or (delta > 0 and cur_idx > #conflicts) then
195+
cur_idx = utils.clamp(cur_idx, 1, #conflicts)
196+
end
197+
198+
next_idx = (cur_idx + delta - 1) % #conflicts + 1
199+
end
200+
177201
local next_conflict = conflicts[next_idx]
178202
local curwin = api.nvim_get_current_win()
179203

@@ -183,40 +207,28 @@ function M.next_conflict()
183207
end)
184208

185209
api.nvim_echo({{ ("Conflict [%d/%d]"):format(next_idx, #conflicts) }}, false, {})
210+
211+
return {
212+
total = #conflicts,
213+
current = next_idx,
214+
cur_conflict = next_conflict,
215+
conflicts = conflicts,
216+
}
186217
end
187218
end
188219
end
189220
end
190221

222+
---Jump to the next merge conflict marker.
223+
---@return diffview.ConflictCount?
224+
function M.next_conflict()
225+
return M.jumpto_conflict(1, true)
226+
end
227+
191228
---Jump to the previous merge conflict marker.
229+
---@return diffview.ConflictCount?
192230
function M.prev_conflict()
193-
local view = lib.get_current_view()
194-
195-
if view and view:instanceof(StandardView.__get()) then
196-
---@cast view StandardView
197-
local main = view.cur_layout:get_main_win()
198-
local curfile = main.file
199-
200-
if main:is_valid() and curfile:is_valid() then
201-
local conflicts, _, cur_idx = vcs_utils.parse_conflicts(
202-
api.nvim_buf_get_lines(curfile.bufnr, 0, -1, false),
203-
main.id
204-
)
205-
206-
if #conflicts > 0 then
207-
local prev_idx = (math.max(cur_idx, 1) - 2) % #conflicts + 1
208-
local prev_conflict = conflicts[prev_idx]
209-
local curwin = api.nvim_get_current_win()
210-
211-
api.nvim_win_call(main.id, function()
212-
api.nvim_win_set_cursor(main.id, { prev_conflict.first, 0 })
213-
if curwin ~= main.id then view.cur_layout:sync_scroll() end
214-
end)
215-
216-
api.nvim_echo({{ ("Conflict [%d/%d]"):format(prev_idx, #conflicts) }}, false, {})
217-
end
218-
end
219-
end
231+
return M.jumpto_conflict(-1, true)
220232
end
221233

222234
---Execute `cmd` for each target window in the current view. If no targets

0 commit comments

Comments
 (0)