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

Feature request: Move to toplevel form #49

Open
phogh opened this issue Dec 1, 2023 · 1 comment
Open

Feature request: Move to toplevel form #49

phogh opened this issue Dec 1, 2023 · 1 comment

Comments

@phogh
Copy link

phogh commented Dec 1, 2023

I miss the [[ and ]] features of vim-sexp to jump to the toplevel form start and end. I initially implemented a solution by iterating the api function move_to_parent_form_{start,end} used in (. It worked fine but it was neater to create new api functions move_to_root_{start,end}. The code is based on move_to_parent_form (Apologies I don't know enough treesitter and nvim lua to know if there's a better approach!):

-- Helper to get cursor pos for form edge.
local function form_node_edge_pos(form_node, direction, lang)
  local form_edges = lang.get_form_edges(form_node)
  local edge_cursor_pos = {
    form_edges[direction].range[1] + 1,
    form_edges[direction].range[2]
  }
  return edge_cursor_pos
end

local function move_to_root(direction)
  local lang = langs.get_language_api()
  local cur_node = ts.get_node_at_cursor()

  local nearest_form_node = traversal.find_nearest_form(cur_node, { lang = lang })
  if not nearest_form_node or nearest_form_node:type() == "source" then
    return
  end

  local cur_cursor_pos = vim.api.nvim_win_get_cursor(0)
  local form_node_to_move_to = nearest_form_node
  repeat
    prev_form = form_node_to_move_to
    form_node_to_move_to = lang.get_node_root(form_node_to_move_to):parent()
  until not form_node_to_move_to or
        form_node_to_move_to:type() == "source" or
        is_cursor_at_form_edge(form_node_to_move_to, direction,  
          form_node_edge_pos(prev_form, direction, lang), lang)

  form_node_to_move_to = prev_form
  move_to_form_edge(form_node_to_move_to, direction, lang)
end

function M.move_to_root_start()
  move_to_root(MOTION_DIRECTIONS.LEFT)
end

function M.move_to_root_end()
  move_to_root(MOTION_DIRECTIONS.RIGHT)
end
@julienvincent
Copy link
Owner

Hi, sorry for taking so long to reply here.

Thanks for your interest!

A similar category of request came in today (#53) and I want to share the comment I made there with this issue: #53 (comment)

Essentially I think this kind of motion can be solved using the existing and more language agnostic nvim-treesitter-textobjects plugin found here: https://github.com/nvim-treesitter/nvim-treesitter-textobjects?tab=readme-ov-file#text-objects-move.

Let me know what you think.

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

No branches or pull requests

2 participants