FillColumnIndicator

Many modern editors and IDEs can graphically indicate the location of the fill column by drawing a thin line (in design parlance, a “rule”) down the length of the editing window. The package fill-column-indicator.el implements this facility in Emacs:

FciRuleStyle

Please note: There is a small incompatibility between this package and the Emacs relase v24.3. A bug in Emacs’s internal display routine that was introduced shortly before that release can cause vertical motion commands to skip blank lines when fci-mode is active. See this discussion for further information.

Installation and Activation

Put the package file in your load path and put (require 'fill-column-indicator) in your .emacs.

To toggle graphical indication of the fill column in a buffer, use the command fci-mode.

Customization

The following are the basic configuration options. For further advanced options, see the headers in the package file. Buffer-local values of the following are supported (so one can, e.g., use a rule of different appearance in different buffers).

General Configuration

Location. By default fci-mode draws a vertical line at the fill column. If you’d like it to be drawn at a different location, set fci-rule-column to the desired column number. (A case in which this is useful is when you want to fill comments at, for example, column 70, but want a vertical rule at column 80 or 100 to indicate the maximum line length for code.) The default behavior is specified by setting fci-rule-column to nil.

Graphical Displays

On graphical displays (displays that can display images) the fill-column rule is drawn using bitmap images.

Width. The width of the rule (in pixels) is determined by the value of the variable fci-rule-width; the default value is 1.

Solid or Dashed Line. By default the rule is drawn as a solid line. To use a dashed line instead set fci-rule-use-dashes to a non-nil value. The length of a dash is, by default, 0.75 of the line height. To use a shorter or longer dash, set fci-dash-pattern to the desired ratio (the value should be between 0 and 1).

Color. The color of the rule is controlled by the variable fci-rule-color, whose value can be any valid color name.

To specify, e.g., a 1-pixel-wide dark blue rule, put the following in your init file:

  (setq fci-rule-width 1)
  (setq fci-rule-color "darkblue")

Image Format. The image formats fci-mode can use are XPM, PBM, and XBM. If Emacs has been compiled with the appropriate library it uses XPM images by default; if not it uses PBM images, which are natively supported. You can specify a particular format by setting fci-rule-image-format to either xpm, xpm, or xbm.

Character Terminals

On non-graphical displays (where images aren’t available), the rule is drawn using textual characters.

Character for Drawing. The default character used to draw the rule on character terminals is `|’ (ascii 124). To use a different character, set the variable fci-rule-character to your desired value.

Color. The color of the rule on character terminals is controlled by the variable fci-rule-character-color, whose value should be either nil or a color name. If nil (the default), the value of fci-rule-color (or the closest approximation thereto that the terminal is capable of) is used.

Using Characters Everywhere. To draw the rule with characters even when images are available, set fci-always-use-textual-rule to t (or any non-nil value).

Further Customization Examples

To turn on fci-mode automatically for certain kinds of files, add 'fci-mode to the appropriate mode hook. For example, to turn it on automatically when visiting a file with C code, put the following line in your init file:

  (add-hook 'c-mode-hook 'fci-mode)

To turn on fci-mode automatically for all files, put the following line in your init file:

  (add-hook 'after-change-major-mode-hook 'fci-mode)

To enable fci-mode as a global minor mode, put the following code to your init file:

  (define-globalized-minor-mode global-fci-mode fci-mode (lambda () (fci-mode 1)))
  (global-fci-mode 1)

Miscellany

There’s a GitHub repository for the package, which might provide a more convenient way of ensuring one has the latest version. (I haven’t found the Emacs Wiki RSS feeds to be entirely reliable.)

If you’re curious about the color scheme in the screenshots on this page, the settings are described on my homepage.

See also

Legacy Version

Fci-mode previously offerred another way of indicating the fill column, viz. shading the area of the window to the right of the fill-column:

FciShadingStyle

This mode of operation turned out to be both less popular than the rule-style indicator and more difficult (read: well-nigh impossible) to implement in such a way as to avoid conflicts with other packages. An earlier version of the package that offers both styles of indicator is still available at FillColumnIndicatorLegacy. (I’ll fix minor bugs in this older version, but don’t plan on making any major changes to it.)

Discussion

How to enabled fci-mode in text and programming modes, but not special buffers, dired, shell, etc.

This package is amazing and I hope it is eventually incorporated in default emacs. However, it would be good if, once loaded, fci-mode was enabled by default for most text and programming modes and disabled for special buffers (like *Messages*, *Buffer List*, *Completions*, etc). It doesn’t make sense either in Dired mode. Enabling fci-mode as a global minor mode is too brute-force. --Manu

This can be fixed by being more picky about when you turn on fci-mode in global-fci-mode:

  (define-globalized-minor-mode global-fci-mode fci-mode
    (lambda ()
      (if (and
           (not (string-match "^\*.*\*$" (buffer-name)))
           (not (eq major-mode 'dired-mode)))
          (fci-mode 1))))
  (global-fci-mode 1)

edam

I think it should suffice to say (if buffer-file-name (fci-mode 1)), i.e. only use fci-mode on buffers that are visiting files. And this section should probably be merged into “Further Customization Examples”, above.

Problems when Using Emacs as a Daemon

Really neat stuff 😊

I’ve just spotted a small problem. In order to use with EmacsAsDaemon one needs to comment out these lines:

    (unless window-system
        (error "Fill-column-indicator only works on window systems"))

j.a.

[Some ensuing back and forth edited out.] After playing around with emacsclient for a while, I think you’re right: The best thing to do is not throw any kind of error when Emacs is running as a daemon, and instead depend on the user to figure out when they can invoke fci-mode and when they can’t. Thanks for pointing out the problem. --AA

As of 1.52, the package should be able to handle daemon mode gracefully, displaying the graphical rule on graphical terminals and the textual rule on character terminals. --AA

Problem using dabbrev-expand

With fci-mode active in a buffer, using dabbrev-expand at the end of a line seems to jump the point down a couple of lines lines. So a buffer containing:

  abcdef
  abc
  foofoo

Position the point after the second abc and use dabbrev-expand, I get the correct expansion, but the point jumps to the third o in foofoo. Without fdi-mode I get the correct expansion and the point is left after the expanded abcdef.

I’ve uploaded a new version (0.28) that fixes the bug. – AA

The new version (0.28) works great, thanks for the quick fix!

Interesting Interaction With show-paren-mode

First, awesome package, I’ve been looking for something like this for years! But, like a typical ungrateful user I’m going to immediately follow my thanks with a bug report!

If I have just the following in my .emacs:

(show-paren-mode t)
(setq show-paren-style 'expression)

;; So I can load fill-column-indicator
(defconst elisp-directory (expand-file-name "~/.elisp/"))
(add-to-list 'load-path elisp-directory)
(require 'fill-column-indicator)

Then open up a new file in c-mode.

Add the following content to the file,

int
main ()
{
  /* Next line has some whitespace on it, the line after that is completely empty. */
      

}

At this point we should have { to } highlighting on, and fci-mode off. Position the point at the character immediately after the closing } and hopefully we should see a highlighted block. Next turn on fci-mode and see how the highlighting changes.

I have no idea how easy this would be to fix, and it’s not a huge issue, just thought it was worth mentioning.

Thanks for pointing this out. The problem is caused by the way fci-mode pads out the end of lines to make the rule or shading appear at the fill column: it puts an overlay on newline characters with a before-string property that contains the necessary amount of padding. Unfortunately, the face attributes of overlay before-strings aren’t merged with those of other overlays that cover the same region, so the show-paren highlighting doesn’t appear on the padding.

This will probably be an issue with libraries other than paren.el, and I’m going to have to think about how to fix things in robust fashion. In the meantime, here’s a version with a workaround: [link removed; this code is now part of the main version]. --AA

I can’t comment on the how much of a hack this is, my elisp isn’t that great 😊 But this does seem to fix the problem for me so far. I’ll switch to using this at work after the weekend and see how I get on.

(A few days later). So far, every way I can think of to make the fill-column padding automatically pick up parenthesis highlighting will break support for character terminals. So I’ve cleaned up the earlier hack and made it, for now, the Official Way We Do Things. (Btw, you might want to have a look at mic-paren.el, which is an improvement on paren.el in just about every respect.) --AA

fci-mode also causes the highlighting of the current line by hl-line-mode to be slightly broken. The highlighting between the last character and the fci column marker is lost. Probably has the same cause as the above problem. Maybe just removing the font property for the current line if hl-line-mode is active would fix this.

You’re right; the problem is essentially the same. Unfortunately, the fix isn’t as straightforward as deleting the fill-column indication on a given line. (That wouldn’t work with global-hl-line-mode, or with hl-line-mode when hl-line-sticky-flag is nil.) I’ve put up a new version (0.40) that’s compatible with hl-line-mode. – AA

From the (E-)Mailbag

I want the fill-column indicator to be appear at column 80, but it only appears at column 70. How do I set it to use a different column?

Fci-mode uses whatever value you have fill-column set to. As 70 is the default, you probably haven’t set fill-column to your desired value. You can use the command set-fill-column to change the value of fill-column in a buffer, or put (setq-default fill-column 80) in your .emacs to set it globally. --AA

Problems with redraw on window size increase

Nice plugin. Exactly what I was looking for. One small nit. In both graphical and terminal emacs, when I increase the size of the window or terminal (for example, to maximize it) the text and other emacs UI elements automatically fill the newly expanded buffer, but the fill-column line does not. Once I do anything (for example, move point) the fill-column line redraws itself down the remainder of the visible buffer area. --rlange

Thanks for pointing that out. I have a fix, but I’d like to test it a little before posting a new version. Check back after the weekend. -AA

I’ve uploaded a new version (1.77) with a fix. On NextStep (OS X) it appears to be possible to confuse it if you rapidly resize the frame several times in the space of a second; on X it seems solid. I can’t reproduce the problem reliably, though; I’m guessing that there’s a subtle bug in the way the NextStep port communicates with the window manager. In any case, this should (I hope 😊 be robust enough for normal usage. --AA

'truncate-lines nil

Currently, using 'truncate-lines nil leads to weird fci rendering. A partial work-around is adding this to your ~/.emacs file:

  (setq-default fci-rule-column 80)
  (setq fci-handle-truncate-lines nil)
  (define-globalized-minor-mode global-fci-mode fci-mode (lambda () (fci-mode 1)))
  (global-fci-mode 1)
  (defun auto-fci-mode (&optional unused)
    (if (> (window-width) fci-rule-column)
        (fci-mode 1)
      (fci-mode 0))
    )
  (add-hook 'after-change-major-mode-hook 'auto-fci-mode)
  (add-hook 'window-configuration-change-hook 'auto-fci-mode)

Essentially it checks if the window-width is greater than fci-rule-column and conditionally enables fci.

There is an open issue about this at: https://github.com/alpaker/Fill-Column-Indicator/issues/26


CategoryFilling