Modules/t-vim

From ConTeXt wiki

NOTE: See the github page of the module for the official documentation

Overview

The vim module highlights code snippets using vim as a syntax highlighter. See the original document for details.

Usage

Highlighting source code can be accomplished in the following ways:

  • Source code snippet
  • Inline source code
  • External source code file

The examples use Ruby code, but could be any syntax and grammar that is recognized by vim, including, but not limited to:

  • C, C++, C#, Go, Java, and PHP
  • Haskell, Lua, Python, and Ruby
  • Perl, bash, zsh, csh, and sh
  • XML, HTML, and XSL

See /usr/share/vim/vim74/syntax/ for a list of the 500+ supported filename extensions.

Source Code Snippet

Here is a short example showing how to use the vim module to introduce syntax-highlighted source code into a document:

   \usemodule[vim]
   \definevimtyping [RUBY]  [syntax=ruby]
   
   \starttext
     \startRUBY
       # Ruby program listing
       print("Hello World")
     \stopRUBY
   \stoptext

To get syntax highlighting for a particular language, find its file type. This can be accomplished as follows:

  1. Start vim.
  2. Type :help syntax.txt.
  3. Review the list of supported languages.
  4. Type :qa! to quit vim.

The \usemodule command includes the functionality for vim syntax highlighting. The \definevimtyping command defines the following:

1. An environment

       \startRUBY
         ...
       \stopRUBY
   The contents of this environment are processed by a vim script
   (2context.vim) and the result is read back in ConTeXt.

2. A macro

       \inlineRUBY{...}
   The contents of this environment are processed by a vim script
   (2context.vim) and the result is read back in ConTeXt.

3. A macro

       \typeRUBYfile{...}
   The argument of this macro must a file name or a url (urls work in MkIV
   only). That file is processed by 2context.vim and the result is read back
   in ConTeXt. For controling how frequently a remote file is downloaded when
   processing a url, see the _Processing remote files_ section of the
   t-filter manual.

In all the three cases, the t-filter module takes care of writing to external file, processing by 2context.vim, and reading the contents back to ConTeXt. The t-vim module simply defines the macros that are used by 2context.vim.

The source code can then be written anywhere in the document.

Start and Stop

The \start<vimtyping> ... \stop<vimtyping> environment and the \type<vimtyping>file macro take an optional argument that is used to set options.

For example, to typeset lines 15 through 25 of a ruby file rails_install.rb, use:

   \typeRUBYfile[start=15,stop=25]{rails_install.rb}

To exclude 10 lines from the end, set stop=-10.

Change Tab Stop

By default, a literal tab (0x09 or ^I) character has a width of 8 spaces. For most cases, this is too excessive. To reduce the shift of a tab, use the tab key. For example:

   \definevimtyping
     [...]
     [...
      tab=4,
      ...]

changes the tab width to four spaces.

Avoid Clutter

Running an external file through vim is slow. So, t-vim reprocesses a snippet or a file only if its contents have changed. To check if the contents have changed, it writes each snippet to a different file and stores the md5 sum of that snippet. As a result, the working directory gets cluttered with lot of temporary files. To avoid this clutter, write the temporary files to a different directory using the directory key. For example,

   \definevimtyping[...]
                   [directory=output/]

ensures that all the temporary files are written to the output directory. See the section on _Output Directory_ in the documentation of t-filter module for more details.

Before and After

Like most ConTeXt environments, \definevimtyping also accepts the before and after options. These can be used, for example, to enclose the output in a frame, etc.

Simple Font Style

Search for style:

\definevimtyping
    [ctyping]
    [style={\switchtobodyfont[small,tt]}]
\starttext
  \startctyping
    #include <stdio.h>
  \stopctyping
\stoptext

To change all typing environments:

 \setupvimtyping
   [style=....]

Flexible Font Style

Font styles can also be implemented as follows:

\starttypescript [mono] [ProjectSourceCode]
  \definefontsynonym [Mono]     [name:inconsolata]
  \definefontsynonym [MonoBold] [name:inconsolatabold]
\stoptypescript

\definetypeface[ProjectFont] [tt] [mono]  [ProjectSourceCode] [default]

\usetypescript[ProjectFont] [ec]
\setupbodyfont[ProjectFont]

\definefont[SourceCodeFont][Mono sa 0.9]
\setupvimtyping[
  style=SourceCodeFont,
]

Color Scheme

This module provides two color schemes:

- pscolor based on ps_color colorscheme for vim by Shi Zhu Pan. - blackandwhite based on print_bw colorscheme for vim by Mike Williams.

A particular color scheme may be chosen using the options:

   \definevimtyping
     [...]
     [...
      alternative=pscolor,
      ...]

The default color scheme is pscolor.

Line Numbering (MkIV)

To enable line numbering for a particular snippet, use:

   \start<vimtyping>[numbering=yes]
     ...
   \stop<vimtyping>

To enable line numbering for all code snippets, use:

   \definevimtyping
     [...]
     [...
      numbering=yes,
      ...]

If you want a particular snippet not to have line numbering, use

   \start<vimtyping>[numbering=no]
     ...
   \stop<vimtyping>

By default, numbering starts from one, all lines are numbered, numbering is reset at each snippet, and numbers are displayed on the left. All these defaults can be changed.

First Line Numbered

By default, the numbering starts from one (that is, the first line is numbered 1). If you want the first line to be numbered something else, say 15, you need to set

     \start<vimtyping>[numberstart=15]

If you want the numbering to continue from where the previous snippet ended, use

     \start<vimtyping>[numbercontinue=yes]

By default, consecutive lines are numbered. If you want alternate lines to be numbered, use

     \start<vimtyping>[numbertstep=2]

If you want every fifth line to be numbered, use

     \start<vimtyping>[numbertstep=5]

Line Numbering Options

These options can only be set using \definevimtyping[...][...] or \setupvimtyping[...][...]. They do not work when used with \start<vimtyping>.

  1. To change the color or style of the numbers, use the numbercolor=... and numberstyle=... options. By default numbercolor is not set, while numberstyle is set to \ttx.
  2. To change the alignment of numbers, use the numberalign=... option. Default value is flushright.
  3. To change the width of the box in which the numbers are typeset, use numberwidth=... option. Default value is 2em.
  4. To change the distance between the numbers and the rest of the code, use numberdistance=... option. Default value is 0.5em.
  5. To change the conversion of numbers, use numberconversion=... option. Default value is numbers.
  6. Use numberleft=... and numberright=... options to typeset something on the left and right of the number. By default, these options are not set.
  7. numbercommand=... is used to set a command for typesetting the number.
  8. numberlocation=... is used to set the location of the numbers. Default value is left. Change this to right if you want the numbers on the right.

Spaces

By default, the space is invisible. If you want to make the space visible, set

   \definevimtyping
       [...]
       [...
        space=on,
        ...]

The default value is space=off.

Remove Leading Spaces

If you are listing a code snippet inside another environment, it is common to indent the TeX code. For example:

   \definevimtyping[C][syntax=C]
   \definevimtyping[ruby][syntax=ruby]
   \startitemize
       \item A hello world example in C
           \startC
             #include<stdio.h>
             int main()
             {
               printf("Hello World")
             }
           \stopC
       \item A hello world example in ruby
           \startruby
             puts "Hello World"
           \stopruby
   \stopitemize

Although, the source code is easy to read, the output will not be. This is because, unlike regular TeX, \start<vimtyping> ... \stop<vimtyping> environment does not ignore white space. So, the output is the same as

   \startitemize
   \item A hello world example in C
   \startC
             #include<stdio.h>
             int main()
             {
               printf("Hello World")
             }
   \stopC
   \item A hello world example in ruby
   \startruby
             puts "Hello World"
   \stopruby
   \stopitemize

So, all the code snippets are indented by nine space. To avoid this behavior, set

   \definevimtyping
       [...]
       [...
        strip=yes,
        ...]

The default value of strip is no.

Left Margin

By default, a <vimtyping> environment resets the left skip to 0pt, so each line is aligned to the left edge. Use the margin key to change the left skip of each line:

   \definevimtyping
       [...]
       [...
        margin=<dimen>,
        ...]

where <dimen> is a valid TeX dimension.

Wrapping Lines

By default, long lines are not wrapped. If you want to wrap long lines, set

   \definevimtyping
       [...]
       [...
        lines=split,
        ...]

The default value is lines=fixed.

Line Emphasis

Sometimes you want to emphasize a particular line (or set of lines). One way to do so it to highlight the lines by a background color. This can be done using:

   \start<vimtyping>[highlight={<list>}]
     ...
   \stop<vimtyping>

where <list> is a comma separated list. For example, if you want to highlight lines 1 and 5, you may use:

   \start<vimtyping>[highlight={1,5}]
     ...
   \stop<vimtyping>

This will highlight lines 1 and 5 with gray background color. To change the highlight color use

   \definevimtyping
       [...]
       [...
        highlightcolor=<color>,
        ...]

where <color> is any valid ConTeXt color.

When you pass a comma list to highlight, the 2context.vim script wraps **each** of those line around \HGL{....} macro. The \HGL is, in turn, set to the value of highlightcommand key. So, if you want to change the way highlighting works, change the highlightcommand:

   \definevimtyping
       [...]
       [...
        highlightcommand=<command>,
        ...]

where <command> is any valid ConTeXt command. The default value is highlightcommand is \syntaxhighlightline; in MkIV, \syntaxhighlightline is defined as a bar; in MkII, \syntaxhighlightline is defined as a text background. The bar mechanism is more efficient but both mechanisms behave differently. The text background starts from the left edge of the line, while the bar starts from the first non-blank character.

TeX Code in Comments

Sometimes one wants to use TeX code in comments, especially for math. To enable this use

   \definevimtyping
       [...]
       [...
        escape=on,
       ]
     

When escape=on, the 2context.vim script passes the Comment syntax region (as identified by vim) verbatim to TeX. So, we may use TeX commands inside the comment region and they will be interpreted by TeX. For example

   \definevimtyping[C][syntax=c, escape=on]
   \startC
   /* The following function computers the roots of \m{ax^2+bx+c=0}
    * using the determinant \m{\Delta=\frac{-b\pm\sqrt{b^2-2ac}}{2a}} 
    */
       double root (double a, double b, double c) {....}
   \stopC
    • Note** that only \ { } have their usual meaning inside the Comment

region when escape=on is set. Thus, to enter a math expression, use \m{...} instead of $...$. Moreover, spaces are active inside the math mode, so, as in the above example, avoid spaces in the math expressions.

Tuning Color Schemes

Some vim syntax files have optional features that are turned on or off using variables. To enable these optional features, you need to first create a vimrc file and then use it.

To create a vimrc file, use

   \startvimrc[name=...]
   ...
   \stopvimrc

The name=... is necessary. To enable the settings in this vimrc file, use:

    \definevimtyping
       [...]
       [...
        vimrc=...,
        ...]

The value of vimrc key needs to be the same as the value of the name key in \startvimrc. You may set the vimrc file for a particular code snippet by

   \start<vimtyping>[vimrc=....]
   ..
   \stop<vimtyping>


To disable loading of vimrc file, use

    \definevimtyping
       [...]
       [...
        vimrc=none,
        ...]
   

The default is not to use any vimrc file.

A vimrc file gets loaded before syntax highlighting is enabled. If you want to override the default syntax highlighting scheme, add the appropriate syn ... commands to a vimrc file, and source that using

    \definevimtyping
       [...]
       [...
        extras=<name of vimrc file>,
        ...]

For example, suppose you are using a C++ library that defines uDouble as a keyword, so you want to highlight it in your code. Use

   \startvimrc[name=cpp_extras]
   syn keyword Type uDouble
   \stopvimrc
   \definevimtyping
     [cpp]
     [
       syntax=cpp,
       extras=cpp_extras,
     ]