3

Is there any way to display messages in vim depending on the filetype being edited? It would be good if the messages pop after some specified time interval.

Use case

We tend to forget style guide while editing files. Auto reminding would be a great feature.

Update 1

It seems that auto reminding is not possible hence, it would be good if those messages could be shown on each write.

4

This is not really a "Vim answer", but it is in my humble opinion the "correct answer".

We tend to forget style guide while editing files. Auto reminding would be a great feature.

So how would this work? Every five minutes you get a message with "hey, don't forget to use the style guide"? Is this really helpful? Because to me it sounds like:

  1. It distracts the programmer from whatever she's working on right now. Programming is hard and requires a lot of short-term memory. Distractions erase part of that short-term memory and it'll take time to "catch up" again.

  2. People are not going to keep paying attention to messages shown regularly. They tend to ignore those. you could make the messages more "in your face", but that would only increase problem 1.

If you absolutely must do something from within Vim, then use syntastic. This allows you to run automated syntax and style checkers whenever you write the file to disk with :w.

Syntastic is a great plugin for checking syntax errors as it allows quick feedback on typos and other errors that really do need to be fixed right now to allow the code to run, but I feel that it's harmful for notifications of style errors for the same reason as above: it breaks the concentration on the actual important and hard parts of programming. Is it really important that that space gets fixed now? I would say not.

I joked about the clippy program in the comments. It was wildly perceived as spectacularly annoying precisely because it distracted people's concentration from the actual important task at hand (such as writing a letter).

The best way to fix this is to set a pre-commit hook in your version control system (mercurial, git, subversion, SCCS, whatever. You are using one, right?) That way the flow of operations is:

  1. Programming receives task.
  2. Programmer works to fix the task.
  3. A tester or programmer discovers bugs, works until they're fixed.
  4. Programmer fixes some "lint" such as style errors.

That way, there is a "separation" between the actual programming (step 2) and fixing the style errors (step 4) in such a way that doesn't distract from the actual important and hard task at hand (step 2).

Ideally, such a pre-commit hook only checks for errors when committing to the main branch(es) and not individual "private" branches.

If setting this up is too much work for now, then just run the tools from the commandline. Setting up a notification to do so with a pre-commit hook is easy, although the "people tend to ignore repeated warnings" still applies here (but you could perhaps echo it in red and have it wait for ten seconds or some such).

Lastly, perhaps you should reconsider your "style guide". I have seen some style guides that dwarf several Bible books and contain all sorts of pedantic details. There are a few truly important things everyone should agree on, but other than that I find that it doesn't really aid much in readability (and slavish obedience to style guides for the sake of it may even harm readability in some cases).


This answer summarized in a cartoon: This answer summarized in a cartoon

4

Important disclaimer

This answer is mostly here for educational purposes: I wouldn't recommend to use the functions shown here.

As @Carpetsmoker pointed at it in the comments and in his answer, this kind of reminder can be pretty harmful for a developer and other solutions exists to check code guidelines.

That being said the functions were fun to create and someone might use the code as inspiration to do something else


Solution 1

Trigger a function each time a buffer is written, if the filetype correspond to a predefined list, then a message to remind you to follow guidelines is prompted:

function! RemindGuideLine()
    " Echo a reminder only for these filetypes
    if &ft =~ 'vim\|txt\|java'
        echo "Remember to follow the corporate guide lines"
    endif
endfunction

autocmd BufWritePre * call RemindGuideLine()

The autocmd calls the function each time a buffer is written and the function checks the filetype and show a message if needed.


Solution 2

This is inspired by the answer linked by Nobe4 in the comments.

Using the autocmd event CursorHold, a function is called after a time of user inactivity. This function checks the amount of time since the last time it was called. If this delta of time is big enough and the filetype matches a predefined list, then a message is echoed. After a defined amount of echoed messages, the function stop giving reminders.

" Call the function when the user doesn't press a key for some time
au CursorHold * call RemindGuideLine()

" When a buffer is opened, set a variable indicating the time it was opened on
au BufRead,BufNewFile * let b:save_time = localtime()
" Also set a variable indicating the number of reminders to show
au BufRead,BufNewFile * let b:numberOfReminders = 3

" Set the minimum time to wait between 2 reminders
let g:remindTime = 10

function! RemindGuideLine()
    " Echo a reminder only for these filetypes
    if &ft =~ 'vim\|txt\|java'
        " If we waited long enough and we haven't show the max number of reminders
        if((localtime() - b:start_time) >= g:remindTime && b:numberOfReminders > 0)
            let b:start_time = localtime()
            let b:numberOfReminders = b:numberOfReminders - 1
            echo "Remember to follow the corporate guide lines" . b:numberOfReminders
        endif
    endif
endfunction

As the comments in the code says, the function is called when the user doesn't press any key for some time (it is probably the best event to trigger to avoid spamming the user).

You can change the number of time the reminder will be prompted to you and the minimum time between the prompts with let b:numberOfReminders and let g:remindTime.

Here the function checks the filetype, the time since the last reminder and the number of reminders left and prompts a new one if necessary.


And to give to Caesar what belongs to Caesar, here as some links:

  • An answer linked by Nobe4 I used to create the second solution.
  • Another answer which inspired me the first solution.
  • :h autocmd-events to customize the autocmd. I think CursorHold is the best event to use in this case, but one might want to change that for reasons.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.