What vimscript magic allows one to create buffers with highly customized behavior, that effectively act like a TUI, such as those presented by NerdTree or other file explorer plugins and Gundo or other undo tree plugins?

Is there a core set of vimscript features that are crucial to creating this sort of behavior?

I'm a vimscript newbie, so this question might sound confusingly vague to the pros but please bear with me. From a naive perspective, there are "TUI-ish" plugins that seem magical but also appear to implement somewhat similar interfaces where there is a read-only buffer that presents information, allows limited selecting, has unusual arrowing/hjkl-ing behavior, and invokes special behavior when <CR>/Enter is pressed. What vimscript magic is needed to implement those behaviors?

Please go ahead and comment to ask for necessary clarifications to answer the question!

(I have experience on other SE sites and I've been meaning to learn deeper vimscript enlightenment but I thought it would be worthwhile to ask this question from a newbie perspective and simply phrase it as best I could.)

1 Answer 1


N.B. I'm not sure if figuring out the behaviour of large, advanced plugins is the best introduction to Vimscript — you might be better off first reading the relevant parts of the user manual (Chapters 40 & 41) to get a grounding in the basics or taking a look at a tutorial such as the excellent Learn Vimscript the Hard Way (which was written by the auther of the Gundo plugin you mention), but in case you're determined to jump in at the deep end…

Plugins use a few methods to achieve the various different aspects you describe.

Firstly, there are several local options that affect the behaviour of buffers (which can be set and queried via the standard :set command). In particular:

  • 'modifiable' prevents you from making any changes to a buffer's content, 'readonly', prevents you from saving any changes you've made to a buffer's content,
  • 'buftype' specifies the type of the buffer: the nofile value is generally used for the buffers you describe,
  • 'buflisted' specifies whether the buffer will appear in the buffer list (e.g. in the output of the :ls command),
  • 'bufhidden' specifies what will happen to buffers when they are no longer displayed in a window: some plugins might use the delete value.

Most of the above (and more) is described in :help special-buffers.

One other thing you could try is running a plain :set with no arguments in the buffer in which you are curious about the behaviour: this will display all the options which do not have their default settings. You can then read the :help for any that you don't recognise. Make sure to include the single quotes in your command to avoid ambiguity:

:help 'buftype'

The behaviour of keystrokes is altered with mappings, using the various variants of the :map command. You can examine, for example, how Gundo implements special movement for the j keystroke by typing nmap j in the Gundo buffer. The problem you're going to have as a Vimscript beginner is interpreting its output:

n  j           &@:call <SNR>28_GundoMove(1)<CR>

This is described in detail in :help map-listing, but essentially, what this tells you is that j is mapped to a function called GundoMove(). You'd need to delve into the plugin's code to figure out how the behaviour is implemented, but again, that's not necessarily the quickest path to understanding for a beginner.

As for presenting information, there are lots of different ways you can add text to a buffer in Vim. Describing all of these is a bit too open-ended of a task for an answer on this site: if you really want to find out how a specific plugin does this, you're going to need to look at that plugin's code. Feel free to ask new questions if you come up with more specific queries while doing so.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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