8

I need a simple (or complex) way to figure out what mode the user is in. I need to know if the user is in Normal, Insert, Visual, Replace, Change etc.

I am aware of the mode() function, however I can't figure out how to make it output a full string instead of just one character.

My plan was to make a function which would dynamically change the statusline's background and foreground colors depending on what string mode() returns. Basically a function with a bunch of ifs and elseifs which would do it for me. There is a flaw with this approach though, I can't know which color the theme setup by default for that.

So basically, I need some tips/help on how to make a function that does the following:

  • Knows which mode the user is in. The rest of the functions react differently every time this changes.
  • Sets some variables with fg and bg values which reflect what the current theme has set for them.
  • Changes the statusline's foreground and background depending on these values.

I tried doing it, but it was a very crude way of doing it and it didn't work at all. It only set the colors once and after that it didn't react every time it changed.

Thanks for your help! :)

EDIT:

Pretty sure what I tried before that didn't work was this:

function! StatuslineModeColor()
    let s:StatuslineMode=mode()
    if s:StatuslineMode == 'n'
        hi Statusline ctermbg=blue guibg=blue
    elseif s:StatuslineMode == 'i'
        hi Statusline ctermbg=red guibg=red
    endif
endfunc

And in the statusline I put the following:

let &stl.='%{StatuslineModeColor()}'

EDIT 2:

I've figured out that basically what I need to do is find a way to grab whatever colors the theme was using before. That's if I use this solution: http://www.reddit.com/r/vim/comments/gexi6/a_smarter_statusline_code_in_comments/c1n2oo5

However this solution is not ideal in my standards, because it's not clean, or as clean as it could be since it makes up a lot of clutter. :/

greduan
  • 4,770
  • 6
  • 45
  • 73
  • @romainl Done, forgot to add that. :) It's not the exact function I used before, but it's pretty near. – greduan Dec 23 '12 at 21:03
  • @romainl I seem to have found a good Reddit version of this: http://www.reddit.com/r/vim/comments/gexi6/a_smarter_statusline_code_in_comments/c1n2oo5 Only problem with this is that it doesn't grab the values from the theme itself, what could be a good way to do that? – greduan Dec 23 '12 at 22:34
  • 1. What for do you need `mode()` to output a full string? 2. What is script-local variable doing in your function? It ought to be local one (`l:` or nothing in place of `s:`). – ZyX Dec 24 '12 at 04:03
  • @ZyX To answer the first one, in case I can't figure this out atleast output a string in the statusline. :) And the second one: I'm still a newbie when it comes to the kinds of variables in Vim, so I wasn't aware of that. However I now know of `l:`, `s:`, `a:` and `g:`. :) – greduan Dec 24 '12 at 13:48
  • @Eduan These are not kinds, but scopes (referred to as “name spaces” in documentation for some reason). They are explained under `:h internal-variables`. For the first one: you can always use dictionary and/or big `if … elseif … elseif … endif` thing, [like this](https://github.com/ZyX-I/vim-powerline/blob/44336183e12d86d2fc75d0575d96fc5e61719f99/autoload/Powerline/Functions.vim#L61). – ZyX Dec 24 '12 at 16:04
  • @ZyX Thanks! I will read up on that then. :) I see, so I have to manually translate it to a more normal output? Also, I don't use Powerline but I'm guessing it was just to show how to. :) – greduan Dec 24 '12 at 16:10
  • @Eduan It is an example. Don’t use *this* powerline, it is deprecated, python-based replacement is now being developed by the same author. I would really not use that big block, but use a dictionary, like [here](https://github.com/ZyX-I/powerline/blob/366fefdfd3f225085c2cb160451b4b3754c850ee/powerline/ext/vim/segments/core.py#L19) (it is new powerline by the way. Precisely, my fork of it.). But that is not a good example as it is python module, not something written in VimL. – ZyX Dec 24 '12 at 16:18
  • I see. Well I'll figure out Vim dictionaries and use that instead, for now I have a big block of ifs and elseifs. – greduan Dec 24 '12 at 16:49
  • @ZyX I implemented the dictionary and other changes: https://github.com/Greduan/dotfiles/blob/master/vim/after/plugin/statusline.vim#L3-L9 All I need to do now is to change the color depending on the mode and find out why `FileInfo()` outputs a zero, probably easy reason though. Mind if we start a chat for this? – greduan Dec 24 '12 at 17:51
  • @Eduan It is exactly where script-local variables defined outside of a function are preferred. Also see `:h line-continuation`, it is not that good as in most languages, but it is there. About changing the color: the only thing I know is that the solution can be found somewhere at `:h 'statusline'` (AFAIR some special atom, not that mess with changing properties of `StatusLine` group, though the latter should work). And that practical solution is buried somewhere inside powerline code (BTW why not use it, it changes color?). I did not ever touch that part of powerline, neither old nor new. – ZyX Dec 24 '12 at 18:07
  • @ZyX let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/21652/discussion-between-eduan-and-zyx) – greduan Dec 24 '12 at 18:15
  • @Eduan “To what part are you referring there? I can't make it fit into my comments.” The same lines you pointed out in the link in your comment obviously. By the way, do not use `/master/` in URL and line URL fragments at the same time, it tends to change over time. Use `/{sha hash}/` instead. – ZyX Dec 24 '12 at 21:16
  • @ZyX Ah, I guess it was kind of obvious, sorry. :) I made another question in the discussion chat I opened earlier, in order to not fill up these comments. :) – greduan Dec 24 '12 at 21:47

1 Answers1

2

Update Oct 2016: Since then my dotfiles have moved to https://gitlab.com/greduan/dotfiles, so the new URL for the file is: https://gitlab.com/greduan/dotfiles/blob/76e16dd8a04501db29989824af512c453550591d/vim/after/plugin/statusline.vim

All the lines are the same.


Since nobody came up with an answer I made my own solution, you can find it here: https://github.com/Greduan/dotfiles/blob/76e16dd8a04501db29989824af512c453550591d/vim/after/plugin/statusline.vim#L3-L42

Basically it does the following:

Lines 3 to 23 define a global variable with a dictionary containing all the different modes, translating it into a readable text. So n which stands for normal gets translated to Normal, i to Insert etc.

Lines 25 to 42 define the function which will change the colors of the statusline. Currently it only supports Solarized and only if your version has this fork/pull request. If you meet these requirements you will get a red background when you're in insert mode and a green background when in any kind of visual mode, the rest of the modes get the same as normal.

And lines 118 to 119 put the defined function in the statusline and it also outputs the current mode in a text format using the global variable defined from lines 3 to 23.

I believe this is a much cleaner solution than the one normally used (auto commands and stuff like that I've seen). Basically the only flaw with it is that there's no way to know the theme's variables, but you can of course do hi! link StatusLine Error for example, which would make the statusline have the same syntax highlighting as your theme's errors.

Hope this helps!

greduan
  • 4,770
  • 6
  • 45
  • 73