Inform Filetype Detection


One of the peculiarities of Inform is that its header files often use a .h extension, just like C header files do, or have no extension at all. Since the number of C coders using Vim vastly outweigh the number of Inform coders, Vim is quite reasonably configured to recognise files with a .h extension as being C code. Similarly, Vim tends to assume that files with no extension are various flavours of shell script. This is irritating to Inform developers, who always have to manually issue a ":setf inform" command so that the file is highlighted as Inform code.

This section dicusses four approaches solving or working around this problem.

  1. Modelines

    Place a comment either near the start or the end of an Inform file saying:

       ! vim:setf inform
    
    On reading the file, Vim will recognize this as a command and execute it.

    This is fine for your own files, but not suitable for files with do not belong to you. Also, some people (myself included) object to this on aesthetic grounds.

  2. Symlinks

    On platforms that support symbolic links (or hard links, I suppose), that is, Linux/Unix, for each Inform file create a corresponding .inf file that is link (symbolic or hard, I recommend symbolic) to that file. When you wish to look at the Inform file with Vim, use the .inf file rather than the original file.

    The drawbacks to this approach are clear. Obviously you must be using a platform with hard or symbolic links. Furthermore you must have permission to create such links, although it is not necessary for such links to reside in the same directory as the file being linked to (although hard links must reside on the same filing system).

  3. Copies

    This is an inferior variant of the symlinks idea, for platforms where links are not supported. Copy each Inform file into a corresponding .inf file.

    The drawbacks are even more severe. Obviously you must be able create such copies (although again such copies can reside anywhere you wish). However, if you actually alter a .inf which is shadowing an Inform file, you must remember to copy the .inf over the original file once an alteration is made. If you cannot do that, then you are stuck. Even if you can, the fact that you must remember to do this makes this technique terribly fragile.

  4. Disambiguation by Vim

    [Most of the ideas and some of the coding in this section are the work of Ross Presser and Neil Cerutti. My thanks to them for solving an awkward problem.]

    The problem is that Vim always decides that any file with a .h extension is a C file. This is almost always the case - unless you are programming in Inform. The trick is to intercept Vim's decision making process. This is a two-stage process.

    Firstly, you need to create a file filetype.vim in your user runtime directory ($HOME/.vim on Unix), containing the following text:

        if exists("did_load_filetypes")
          finish
        endif
        augroup filetypedetect
          au BufNewFile,BufRead *.h             call FTCheck_inform()
        augroup END
    
        " function to detect inform code (any extension)
        fun! FTCheck_inform()
            if getline(1) =~ "^!"
               setfiletype inform
            elseif getline(2) =~ "^!"
               setfiletype inform
            else
                let s:colnum = col('.')
                let s:linenum = line('.')
                call cursor(500, 1)
                if search('^\s*\(\h\w*\s*\)\=\[\(\h\w*\)\=\(\s\+\h\w*\)*\s*;', 'bW') > 0
                    setfiletype inform
                endif
                call cursor(s:linenum, s:colnum)
            endif
        endfun
    

    What this does is to cause Vim to call a function when given a .h file. That function checks the file contents, looking for Inform-specific syntax or idioms. If one is found it is assumed the file is really an Inform file and the filetype is set accordingly. If none are found, it leaves the filetype unset. This allows Vim's standard way of recognizing .h files to complete the job.

    The second part of the process is to deal with the situation when an Inform file has no extension, giving Vim no hint at all. Vim has a general mechanism for dealing with this situation, it is just that Inform is not one of the options it normally considers. To change that, create a file called scripts.vim in your Vim user runtime directory:

       " local scripts.vim gets called when
       " all autocommands have failed to identify file type,
       " but before global scripts.vim
       "
       call FTCheck_inform()
    
    (For the curious, the constructs searched for are:

    The first construct could be legal C, although it is unlikely. The second construct is not legal C.)

    I have used this technique for some time, in a mainly C coding environment. Not once has it mis-identified a C file as Inform. That said, the risk of this happening is merely very low, not zero. For example, it is possible to encounter Perl scripts with no extension, and the constructs searched for might conceivably be legal Perl, causing a Perl file to be mis-identified as Inform. Consequently, this technique will never be made standard part of Vim.


Updated: 9th August 2003