nvim-treesitter-context
nvim-treesitter-context copied to clipboard
the 'else' is not show in context bar
Description
A test code as below it is a simple if ... else
, when navigating the else
part the context shows only the if
without else
.
This is misleading.
int main() {
if ( 1 == 1 ) {
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
} else {
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
}
return 0;
}
neovim version version 0.9.1, Build type: Release nvim-treesitter-context is download on 2023.10.20
packer.nvim lua config: use 'nvim-treesitter/nvim-treesitter-context'
nvim-treesitter-context.lua :
require 'treesitter-context'.setup {
enable = true, -- Enable this plugin (Can be enabled/disabled later via commands)
max_lines = 0, -- How many lines the window should span. Values <= 0 mean no limit.
min_window_height = 0, -- Minimum editor window height to enable context. Values <= 0 mean no limit.
line_numbers = true,
multiline_threshold = 20, -- Maximum number of lines to show for a single context
trim_scope = 'outer', -- Which context lines to discard if `max_lines` is exceeded. Choices: 'inner', 'outer'
mode = 'cursor', -- Line used to calculate context. Choices: 'cursor', 'topline'
-- Separator between context and content. Should be a single character string, like '-'.
-- When separator is set, the context will only show up when there are at least 2 lines above cursorline.
separator = nil,
zindex = 20, -- The Z-index of the context window
on_attach = nil, -- (fun(buf: integer): boolean) return false to disable attaching
}
Neovim version
0.9.1
Expected behavior
in if ... else
context, show the else
context.
Actual behavior
in if ... else
context, no else
context is shown
Minimal config
packer.nvim lua config: `use 'nvim-treesitter/nvim-treesitter-context'`
nvim-treesitter-context.lua :
require 'treesitter-context'.setup {
enable = true, -- Enable this plugin (Can be enabled/disabled later via commands)
max_lines = 0, -- How many lines the window should span. Values <= 0 mean no limit.
min_window_height = 0, -- Minimum editor window height to enable context. Values <= 0 mean no limit.
line_numbers = true,
multiline_threshold = 20, -- Maximum number of lines to show for a single context
trim_scope = 'outer', -- Which context lines to discard if max_lines
is exceeded. Choices: 'inner', 'outer'
mode = 'cursor', -- Line used to calculate context. Choices: 'cursor', 'topline'
-- Separator between context and content. Should be a single character string, like '-'.
-- When separator is set, the context will only show up when there are at least 2 lines above cursorline.
separator = nil,
zindex = 20, -- The Z-index of the context window
on_attach = nil, -- (fun(buf: integer): boolean) return false to disable attaching
}
-- ADD INIT.LUA SETTINGS THAT IS _NECESSARY_ FOR REPRODUCING THE ISSUE
Steps to reproduce
install nvim-treesitter-context, then use neovim to review below code, go to the last else
line.
int main() {
if ( 1 == 1 ) {
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
2 = 2;
} else {
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
3 = 3;
}
return 0;
}
This looks like C, does it?
Generally this plugin just uses the hierarchical tree structure that the treesitter parser for the language provides. For example with python or rust, this works fine.
You can inspect what the parser provides using the :InspectTree
(in a recent neovim version).
So my hunch would be that this should actually be an issue / request to the treesitter C parser.
thanks syphar
No it is a cc file. I copy it as a c file, the else
part is not shown either.
:InspectTree
shows below info.
I notice that alternative: (else_clause) ; [23:7 - 49:5]
corresponds to the else
branch, so will treesitter-context handle the alternative: (else_clause)
?
(preproc_include) ; [1:1 - 2:0]
path: (string_literal) ; [1:10 - 18]
(string_content) ; [1:11 - 17]
(function_definition) ; [3:1 - 51:1]
type: (primitive_type) ; [3:1 - 3]
declarator: (function_declarator) ; [3:5 - 10]
declarator: (identifier) ; [3:5 - 8]
parameters: (parameter_list) ; [3:9 - 10]
body: (compound_statement) ; [3:12 - 51:1]
(if_statement) ; [4:5 - 49:5]
condition: (condition_clause) ; [4:8 - 17]
value: (binary_expression) ; [4:10 - 15]
left: (number_literal) ; [4:10 - 10]
right: (number_literal) ; [4:15 - 15]
consequence: (compound_statement) ; [4:19 - 23:5]
(expression_statement) ; [5:9 - 14]
(assignment_expression) ; [5:9 - 13]
left: (user_defined_literal) ; [5:9 - 9]
(number_literal) ; [5:9 - 9]
(literal_suffix) ; [5:10 - 9]
right: (number_literal) ; [5:13 - 13]
(expression_statement) ; [6:9 - 14]
(assignment_expression) ; [6:9 - 13]
left: (user_defined_literal) ; [6:9 - 9]
(number_literal) ; [6:9 - 9]
(literal_suffix) ; [6:10 - 9]
right: (number_literal) ; [6:13 - 13]
(expression_statement) ; [7:9 - 14]
(assignment_expression) ; [7:9 - 13]
left: (user_defined_literal) ; [7:9 - 9]
(number_literal) ; [7:9 - 9]
(literal_suffix) ; [7:10 - 9]
right: (number_literal) ; [7:13 - 13]
(expression_statement) ; [8:9 - 14]
(assignment_expression) ; [8:9 - 13]
left: (user_defined_literal) ; [8:9 - 9]
(number_literal) ; [8:9 - 9]
(literal_suffix) ; [8:10 - 9]
right: (number_literal) ; [8:13 - 13]
(expression_statement) ; [9:9 - 14]
(assignment_expression) ; [9:9 - 13]
left: (user_defined_literal) ; [9:9 - 9]
(number_literal) ; [9:9 - 9]
(literal_suffix) ; [9:10 - 9]
right: (number_literal) ; [9:13 - 13]
(expression_statement) ; [10:9 - 14]
(assignment_expression) ; [10:9 - 13]
left: (user_defined_literal) ; [10:9 - 9]
(number_literal) ; [10:9 - 9]
(literal_suffix) ; [10:10 - 9]
right: (number_literal) ; [10:13 - 13]
(expression_statement) ; [11:9 - 14]
(assignment_expression) ; [11:9 - 13]
left: (user_defined_literal) ; [11:9 - 9]
(number_literal) ; [11:9 - 9]
(literal_suffix) ; [11:10 - 9]
right: (number_literal) ; [11:13 - 13]
(expression_statement) ; [12:9 - 14]
(assignment_expression) ; [12:9 - 13]
left: (user_defined_literal) ; [12:9 - 9]
(number_literal) ; [12:9 - 9]
(literal_suffix) ; [12:10 - 9]
right: (number_literal) ; [12:13 - 13]
(expression_statement) ; [13:9 - 14]
(assignment_expression) ; [13:9 - 13]
left: (user_defined_literal) ; [13:9 - 9]
(number_literal) ; [13:9 - 9]
(literal_suffix) ; [13:10 - 9]
right: (number_literal) ; [13:13 - 13]
(expression_statement) ; [14:9 - 14]
(assignment_expression) ; [14:9 - 13]
left: (user_defined_literal) ; [14:9 - 9]
(number_literal) ; [14:9 - 9]
(literal_suffix) ; [14:10 - 9]
right: (number_literal) ; [14:13 - 13]
(expression_statement) ; [15:9 - 14]
(assignment_expression) ; [15:9 - 13]
left: (user_defined_literal) ; [15:9 - 9]
(number_literal) ; [15:9 - 9]
(literal_suffix) ; [15:10 - 9]
right: (number_literal) ; [15:13 - 13]
(expression_statement) ; [16:9 - 14]
(assignment_expression) ; [16:9 - 13]
left: (user_defined_literal) ; [16:9 - 9]
(number_literal) ; [16:9 - 9]
(literal_suffix) ; [16:10 - 9]
right: (number_literal) ; [16:13 - 13]
(expression_statement) ; [17:9 - 14]
(assignment_expression) ; [17:9 - 13]
left: (user_defined_literal) ; [17:9 - 9]
(number_literal) ; [17:9 - 9]
(literal_suffix) ; [17:10 - 9]
right: (number_literal) ; [17:13 - 13]
(expression_statement) ; [18:9 - 14]
(assignment_expression) ; [18:9 - 13]
left: (user_defined_literal) ; [18:9 - 9]
(number_literal) ; [18:9 - 9]
(literal_suffix) ; [18:10 - 9]
right: (number_literal) ; [18:13 - 13]
(expression_statement) ; [19:9 - 14]
(assignment_expression) ; [19:9 - 13]
left: (user_defined_literal) ; [19:9 - 9]
(number_literal) ; [19:9 - 9]
(literal_suffix) ; [19:10 - 9]
right: (number_literal) ; [19:13 - 13]
(expression_statement) ; [20:9 - 14]
(assignment_expression) ; [20:9 - 13]
left: (user_defined_literal) ; [20:9 - 9]
(number_literal) ; [20:9 - 9]
(literal_suffix) ; [20:10 - 9]
right: (number_literal) ; [20:13 - 13]
(expression_statement) ; [21:9 - 14]
(assignment_expression) ; [21:9 - 13]
left: (user_defined_literal) ; [21:9 - 9]
(number_literal) ; [21:9 - 9]
(literal_suffix) ; [21:10 - 9]
right: (number_literal) ; [21:13 - 13]
(expression_statement) ; [22:9 - 14]
(assignment_expression) ; [22:9 - 13]
left: (user_defined_literal) ; [22:9 - 9]
(number_literal) ; [22:9 - 9]
(literal_suffix) ; [22:10 - 9]
right: (number_literal) ; [22:13 - 13]
alternative: (else_clause) ; [23:7 - 49:5]
(compound_statement) ; [23:12 - 49:5]
(expression_statement) ; [24:9 - 14]
(assignment_expression) ; [24:9 - 13]
left: (user_defined_literal) ; [24:9 - 9]
(number_literal) ; [24:9 - 9]
(literal_suffix) ; [24:10 - 9]
right: (number_literal) ; [24:13 - 13]
(expression_statement) ; [25:9 - 14]
(assignment_expression) ; [25:9 - 13]
left: (user_defined_literal) ; [25:9 - 9]
(number_literal) ; [25:9 - 9]
(literal_suffix) ; [25:10 - 9]
right: (number_literal) ; [25:13 - 13]
(expression_statement) ; [26:9 - 14]
(assignment_expression) ; [26:9 - 13]
left: (user_defined_literal) ; [26:9 - 9]
(number_literal) ; [26:9 - 9]
(literal_suffix) ; [26:10 - 9]
right: (number_literal) ; [26:13 - 13]
(expression_statement) ; [27:9 - 14]
(assignment_expression) ; [27:9 - 13]
left: (user_defined_literal) ; [27:9 - 9]
(number_literal) ; [27:9 - 9]
(literal_suffix) ; [27:10 - 9]
right: (number_literal) ; [27:13 - 13]
(expression_statement) ; [28:9 - 14]
(assignment_expression) ; [28:9 - 13]
left: (user_defined_literal) ; [28:9 - 9]
(number_literal) ; [28:9 - 9]
(literal_suffix) ; [28:10 - 9]
right: (number_literal) ; [28:13 - 13]
(expression_statement) ; [29:9 - 14]
(assignment_expression) ; [29:9 - 13]
left: (user_defined_literal) ; [29:9 - 9]
(number_literal) ; [29:9 - 9]
(literal_suffix) ; [29:10 - 9]
right: (number_literal) ; [29:13 - 13]
(expression_statement) ; [30:9 - 14]
(assignment_expression) ; [30:9 - 13]
left: (user_defined_literal) ; [30:9 - 9]
(number_literal) ; [30:9 - 9]
(literal_suffix) ; [30:10 - 9]
right: (number_literal) ; [30:13 - 13]
(expression_statement) ; [31:9 - 14]
(assignment_expression) ; [31:9 - 13]
left: (user_defined_literal) ; [31:9 - 9]
(number_literal) ; [31:9 - 9]
(literal_suffix) ; [31:10 - 9]
right: (number_literal) ; [31:13 - 13]
(expression_statement) ; [32:9 - 14]
(assignment_expression) ; [32:9 - 13]
left: (user_defined_literal) ; [32:9 - 9]
(number_literal) ; [32:9 - 9]
(literal_suffix) ; [32:10 - 9]
right: (number_literal) ; [32:13 - 13]
(expression_statement) ; [33:9 - 14]
(assignment_expression) ; [33:9 - 13]
left: (user_defined_literal) ; [33:9 - 9]
(number_literal) ; [33:9 - 9]
(literal_suffix) ; [33:10 - 9]
right: (number_literal) ; [33:13 - 13]
(expression_statement) ; [34:9 - 14]
(assignment_expression) ; [34:9 - 13]
left: (user_defined_literal) ; [34:9 - 9]
(number_literal) ; [34:9 - 9]
(literal_suffix) ; [34:10 - 9]
right: (number_literal) ; [34:13 - 13]
(expression_statement) ; [35:9 - 14]
(assignment_expression) ; [35:9 - 13]
left: (user_defined_literal) ; [35:9 - 9]
(number_literal) ; [35:9 - 9]
(literal_suffix) ; [35:10 - 9]
right: (number_literal) ; [35:13 - 13]
(expression_statement) ; [36:9 - 14]
(assignment_expression) ; [36:9 - 13]
left: (user_defined_literal) ; [36:9 - 9]
(number_literal) ; [36:9 - 9]
(literal_suffix) ; [36:10 - 9]
right: (number_literal) ; [36:13 - 13]
(expression_statement) ; [37:9 - 14]
(assignment_expression) ; [37:9 - 13]
left: (user_defined_literal) ; [37:9 - 9]
(number_literal) ; [37:9 - 9]
(literal_suffix) ; [37:10 - 9]
right: (number_literal) ; [37:13 - 13]
(expression_statement) ; [38:9 - 14]
(assignment_expression) ; [38:9 - 13]
left: (user_defined_literal) ; [38:9 - 9]
(number_literal) ; [38:9 - 9]
(literal_suffix) ; [38:10 - 9]
right: (number_literal) ; [38:13 - 13]
(expression_statement) ; [39:9 - 14]
(assignment_expression) ; [39:9 - 13]
left: (user_defined_literal) ; [39:9 - 9]
(number_literal) ; [39:9 - 9]
(literal_suffix) ; [39:10 - 9]
right: (number_literal) ; [39:13 - 13]
(expression_statement) ; [40:9 - 14]
(assignment_expression) ; [40:9 - 13]
left: (user_defined_literal) ; [40:9 - 9]
(number_literal) ; [40:9 - 9]
(literal_suffix) ; [40:10 - 9]
right: (number_literal) ; [40:13 - 13]
(expression_statement) ; [41:9 - 14]
(assignment_expression) ; [41:9 - 13]
left: (user_defined_literal) ; [41:9 - 9]
(number_literal) ; [41:9 - 9]
(literal_suffix) ; [41:10 - 9]
right: (number_literal) ; [41:13 - 13]
(expression_statement) ; [42:9 - 14]
(assignment_expression) ; [42:9 - 13]
left: (user_defined_literal) ; [42:9 - 9]
(number_literal) ; [42:9 - 9]
(literal_suffix) ; [42:10 - 9]
right: (number_literal) ; [42:13 - 13]
(expression_statement) ; [43:9 - 14]
(assignment_expression) ; [43:9 - 13]
left: (user_defined_literal) ; [43:9 - 9]
(number_literal) ; [43:9 - 9]
(literal_suffix) ; [43:10 - 9]
right: (number_literal) ; [43:13 - 13]
(expression_statement) ; [44:9 - 14]
(assignment_expression) ; [44:9 - 13]
left: (user_defined_literal) ; [44:9 - 9]
(number_literal) ; [44:9 - 9]
(literal_suffix) ; [44:10 - 9]
right: (number_literal) ; [44:13 - 13]
(expression_statement) ; [45:9 - 14]
(assignment_expression) ; [45:9 - 13]
left: (user_defined_literal) ; [45:9 - 9]
(number_literal) ; [45:9 - 9]
(literal_suffix) ; [45:10 - 9]
right: (number_literal) ; [45:13 - 13]
(expression_statement) ; [46:9 - 14]
(assignment_expression) ; [46:9 - 13]
left: (user_defined_literal) ; [46:9 - 9]
(number_literal) ; [46:9 - 9]
(literal_suffix) ; [46:10 - 9]
right: (number_literal) ; [46:13 - 13]
(expression_statement) ; [47:9 - 14]
(assignment_expression) ; [47:9 - 13]
left: (user_defined_literal) ; [47:9 - 9]
(number_literal) ; [47:9 - 9]
(literal_suffix) ; [47:10 - 9]
right: (number_literal) ; [47:13 - 13]
(expression_statement) ; [48:9 - 14]
(assignment_expression) ; [48:9 - 13]
left: (user_defined_literal) ; [48:9 - 9]
(number_literal) ; [48:9 - 9]
(literal_suffix) ; [48:10 - 9]
right: (number_literal) ; [48:13 - 13]
(return_statement) ; [50:5 - 13]
(number_literal) ; [50:12 - 12]
The queries for C (and thus C++ since it inherits the C queries and adds a few more) don't seem to contain anything catching else if
or else
, but this seems to be the case for most (all?) languages.
(I wrote a wrong solution before, see update.)
UPDATE: The above doesn't work as I expected. I have made a fork and tested a bit now. I think that replacing the if_statement
query with
(if_statement
consequence: (_) @context.end
) @context
(else_clause
(_) @context.end
) @context
behaves more like what I would expect. This caputures else if
and if
as I would expect:
thanks Danielkonge. The behavior in your screenshot is just as what I expected.
Note: If you want to always include {
if you ever put it on the next line instead of the end of the current line, then you need slightly more complicated queries.
(if_statement
consequence: (_ "{" (_) @context.end)
) @context
(else_clause
(_ "{" (_) @context.end)
) @context
or
(if_statement
consequence: (_ "{" @context.final)
) @context
(else_clause
(_ "{" @context.final)
) @context
seems to work fine for that.
Previous queries:
New queries:
With the formatting of my previous comment, these queries behave the same.
Hi Danielkonge, I am wondering if you will pull your new context.scm code to pull request ? Frankly speaking I am not that familiar with the syntax of scm file ...
Hi Danielkonge, I am wondering if you will pull your new context.scm code to pull request ? Frankly speaking I am not that familiar with the syntax of scm file ...
I can make a pull request that includes the else
statements like in my pictures, but we should probably have some general consensus for what to include. Should the {
always be included here?
Hi Danielkonge, I personally perfer the "Previous queries" in your comment, i.e., NOT to always include {
. Maybe we can even have an option to turn it on/off to "always in include the {
?
Hi Danielkonge, I personally perfer the "Previous queries" in your comment, i.e., NOT to always include
{
. Maybe we can even have an option to turn it on/off to "always in include the{
?
To have an option like that is probably not worth it to try to implement and maintain just for c. Instead it would probably make more sense to allow use of custom queries, though I am not sure if that is already possible to do?
Also, I have made a pull request now.
Instead it would probably make more sense to allow use of custom queries, though I am not sure if that is already possible to do?
That is already possible.
Instead it would probably make more sense to allow use of custom queries, though I am not sure if that is already possible to do?
That is already possible.
This has to be defined for every language? Can it be generalized? I think the else
is a very important piece of context.
You'd have to dig into the code and investigate.