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

next() and next_up() do not jump to the next tag in the vue file #183

Closed
Wjinlei opened this issue Nov 11, 2022 · 7 comments
Closed

next() and next_up() do not jump to the next tag in the vue file #183

Wjinlei opened this issue Nov 11, 2022 · 7 comments
Assignees
Labels
bug Something isn't working

Comments

@Wjinlei
Copy link

Wjinlei commented Nov 11, 2022

Describe the bug

I'm not sure if it's a bug, but it's really weird
next() and next_up() do not jump to the next tag in the vue file, prev() and prev_up() are fine,

System information

  • OS: [ArchLinux]
  • Neovim version: 0.9.0-dev
  • AerialInfo:
Aerial Info
-----------
Filetype: vue
Configured backends:
  lsp (supported) (attached)
  treesitter (not supported) [No query file for 'vue']
  markdown (not supported) [Filetype is not markdown]
  man (not supported) [Filetype is not man]
Show symbols: Class, Constructor, Enum, Function, Interface, Module, Method, Struct
  • Aerial config:
	require("aerial").setup({
		-- Priority list of preferred backends for aerial.
		-- This can be a filetype map (see :help aerial-filetype-map)
		backends = { "lsp", "treesitter", "markdown", "man" },

		layout = {
			-- These control the width of the aerial window.
			-- They can be integers or a float between 0 and 1 (e.g. 0.4 for 40%)
			-- min_width and max_width can be a list of mixed types.
			-- max_width = {40, 0.2} means "the lesser of 40 columns or 20% of total"
			max_width = { 40, 0.2 },
			width = nil,
			min_width = 10,

			-- key-value pairs of window-local options for aerial window (e.g. winhl)
			win_opts = {},

			-- Determines the default direction to open the aerial window. The 'prefer'
			-- options will open the window in the other direction *if* there is a
			-- different buffer in the way of the preferred direction
			-- Enum: prefer_right, prefer_left, right, left, float
			default_direction = "prefer_right",

			-- Determines where the aerial window will be opened
			--   edge   - open aerial at the far right/left of the editor
			--   window - open aerial to the right/left of the current window
			placement = "window",
		},

		-- Determines how the aerial window decides which buffer to display symbols for
		--   window - aerial window will display symbols for the buffer in the window from which it was opened
		--   global - aerial window will display symbols for the current window
		attach_mode = "window",

		-- List of enum values that configure when to auto-close the aerial window
		--   unfocus       - close aerial when you leave the original source window
		--   switch_buffer - close aerial when you change buffers in the source window
		--   unsupported   - close aerial when attaching to a buffer that has no symbol source
		close_automatic_events = {},

		-- Keymaps in aerial window. Can be any value that `vim.keymap.set` accepts OR a table of keymap
		-- options with a `callback` (e.g. { callback = function() ... end, desc = "", nowait = true })
		-- Additionally, if it is a string that matches "aerial.<name>",
		-- it will use the mapping at require("aerial.action").<name>
		-- Set to `false` to remove a keymap
		keymaps = {
			["?"] = "actions.show_help",
			["g?"] = "actions.show_help",
			["<CR>"] = "actions.jump",
			["<2-LeftMouse>"] = "actions.jump",
			["<C-v>"] = "actions.jump_vsplit",
			["<C-s>"] = "actions.jump_split",
			["p"] = "actions.scroll",
			["<C-j>"] = "actions.down_and_scroll",
			["<C-k>"] = "actions.up_and_scroll",
			["{"] = "actions.prev",
			["}"] = "actions.next",
			["[["] = "actions.prev_up",
			["]]"] = "actions.next_up",
			["q"] = "actions.close",
			["o"] = "actions.tree_toggle",
			["za"] = "actions.tree_toggle",
			["O"] = "actions.tree_toggle_recursive",
			["zA"] = "actions.tree_toggle_recursive",
			["l"] = "actions.tree_open",
			["zo"] = "actions.tree_open",
			["L"] = "actions.tree_open_recursive",
			["zO"] = "actions.tree_open_recursive",
			["h"] = "actions.tree_close",
			["zc"] = "actions.tree_close",
			["H"] = "actions.tree_close_recursive",
			["zC"] = "actions.tree_close_recursive",
			["zr"] = "actions.tree_increase_fold_level",
			["zR"] = "actions.tree_open_all",
			["zm"] = "actions.tree_decrease_fold_level",
			["zM"] = "actions.tree_close_all",
			["zx"] = "actions.tree_sync_folds",
			["zX"] = "actions.tree_sync_folds",
		},

		-- When true, don't load aerial until a command or function is called
		-- Defaults to true, unless `on_attach` is provided, then it defaults to false
		lazy_load = false,

		-- Disable aerial on files with this many lines
		disable_max_lines = 10000,

		-- Disable aerial on files this size or larger (in bytes)
		disable_max_size = 2000000, -- Default 2MB

		-- A list of all symbols to display. Set to false to display all symbols.
		-- This can be a filetype map (see :help aerial-filetype-map)
		-- To see all available values, see :help SymbolKind
		filter_kind = {
			"Class",
			"Constructor",
			"Enum",
			"Function",
			"Interface",
			"Module",
			"Method",
			"Struct",
		},

		-- Determines line highlighting mode when multiple splits are visible.
		-- split_width   Each open window will have its cursor location marked in the
		--               aerial buffer. Each line will only be partially highlighted
		--               to indicate which window is at that location.
		-- full_width    Each open window will have its cursor location marked as a
		--               full-width highlight in the aerial buffer.
		-- last          Only the most-recently focused window will have its location
		--               marked in the aerial buffer.
		-- none          Do not show the cursor locations in the aerial window.
		highlight_mode = "split_width",

		-- Highlight the closest symbol if the cursor is not exactly on one.
		highlight_closest = true,

		-- Highlight the symbol in the source buffer when cursor is in the aerial win
		highlight_on_hover = false,

		-- When jumping to a symbol, highlight the line for this many ms.
		-- Set to false to disable
		highlight_on_jump = 300,

		-- Define symbol icons. You can also specify "<Symbol>Collapsed" to change the
		-- icon when the tree is collapsed at that symbol, or "Collapsed" to specify a
		-- default collapsed icon. The default icon set is determined by the
		-- "nerd_font" option below.
		-- If you have lspkind-nvim installed, it will be the default icon set.
		-- This can be a filetype map (see :help aerial-filetype-map)
		icons = {},

		-- Control which windows and buffers aerial should ignore.
		-- If attach_mode is "global", focusing an ignored window/buffer will
		-- not cause the aerial window to update.
		-- If open_automatic is true, focusing an ignored window/buffer will not
		-- cause an aerial window to open.
		-- If open_automatic is a function, ignore rules have no effect on aerial
		-- window opening behavior; it's entirely handled by the open_automatic
		-- function.
		ignore = {
			-- Ignore unlisted buffers. See :help buflisted
			unlisted_buffers = true,

			-- List of filetypes to ignore.
			filetypes = {},

			-- Ignored buftypes.
			-- Can be one of the following:
			-- false or nil - No buftypes are ignored.
			-- "special"    - All buffers other than normal buffers are ignored.
			-- table        - A list of buftypes to ignore. See :help buftype for the
			--                possible values.
			-- function     - A function that returns true if the buffer should be
			--                ignored or false if it should not be ignored.
			--                Takes two arguments, `bufnr` and `buftype`.
			buftypes = "special",

			-- Ignored wintypes.
			-- Can be one of the following:
			-- false or nil - No wintypes are ignored.
			-- "special"    - All windows other than normal windows are ignored.
			-- table        - A list of wintypes to ignore. See :help win_gettype() for the
			--                possible values.
			-- function     - A function that returns true if the window should be
			--                ignored or false if it should not be ignored.
			--                Takes two arguments, `winid` and `wintype`.
			wintypes = "special",
		},

		-- Use symbol tree for folding. Set to true or false to enable/disable
		-- Set to "auto" to manage folds if your previous foldmethod was 'manual'
		-- This can be a filetype map (see :help aerial-filetype-map)
		manage_folds = false,

		-- When you fold code with za, zo, or zc, update the aerial tree as well.
		-- Only works when manage_folds = true
		link_folds_to_tree = false,

		-- Fold code when you open/collapse symbols in the tree.
		-- Only works when manage_folds = true
		link_tree_to_folds = true,

		-- Set default symbol icons to use patched font icons (see https://www.nerdfonts.com/)
		-- "auto" will set it to true if nvim-web-devicons or lspkind-nvim is installed.
		nerd_font = "auto",

		-- Call this function when aerial attaches to a buffer.
		on_attach = function(bufnr)
			vim.keymap.set("n", "<C-m>", "<cmd>AerialToggle!<CR>", { buffer = bufnr })
			vim.keymap.set("n", "<C-k>", "<cmd>lua require('aerial').prev()<CR>", { buffer = bufnr })
			vim.keymap.set("n", "<C-j>", "<cmd>lua require('aerial').next()<CR>", { buffer = bufnr })
			vim.cmd([[augroup AerialClose]])
			vim.cmd([[autocmd! * <buffer>]])
			vim.cmd([[autocmd BufLeave <buffer> :AerialClose]])
			vim.cmd([[augroup END]])
		end,

		-- Call this function when aerial first sets symbols on a buffer.
		-- on_first_symbols = function(bufnr) end,

		-- Automatically open aerial when entering supported buffers.
		-- This can be a function (see :help aerial-open-automatic)
		open_automatic = false,

		-- Run this command after jumping to a symbol (false will disable)
		post_jump_cmd = "normal! zz",

		-- When true, aerial will automatically close after jumping to a symbol
		close_on_select = false,

		-- The autocmds that trigger symbols update (not used for LSP backend)
		update_events = "TextChanged,InsertLeave",

		-- Show box drawing characters for the tree hierarchy
		show_guides = false,

		-- Customize the characters used when show_guides = true
		guides = {
			-- When the child item has a sibling below it
			mid_item = "├─",
			-- When the child item is the last in the list
			last_item = "└─",
			-- When there are nested child guides to the right
			nested_top = "",
			-- Raw indentation
			whitespace = "  ",
		},

		-- Options for opening aerial in a floating win
		float = {
			-- Controls border appearance. Passed to nvim_open_win
			border = "rounded",

			-- Determines location of floating window
			--   cursor - Opens float on top of the cursor
			--   editor - Opens float centered in the editor
			--   win    - Opens float centered in the window
			relative = "cursor",

			-- These control the height of the floating window.
			-- They can be integers or a float between 0 and 1 (e.g. 0.4 for 40%)
			-- min_height and max_height can be a list of mixed types.
			-- min_height = {8, 0.1} means "the greater of 8 rows or 10% of total"
			max_height = 0.9,
			height = nil,
			min_height = { 8, 0.1 },

			override = function(conf)
				-- This is the config that will be passed to nvim_open_win.
				-- Change values here to customize the layout
				return conf
			end,
		},

		lsp = {
			-- Fetch document symbols when LSP diagnostics update.
			-- If false, will update on buffer changes.
			diagnostics_trigger_update = true,

			-- Set to false to not update the symbols when there are LSP errors
			update_when_errors = true,

			-- How long to wait (in ms) after a buffer change before updating
			-- Only used when diagnostics_trigger_update = false
			update_delay = 300,
		},

		treesitter = {
			-- How long to wait (in ms) after a buffer change before updating
			update_delay = 300,
		},

		markdown = {
			-- How long to wait (in ms) after a buffer change before updating
			update_delay = 300,
		},

		man = {
			-- How long to wait (in ms) after a buffer change before updating
			update_delay = 300,
		},

To Reproduce
Steps to reproduce the behavior:

  1. open .vue file
  2. invoke aerial.next() or aerial.next_up()
@Wjinlei Wjinlei added the bug Something isn't working label Nov 11, 2022
@stevearc
Copy link
Owner

That certainly sounds like a bug. Could you provide a minimal sample file that exhibits this problem?

Also, I assume that you're using vuels as your language server?

@Wjinlei
Copy link
Author

Wjinlei commented Nov 16, 2022

@stevearc Configuration file as above, I bind the key is

vim.keymap.set("n", "<C-m>", "<cmd>AerialToggle!<CR>", { buffer = bufnr })
vim.keymap.set("n", "<C-k>", "<cmd>lua require('aerial').prev()<CR>", { buffer = bufnr })
vim.keymap.set("n", "<C-j>", "<cmd>lua require('aerial').next()<CR>", { buffer = bufnr })

Here's a demo
Peek 2022-11-16 09-40

As you can see, when I press Ctrl+k, everything works fine, but when I press Ctrl+j, it doesn't seem to work.

The lsp server I use is volar
lsp

@stevearc
Copy link
Owner

I meant can you provide a minimal .vue file. I don't use vue or volar and it will be easier for me to repro this if I don't have to first figure out how to set up a vue project. Also there will be fewer differences between our two setups when I test it.

@Wjinlei
Copy link
Author

Wjinlei commented Nov 16, 2022

@stevearc This is a demo vue file

<template>
  <h1>Hello {{ world }}</h1>
</template>

<script>
export default {
  name: 'Demo',
  data() {
    return {
      world: 'vue'
    }
  }
}
</script>

@Wjinlei
Copy link
Author

Wjinlei commented Nov 16, 2022

@stevearc Here's another one

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hello World</title>
    <script src="https://unpkg.com/vue@3.2.31/dist/vue.global.js"></script> <!-- 引入Vue3 -->
</head>

<body>
    <div id="app">
        <h1>Hello {{ lanuage }}</h1>
    </div>
</body>

<script>
    const app = Vue.createApp({
        data() {
            return {
                lanuage: "Vue"
            }
        }
    })
    const vm = app.mount("#app")
</script>

</html>

@stevearc
Copy link
Owner

Ugh, as expected this is because volar is giving...if not incorrect symbol ranges, then at least surprising ones. The starting column of the symbols is off the end of the line, which means that it's impossible for us to ever be exactly on that symbol and that generally creates issues (navigation being the most obvious).

I've added a hack that should work around this, but the real solution is for the language server to produce correct symbol positions. I've reported this upstream vuejs/language-tools#2118

@Wjinlei
Copy link
Author

Wjinlei commented Nov 16, 2022

@stevearc Thank you, it's working fine now, hopefully upstream can fix it too

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants