Tip 1308 Printable Monobook Previous Next

created August 16, 2006 · complexity advanced · author Yakov Lerner · version n/a

This tip is deprecated for the following reasons:

the functionality in the conceal patch has been included in Vim 7.3

Introduction[edit | edit source]

The conceal patch by Vince Negri allows one to "conceal" parts of lines (in-line folding). One can make those parts completely invisible or replace them with shorter/alternate characters. Uses for this patch include:

  • Creating vertical folds (folding visual blocks or columns). See the foldcol.vim script, which uses the conceal patch to achieve this.
  • Hiding certain "distracting" characters, like ANSI escape sequences. See the AnsiEsc.vim script. (Although it seems the conceal version of the script has been replaced with one using "ignore" highlighting.)
  • Hiding or altering HTML tags. For example "Text in <b>bold</b>" can appear as "Text in *bold*", or simply as "Text in bold".

When used with color highlighting, conceal can be a very useful feature, allowing one to see the bare text in an HTML or LaTeX document without the clutter of markup.

This is achieved by making/altering a vim syntax file and using the "conceal" argument to specify which keywords, regions, or patterns can be concealed or replaced with different characters. Then one sets the "conceallevel" option to turn the concealing on or off.

Without the conceal patch, the only way to achieve a similar effect is to use ignore highlighting to toggle the visibility of certain markup. However, this is effectively equivalent to making the color of the markup match the background of the text editor. The markup still takes up space and can be seen when selected. The conceal patch, on the other hand, brings a whole new level of control over how Vim displays text.

The conceal patch also comes with two features useful in situations beyond concealing text. The ownsyntax option allows for two or more windows of the same file to use different syntax files. This allows one to view the same document with different highlighting. The other, related feature, cursorbind, is similar to scrollbind and allows two or more windows to remain in sync as one of them scrolls (useful for diff-ing documents).

Where to Get it[edit | edit source]

The conceal patch is not officially supported by Vim (to change this, vote for the patch). No pre-compiled binaries of Vim with the patch can easily be found on the web (except for this experimental binary: Gvim 7.0.17, native 16-bit Windows build). This means that one has to compile Vim from the source code and apply the patch manually.

The patch can be downloaded at: http://vince.negri.googlepages.com/

Also see Vince Negri's description of the patch, showing its use for abbreviating a LaTeX document.

Installing the Patch on UNIX/Linux[edit | edit source]

Currently, the patch is only available for Vim 6.4.10 and 7.0.35.
I personally have had trouble building 7.0.35 on Ubuntu Gutsy (see Appendix C), though 6.4.10 compiles fine. If you have trouble building one of the versions, try the other.

Vim 6.4.10 Source Files[edit | edit source]

If installing Vim 6.4.10, you will need this source file:
[Required] ftp://ftp.vim.org/pub/vim/unix/vim-6.4.tar.bz2
The 'extra' sources are only necessary for installing on non-UNIX/Linux systems. However, installing the extras won't hurt and may make patching easier.
[Optional] ftp://ftp.vim.org/pub/vim/extra/vim-6.4-extra.tar.gz
You may also want the language sources for languages other than English/US:
[Optional] ftp://ftp.vim.org/pub/vim/extra/vim-6.4-lang.tar.gz
You should get patches 6.4.001 through 6.4.010 to patch Vim 6.4 to Vim 6.4.010. However, this doesn't seem to be necessary as the conceal patch appears to work for Vim 6.4. If you're not installing the 'extra' sources mentioned above, don't install the patches marked (extra) in the patches README file.
[Semi-Optional] ftp://ftp.vim.org/pub/vim/patches/6.4/
Finally, you will need the 6.4.10 conceal patch:
[Required] http://vince.negri.googlepages.com/conceal-ownsyntax-v64.diff

Vim 7.0.35 Source Files[edit | edit source]

For Vim 7.0.35, here is the source file along with the extras and language sources:
[Required] ftp://ftp.vim.org/pub/vim/unix/vim-7.0.tar.bz2
[Optional] ftp://ftp.vim.org/pub/vim/extra/vim-7.0-extra.tar.gz
[Optional] ftp://ftp.vim.org/pub/vim/extra/vim-7.0-lang.tar.gz
You will want patches 7.0.001 through 7.0.035 to patch Vim 7.0 to Vim 7.0.35, but this doesn't seem to be necessary. If you're not installing the 'extra' sources, don't get the patches marked (extra) in the patches README file.
[Semi-Optional] ftp://ftp.vim.org/pub/vim/patches/7.0/
Finally, you will need the 7.0.35 conceal patch:
[Required] http://vince.negri.googlepages.com/conceal-ownsyntax.diff

Patching and Building[edit | edit source]

In order to build Vim, several development packages and libraries will need to be installed. On Ubuntu systems make sure you at least have the build-essential and libncurses5-dev packages installed. To compile Vim with GUI support, you'll also need libgtk2.0-dev, libxaw7-dev, and libx11-dev (should already be installed). You may also want libgnome2-dev and libgnomeui-dev, but it seems to compile on GNOME fine without these.

sudo apt-get install build-essential libncurses5-dev libgtk2.0-dev libxaw7-dev libx11-dev

Other packages may also be necessary. If you need other packages, configure (see below) should warn you about missing packages.

Next, create a directory for building Vim.

mkdir ~/.build

Move the downloaded source files into ~/.build and unpack them. For example (if you're building Vim 6.4):

tar xvfj vim-6.4.tar.bz2
tar xvfz vim-6.4-extra.tar.gz

...and so on. The sources will extract to ~/.build/vim64.

Create a ~/.build/vim64/patches folder and move the patches there. Now start patching the sources from the ~/.build/vim64 directory.

patch -p0 patches/6.4.002
patch -p0 patches/6.4.003
patch -p0 patches/6.4.009

Go through the patches one-by-one, in ascending order, skipping the extra patches if you're not installing the extra sources. This can be a long process, so you may want to use the code in the script provided in Appendix A.
Now you can apply the conceal patch. For Vim 6.4:

patch -p0 patches/conceal-ownsyntax-v64.diff

or for Vim 7.0:

patch -p0 patches/conceal-ownsyntax.diff

Watch for any errors. If everything went well, you can now run configure. You will at minimum need to enable the conceal and huge features:

./configure --enable-conceal --with-features=huge

However, if you want to be able to use a GUI (i.e. gvim), you will need to enable a few more features. These options should work on Ubuntu Gutsy:

./configure --enable-conceal --with-features=huge --with-x --enable-gui=gtk2 --enable-gnome-check --x-includes=/usr/include/X11 --x-libraries=/usr/lib

You may want other options enabled as well (for example --enable-multibyte for Asian character languages). Type ./configure --help to see what other features/packages are available. Then search the Vim documentation for more information on each feature (in particular see various.txt).
If you get errors, you are probably missing a required development package. Try to discern the error to figure out what you need. (Googling the text of the error often helps).

Now you can compile the code. If you're going to install the compiled Vim binary into your system, simply run make, then make install, and you're done.

make install

However, there are many reasons for not installing this patched version of Vim directly into your system. You may want to keep a more up-to-date, stabler version as the default Vim binary. Also, installing the binary directly can cause problems because it's not packaged specifically for your system (like it would be with apt-get install vim). You would also need to uninstall your current Vim package first, but it can be difficult to completely remove Vim on many systems, like Ubuntu Linux. It is possible to have two versions of Vim installed on your system, but it's a bit complicated.

A simpler solution is to leave the Vim binary in the build directory and then create a symbolic link to it. This will let you keep your existing version of Vim, while giving you the option of using your patched version of Vim when you need to. If you're choosing this route, you'll need to pass the runtime directory of the build to make (see ~/.build/vim64/src/INSTALL for more information). For example:

make VIMRUNTIMEDIR=~/.build/vim70/runtime MAKE="make -e"

This is necessary so that your patched Vim doesn't try to look for the runtime files in /usr/share/vim and instead looks in its own runtime directory.

If the make compilation finished without errors, you should now see a Vim binary in ~/.build/vim64/src/vim. Check to see if it compiled with the conceal feature.

~/.build/vim64/src/vim --version

You should see a +conceal feature listed in the output. If it says -conceal then conceal is not installed and something went wrong.

You can now start Vim with conceal! Just type ./vim or ./vim -g for GUI mode.

If you didn't run make install, then you can create a symbolic link to the built Vim binary for easy access on the command line. You should call the links something different from vim, gvim, vim.full, etc.

sudo ln -s ~/.build/vim64/src/vim /usr/bin/cvim
sudo ln -s ~/.build/vim64/src/vim /usr/bin/gcvim

Here we made two links to the Vim binary, gcvim and cvim (conceal-Vim). Because the gcvim link starts with a "g", it will automatically launch Vim in GUI mode (same as vim -g).

You can also create symbolic links to your syntax files, so that both Vim binaries can use it. For example:

sudo ln -s /usr/share/vim/vimcurrent/syntax/my_syntax.vim ~/.build/vim64/runtime/syntax/my_syntax.vim

Since you'll be using the same .vimrc / .gvimrc files for two Vim binaries with different version numbers, you will get errors when setting newer features with the older binary. To get around this, check the version number in your .vimrc file.

if version > 604
    set cursorline

This way, Vim will only run the command cursorline if the version number is greater than Vim 6.4.

For more information on patching and building Vim, see: Vim: Compiling How-To and Compiling gVim on Ubuntu/Debian.

Using Conceal[edit | edit source]

Here's a quick look at how to use the features available in the conceal patch. First, let's make a syntax file.

"chtml.vim: html with conceal
set conc=2

syn region inBold concealends matchgroup=bTag start="<b>" end="</b>"
syn match newLine "<br>" conceal cchar=}

hi inBold gui=bold
hi bTag guifg=blue
hi newLine guifg=green

Call this file chtml.vim and place it in /usr/share/vim/vimcurrent/syntax/ or similar syntax directory. Next, create a simple HTML file, hello.chtml:

Here is some <b>bold</b> HTML!<br>

Edit this file with Vim (patched with conceal). Now to apply the syntax file, you'll need to source it. From Vim run:

:so /path/to/chtml.vim

You can also automatically apply the chtml.vim syntax file to files ending in .chtml by adding this line to .vimrc:

autocmd BufRead *.chtml set filetype=chtml

You should now see the tags highlighted.

Here is some <b>bold</b> HTML!<br>

Now we can conceal the tags by using the conceallevel option:

:set conceallevel=2

(Or :se conc=2 for short). The HTML will now look like this:

Here is some bold HTML!}

Let's look at how this works.
Setting the conceallevel option to "2" hides concealed text or replaces it with another character. In this case the <b> tags are hidden and the <br> tags are replaced with the shorter "}" character.

This is dictated by the syntax file. The conceal argument indicates that the "<br>" match is concealable. The cchar argument provides an alternate character that can be shown in place of "<br>". The cchar argument is optional; if it isn't present then the concealed text is simply hidden when the conceallevel is set to "2".

The concealends argument allows for the start and end portions of a region to be concealed, while the inner text remains unconcealed. You need to provide a matchgroup argument that will create a group name for the start and end patterns, which can then be highlighted differently.

You can also set conceallevel to "3", which will hide all the concealable tags, ignoring the cchar alternate characters. Or you can set conceallevel to "1", which will replace all the concealable tags with a "-" (dash), aside from the cchar tags. To go back to unconcealed text, set concellevel to "0". You can quickly toggle concealed text by mapping :se conc=0 and :se conc=2 to two different keys. You can also start the file in a concealed mode on opening it by putting set conc=2 in your syntax file.

Note that the text of the line on which the cursor is on is never concealed. There seems to be no way to avoid this, even though it would certainly be useful in many cases to leave all text concealed while editing around the concealed portions. However, it is possible to see the full unconcealed text in a separate window from the one you're working on. To do this, start by splitting the window.


You can jump from window to window by using "CTRL-W-W". Then simply set the conceallevel to "0" in one window and "2" in the other.

One issue you'll quickly notice is that the two windows won't always be in sync when you start scrolling up and down. To address this, the conceal patch comes with another option -- cursorbind. Simply enter:

:se cursorbind

Now the two windows will be in sync, both by line and column. Note that cursorbind (crb) is similar to scrollbind (scb), which comes with Vim. There are slight differences between the two -- for instance using CTRL-Y and CTRL-E will scroll both windows with scrollbind, but not with cursorbind.

Finally, you can use the ownsyntax option that comes with the conceal patch to use different syntax files for the two windows (normally you can't use two syntax styles on the same file in Vim). You can use this to create one style of highlighting for the concealed markup-free version of the document, while using another for the window with markup. This also lets you keep the conceal version of your syntax file separate from the standard syntax file.

For instance, with our sample html document, you can split the windows and apply two different styles. To use the html.vim syntax file for the first window, simply enter:

:ownsyntax html

Then switch to the other window and apply the chtml.vim syntax file:

:ownsyntax chtml

Or, alternatively, enter :ownsyntax in both windows and you'll be able to source a separate syntax file in each window.

For the complete details, see the conceal documentation in Vim help (Appendix B).

Appendix A: Scripts to Download Sources and Build Vim[edit | edit source]

Here are two sets of scripts that summarize and automate the install process described above. I don't recommend running these scripts the first time you build Vim because so many things can go wrong. Rather, once you can patch and build Vim without problems, you can tweak these scripts and use them to rebuild Vim when necessary. The one part of the scripts you may want to use the first time you're building is the loop for downloading/applying the patches.

These scripts don't use the 'extra' and 'language' sources, but they can easily be modified to do so. Also, the scripts don't install Vim, but rather make a symbolic link to the new Vim binary.

Copy and paste each script into a text file. Then make it executable and run it from ~/.build. First run the get script to download the sources; then run the go script to build.

cd ~/.build
chmod +x get_vim_conceal_64.sh
chmod +x go_vim_conceal_64.sh

Scripts for Vim 6.4.10[edit | edit source]

get_vim_conceal_64.sh: for downloading sources[edit | edit source]

# get_vim_conceal_64.sh
# This script will download the necessary sources and patches for building Vim 6.4.10.
# After it runs your build directory should look like this:
# ~/.build/vim6.4.tar.bz2
# ~/.build/patches/6.4.002
# ~/.build/patches/6.4.003
# ...
# ~/.build/patches/6.4.009
# ~/.build/patches/conceal-ownsyntax-v64.diff
# Note that it doesn't download the "extra" patches 6.4.001 and 6.4.010. So really this script builds Vim 6.4.09.

wget ftp://ftp.vim.org/pub/vim/unix/vim-6.4.tar.bz2

mkdir patches


while [ $cnt -lt 10 ]; do
    wget -P patches ftp://ftp.vim.org/pub/vim/patches/6.4/6.4.00${cnt}
    let cnt+=1

wget -P patches http://vince.negri.googlepages.com/conceal-ownsyntax-v64.diff

go_vim_conceal_64.sh: for building the binary[edit | edit source]

# go_vim_conceal_64.sh
# This script extracts the source files and copies the patches folder to the vim64 folder.
# It then patches and builds Vim, with GUI/GNOME support options for Ubuntu Gutsy or similar systems.
# It doesn't install Vim, but rather makes a symbolic link to the built binary.
# After running the script, the binary can be started with the command "cvim".

tar xvfj vim-6.4.tar.bz2

cp -r patches vim64/patches

cd vim64

ls patches/6* | while read file
    patch -p0 < "${file}"

patch -p0 < patches/conceal-ownsyntax-v64.diff

./configure --enable-conceal --with-features=huge --with-x --enable-gui=gtk2 --enable-gnome-check --x-includes=/usr/include/X11 --x-libraries=/usr/lib
make VIMRUNTIMEDIR=~/.build/vim64/runtime MAKE="make -e"
sudo ln -s ~/.build/vim64/src/vim /usr/bin/cvim
sudo ln -s ~/.build/vim64/src/vim /usr/bin/gcvim

Scripts for Vim 7.0.35[edit | edit source]

get_vim_conceal_70.sh: for downloading sources[edit | edit source]

# get_vim_conceal_70.sh
# This script will download the necessary sources and patches for building Vim 7.0.35.
# After it runs your build directory should look like this:
# ~/.build/vim7.0.tar.bz2
# ~/.build/patches/7.0.001
# ~/.build/patches/7.0.002
# ...
# ~/.build/patches/7.0.035
# ~/.build/patches/conceal-ownsyntax.diff
# Note that it doesn't download any "extra" patches.

wget ftp://ftp.vim.org/pub/vim/unix/vim-7.0.tar.bz2

mkdir patches


# Two loops seem necessary to download patches #1-9 and 10-35 (while keeping the script easy to read).
# The "extra" patches #5, 27, 28, and 32 are skipped.

while [ $cnt -lt 10 ]; do
    if [ $cnt -ne 5 ]; then
        wget -P patches ftp://ftp.vim.org/pub/vim/patches/7.0/7.0.00${cnt}
    let cnt+=1

while [ $cnt -lt 36 ]; do
    if [ $cnt -ne 27 -a $cnt -ne 28 -a $cnt -ne 32 ]; then
        wget -P patches ftp://ftp.vim.org/pub/vim/patches/7.0/7.0.0${cnt}
    let cnt+=1

wget -P patches http://vince.negri.googlepages.com/conceal-ownsyntax.diff

go_vim_conceal_70.sh: for downloading sources[edit | edit source]

# go_vim_conceal_70.sh
# This script extracts the source files and copies the patches folder to the vim70 folder.
# It then patches and builds Vim, with GUI/GNOME support options for Ubuntu Gutsy or similar systems.
# It doesn't install Vim, but rather makes a symbolic link to the built binary.
# After running the script, the binary can be started with the command "cvim".

tar xvfj vim-7.0.tar.bz2

cp -r patches vim70/patches

cd vim70

ls patches/7* | while read file
    patch -p0 < "${file}"

patch -p0 < patches/conceal-ownsyntax.diff

./configure --enable-conceal --with-features=huge --with-x --enable-gui=gtk2 --enable-gnome-check --x-includes=/usr/include/X11 --x-libraries=/usr/lib
make VIMRUNTIMEDIR=~/.build/vim70/runtime MAKE="make -e"
sudo ln -s ~/.build/vim70/src/vim /usr/bin/cvim
sudo ln -s ~/.build/vim70/src/vim /usr/bin/gcvim

Appendix B: Vim Help Documentation for Conceal[edit | edit source]

Provided here for reference is the documentation that comes with the Vim 6.4.10 conceal patch, taken from the help files.

options.txt[edit | edit source]

'conceallevel' 'conc'		*'conceallevel'* *'conc'*
			number (default 0)
			local to window
			{not in Vi}
			{not available when compiled without the |+conceal|
	Determine how text with the "conceal" syntax attribute is shown:

	'conceallevel'	Effect
	0		Text is shown normally
	1		Each block of concealed text is replaced with the
			character defined in 'listchars' (default is a dash)
			and highlighted with the "Conceal" highlight group.
	2		Concealed text is completely hidden unless it has a
			custom replacement character defined (see
	3		Concealed text is completely hidden.

			*'cursorbind'* *'crb'* *'nocursorbind'* *'nocrb'*

'cursorbind' 'crb'	boolean  (default off)
			local to window
			{not in Vi}
			{not available when compiled without the |+cursorbind|
	When this option is set, as the cursor in the current
	window moves other cursorbound windows (windows that also have
	this option set) move their cursors to the corresponding line and
	column.  This option is useful for viewing the
	differences between two versions of a file (see 'diff'); in diff mode,
	inserted and deleted lines (though not characters within a line) are
	taken into account.
						*'highlight'* *'hl'*
'highlight' 'hl'	string	(default (as a single string):
			{not in Vi}
	This option can be used to set highlighting mode for various
	occasions.  It is a comma separated list of character pairs.  The
	first character in a pair gives the occasion, the second the mode to
	use for that occasion.	The occasions are:

        <--- cut --->

	|hl-Conceal|	 x  the placeholders used for concealed characters
			    (see 'conceallevel')

        <--- cut --->

						*'listchars'* *'lcs'*
'listchars' 'lcs'	string	(default "eol:$")
			{not in Vi}
	Strings to use in 'list' mode.	It is a comma separated list of string

        <--- cut --->

	  conceal:c	Character to show in place of concealed text, when
	  		'conceallevel' is set to 1.

        <--- cut --->

syntax.txt[edit | edit source]

16. Window-local syntax				*:ownsyntax*

Normally all windows on a buffer share the same syntax settings. It is
possible, however, to set a particular window on a file to have its own
private syntax setting. A possible example would be to edit LaTeX source
with conventional highlighting in one window, while seeing the same source
highlighted differently (so as to hide control sequences and indicate bold,
italic etc regions) in another. The 'scrollbind' option is useful here.

To set the current window to have the syntax "foo", separately from all other
windows on the buffer: >
   :ownsyntax foo

Once a window has its own syntax, syntax commands executed from other windows
on the same buffer (including :syntax clear) have no effect. Conversely,
syntax commands executed from that window do not effect other windows on the
same buffer.

A window with its own syntax reverts to normal behaviour when another buffer
is loaded into that window.
6. :syntax arguments					*:syn-arguments*

The :syntax commands that define syntax items take a number of arguments.
The common ones are explained here.  The arguments may be given in any order
and may be mixed with patterns.

Not all commands accept all arguments.	This table shows which arguments
can not be used for all commands:
							*E395* *E396*
		    contains  oneline	fold  display  extend concealends~
:syntax keyword		 -	 -	 -	 -	 -      -
:syntax match		yes	 -	yes	yes	yes     -
:syntax region		yes	yes	yes	yes	yes    yes

These arguments can be used for all three commands:

conceal							*:syn-conceal*

When the "conceal" argument is given, the item is marked as concealable.
Whether or not it is actually concealed depends on the setting on the
'conceallevel' option.

concealends						*:syn-concealends*

When the "concealends" argument is given, the start and end matches of
the region, but not the contents of the region, are marked as concealable.
Whether or not they are actually concealed depends on the setting on the
'conceallevel' option. The ends of a region can only be concealed separately
in this way when they have their own highlighting via "matchgroup"

cchar							*:syn-cchar*

The "cchar" argument defines the character shown in place of the item
when it is concealed (setting "cchar" only makes sense when the conceal
argument is given.) If "cchar" is not set then the default conceal
character defined in the 'listchars' option is used. Example: >
   :syntax match Entity "&" conceal cchar=&

IMPLICIT CONCEAL					*:syn-conceal-implicit*

:sy[ntax] conceal [on|off]
	This defines if the following ":syntax" commands will define keywords,
	matches or regions with the "conceal" flag set. After ":syn conceal
	on", all subsequent ":syn keyword", ":syn match" or ":syn region"
	defined will have the "conceal" flag set implicitly. ":syn conceal
	off" returns to the normal state where the "conceal" flag must be
	given explicitly.

					*highlight-groups* *highlight-default*
These are the default highlighting groups.  These groups are used by the
'highlight' option default.  Note that the highlighting depends on the value
of 'background'.  You can see the current settings with the ":highlight"
Conceal		placeholder characters substituted for concealed
		text (see 'conceallevel')

        <--- cut --->

eval.txt[edit | edit source]

						*window-variable* *w:var*
A variable name that is preceded with "w:" is local to the current window.  It
is deleted when the window is closed.

One local window variable is predefined:
					*w:ownsyntax-variable* *ownsyntax*
w:ownsyntax	Set to 1 if the window has an independent syntax installed
		via the |:ownsyntax| command. The default for a window is
		0. Syntax scripts can use this to determine whether they
		should set b:current_syntax or w:current_syntax.

Appendix C: Compile Errors[edit | edit source]

I personally have not been able to compile Vim 7.0.35 with the conceal patch on Ubuntu Gutsy. All the patches work and configure runs fine, but make gives the following error:

gcc -c -I. -Iproto -DHAVE_CONFIG_H     -g -O2         -o objects/option.o option.c
option.c:795: error: ‘WV_CONCEAL’ undeclared here (not in a function)
option.c:886: error: ‘WV_CRBIND’ undeclared here (not in a function)
option.c: In function ‘get_varp’:
option.c:9032: error: case label does not reduce to an integer constant
option.c:9035: error: case label does not reduce to an integer constant
make[1]: *** [objects/option.o] Error 1
make[1]: Leaving directory `/home/user/.build/vim70/src'
make: *** [first] Error 2

This error doesn't happen when compiling Vim 6.4.10 on the same system. Can someone resolve the cause of this error?
If anyone has success compiling Vim 7.0.35 on Ubuntu Gutsy, please post your findings.

Appendix D: Request for More Information[edit | edit source]

Please post your findings to these issues:

  • What development packages are required on other distros besides Ubuntu?
  • What is the cause of the error when making Vim 7.0.35 on Ubuntu Gutsy (see Appendix C)?
  • Is there any way (proper solution or hack) to avoid the unconcealment of the line on which the cursor is on?
  • Post any useful syntax files you've made that use conceal on vim.org and link them here.

Comments[edit | edit source]

Community content is available under CC-BY-SA unless otherwise noted.