In this section, we will look at a few extra tips that can be handy when you create scripts for Vim. Some are simple code pieces you can add directly in your script, while others are good-to-know tips.
Gvim or Vim?
Some scripts have extra features when used in the GUI version of Vim (Gvim). This could be adding menus, toolbars, or other things that only work if you are using Gvim. So what do you do to check if the user runs the script in a console Vim or in Gvim? Vim has already prepared the information for you. You simply have to check if the feature gui_running is enabled. To do so, you use a function called has(), which returns 1 (true) if a given feature is supported / enabled and 0 (false), otherwise.
An example could be:
"execute gui-only commands here.
This is all you need to do to check if a user has used Gvim or not. Note that it is not enough to check if the feature “gui” exists, because this will return true if your Vim is just compiled with GUI support—even if it is not using it.
Look in :help ‘feature-list’ for a complete list of other features you can check with the has() function.
Which operating system?
If you have tried to work with multiple operating systems such as Microsoft Windows and Linux, you will surely know that there are many differences.
This can be everything from where programs are placed, to which programs you have available and how access to files is restricted.
Sometimes, this can also have an influence on how you construct your Vim script as you might have to call external programs, or use other functionality, specific for a certain operating system.
Vim lets you check which operation system you are on, such that you can stop executing your script or make decisions about how to configure your script. This is done with the following piece of code:
if has("win16") || has("win32") || has("win64")|| has("win95")
" do windows things here
" do linux/unix things here
This example only shows how to check for Windows (all flavors available) and Linux / Unix. As Vim is available on a wide variety of platforms, you can of course also check for these. All of the operating systems can be found in:
Which version of Vim?
Throughout the last decade or two, Vim has developed and been extended with a large list of functions. Sometimes, you want to use the newest functions in your script, as these are the best / easiest to use. But what about the users who have a version of Vim that is older than the one you use, and hence don’t have access to the functions you use?
You have three options:
- Don’t care and let it be the user’s own problem (not a good option).
- Check if the user uses an old version of Vim, and then stop executing the script if this is the case.
- Check if the user has too old a version of Vim, and then use alternative code.
The first option is really not one I would recommend anyone to use, so please don’t use it.
The second option is acceptable, if you can’t work around the problem in the old version of Vim. However, if it is possible to make an alternative solution for the older version of Vim, then this will be the most preferable option.
So let’s look at how you can check the version of Vim.
Before we look at how to check the version, we have to take a look at how the version number is built.
The number consists of three parts:
- Major number (for example, 7 for Vim version 7)
- Minor number (for example, 3 for Vim version 6.3)
- Patch number (for example, 123 for Vim 7.0.123)
The first two numbers are the actual version number, but when minor features / patches are applied to a version of Vim, it is mostly only the patch number that is increased. It takes quite a bit of change to get the minor number to increase, and a major part of Vim should change in order to increase the major version number.
Therefore, when you want to check which version of Vim the user is using, you do it for two versions—major and minor versions and patch number. The code for this could look like:
if v:version >= 702 || v:version == 701 && has("patch123")
" code here is only done for version 7.1 with patch 123
" and version 7.2 and above
The first part of the if condition checks if our version of Vim is version 7.2 (notice that the minor version number is padded with 0 if less than 10) or above. If this is not the case, then it checks to see if we have a version 7.1 with patch 123. If patch version 124 or above is included, then you also have patch 123 automatically.
Printing longer lines
Vim was originally created for old text terminals where the length of lines was limited to a certain number of characters. Today, this old limitation shows up once in a while.
One place where you meet this limitation of line length is when printing longer lines to the screen using the “echo” statement. Even though you use Vim in a window where there are more than the traditional 80 characters per line, Vim will still prompt you to press Enter after echoing lines longer than 80 characters. There is, however, a way to get around this, and make it possible to use the entire window width to echo on. Window width means the total number of columns in the Vim window minus a single character. So if your Vim window is wide enough to have 120 characters on each line, then the window width is 120-1 characters.
By adding the following function to your script, you will be able to echo screen-wide long lines in Vim:
" WideMsg() prints [long] message up to (&columns-1) length
let x=&ruler | let y=&showcmd
set noruler noshowcmd
let &ruler=x | let &showcmd=y
This function was originally proposed by the Vim script developer Yakov Lerner on the Vim online community site at http://www.vim.org.
Now whenever you need to echo a long line of text in your script, instead of using the echo statement you simply use the function Widemsg(). An example could be:
:call WideMsg("This should be a very long line of text")
The length of a single line message is still limited, but now it is limited to the width of the Vim window instead of the traditional 80-1 characters.
Debugging Vim scripts
Sometimes things in your scripts do not work exactly as you expect them to. In these cases, it is always good to know how to debug your script.
In this section, we will look at some of the methods you can use to find your error.
Well-structured code often has fewer bugs and is also easier to debug.
In Vim, there is a special mode to perform script debugging. Depending on what you want to debug, there are some different ways to start this mode. So let’s look at some different cases.
If Vim just throws some errors (by printing them at the bottom of the Vim window), but you are not really sure where it is or why it happens, then you might want to try to start Vim directly in debugging mode. This is done on the command line by invoking Vim with the -Dargument.
vim -D somefile.txt
The debugging mode is started when Vim starts to read the first vimrc file it loads (in most cases the global vimrc file where Vim is installed). We will look at what to do when you get into debug mode in a moment.
Another case where you might want to get into debug mode is when you already know which function the error (most likely) is in, and hence, just want to debug that function. In that case you just open Vim as normal (load the script with the particular function if needed) and then use the following command:
:debug call Myfunction()
Here everything after the :debug is the functionality you want to debug. In this case, it is a simple call of the function Myfunction(), but it could just as well be any of the following:
:debug read somefile.txt
:debug nmap ,a :call Myfunction() <CR>
:debug help :debug
So let’s look at what to do when we get into the debugging mode.
When reaching the first line that it should debug, Vim breaks the loading and shows something like:
Entering Debug mode. Type "cont" to continue.
cmd: call MyFunction()
Now you are in the Vim script debugger and have some choices for what to make Vim do.
If you are not familiar with debugging techniques, it might be a good idea to read up on this subject before starting to debug your scripts.
The following commands are available in the debugger (shortcuts are in parentheses):
- cont (c): Continue running the scripts / commands as normal (no debugging) until the next breakpoint (more about this later).
- quit (q): Quit the debugging process without executing the last lines.
- interrupt (i): Stop the current process like quit, but go back to the debugger.
- step (s): Execute the next line of code and come back to the debugger when it is finished. If a line calls a function or sources a file, then it will step into the function / file.
- next (n): Execute the next command and come back to the debugger when it is finished. If used on a line with a function call, it does not go into the function but steps over it.
- finish (f): Continue executing the script without stopping on breakpoints. Go into debug mode when done.