ycm-core / YouCompleteMe

A code-completion engine for Vim
http://ycm-core.github.io/YouCompleteMe/
GNU General Public License v3.0
25.36k stars 2.8k forks source link

position of popup windows #3676

Closed cridemichel closed 4 years ago

cridemichel commented 4 years ago

Issue Prelude

Please complete these steps and check these boxes (by putting an x inside the brackets) before filing your issue:

Thank you for adhering to this process! It ensures your issue is resolved quickly and that neither your nor our time is needlessly wasted.

Issue Details

Provide a clear description of the problem, including the following key questions:

I used the new hover function to get documentation of LSP symbols (from texlab LSP) via the following mapping:

nmap <leader>yh <plug>(YCMHover)

and if symbol hovered is close to left margin, this is what I get:

Schermata 2020-05-10 alle 11 06 57

please note the shrunk popup on the right margin. Is there a way to set a minimum width for the popup window?

minimal .vimrc to reproduce the issue

set nocompatible
call plug#begin('~/.vim/plugged')
Plug 'Valloric/YouCompleteMe' 
Plug 'lervag/vimtex' 
call plug#end()            
filetype plugin indent on
syntax enable
let mapleader=' '
nmap <leader>yh <plug>(YCMHover)
let g:ycm_server_python_interpreter='/usr/local/bin/python3'
let g:ycm_language_server = [
  \   {
  \     'name': 'latex',
  \     'cmdline': [ 'texlab' ],
  \     'filetypes': [ 'tex' ],
  \     'root_files': [ '.criprojroot' ],
  \   },
  \ ]
let g:vimtex_enabled=1
if !exists('g:ycm_semantic_triggers')
   let g:ycm_semantic_triggers = {}
endif
au VimEnter * let g:ycm_semantic_triggers.tex=g:vimtex#re#youcompleteme

Output of vim --version

VIM - Vi IMproved 8.2 (2019 Dec 12, compilato May  6 2020 06:17:56)
Argomento di opzione sconosciuto: "--versio"
Maggiori informazioni con: "vim -h"
❯ vim --version
VIM - Vi IMproved 8.2 (2019 Dec 12, compilato May  6 2020 06:17:56)
Versione macOS
Patch incluse: 1-700
Compilato da Homebrew
Versione gigante senza GUI.  Funzionalità incluse (+) o escluse (-):
+acl               -farsi             +mouse_sgr         +tag_binary
+arabic            +file_in_path      -mouse_sysmouse    -tag_old_static
+autocmd           +find_in_path      +mouse_urxvt       -tag_any_white
+autochdir         +float             +mouse_xterm       -tcl
-autoservername    +folding           +multi_byte        +termguicolors
-balloon_eval      -footer            +multi_lang        +terminal
+balloon_eval_term +fork()            -mzscheme          +terminfo
-browse            +gettext           +netbeans_intg     +termresponse
++builtin_terms    -hangul_input      +num64             +textobjects
+byte_offset       +iconv             +packages          +textprop
+channel           +insert_expand     +path_extra        +timers
+cindent           +ipv6              +perl              +title
-clientserver      +job               +persistent_undo   -toolbar
+clipboard         +jumplist          +popupwin          +user_commands
+cmdline_compl     +keymap            +postscript        +vartabs
+cmdline_hist      +lambda            +printer           +vertsplit
+cmdline_info      +langmap           +profile           +virtualedit
+comments          +libcall           -python            +visual
+conceal           +linebreak         +python3           +visualextra
+cryptv            +lispindent        +quickfix          +viminfo
+cscope            +listcmds          +reltime           +vreplace
+cursorbind        +localmap          +rightleft         +wildignore
+cursorshape       +lua               +ruby              +wildmenu
+dialog_con        +menu              +scrollbind        +windows
+diff              +mksession         +signs             +writebackup
+digraphs          +modify_fname      +smartindent       -X11
-dnd               +mouse             -sound             -xfontset
-ebcdic            -mouseshape        +spell             -xim
+emacs_tags        +mouse_dec         +startuptime       -xpm
+eval              -mouse_gpm         +statusline        -xsmp
+ex_extra          -mouse_jsbterm     -sun_workshop      -xterm_clipboard
+extra_search      +mouse_netterm     +syntax            -xterm_save
   file vimrc di sistema: "$VIM/vimrc"
       file vimrc utente: "$HOME/.vimrc"
    II file vimrc utente: "~/.vim/vimrc"
        file exrc utente: "$HOME/.exrc"
        file dei default: "$VIMRUNTIME/defaults.vim"
         $VIM di riserva: "/usr/local/share/vim"
Compilazione: clang -c -I. -Iproto -DHAVE_CONFIG_H   -DMACOS_X -DMACOS_X_DARWIN  -g -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
Link: clang   -L. -fstack-protector-strong -L/usr/local/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/openssl@1.1/lib -L/usr/local/opt/readline/lib  -L/usr/local/lib -o vim        -lncurses -liconv -lintl -framework AppKit  -L/usr/local/opt/lua/lib -llua5.3 -mmacosx-version-min=10.15 -fstack-protector-strong -L/usr/local/lib  -L/usr/local/Cellar/perl/5.30.2_1/lib/perl5/5.30.2/darwin-thread-multi-2level/CORE -lperl -lm -lutil -lc  -L/usr/local/opt/python@3.8/Frameworks/Python.framework/Versions/3.8/lib/python3.8/config-3.8-darwin -lpython3.8 -framework CoreFoundation  -lruby.2.7

Output of YcmDebugInfo

Printing YouCompleteMe debug information...
-- Completion API: 1
-- Client logfile: /var/folders/26/9q3nft3x4xg2zbj45nzm__100000gn/T/ycm_5wpfgxrm.log
-- Server Python interpreter: /usr/local/opt/python/bin/python3.7
-- Server Python version: 3.7.7
-- Server has Clang support compiled in: False
-- Clang version: None
-- No extra configuration file found
-- GenericLSP completer debug information:
--   latexCompleter running
--   latexCompleter process ID: 61158
--   latexCompleter executable: ['/usr/local/bin/texlab']
--   latexCompleter logfiles:
--     /var/folders/26/9q3nft3x4xg2zbj45nzm__100000gn/T/latexcompleter_stderr8y3pu6e_.log
--   latexCompleter Server State: Initialized
--   latexCompleter Project Directory: /Users/demichel/VIM_STUFF
--   latexCompleter Settings: {}
-- Server running at: http://127.0.0.1:58371
-- Server process ID: 61155
-- Server logfiles:
--   /var/folders/26/9q3nft3x4xg2zbj45nzm__100000gn/T/ycmd_58371_stdout_kphlr0_u.log
--   /var/folders/26/9q3nft3x4xg2zbj45nzm__100000gn/T/ycmd_58371_stderr_bbp29_ps.log

Output of YcmDiags

/Users/demichel/PAPERS/HAIRPIN/manuscriptV1.tex|1 col 1 warning| Unused global option(s):
/Users/demichel/PAPERS/HAIRPIN/manuscriptV1.tex|1 col 1 warning| Float too large for page by 11.7994pt on input line 151.
/Users/demichel/PAPERS/HAIRPIN/manuscriptV1.tex|98 col 1 warning| Underfull \hbox (badness 2221) in paragraph at lines 98--106
/Users/demichel/PAPERS/HAIRPIN/manuscriptV1.tex|203 col 1 warning| Underfull \hbox (badness 2318) in paragraph at lines 203--212
/Users/demichel/PAPERS/HAIRPIN/manuscriptV1.tex|256 col 1 warning| Underfull \hbox (badness 1242) in paragraph at lines 256--260
/Users/demichel/PAPERS/HAIRPIN/manuscriptV1.tex|285 col 1 warning| Overfull \hbox (2.1496pt too wide) in paragraph at lines 285--286
/Users/demichel/PAPERS/HAIRPIN/manuscriptV1.tex|135 col 1 warning| Underfull \hbox (badness 1721) in paragraph at lines 135--142

Output of git rev-parse HEAD in YouCompleteMe installation directory

b48e6d49fa3441f507f91a9dae3437ff64f876f6

Contents of YCM, ycmd and completion engine logfiles

Reproduce the issue with vim -Nu /path/to/YCM/vimrc_ycm_minimal, which enabled debug logging and other useful diagnostics. Include a link to a gist containing all of the log files listed by :YcmToggleLogs.

OS version, distribution, etc.

mac osx catilina 10.15.4

Include system information here.

Output of build/install commands

Include link to a gist containing the invocation and entire output of install.py if reporting an installation issue.

puremourning commented 4 years ago

I noticed this too. It seems the only solution is to set 'wrap': 0 for the popup here

But that has its own problems.

I really don't want to write more complex code for popup positioning...

not sure what to do here.

puremourning commented 4 years ago

actually I cooked up some logic that might work....

    call popup_hide( s:cursorhold_popup )
    let [ _, row, col, _, _ ] = getcurpos()
    let pos = screenpos( win_getid(), row, col )
    let lines = split( response, "\n" )
    let len = max( map( lines, "len( v:val )" ) )
    let wrap = 0
    if len >= &columns
      let place_at = 'botleft'
      let wrap = 1
    elseif pos.col + len >= &columns
      let place_at = 'botright'
    else
      let place_at = 'botleft'
    endif
    let s:cursorhold_popup = popup_atcursor(
          \   split( response, "\n" ),
          \   {
          \     'pos': place_at,
          \     'padding': [ 0, 1, 0, 1 ],
          \     'moved': 'word',
          \     'maxwidth': &columns,
          \     'close': 'click',
          \     'wrap': wrap,
          \   }
          \ )
cridemichel commented 4 years ago

thank you for the prompt reply ...but how could I test this? My idea was simply the following: if cursor is at position (x,y) (where 1 < x <= winwidth and 1 < y <= winheight), then if x+minwidth > winwidth, set x = winwidth-minwidth, and mutatis mutandis do the same for y-axis.

puremourning commented 4 years ago

Try changing these lines to the above

cridemichel commented 4 years ago

still getting this:

Schermata 2020-05-10 alle 14 19 56

puremourning commented 4 years ago

You can't have made the changes correctly then. At the very least, wrap should have been disabled.

I pushed the change to my fork

cridemichel commented 4 years ago

I copied the file autoload/youcompleteme.vim from your fork over mine and I am still getting this: Schermata 2020-05-10 alle 14 38 18

puremourning commented 4 years ago

Please list exact steps to reproduce, per CONTRIBUTING.md

Please also try with the minimal vimrc, per the CONTRIBUTING.md instructions.

cridemichel commented 4 years ago

I have already provided a minimal vimrc file to use and all what you have to do is to open the hover popup...

puremourning commented 4 years ago

There's a reason that I asked for that.

The reasons are clearly explained in CONTRIBUTING.md. Your test case is not minimal and you have not listed the exact steps to reproduce.

Screenshot 2020-05-10 at 13 46 10

Frankly I find that attitude disappointing and somewhat entitled. We do this in our spare time with literally no reward, so when I see that sort of response I'm often disinclined to work further on the request or issue. I have many other things I could be doing with my Sunday.

I'm going to give the benefit of the doubt here and assume you didn't mean to come across as entitled or unwilling to engage.

cridemichel commented 4 years ago

Dear, I apologize if I have hurt you somehow, it was not my intention at all. I think that the culprit was the use use of "botleft" in the first "place_at", indeed if I replace "botleft" with "botright", i.e.

if len >= &columns
      let place_at = 'botright'
      let wrap = 1
    elseif pos.col + len >= &columns
      let place_at = 'botright'
    else
      let place_at = 'botleft'
    endif

I get the more pleasant layout as follows:

Schermata 2020-05-10 alle 15 03 46

an issue of the present solution is that the popup overlaps the sign column, best Cristiano

puremourning commented 4 years ago

hmm. I think that would go wrong now on the other side of the screen.

I think I worked it out. When a single line of the text is > the screen width, we have to be smarter.

I pushed a new commit: https://github.com/puremourning/YouCompleteMe/commit/2828271b092a3bf34c330b9a317f77177b280955

I was able to repro with this (btw, this is how you write steps to reproduce, you'll find this useful when approaching other open source or professional issues)

def Really_Long_Method( which, has, some, param, that, take, the, whole, line ):
  """Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum egestas libero urna, vel sagittis felis condimentum in. Nulla arcu eros, aliquet vel mollis vitae, semper eu ex. Donec posuere quam et ornare sagittis. Curabitur nunc ex, fringilla quis lorem sed, dignissim congue felis. Integer vestibulum ac elit vel blandit. Nam non dui urna. Integer eu semper massa. Nullam ac elit interdum, aliquet elit nec, porttitor orci. Duis tempus justo lorem, ac fringilla ante viverra egestas. Etiam eleifend enim ac libero dapibus, quis condimentum lectus tristique. Fusce feugiat, lorem et faucibus eleifend, ipsum nisi maximus justo, at consectetur ligula leo vitae justo."""
  # Really long one-line
  pass

def Really_Long_Method_2():
  """Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum egestas
  libero urna, vel sagittis felis condimentum in. Nulla arcu eros, aliquet vel
  mollis vitae, semper eu ex. Donec posuere quam et ornare sagittis. Curabitur
  nunc ex, fringilla quis lorem sed, dignissim congue felis. Integer vestibulum
  ac elit vel blandit. Nam non dui urna. Integer eu semper massa. Nullam ac elit
  interdum, aliquet elit nec, porttitor orci. Duis tempus justo lorem, ac
  fringilla ante viverra egestas. Etiam eleifend enim ac libero dapibus, quis
  condimentum lectus tristique. Fusce feugiat, lorem et faucibus eleifend, ipsum
  nisi maximus justo, at consectetur ligula leo vitae justo."""
  # Really long one para
  pass

def Moan():
  Really_Long_Method()
  Really_Long_Method_2()

Expect: The popup shows the full text of the lorum ipsom Actual: It is squished.

With my latest change:

Expect: the popup shows the full text of the lorum ipsum Actual: Popup is shown at column 1 and wrapped :

Screenshot 2020-05-10 at 14 13 33
cridemichel commented 4 years ago

by setting 'col' to 1 if len >= &columns seems to fix the issue and now the placement of the popup is ok. The other minor issue I noticed is that popup window overlaps the sign column but this is a thing one can get to live with.

puremourning commented 4 years ago

The other minor issue I noticed is that popup window overlaps the sign column but this is a thing one can get to live with.

How can I repro this? When you say overlaps, do you mean that the signs are drawn on top of the popup or, that you don't want the popup to draw on top of the signs ?

I did a quick test and vim draws popups over the signs, which Is what I would expect.

cridemichel commented 4 years ago

yes I get popups over the signs (see below), if this is what expected, that's fine!

Schermata 2020-05-10 alle 16 28 46

bstaletic commented 4 years ago

That's what "column 1" means. Technically, the popup could be offsetted by the sign column width which is always 2 characters. Something like:

if &signcolumn ==# 'no'
  column = 1
elseif &signcolumn ==# 'always'
  column = 3
elseif &signcolumn ==# 'auto'
  if len(sign_getplaced('%'))
    column = 3
  else
    column = 1
  endif
else " &signcolumn ==# 'number'
  " 1, except when the line column is disabled and there are signs placed...
  if !&number || !&relativenumber
    if len(sign_getplaced('%'))
      column = 3
    endif
  else
    column = 1
  endif
endif
" Let's offset by the width of the line number columns count
if &relativenumber || &number
  column += max(4, log10(getbufinfo('%').linecount) + 1)
endif
" One-liner for curious (it's branch-free, so a C compiler will be happier with the solution below):
column = 1 + 2 * (&signcolumn ==# 'always' || (&signcolumn ==# 'auto' && bool(len(sign_getplaced('%')))) || (&signcolumn ==# 'number' && !&nu && !&rnu && len(sign_getplaced('%')))) + (&rnu || &nu) * max(4, log10(getbufinfo('%').linecount) + 1)

I'm not sure the added complexity here is justified.

puremourning commented 4 years ago

I'm not sure the added complexity here is justified.

nor me. ;)

I pushed a.PR to resolve this.