Skip to content

Vim plugin that shows the context of the currently visible buffer contents

License

Notifications You must be signed in to change notification settings

wellle/context.vim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

context.vim

A Vim plugin that shows the context of the currently visible buffer contents. It's supposed to work on a wide range of file types, but is probably most useful when looking at source code files. In most programming languages this context will show you which function you're looking at, and within that function which loops or conditions are surrounding the visible code.

Here's an animation which shows it in action. See below for an explanation.

Motivation

Do you ever find yourself looking at code with long functions or deeply nested loops and conditions? Do you ever lose your place and start scrolling in your buffer to see where you are? This plugin aims to always show you that context for your currently active buffer so you always know your place.

Example

Here's an screenshot showing parts of eval.c in the Vim source code:

At the bottom you see the actual buffer. At the top you see a popup window used by context.vim to show the context of that code. So here we are looking at some code within the echo_string function. And within that function we are currently handling the case where tv->v_type is VAR_LIST and so on.

In the animation above you can see how the context changes as we scroll through this function.

How it works

This plugin should work out of the box for most file types. It's based on indentation and some regular expressions.

Below is an illustration of how it works: Start at the grey box in the bottom left corner. It shows the original visible buffer content as you would see it without this plugin. Above the box we can see what's usually hidden, the file contents above the visible area. You'd need to scroll up to see it.

This plugin scans upwards through these hidden lines to collect the context. Every time it hits a line with a lower indentation than the last one it will add it to the context. There is also some logic to add lines with same indentation to the context in some cases. For example it adds the else line which belongs to the first { and also the else if and if lines. So you know exactly what this else case is about. All lines which are part of the context in this example are displayed with color while the remaining lines are greyed out.

In the top right corner we see again all these lines which make up the context. Below is a condensed version where some lines were joined. We show ellipsis (···) between the joined parts if there was text between them in the original buffer. So this tells you that there was code within the else if block, but not between the else if condition and the { line below it.

In the bottom right corner we see the final result: The context is displayed in a preview window above the original buffer.

Installation

Plugin Manager Command
Vim-plug Plug 'wellle/context.vim'
Vundle Bundle 'wellle/context.vim'
NeoBundle NeoBundle 'wellle/context.vim'
Dein call dein#add('wellle/context.vim')

Settings

This plugin is supposed to work out of the box. But there are some variables which can be set to different values to tweak the behavior. Below we show each of those together with their default value for reference. Copy/paste these lines to your vimrc and change the values to your liking.

If you feel like one of these default settings are bad in some way or could be improved to create more useful contexts in some file types, please open an issue and let me know. Also if you feel like any of these settings would need to be settable on a per buffer/per file type basis.

let g:context_enabled = 1

This plugin is enabled by default. Set this variable to 0 to disable it. You can then use :ContextEnable or :ContextToggle to enable it on demand.

let g:context_filetype_blacklist = []

By default, no filetypes will be ignored for the context buffer to appear. If you wish to blacklist a specific filetype, add the name of the filetype to this list.

let g:context_buftype_blacklist = []

By default, no buftypes will be ignored for the context buffer to appear. If you wish to blacklist a specific buftype, add the name of the buftype to this list.

let g:context_add_mappings = 1

By default we create some mappings to update the context on all Vim commands which scroll the buffer. Set this variable to 0 to disable that. See below on how to customize these mappings if needed.

Note: Ideally there would be an auto command event for when the buffer had scrolled, but unfortunately that doesn't exist. vim#776

let g:context_add_autocmds = 1

By default we set up some auto commands to update the context every time the buffer might have scrolled. Most notably on CursorMoved. Set this variable to 0 to disable that. See below on how to customize these auto commands if needed.

let g:context_presenter = <depends>

This variable can be used to control how the context is presented. The default logic works like this: If you're running a Neovim version which supports floating windows, use them ('nvim-float'). If you're running a Vim version which supports popup windows, use them ('vim-popup'). Otherwise use a preview window ('preview'). So for example you could force the usage of preview windows by setting g:context_presenter to 'preview'. It is recommended to stick to the default though (by not setting this variable) as floating/popup windows should lead to the best experience.

let g:context_max_height = 21

If the context gets bigger than 21 lines, it will only show the first ten, then one line with ellipsis (···) and then the last ten context lines.

let g:context_max_per_indent = 5

If we extend the context on some indent and collect more than five lines, it will only show the first two, ellipsis (···) and then the last two.

Note: This is likely to happen if you have many else if conditions or many case statements within a switch.

let g:context_max_join_parts = 5

If we extend the context on some indent we try to join them. By default we join a context line into the previous line of same indent if the former has no word characters. For example in C-style indentation we would join the { line to the if (condition) line. So in the context it would show up as if (condition) {.

In complex cases there can be a big number of such context lines which we will join together. By default we only show up to 5 such parts.

Note: This can happen if you have long lists of struct literals, so in the context it would look like { ··· }, { ··· }, { ··· }. Set g:context_max_join_parts to 2 or 1 to shorten this to { ··· or just { respectively.

let g:context_ellipsis_char = '·'

By default we use this character (digraph .M) in our ellipsis (···). Change this variable if this character doesn't work for you or if you don't like it.

g:context_border_char = ''

If your Vim/Neovim version supports popup/floating windows we draw a line to separate the context from your buffer context. This character is used to do that.

let g:context_highlight_normal = 'Normal'
let