Skip to content

Commit f9076a4

Browse files
committed
feat(enhancement): support nearest parent
Fixes #453
1 parent 153a076 commit f9076a4

File tree

4 files changed

+65
-12
lines changed

4 files changed

+65
-12
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,9 +404,13 @@ hi TreesitterContextLineNumberBottom gui=underline guisp=Grey
404404
## Jumping to context (upwards)
405405

406406
```lua
407-
vim.keymap.set("n", "[c", function()
407+
vim.keymap.set("n", "[C", function()
408408
require("treesitter-context").go_to_context(vim.v.count1)
409409
end, { silent = true })
410+
411+
vim.keymap.set("n", "[c", function()
412+
require("treesitter-context").go_to_parent(vim.v.count1)
413+
end, { silent = true })
410414
```
411415

412416
## Adding support for other languages

doc/nvim-treesitter-context.txt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,28 @@ go_to_context({depth}) *nvim-treesitter-context-go_to_context()*
120120

121121
Example use in a keymap:
122122
>lua
123-
vim.keymap.set("n", "[c", function()
123+
vim.keymap.set("n", "[C", function()
124124
require("treesitter-context").go_to_context(vim.v.count1)
125125
end, { silent = true })
126126
<
127127

128128
Parameters: ~
129129
{depth} (`integer`, default: `1`) Depth to jump to.
130130

131+
go_to_parent({depth}) *nvim-treesitter-context-go_to_parent()*
132+
133+
Jump to the parent at {depth}.
134+
135+
Example use in a keymap:
136+
>lua
137+
vim.keymap.set("n", "[c", function()
138+
require("treesitter-context").go_to_parent(vim.v.count1)
139+
end, { silent = true })
140+
<
141+
142+
Parameters: ~
143+
{depth} (`integer`, default: `1`) Depth to jump to.
144+
131145

132146
setup({config}) *nvim-treesitter-context-setup()*
133147

lua/treesitter-context.lua

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ local Render = defer_require('treesitter-context.render')
2626
--- @type table<integer, Range4[]>
2727
local all_contexts = {}
2828

29+
--- @type table<integer, Range4[]>
30+
local all_parent_ranges = {}
31+
2932
--- Schedule a function to run on the next event loop iteration.
3033
--- If the function is called again within 150ms, it will be scheduled
3134
--- again to run on the next event loop iteration. This means that
@@ -115,8 +118,10 @@ local update_single_context = throttle_by_id(function(winid)
115118
return
116119
end
117120

118-
local context_ranges, context_lines = require('treesitter-context.context').get(bufnr, winid)
121+
local context_ranges, context_lines, parent_ranges =
122+
require('treesitter-context.context').get(bufnr, winid)
119123
all_contexts[bufnr] = context_ranges
124+
all_parent_ranges[bufnr] = parent_ranges
120125

121126
if not context_ranges or #context_ranges == 0 then
122127
Render.close(winid)
@@ -310,13 +315,11 @@ function M.setup(options)
310315
end
311316
end
312317

313-
--- @param depth integer? default 1
314-
function M.go_to_context(depth)
315-
depth = depth or 1
318+
--- @param depth integer
319+
--- @param contexts Range4[]
320+
function go_to(depth, contexts)
316321
local line = api.nvim_win_get_cursor(0)[1]
317322
local context = nil
318-
local bufnr = api.nvim_get_current_buf()
319-
local contexts = all_contexts[bufnr] or {}
320323

321324
for idx = #contexts, 1, -1 do
322325
local c = contexts[idx]
@@ -333,8 +336,29 @@ function M.go_to_context(depth)
333336
return
334337
end
335338

336-
vim.cmd([[ normal! m' ]]) -- add current cursor position to the jump list
339+
vim.cmd([[normal! m']]) -- add current cursor position to the jump list
337340
api.nvim_win_set_cursor(0, { context[1] + 1, context[2] })
341+
vim.cmd([[normal! ^]]) -- place cursor at start of text
342+
end
343+
344+
--- jump to the nearest parent
345+
---
346+
--- @param depth integer? default 1
347+
function M.go_to_parent(depth)
348+
depth = depth or 1
349+
local bufnr = api.nvim_get_current_buf()
350+
local contexts = all_parent_ranges[bufnr] or {}
351+
go_to(depth, contexts)
352+
end
353+
354+
--- jump to the nearest context parent
355+
---
356+
--- @param depth integer? default 1
357+
function M.go_to_context(depth)
358+
depth = depth or 1
359+
local bufnr = api.nvim_get_current_buf()
360+
local contexts = all_contexts[bufnr] or {}
361+
go_to(depth, contexts)
338362
end
339363

340364
return M

lua/treesitter-context/context.lua

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ end
316316

317317
--- @param bufnr integer
318318
--- @param winid integer
319-
--- @return Range4[]?, string[]?
319+
--- @return Range4[]?, string[]?, Range4[]?
320320
function M.get(bufnr, winid)
321321
-- vim.treesitter.get_parser() calls bufload(), but we don't actually want to load the buffer:
322322
-- this method is called during plugin init, before other plugins or the user's config
@@ -345,6 +345,7 @@ function M.get(bufnr, winid)
345345
end
346346

347347
local context_ranges = {} --- @type Range4[]
348+
local parent_ranges = {} --- @type Range4[]
348349
local context_lines = {} --- @type string[][]
349350
local contexts_height = 0
350351

@@ -354,6 +355,7 @@ function M.get(bufnr, winid)
354355
local line_range = { node_row, col0, node_row, col0 + 1 }
355356

356357
context_ranges = {}
358+
parent_ranges = {}
357359
context_lines = {}
358360
contexts_height = 0
359361

@@ -366,7 +368,7 @@ function M.get(bufnr, winid)
366368

367369
local contexts_end_row = top_row + separator_offset + math.min(max_lines, contexts_height)
368370

369-
-- Only process the parent if it is not in view.
371+
-- context_ranges: Only process the parent if it is not in view.
370372
if parent_start_row < contexts_end_row then
371373
local range0 = context_range(parent, bufnr, query)
372374
if range0 and range_is_valid(range0) then
@@ -386,6 +388,15 @@ function M.get(bufnr, winid)
386388
end
387389
end
388390
end
391+
392+
-- parent_ranges: Process all
393+
local range0 = context_range(parent, bufnr, query)
394+
if range0 and range_is_valid(range0) then
395+
local range, _lines = get_text_for_range(range0, bufnr)
396+
if range_is_valid(range) then
397+
parent_ranges[#parent_ranges + 1] = range
398+
end
399+
end
389400
end
390401
end
391402

@@ -401,7 +412,7 @@ function M.get(bufnr, winid)
401412
trim_contexts(context_ranges, context_lines, trim, config.trim_scope == 'outer')
402413
end
403414

404-
return context_ranges, tbl_flatten(context_lines)
415+
return context_ranges, tbl_flatten(context_lines), parent_ranges
405416
end
406417

407418
return M

0 commit comments

Comments
 (0)