Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-line nodes are not working #65

Closed
zeertzjq opened this issue Aug 27, 2021 · 4 comments · Fixed by #71
Closed

Multi-line nodes are not working #65

zeertzjq opened this issue Aug 27, 2021 · 4 comments · Fixed by #71

Comments

@zeertzjq
Copy link
Contributor

Screenshot_20210828_054743
Screenshot_20210828_054756

Are there any solutions for this?

@ldelossa
Copy link

Running into this too, some c style guides will write functions like this often.

@romgrk
Copy link
Collaborator

romgrk commented Oct 2, 2021

Supposed to be implemented by df4ecbc but it's buggy apparently. Might take a look at it soon.

@romgrk romgrk changed the title Shows only the return type of a C function if it occupies a whole line Multi-line nodes are not working Oct 2, 2021
@lyokha
Copy link
Contributor

lyokha commented Oct 4, 2021

With the following diff it works for C files

diff --git a/lua/treesitter-context.lua b/lua/treesitter-context.lua
index b204dd7..b5fe694 100644
--- a/lua/treesitter-context.lua
+++ b/lua/treesitter-context.lua
@@ -23,7 +23,7 @@ ffi.cdef'int curwin_col_off(void);'
 -- Tells us at which node type to stop when highlighting a multi-line
 -- node. If not specified, the highlighting stops after the first line.
 local last_types = {
-  ['function'] = {
+  ['function_definition'] = {
     c = 'function_declarator',
     cpp = 'function_declarator',
     lua = 'parameters',
@@ -106,7 +106,7 @@ local get_type_pattern = function(node, type_patterns)
   return nil
 end
 
-local get_text_for_node = function(node, type)
+local get_text_for_node = function(node)
   local start_row, start_col = node:start()
   local end_row, end_col     = node:end_()
 
@@ -118,7 +118,7 @@ local get_text_for_node = function(node, type)
   start_col = 0
 
   local filetype = api.nvim_buf_get_option(0, 'filetype')
-  local last_type = (last_types[type] or {})[filetype]
+  local last_type = (last_types[node:type()] or {})[filetype]
   local last_position = nil
 
   if last_type ~= nil then

but not for everything, say

static char *
ngx_http_haskell(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

still shows static char * because function_declarator is deeply nested inside function_definition through pointer_declarator. To fix such cases, get_text_for_node() should do recursion over node:iter_children().

@lyokha
Copy link
Contributor

lyokha commented Oct 4, 2021

The following diff should fix cases with nested declarators.

diff --git a/lua/treesitter-context.lua b/lua/treesitter-context.lua
index b204dd7..584d62e 100644
--- a/lua/treesitter-context.lua
+++ b/lua/treesitter-context.lua
@@ -23,7 +23,7 @@ ffi.cdef'int curwin_col_off(void);'
 -- Tells us at which node type to stop when highlighting a multi-line
 -- node. If not specified, the highlighting stops after the first line.
 local last_types = {
-  ['function'] = {
+  ['function_definition'] = {
     c = 'function_declarator',
     cpp = 'function_declarator',
     lua = 'parameters',
@@ -106,7 +106,23 @@ local get_type_pattern = function(node, type_patterns)
   return nil
 end
 
-local get_text_for_node = function(node, type)
+local function find_node(node, type)
+  local children = ts_utils.get_named_children(node)
+  for _, child in ipairs(children) do
+    if child:type() == type then
+      return child
+    end
+  end
+  for _, child in ipairs(children) do
+    local deep_child = find_node(child, type)
+    if deep_child ~= nil then
+      return deep_child
+    end
+  end
+  return nil
+end
+
+local get_text_for_node = function(node)
   local start_row, start_col = node:start()
   local end_row, end_col     = node:end_()
 
@@ -118,23 +134,20 @@ local get_text_for_node = function(node, type)
   start_col = 0
 
   local filetype = api.nvim_buf_get_option(0, 'filetype')
-  local last_type = (last_types[type] or {})[filetype]
+  local last_type = (last_types[node:type()] or {})[filetype]
   local last_position = nil
 
   if last_type ~= nil then
-    for child, _ in node:iter_children() do
-      local ctype = child:type()
+    local child = find_node(node, last_type)
 
-      if ctype == last_type then
-        last_position = {child:end_()}
+    if child ~= nil then
+      last_position = {child:end_()}
 
-        end_row = last_position[1]
-        end_col = last_position[2]
-        local last_index = end_row - start_row
-        lines = slice(lines, 1, last_index + 1)
-        lines[#lines] = slice(lines[#lines], 1, end_col)
-        break
-      end
+      end_row = last_position[1]
+      end_col = last_position[2]
+      local last_index = end_row - start_row
+      lines = slice(lines, 1, last_index + 1)
+      lines[#lines] = slice(lines[#lines], 1, end_col)
     end
   end

lyokha added a commit to lyokha/nvim-treesitter-context that referenced this issue Oct 4, 2021
@romgrk romgrk closed this as completed in #71 Oct 5, 2021
romgrk pushed a commit that referenced this issue Oct 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants