vim-airline / vim-airline

lean & mean status/tabline for vim that's light as air
MIT License
17.79k stars 1.11k forks source link

Getting vim-airline working in Windows 10 with latest nvim and nvim-qt releases. #1259

Closed dennmat closed 8 years ago

dennmat commented 8 years ago

environment

Disclaimer: New to VIM, new to Neo VIM. (Like yesterday new)

Errors coming from highlighter.vim. That made it unuseable, anytime a buffer or window changed I was flooded with red error messages rendering neovim useless for me, but I really wanted this plugin.

When using Neovim-QT (Which from my understanding counts as a GUI and not a Terminal) it seems that airline still tries to treat it as an old windows terminal and ends up calling a function airline#msdos#round_msdos_colors(rgblist) which would have an index error on a:rgblist[2]. I found that I was able to simply change: return airline#msdos#round_msdos_colors(rgb) in highlighter.vim to return rgb

Which brought me to the next series of errors, that seemed to be some formatting issues of the hi command undoubtedly from my changes above I figured. However by removing the if s:is_win32term condition and body altogether it fixed the problems and airline seems to be working flawlessly now.

Although I can essentially guarantee my fixes aren't the appropriate fixes to fix this problem I hope they can help you guys figure out whats up. Here's my vimrc(Yes it's messy yes it's nooby):

set background=dark

call plug#begin('~/AppData/Local/nvim/plugged')

Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'

Plug 'scrooloose/nerdtree', { 'on':  'NERDTreeToggle' }
Plug 'flazz/vim-colorschemes'
Plug 'kien/ctrlp.vim'
Plug 'terryma/vim-multiple-cursors'

call plug#end()

filetype plugin on
filetype indent on

set autoread

let mapleader = ","
let g:mapleader = ","

let g:enable_bold_font = 1 

set history=700

set wildmenu

set tabstop=4

set title

set number

set cursorline

set noswapfile
set nobackup
set nowb

set softtabstop=0 noexpandtab

set shiftwidth=4

set noerrorbells
set vb t_vb=

let g:airline#extensions#tabline#enabled = 1

NERDTree D:\

colorscheme BlackSea

map <Leader>c :e C:/Users/dennmat/AppData/Local/nvim/init.vim <CR>
map <c-s> :w <CR>

nmap <C-h> <C-w>h
nmap <C-j> <C-w>j
nmap <C-k> <C-w>k
nmap <C-l> <C-w>l

inoremap jj <Esc>

" Copy to system clipboard
vnoremap <C-c> "+y
" Paste from system clipboard with Ctrl + v
inoremap <C-v> <Esc>"+p
nnoremap <Leader>p "0p

" Toggle between last 2 buffers
nnoremap <leader><tab> <c-^>

But from very little knowledge in any and all of this, my best guess is it seems like it's trying to treat nvim-qt as a windows terminal with limited color pallet instead of as a gui. Perhaps there was an easy flag I could have set somewhere but I couldn't find it or mention of it anywhere online.

Also there is a possibility that this could be a nvim or nvim-qt issue(in that it's not reporting what it is properly or something) if so let me know and I'll move this issue over there

Thanks, if you look at this great, if not that's cool to. Thanks for maintaining and writing this cool plugin :)

chrisbra commented 8 years ago

I don't understand. In nvim, doesn't has("gui_running") not return 1? It should, if it is a gui. I also don't understand, what other changes you made. can you show me a diff please?

dennmat commented 8 years ago

I ran this: :echom has("gui_running") the result was a 0 so I'm assuming that this then is a nvim-qt/nvim issue. If so sorry for taking up your time, still new to all this!

Anyway, if you're still curious, my git diff (I just commented stuff out instead of removing, as I was experimenting)

diff --git a/autoload/airline/highlighter.vim b/autoload/airline/highlighter.vim
index 58a481b..95f3974 100644
--- a/autoload/airline/highlighter.vim
+++ b/autoload/airline/highlighter.vim
@@ -13,7 +13,7 @@ function! s:gui2cui(rgb, fallback)
     return a:rgb
   endif
   let rgb = map(split(a:rgb[1:], '..\zs'), '0 + ("0x".v:val)')
-  return airline#msdos#round_msdos_colors(rgb)
+  return rgb "airline#msdos#round_msdos_colors(rgb)
 endfunction

 function! s:get_syn(group, what)
@@ -57,10 +57,10 @@ function! airline#highlighter#exec(group, colors)
     return
   endif
   let colors = a:colors
-  if s:is_win32term
-    let colors[2] = s:gui2cui(get(colors, 0, ''), get(colors, 2, ''))
-    let colors[3] = s:gui2cui(get(colors, 1, ''), get(colors, 3, ''))
-  endif
+  "if s:is_win32term
+  "  let colors[2] = s:gui2cui(get(colors, 0, ''), get(colors, 2, ''))
+  "  let colors[3] = s:gui2cui(get(colors, 1, ''), get(colors, 3, ''))
+  "endif
   let old_hi = airline#highlighter#get_highlight(a:group)
   if len(colors) == 4
     call add(colors, '')

Thanks

chrisbra commented 8 years ago

Hi Matthew!

On Sa, 17 Sep 2016, Matthew Dennis wrote:

I ran this: :echom has("gui_running") the result was a 0 so I'm assuming that this then is a nvim-qt/nvim issue. If so sorry for taking up your time, still new to all this!

Please report that than to the neovim-qt project.

Best,

Christian

Reich ist man nicht durch das was man besitzt, sondern durch das, was man bereit ist zu entbehren! -- Epikur von Samos (341-271 v.Chr.)

ybbarng commented 7 years ago

Hello, I had this same issue and I want you to re-open this issue to deal with it. I wanted to use vim-airline with neovim-qt on Windows 10 and everything looked fine. But when I type 'vs' to open vertical split, lots of error messages poured. vim-airline-error-on-neovim-qt I found this page which says that this issue is the fault of neovim-qt and is closed. But I found some historical processes and I think perhaps vim-airline has to deal with it.

First, NeoVim GUI only opens after init.vim. Therefore gui_running in init.vim is always 0. We can configure vim-airline in ginit.vim to avoid this issue, but it is not good solution. Vim-airline can be used in tui, so there is no reason that it is placed in ginit.vim only.

Second, NeoVim removed telling lie about gui_running. Therefore, lots of plugins using gui_running modified thier checking conditions.

Third, after that, there was an issue for this change, and a PR was made for this issue and merged.

Fourth, but 's:is_win32term' in highlighter.vim just checks 'gui_running', so when neovim-qt run, is_win32term returns true, then s:gui2cui is executed, then airline#msdos#round_msdos_colors() is executed, then lots of crashes occurs.

I fixed this issue by appending && !has('nvim') in the line of definition of s:is_win32term. However, I don't know all structures of this project and other environments, so I don't believe this is the correct action which is enough to be merged in this project.

Therefore, I would like this issue to be re-opened and some neat solutions to be found and to be merged to this project.

Thanks.

chrisbra commented 7 years ago

if the length of the color list is not 3 items, I think it is neovims fault. Please discuss with them then.

ybbarng commented 7 years ago

Well, did you mean that on Windows, even if it is GUI environment, 'is_win32term' is true and the function 'gui2cui' must be called? (Even working well without them) I don't know much about the difference between GUI and CUI management in vim but it looks little curious.

chrisbra commented 7 years ago

no. is_win32term is only supposed to be true, when running in the terminal.

ybbarng commented 7 years ago

Okay, then the problem is that neovim_qt is GUI, but gui_running is not set when vim-airline is loaded. TL;DR I just want vim-airline to change its win32 CUI/GUI distinguish algorithm for neovim-qt, which is missed in this change.

  1. Here are some backgrounds

    1. nvim vs nvim-qt Nvim is CUI but nvim-qt is GUI client. If nvim run with vim-airline, it works fine. The problem is nvim-qt, which is GUI environment.
    2. init.vim vs ginit.vim There are two configuration file(like vimrc, gvimrc), init.vim and ginit.vim. When init.vim is loaded, gui_running is not set. After that it is loaded completely, then ginit.vim is loaded. Nvim loads just init.vim, and nvim-qt load init.vim and ginit.vim consecutively.
    3. Problem The problem is that vim-airline is loaded in init.vim when nvim-qt is run. Because it is not in ginit.vim, gui_running is not set. But the environment is GUI.
  2. There are some options

    1. Move to vim-airline loading from init.vim to ginit.vim We can choose the option that moving the vim-airline loading from init.vim to ginit.vim. It looks working because no crash occurs. But some feature is not working, such as NORMAL text region at the left bottom is disappeared. However I think vim-airline is not GUI-only plugin, so It can work properly when it is loaded in init.vim.
    2. Change neovim side to set 'gui_running' when init.vim is loaded on nvim-qt NeoVim decided not do that. Look at this [RFC] ui: revert "gui_running" hack #4155. This decision can seem somewhat onreasonable or selfish, because lots of plugins with colorscheme use this variable to check CUI/GUI. But vim-airline already handled this issue. Move to next.
    3. Change vim-airline's terminal checking algorithm Vim-airline already handled this issue. Neovim true color support #991 But 'is_win32term' is missed. It might be changed properly but it didn't. It just check 'gui_running' to distinguish CUI and GUI which is not working on nvim-qt.

I hope you could understand what I mean. I understand that you doesn't need to support every vim environments. I just want to notice a point that enlarges your coverage and makes more the users of vim-airline be happy. Anyway, It is very very rare case that Windows 10 + NeoVim QT + Vim-Airline....

Thank you for reading and answers even though it is a closed issue. I am sorry if my sentence seemed impolite. I am not a English native.

chrisbra commented 7 years ago

Are you sure, that vim-airline is loaded before ginit.vim is sourced? That sounds wrong and I believe this is different than for Vim. I think there it first loads vimrc, then gvimrc and plugins are loaded last. I would be fine with changing the is_win32term logic to include something like has("nvim") but how can we then distinguish between a nvim running in the terminal and nvim-qt? or perhaps we shouldn't make that variable static? Hm, does this patch change anything:

diff --git a/autoload/airline/highlighter.vim b/autoload/airline/highlighter.vim
index 16ae66e..eee256b 100644
--- a/autoload/airline/highlighter.vim
+++ b/autoload/airline/highlighter.vim
@@ -3,7 +3,6 @@

 scriptencoding utf-8

-let s:is_win32term = (has('win32') || has('win64')) && !has('gui_running') && (empty($CONEMUBUILD) || &term !=? 'xterm')

 let s:separators = {}
 let s:accents = {}
@@ -64,7 +63,8 @@ function! airline#highlighter#exec(group, colors)
     return
   endif
   let colors = a:colors
-  if s:is_win32term
+  let is_win32term = (has('win32') || has('win64')) && !has('gui_running') && (empty($CONEMUBUILD) || &term !=? 'xterm')
+  if is_win32term
     let colors[2] = s:gui2cui(get(colors, 0, ''), get(colors, 2, ''))
     let colors[3] = s:gui2cui(get(colors, 1, ''), get(colors, 3, ''))
   endif
ybbarng commented 7 years ago

I thought that the 'gui_running' is set when ginit.vim is loaded, but I am wrong. I tested your suggested code and force vim-airline to be loaded in ginit.vim using vim-plug. There is no 'gui_running' even after vim loaded ginit.vim. I have same concern that how we can distinguish between nvim and nvim-qt. The comment of this issue of neovim-qt says that 'g:GuiLoaded' can distinguish those. Your suggestion + checking 'g:GuiLoaded' solves the errors, but it can't distinguish nvim and nvim qt. According to my experiment, running nvim in terminal also sets g:GuiLoaded. All of these things, 'nvim', 'gui_running', 'g:GuiLoaded' can not be used to distinguish nvim and nvim-qt. At last, I think the approach is very different between gvim and neovim. I thought there might be a simple solution, but now I think I was wrong. Thank you for your attention.

chrisbra commented 7 years ago

I left a comment there. Hopefully those guys know how to properly distinguish it then. If this ever gets resolved properly, feel free to open a new issue (or leave a comment here)

equalsraf commented 7 years ago

According to my experiment, running nvim in terminal also sets g:GuiLoaded

@ybbarng this should only happen if you are loading the gui shim manually in your init.vim, usually nvim-qt loads that for you. Are forcing this in init.vim?

I think the approach is very different between gvim and neovim. I thought there might be a simple solution, but now I think I was wrong.

Correct. Neovim allows for a GUI to attach/detach at any time and you can have multiple interfaces open, which means a global gui_running option would not make sense. gui_running in nvim is ALWAYS false. Since s:is_win32term uses has('gui_running') then it is no surprise that it does not work as intended.

Internally nvim always starts in a state where there is no GUI. The GUI then attaches to neovim. Processing of init.vim happens before the GUI attaches. Processing of ginit.vim happens after the GUI attaches.

In a nutshell there is currently no standard way to identify whether the a GUI is about to be attached from within init.vim. g:GuiLoaded is nvim-qt specific, and only tells you that the gui plugin was loaded not whether a GUI is attached. There are already open issues upstream to address this, but a viable PR has yet to be merged.

Defering plugin loading to ginit.vim works for the GUI but disables the plugin for the terminal which is not ideal for most people. For a dirty workaround in init.vim you can use nvim-qt -- --cmd "let g:DelayPluginsForGUI=1" and use that variable for the checks. I certainly dont mind merging a similar solution in nvim-qt, but this is only useful for init.vim hacks.

PS: keep in mind that in Windows, the terminal UI is not available in the latest stable nvim release, only in the master branch. So any specific issues concerning wrong colors or state really should be pushed upstream.

chrisbra commented 7 years ago

@equalsraf IIRC, that problem exists for as long as neovim exists and is very unsatisfying. Can't you simply lie to the plugins, if you know that there will be a GUI attached anytime soon? Or perhaps, have another has('nvim_gui_is_starting') so that the decision can be detected and left to the plugin writers what to do?

equalsraf commented 7 years ago

If the problem here is only color support I think we are over complicating things.

If the option termguicolors is set then you are in 24 bit terminal or in a GUI. AFAIK all nvim GUIs set this. This can can be used init.vim, the GUI ensures nvim sets this prior to sourcing it.

So adding something like this to s:is_win32term

&& !(has('nvim') && &termguicolors )

This is not fully accurate, the option is not set by default even when a terminal supports colors. But there is no working terminal UI for nvim in Windows right now so its hard to be sure if it will have support.

It may happen that the nvim windows TUI ends up supporting all the colors and then I'm sure someone will complain later to fix it :D, but I think this as correct as it can be right now.

chrisbra commented 7 years ago

okay, good suggestion. I changed your condition (57e564b22748e5ffcd7a45) slightly to:

&& !(exists("+termguicolors") && &termguicolors)

which makes it work for Vim as well.