Skip to content

Commit 5513c2b

Browse files
committed
feat(enhancement): support nearest parent
Fixes #453
1 parent 33b3f5a commit 5513c2b

File tree

4 files changed

+68
-20
lines changed

4 files changed

+68
-20
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: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,18 +116,38 @@ enable() *nvim-treesitter-context-enable()*
116116

117117
go_to_context({depth}) *nvim-treesitter-context-go_to_context()*
118118

119-
Jump to the context at {depth}.
119+
Jump to parent scope within the context window at {depth}.
120+
121+
A depth of 1 implies nearest, 2 second nearest and so on. Set to
122+
`vim.v.count1` to support motions with counts as depth.
120123

121124
Example use in a keymap:
122125
>lua
123-
vim.keymap.set("n", "[c", function()
126+
vim.keymap.set("n", "[C", function()
124127
require("treesitter-context").go_to_context(vim.v.count1)
125128
end, { silent = true })
126129
<
127130

128131
Parameters: ~
129132
{depth} (`integer`, default: `1`) Depth to jump to.
130133

134+
go_to_parent({depth}) *nvim-treesitter-context-go_to_parent()*
135+
136+
Jump to parent scope at {depth}.
137+
138+
A depth of 1 implies nearest, 2 second nearest and so on. Set to
139+
`vim.v.count1` to support motions with counts as depth.
140+
141+
Example use in a keymap:
142+
>lua
143+
vim.keymap.set("n", "[c", function()
144+
require("treesitter-context").go_to_parent(vim.v.count1)
145+
end, { silent = true })
146+
<
147+
148+
Parameters: ~
149+
{depth} (`integer`, default: `1`) Depth to jump to.
150+
131151

132152
setup({config}) *nvim-treesitter-context-setup()*
133153

lua/treesitter-context.lua

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -301,30 +301,53 @@ function M.setup(options)
301301
end
302302
end
303303

304-
--- @param depth integer? default 1
305-
function M.go_to_context(depth)
306-
depth = depth or 1
304+
--- @param depth integer
305+
--- @param ranges Range4[]
306+
local function go_to(depth, ranges)
307307
local line = api.nvim_win_get_cursor(0)[1]
308-
local context = nil
309-
local contexts = require('treesitter-context.context').get() or {}
308+
local range = nil
310309

311-
for idx = #contexts, 1, -1 do
312-
local c = contexts[idx]
310+
for idx = #ranges, 1, -1 do
311+
local c = ranges[idx]
313312
if depth == 0 then
314313
break
315314
end
316315
if c[1] + 1 < line then
317-
context = c
316+
range = c
318317
depth = depth - 1
319318
end
320319
end
321320

322-
if not context then
321+
if not range then
323322
return
324323
end
325324

326-
vim.cmd([[ normal! m' ]]) -- add current cursor position to the jump list
327-
api.nvim_win_set_cursor(0, { context[1] + 1, context[2] })
325+
vim.cmd([[normal! m']]) -- add current cursor position to the jump list
326+
api.nvim_win_set_cursor(0, { range[1] + 1, range[2] })
327+
end
328+
329+
--- Jump to parent scope at depth.
330+
---
331+
--- A depth of 1 implies nearest, 2 second nearest and so on. Set to
332+
--- `vim.v.count1` to support motions with counts as depth.
333+
---
334+
--- @param depth integer? default 1
335+
function M.go_to_parent(depth)
336+
depth = depth or 1
337+
local ranges = require('treesitter-context.context').get(nil, true) or {}
338+
go_to(depth, ranges)
339+
end
340+
341+
--- Jump to parent scope within the context window at depth.
342+
---
343+
--- A depth of 1 implies nearest, 2 second nearest and so on. Set to
344+
--- `vim.v.count1` to support motions with counts as depth.
345+
---
346+
--- @param depth integer? default 1
347+
function M.go_to_context(depth)
348+
depth = depth or 1
349+
local ranges = require('treesitter-context.context').get() or {}
350+
go_to(depth, ranges)
328351
end
329352

330353
return M

lua/treesitter-context/context.lua

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ end
190190
--- @param bufnr integer
191191
--- @return Range4, string[]
192192
local function get_text_for_range(range, bufnr)
193-
local start_row, end_row, end_col = range[1], range[3], range[4]
193+
local start_row, start_col, end_row, end_col = range[1], range[2], range[3], range[4]
194194

195195
if end_col == 0 then
196196
end_row = end_row - 1
@@ -218,7 +218,7 @@ local function get_text_for_range(range, bufnr)
218218
end_row = end_row + 1
219219
end
220220

221-
return { start_row, 0, end_row, end_col }, lines
221+
return { start_row, start_col, end_row, end_col }, lines
222222
end
223223

224224
local M = {}
@@ -313,8 +313,10 @@ local function range_is_valid(range)
313313
end
314314

315315
--- @param winid? integer
316+
--- @param full_context? boolean default false
316317
--- @return Range4[]?, string[]?
317-
function M.get(winid)
318+
function M.get(winid, full_context)
319+
full_context = full_context or false
318320
winid = winid or api.nvim_get_current_win()
319321
local bufnr = api.nvim_win_get_buf(winid)
320322

@@ -369,8 +371,8 @@ function M.get(winid)
369371

370372
local contexts_end_row = top_row + separator_offset + num_context_lines
371373

372-
-- Only process the parent if it is not in view.
373-
if parent_start_row < contexts_end_row then
374+
-- context_ranges: Only process the parent if it is not in view.
375+
if parent_start_row < contexts_end_row or full_context then
374376
local range0 = context_range(parent, bufnr, query)
375377
if range0 and range_is_valid(range0) then
376378
local range, lines = get_text_for_range(range0, bufnr)
@@ -382,7 +384,6 @@ function M.get(winid)
382384
context_ranges[#context_ranges] = nil
383385
context_lines[#context_lines] = nil
384386
end
385-
386387
contexts_height = contexts_height + util.get_range_height(range)
387388
context_ranges[#context_ranges + 1] = range
388389
context_lines[#context_lines + 1] = lines

0 commit comments

Comments
 (0)