Vim Tips Wiki

Forgetting to save changes on FocusLost

1,623pages on
this wiki

Add these lines to autocmd.vim:

:au FocusLost   * if(&modified)                " buffer changes...: * PENDING
:au FocusLost   * :hi Normal guibg='#330000'   " window background: * ALARM
:au FocusLost   * else"                        " buffer changes...: o none
:au FocusLost   * :hi Normal guibg='#000033'   " window background: o ok
:au FocusLost   * cclose                       " quickfix window..: o close
:au FocusLost   * endif

:au FocusGained *  :hi Normal guibg='#000000'
The first line is about the current buffer only (the one from the window where the input focus is)

Replacing it with the line bellow will check up to 3 windows:

:au FocusLost   * if (getbufvar(winbufnr(1), '&modified') != 0) || (getbufvar(winbufnr(2), '&modified') != 0) || (getbufvar(winbufnr(3), '&modified') != 0)


What is this about? Why does ":hi" have a colon? JohnBeckett (talk) 10:25, June 24, 2016 (UTC)

--- Answer to the request for some explanation from JohnBeckett ---

I'm totally confident about how vim syntax keywords do convey enough real-life-language semantics to be significant by themselves. If it is not the case for a reader, I think she,he is not on the right path of an efficient learning curve.

Still, for the sake of positive thinking that can't hurt:

Losing focus, in the context of using an editor, can only mean one thing: The user is switching his,her attention on something else - mostly some kind of next-step along the current process.

This auto-command is supposed to attract her,his attention on the fact that something may be missing as a "supposedly" to-be-committed previous step of that process by slightly changing the vim window background.

That's all there is to it.

As, for the colon of the :hilightight command,

1 - It comes from my personal intensive use of single line vim commands saved in project-specific scratchpad-files I use every day by hitting a single key. My F1 is mapped to execute whatever there is in the line under the cursor (hence the colon to enter command-mode):

:map  <F1> "ayy@a

...that's: Yank this line and @xecute it as a command-line as if I was typing it myself

2 - This allows line-by-line execution while editing a script.

3 - And it does not hurt a bit to leave them there for further editing.

Instead of the hard-coded 3-buffer check, I'd suggest using a :for loop over numbers from 1 to bufnr('$'), check if the buffer exists with bufexists(), and then get the modified flag as you're doing. Then you can check all the buffers instead of only a few. There may even be a better way to loop over the buffers but this should work at least. --Fritzophrenic (talk) 16:53, July 14, 2016 (UTC)

Right, I knew that it would come to something more than a few easy trick-lines eventually... You are absolutely right when it comes to hard-coded values mixed up with hard-coded logic. As of now, values belong to user space, logic is not mature enough for dynamic mutation... Digression aside, here is my next-step working solution:

 :augroup focus_buffer_check " (160715) {{{

 "---------------- FOCUS GAINED: Set your working GUI BACKGROUND COLOR
 :au FocusGained *  :hi Normal guibg='#000000'

 "---------------- FOCUS LOST: check the 'modified' option of all visible buffers
 :au FocusLost   * let i = 0
 :au FocusLost   * while i < bufnr('$')
 :au FocusLost   *  if getbufvar(winbufnr(i), '&modified')
 :au FocusLost   *   break
 :au FocusLost   *  endif
 :au FocusLost   *  let i = i+1
 :au FocusLost   * endwhile
 :au FocusLost   * if i < bufnr("$")            " FOUND SOME 'modified' buffer
 :au FocusLost   *  :hi Normal guibg='#330000'  " -> [ALARM-COLOR]
 :au FocusLost   * else"                        " FOUND   NO 'modified' buffer
 :au FocusLost   *  :hi Normal guibg='#000033'  " -> [OK-COLOR]
 :au FocusLost   *  cclose                      " -> close quickfix window
 :au FocusLost   * endif

 :augroup END	" focus_buffer_check }}}

...I dropped the bufexists() check for now, until I stumble on a use case to solve

Nice! Feel free to go back and edit rather than just leaving a comment.
By the way, were you aware continuation lines work in an autocmd? For example for just one of your "if" statements:
 :au FocusLost   *  if getbufvar(winbufnr(i), '&modified') |
       \              break |
       \            endif
--Fritzophrenic (talk) 14:52, July 15, 2016 (UTC)

I do appreciate both remarks - I only left the initial "simplistic" version, so serve as a concise topic intro (at least that was the idea). - As for the continuation line, that's good to know. But that too is the result of long-term habits aimed at preserving line-swappability as much as possible. (Curiously enough, after 35 years using ed, vi, vim, gvim!, I still have no idea why I still have no real knowledge about vim-scripting... (much to learn for me there is, hehe)

Around Wikia's network

Random Wiki