Appendix B. Editing CFEngine 3 Configurations in Vim

Neil H. Watson

Not to be outdone by Emacs, Vim can be equally productive in editing CFEngine files. Here I’ll show you how to set up and get started with the vim_cf3 plugin.

Setting Up

The vim_cf3 plugin can be found at https://github.com/neilhwatson/vim_cf3. Copy the relevant parts into your $HOME/.vim/ directory:

  • The file type plugin for file editing: $HOME/.vim/ftplugin/cf3.vim.

  • The syntax highlighting file: $HOME/.vim/syntax/cf3.vim.

  • The help file: $HOME/.vim/doc/cf3.txt.

  • The help directory and its contents: $HOME/.vim/snippets.

Here is a minimum .vimrc to make the plugin work and associate it with filenames ending in .cf:

      set smartindent
      set autoindent
      syntax on
      filetype plugin indent on

      :helptags ~/.vim/doc/
      au BufRead,BufNewFile *.cf set ft=cf3
      " enable vim_cf3 plugin abbreviations
      let g:EnableCFE3KeywordAbbreviations=1

      fun! Getchar()
        let c = getchar()
        if c != 0
          let c = nr2char(c)
        endif
        return c
      endfun

      fun! Eatchar(pat)
         let c = Getchar()
         return (c =~ a:pat) ? '' : c
      endfun

There is a Vim help file that comes with vim_cf3. In command mode, :help cf3 will call the help. You can also be more specific (for example, :help cf3abb) to call help about abbreviations.

Once the plugin is installed you can begin using it. Edit any exiting or new CFEngine file. The filename must end in .cf in order for the plugin to recognize it (you can also activate the plugin by hand on any file by executing :set ft=cf3). Let’s start with a blank file. Our first useful command will build the skeleton for a self-contained CFEngine file. Self-contained files, like this, are what I normally use in developing prototype or bug reporting bundles. In normal mode, press the keys ,-k (comma, k) in order. The following template is automatically inserted:

body common control
       {
       bundlesequence =>
       {
                "main",
        };
        inputs =>
        {
                "cfengine_stdlib.cf",
        };
}
bundle agent main
{
        methods:
        "any" usebundle => test;
}
bundle agent test
{
}

You’ll notice that there is syntax highlighting. Folding, which lets you switch between overview and detailed views of functions, is also enabled. If everything is folded at the moment, press z-R to unfold. Any bundle or body can be folded. For example, in the text just inserted, move the cursor inside the body of bundle agent main, anywhere between the curly brackets, and press z-c. You should see the following:

+--  7 lines: bundle agent main
    {

The bundle is now folded. You can open it with z-o. Everything in the current file can be unfolded with z-R. See Vim’s help on folding for more information about this topic.

When typing, you can take advantage of multiple helpful abbreviations, which can be seen in Table B-1. In insert mode, if you type any of the strings from the first column, then a space, the text will expand automatically to the second column.

Sometimes you may want to disable these abbreviations, such as during paste inserts. To do so, use the keys ,-i to toggle the abbreviations on and off.

There are a few other useful key sequences that operate in normal mode:

The code for this plugin is available on GitHub. You are welcome to use and modify it, either to customize it for your own needs, or to contribute your changes back to the code base as pull requests. The two main user-accessible components defined in the plugin are abbreviations and maps.

Installing vim_cf3 Using CFEngine

Here is a CFEngine agent bundle that can be used to install the plugin on a machine so that all users have access to it:

bundle agent vim_cf3
{
# Assumes that vimfiles source directory contains the following:
# ./vimfiles/doc/cf3.txt
# ./vimfiles/ftplugin/cf3.vim
# ./vimfiles/syntax/cf3.vim
# You need to customize the copy_from line according to your own
# configuration
  files:
      "/usr/share/vim/vimfiles/."
        perms        => mog("0644","root","root"),
        create       => "true",
        depth_search => recurse("inf"),
        classes      => if_repaired( "vim_helptags" ),
        copy_from    => remote_dcp(
          "${g.sitefiles}/misc/vimfiles",
          "${sys.policy_hub}"
        );
  commands:
    vim_helptags::
      "/bin/echo ':helptags /usr/share/vim/vimfiles/doc'|/usr/bin/vim -es -"
        comment => "Generate help tags",
        contain => in_shell_and_silent;
}