dense-analysis / ale

Check syntax in Vim/Neovim asynchronously and fix files, with Language Server Protocol (LSP) support
BSD 2-Clause "Simplified" License
13.55k stars 1.44k forks source link

Balloons not functional in terminal vim 8.1.1073 #2442

Closed jthornhill closed 5 years ago

jthornhill commented 5 years ago

Hello! I am trying to get balloons working in my terminal for the first time. Everything works with gvim, but the balloons don't work in console vim. This is using gnome-terminal on arch linux.

The relevant portion of my vimrc is included below; I load the plugin with pathogen only after setting (what I think to be) the required options:

set mouse=a
set ttymouse=xterm2
" ...snip...
let g:ale_enabled=1
let g:ale_set_balloons=1
" ...snip...
execute pathogen#infect()

I can confirm that in general mouse support works fine for me (I've been using those settings for a long time without issue) in terminal vim, and also I can manually run e.g. call balloon_show(bufname('%')) which does display a balloon under the location of my cursor. So I guess it's an ALE specific issue (either a misconfiguration on my end or a bug).

ALEInfo included below:

 Current Filetype: ruby
Available Linters: ['brakeman', 'rails_best_practices', 'reek', 'rubocop', 'ruby', 'solargraph', 'standardrb']
  Enabled Linters: ['rubocop']
 Suggested Fixers: 
  'remove_trailing_lines' - Remove all blank lines at the end of a file.
  'rubocop' - Fix ruby files with rubocop --auto-correct.
  'rufo' - Fix ruby files with rufo
  'standardrb' - Fix ruby files with standardrb --fix
  'trim_whitespace' - Remove all trailing whitespace characters at the end of every line.
 Linter Variables:

let g:ale_ruby_rubocop_executable = 'rubocop'
let g:ale_ruby_rubocop_options = ''
 Global Variables:

let g:ale_cache_executable_check_failures = v:null
let g:ale_change_sign_column_color = 0
let g:ale_command_wrapper = ''
let g:ale_completion_delay = v:null
let g:ale_completion_enabled = 0
let g:ale_completion_max_suggestions = v:null
let g:ale_echo_cursor = 1
let g:ale_echo_msg_error_str = 'Error'
let g:ale_echo_msg_format = '%code: %%s'
let g:ale_echo_msg_info_str = 'Info'
let g:ale_echo_msg_warning_str = 'Warning'
let g:ale_enabled = 1
let g:ale_fix_on_save = 0
let g:ale_fixers = {'ruby': ['rubocop'], 'javascript': ['prettier']}
let g:ale_history_enabled = 1
let g:ale_history_log_output = 1
let g:ale_keep_list_window_open = 0
let g:ale_lint_delay = 200
let g:ale_lint_on_enter = 1
let g:ale_lint_on_filetype_changed = 1
let g:ale_lint_on_insert_leave = 0
let g:ale_lint_on_save = 1
let g:ale_lint_on_text_changed = 'always'
let g:ale_linter_aliases = {}
let g:ale_linters = {'ruby': ['rubocop'], 'javascript': ['prettier']}
let g:ale_linters_explicit = 0
let g:ale_list_vertical = 0
let g:ale_list_window_size = 10
let g:ale_loclist_msg_format = '%code: %%s'
let g:ale_lsp_root = {}
let g:ale_max_buffer_history_size = 20
let g:ale_max_signs = -1
let g:ale_maximum_file_size = v:null
let g:ale_open_list = 0
let g:ale_pattern_options = v:null
let g:ale_pattern_options_enabled = v:null
let g:ale_set_balloons = 1
let g:ale_set_highlights = 1
let g:ale_set_loclist = 1
let g:ale_set_quickfix = 0
let g:ale_set_signs = 1
let g:ale_sign_column_always = 0
let g:ale_sign_error = '✖︎✖︎'
let g:ale_sign_info = '!!'
let g:ale_sign_offset = 1000000
let g:ale_sign_style_error = '✖︎✖︎'
let g:ale_sign_style_warning = '!!'
let g:ale_sign_warning = '!!'
let g:ale_statusline_format = v:null
let g:ale_type_map = {}
let g:ale_use_global_executables = v:null
let g:ale_virtualtext_cursor = 0
let g:ale_warn_about_trailing_blank_lines = 1
let g:ale_warn_about_trailing_whitespace = 1

Thanks!

pbnj commented 5 years ago

I would like to report the same problem with a slightly different configuration:

My relevant vimrc:

set nocompatible
syntax enable
filetype plugin on

set ballooneval
set balloonevalterm
set mouse=a
set ttymouse=sgr                          " also tried `xterm` and `xterm2`

let g:ale_completion_enabled = 1 " must be set before w0rp/ale is loaded per docs
Plug 'w0rp/ale'
let g:ale_set_quickfix = 1
let g:ale_fix_on_save = 1
let g:ale_set_balloons = 1
let g:ale_fixers = {
            \   '*': ['remove_trailing_lines', 'trim_whitespace'],
            \   'rust': ['rustfmt'],
            \   'markdown': ['prettier'],
            \   'yaml': ['prettier'],
            \   'go': ['goimports'],
            \}
call plug#end()

" ...snip

My ALEInfo:

 Current Filetype: go
Available Linters: ['bingo', 'gobuild', 'gofmt', 'golangci-lint', 'golint', 'gometalinter', 'gopls', 'gosimple', 'gotype', 'govet', 'golangserver', 'staticcheck']
   Linter Aliases:
'gobuild' -> ['go build']
'govet' -> ['go vet']
  Enabled Linters: ['gofmt', 'golint', 'govet']
 Suggested Fixers: 
  'gofmt' - Fix Go files with go fmt.
  'goimports' - Fix Go files imports with goimports.
  'remove_trailing_lines' - Remove all blank lines at the end of a file.
  'trim_whitespace' - Remove all trailing whitespace characters at the end of every line.
 Linter Variables:

let g:ale_go_golint_executable = 'golint'
let g:ale_go_golint_options = ''
let g:ale_go_govet_options = ''
 Global Variables:

let g:ale_cache_executable_check_failures = v:null
let g:ale_change_sign_column_color = 0
let g:ale_command_wrapper = ''
let g:ale_completion_delay = 100
let g:ale_completion_enabled = 1
let g:ale_completion_max_suggestions = 50
let g:ale_echo_cursor = 1
let g:ale_echo_msg_error_str = 'Error'
let g:ale_echo_msg_format = '%code: %%s'
let g:ale_echo_msg_info_str = 'Info'
let g:ale_echo_msg_warning_str = 'Warning'
let g:ale_enabled = 1
let g:ale_fix_on_save = 1
let g:ale_fixers = {'go': ['goimports'], 'markdown': ['prettier'], '*': ['remove_trailing_lines', 'trim_whitespace'], 'yaml': ['prettier'], 'rust': ['rustfmt']}
let g:ale_history_enabled = 1
let g:ale_history_log_output = 1
let g:ale_keep_list_window_open = 0
let g:ale_lint_delay = 200
let g:ale_lint_on_enter = 1
let g:ale_lint_on_filetype_changed = 1
let g:ale_lint_on_insert_leave = 0
let g:ale_lint_on_save = 1
let g:ale_lint_on_text_changed = 'always'
let g:ale_linter_aliases = {}
let g:ale_linters = {}
let g:ale_linters_explicit = 0
let g:ale_list_vertical = 0
let g:ale_list_window_size = 10
let g:ale_loclist_msg_format = '%code: %%s'
let g:ale_lsp_root = {}
let g:ale_max_buffer_history_size = 20
let g:ale_max_signs = -1
let g:ale_maximum_file_size = v:null
let g:ale_open_list = 0
let g:ale_pattern_options = v:null
let g:ale_pattern_options_enabled = v:null
let g:ale_set_balloons = 1
let g:ale_set_highlights = 1
let g:ale_set_loclist = 1
let g:ale_set_quickfix = 1
let g:ale_set_signs = 1
let g:ale_sign_column_always = 0
let g:ale_sign_error = '>>'
let g:ale_sign_info = '--'
let g:ale_sign_offset = 1000000
let g:ale_sign_style_error = '>>'
let g:ale_sign_style_warning = '--'
let g:ale_sign_warning = '--'
let g:ale_statusline_format = v:null
let g:ale_type_map = {}
let g:ale_use_global_executables = v:null
let g:ale_virtualtext_cursor = 0
let g:ale_warn_about_trailing_blank_lines = 1
let g:ale_warn_about_trailing_whitespace = 1
  Command History:

(executable check - success) gofmt
(finished - exit code 0) ['/usr/local/bin/bash', '-c', 'gofmt -e ''/var/folders/vg/4dvl179n1z36m4t4yqg65xb40000gn/T/vDpbihc/0/main.go''']

<<<NO OUTPUT RETURNED>>>

(executable check - success) golint
(finished - exit code 0) ['/usr/local/bin/bash', '-c', '''golint'' ''/var/folders/vg/4dvl179n1z36m4t4yqg65xb40000gn/T/vDpbihc/1/main.go''']

<<<NO OUTPUT RETURNED>>>

(executable check - success) go
(finished - exit code 0) ['/usr/local/bin/bash', '-c', 'cd ''/Users/pb250031/go/src/github.com/petermbenjamin/gitignore'' &&  go vet  .']

<<<NO OUTPUT RETURNED>>>
w0rp commented 5 years ago

Try putting let g:ale_set_balloons = 1 before Plug 'w0rp/ale'.

w0rp commented 5 years ago

Also, let me know what the output of :set balloonexpr is.

pbnj commented 5 years ago

I moved let g:ale_set_balloons = 1 to before Plug 'w0rp/ale', but still no luck.

The output of :set balloonexpr is ale#balloon#Expr()

w0rp commented 5 years ago

I can't figure out myself how to enable balloons in any terminal I've tried. Maybe @gagbo has some advice. My advice is to use GVim.

pbnj commented 5 years ago

It's not working as expected in GVim (MacVim) for me. It only works on linting errors, but not for type definitions.

However, I did find a weird behavior to get balloons to show up in terminal Vim the same way they do in GVim (i.e. linting error balloons). I would not call it a workaround either, just a weird behavior.

Here is a screenshot for reference:

Screen Shot 2019-05-01 at 3 04 06 PM

The steps to reproduce are:

  1. Hover mouse over the error (nothing shows up yet)
  2. Go into command mode (i.e. type :). Then error balloon shows up 🤔
w0rp commented 5 years ago

Which tools are you using that that you expect to see hover information from? Are you using a language server, and can you get diagnostics from it? Does the language sever you are using support hover information?

johnelliott commented 5 years ago

Terminal.app: VIM version 8.1.950 no tmux or screen ttymouse=sgr ESLint

image image

Steps to see brief balloon:

  1. Put vim cursor on line with a lint error
  2. Put mouse cursor on line with lint so cursor is visible
  3. Move vim cursor up (brief flash as mouse cursor is hidden)
  4. Move vim cursor (no balloons)

It seems like the balloon won't show if the mouse cursor is not visible. Since keyboard input hides the mouse cursor this is quickly kills the balloon.

The issue with terminal vim seems to be that the balloon won't show up unless you're mouse-hovering and then the vim cursor moves. This shows a brief flash of the balloon, but only sometimes. The position of the vim cursor doesn't appear to matter, just that it moves while the mouse cursor is hovering and visible.

I haven't gone in to any source code, just doing some interactive testing here.

pbnj commented 5 years ago

Sorry if I am confused about the balloon-eval feature in Vim. I arrived at my current understanding of it after:

  1. Reading :h balloon-eval, which say it is used "to display dynamic information based on where the mouse is pointing."
  2. Reading govim docs
  3. Seeing a demo of govim (an alternative to vim-go plugin) which uses gopls language server and it seemed that any symbol that was hovered over in terminal Vim or GVim displayed info (see demo).

Having said that, I decided to try replacing vim-go with govim and keeping all my ale configs the same, and lo and behold, hovering over symbols shows type information.

So, I think it's safe to say that it's the language plugin that is providing this type definition information on hover? Although, if it is possible via a language plugin, it would sure be nice to have a consistent behavior across all languages via ALEHover and balloons?

pbnj commented 5 years ago

@johnelliott - the behavior you're experiencing somewhat resembles what I have experienced and reported earlier in this thread

TL;DR - hover over with mouse and some other event (like going into command mode by typing :) seems to trigger balloons to show (consistently for me), with the added bit from my latest realization that individual language plugins can have an impact on the behavior of balloons (in my case govim versus vim-go lead to different behaviors about what gets shown in balloons).

johnelliott commented 5 years ago

@petermbenjamin Oh yeah, going to command more is way more sticky than what I was doing previously.

jthornhill commented 5 years ago

The ability to show balloons when hitting : makes this seem like it might just be a vim bug/limitation rather than an ALE issue (see: https://github.com/vim/vim/issues/2481 and https://github.com/vim/vim/issues/2352 ).

gagbo commented 5 years ago

I haven't used Vim in a while :)

For reference, it all started on this PR and there's a gif with how it worked with RLS in gvim (Linux) when it was merged. I had no issues with terminal either when I tested it (but I didn't do a gif with working state at the time because reasons)

It seems like the balloon won't show if the mouse cursor is not visible. Since keyboard input hides the mouse cursor this is quickly kills the balloon.

seems like intended behaviour : https://github.com/vim/vim/blob/master/runtime/doc/options.txt#L1147 . Checking the code is the only way to be 100% sure.

The ability to show balloons when hitting : makes this seem like it might just be a vim bug/limitation rather than an ALE issue (see: vim/vim#2481 and vim/vim#2352 ).

👍 especially 2481.

Also, I can confirm on MacOs with

vim --version
VIM - Vi IMproved 8.1 (2018 May 18, compiled Feb 19 2019 12:07:03)
macOS version
Included patches: 1-950
Compiled by Homebrew
Huge version with MacVim GUI.
...
All balloon_eval in the world

I cannot get balloons to work in Terminal, iTerm2, or Alacritty with the sample file below (adapted from vim help)

" vim --clean beval_test.vim | source %
function! MyBalloonExpr()
    return 'Cursor is at line ' . v:beval_lnum .
                \', column ' . v:beval_col .
                \ ' of file ' .  bufname(v:beval_bufnr) .
                \ ' on word "' . v:beval_text . '"'
endfunction
set bexpr=MyBalloonExpr()
set ballooneval
set balloonevalterm
set ttymouse=sgr " I copied that from an earlier comment just to be sure, same behaviour without this line

I don't have any issues making this work with the associated mvim. So at least until the above snippet works in terminal vim, this is a vim issue first. If this works and fails in ALE, this will become an ALE issue.

w0rp commented 5 years ago

One issue with mouse support in terminals is that it might not be Vim's fault either. Some terminals don't track where the mouse is.

gagbo commented 5 years ago

Fair enough, I should have said it's an "upstream (vim and/or terminal)" issue first, instead of just a "vim issue". The short script provides an easy first step for checking balloon problems at least.

tsony-tsonev commented 5 years ago

I had problem with balloons auto closing very quickly after showing on vim version 8.1.1073, so I built the latest version and the problem disappeared. I even made franken balloonexpr gathered from different approaches from the internet.

I'm using zsh5.4.2 tmux2.9a vim8.1-1826

The custom balloon func previews - folds, ale lint warnings/errors, golang info.

vimrc:

set ttymouse=sgr
set balloondelay=250
set ballooneval
set balloonevalterm

" Returns either the contents of a fold, lint err/warn or godef.
function! BalloonExpr()
  let foldStart = foldclosed(v:beval_lnum)

  " check if we are in a fold
  if foldStart >= 0
    let foldEnd = foldclosedend(v:beval_lnum)
    let numLines = foldEnd - foldStart + 1
    let lines = []
    " Up to 31 lines get shown okay; beyond that, only 30 lines are shown with
    " ellipsis in between to indicate too much. The reason why 31 get shown ok
    " is that 30 lines plus one of ellipsis is 31 anyway.
    if ( numLines > 31 )
      let lines = getline( foldStart, foldStart + 14 )
      let lines += [ '-- Snipped ' . ( numLines - 30 ) . ' lines --' ]
      let lines += getline( foldEnd - 14, foldEnd )
    else
      let lines = getline( foldStart, foldEnd )
    endif

    "return join( lines, has( "balloon_multiline" ) ? "\n" : " " )
    call popup_beval(lines, #{mousemoved:'word'})
    return ""
  endif

  " check if there is a lint error on the line
  let l:loclist = get(g:ale_buffer_info, v:beval_bufnr, {'loclist': []}).loclist
  let l:index = ale#util#BinarySearch(l:loclist, v:beval_bufnr, v:beval_lnum, v:beval_col)
  " get the lint message if found
  if l:index >= 0
    return l:loclist[l:index].text
  endif

  " use golang as default
  return go#tool#DescribeBalloon()
endfunction
set balloonexpr=BalloonExpr()
w0rp commented 5 years ago

I don't think there's a bug in ALE here. It's either troubles with different terminal types, Vim configuration, or bugs in Vim.

kevr commented 3 years ago

I can't figure out myself how to enable balloons in any terminal I've tried. Maybe @gagbo has some advice. My advice is to use GVim.

This does not seem like an answer to the issue at hand; it seems like a dodge of dealing with the issue because you personally use gvim and think that is the way to go.

This is still an issue. We can see that many projects with language servers have this working in vim, so I don't think it's a vim drawback.