Emacs: Form Feed ^L Problem
The Form Feed character (unicode codepoint 12) is used in 1990s or earlier to cause printer to start a new page. Printers today no longer use that in their protocol.
In emacs lisp source code, often you'll see the “Form Feed” character, displayed as “^L”.
In Emacs Lisp source code, the Form Feed is used as a section marker.
For example, Alt+x describe-function
, then type “dired”, then click on the “dired.el” link to view the source code.
Scroll around and you'll see it.
It is also used in C source code from GNU projects, or old Python source code. In general, most code after 2000 no longer follow this convention.
Problems of Form Feed as Section Marker in Emacs Lisp
The convention of using Form Feed character as code section marker has several problems:
- It is a 1970 or 1980's convention, it's outdated. Vast majority of programers don't know this Form Feed char convention, and vast majority of programing language source code since about 2000 don't use it anymore.
- The Form Feed is hard to type. Most text editors do not provide easy ways to type it, except old editors like emacs.
- The ^L is hard to read. It should be displayed as a line. There are several elisp packages that makes emacs display Form Feed as a line. However, it is not bundled in GNU Emacs.
Suggested Solution
Emacs should display the Form Feed character as a horizontal line.
For example, bundle and turn on the package page-break-lines.el
.
Problems of Section Navigation Key in Emacs
Emacs has keys to jump to the Form Feed char. By default, the keys are:
forward-page
【Ctrl+x ]】backward-page
【Ctrl+x [】
It's hard to use. For example, you cannot hold on a key to keep paging.
Setup Easy Key to Move Cursor to Prev/Next Formfeed
Emacs should make the keys Ctrl+Alt+PageUp and Ctrl+Alt+PageDown as default.
;; keys for moving to prev/next code section (Form Feed; ^L) (global-set-key (kbd "<C-M-prior>") 'backward-page) ; Ctrl+Alt+PageUp (global-set-key (kbd "<C-M-next>") 'forward-page) ; Ctrl+Alt+PageDown
Using Ctrl+Alt makes it consistent with the default keys to navigate lisp code. 〔see Emacs: Navigate Lisp Code as Tree〕
Design Analysis of Using Form Feed Character as Code Section Marker
A single specialized character as a universal markup for source code section break, is quite elegant and useful.
Advantages of Using Form Feed as Section Marker in Source Code
Normally, programer mark section in source code with lots of comment chars. For example:
;-------------------------------------------------- ; emacs lisp
#__________________________________________________ # perl, ruby, python, bash
################################################### # perl, ruby, python, bash
/////////////////////////////////////////////////// // c, cpp, java
These are not as elegant or convenient as the Form Feed char. First problem is typing them. Even if your editor provide a easy way to type the char repeatedly, such as emacs's Ctrl+u 50 prefix, that's still 4 or 5 extra keys to press.
It is also hard to search. Because the style varies, some source code repeat the comment chars such as “##########”, some start with a comment char then followed by dashes “#----------”, some uses underline, some draws a ASCII art box, like this:
############################## # PRETTY! # ##############################
All these variations make it hard to jump to the section. Typically, you search the string, for example, search a sequence of 5 #, but because the line has more than 5, your search will linger on the same line. Instead, you have to search almost the exact the number of chars used for this, and it is common that the number of chars for such line is not consistent. Or, you may use regex, but again, much more typing and the result is not precise.
The Form Feed char has several advantages over this. If you use it for section mark, it makes it precise, easy to locate, and easy to navigate to all different sections. All this because there's a unique single character as a delimiter, and its meaning is basically universal.
The fundamental reason of the Form Feed char as section marker advantage over ASCII text, is due to the semantic vs presentation issue. For discussion of various common issues on this, see:
- Emacs Why line-move-visual
- The Harm of Hard-wrapping Lines
- Tabs versus Spaces in Source Code
- A Simple Lisp Code Formatter
- A Text Editor Feature: Extend Selection By Semantic Unit
Problems of Using Form Feed as Section Marker
In lisp, the Form Feed char is ignored by the compiler. This is probably true for vast majority of languages today still. However, it causes problems in some languages.
Cygwin Bash
Cygwin Bash will generate this error if your shell script contains the Form Feed char that's not in comment.
bash: $'\f': command not found
AutoHotkey
AutoHotkey scripting language generates compiler error if you have a uncommented Form Feed char in source code.
〔see AutoHotkey Tutorial〕
PHP
PHP would print a warning about it: “Warning: Unexpected character in the input: '^L' (ASCII=12)”. This is in PHP bug database
Emacs: Form Feed Must be on a Line by Itself
If your language does not allow uncomment Form Feed char, and if you put a comment character in front, but emacs's {forward-page
, backward-page
} commands won't recognize Form Feed char as section break if they are not the only char in a line.
Other Issues
A major problem of using Form Feed char for section break is simply the visibility. Almost no editors display the Form Feed as a line. So, for vast majority of coders, a sequence of dash “----------” is simply the more practical solution. Also, today, few programers know how to insert a Form Feed character in their editor.
For reasons of why it is displayed in emacs as ^L, see: Emacs Key Syntax Explained.
A Universal Source Code Section Markup
Unfortunately, there is no good or standard replacement. Usually, people just add a bunch of hyphen like this -----
or equal sing =====
or underscore _____
or just a sequence of comment char. These are hackish. The problem with these approach is you cannot have a key to do paging because the page marker is not standardized.
So, a workaround i came up is to use the Unicode SECTION SIGN §, followed by the Unicode BOX DRAWINGS LIGHT HORIZONTAL (U+2500) ─. Like this:
; § ────────── ────────── ────────── ────────── ──────────
- The section sign is a proper symbol to indicate a code section.
- The Unicode box drawing character is a proper character for visual lines.
- The line is meant to be a visual aid for lack of better alternative at the moment. (better would be to have the editor automatically display the section char with a line after it.)
- The space between the lines is to make this mark up more unique. So it is less likely to be confused with other text drawings when parsed by a program.
This approach is designed for all source code. It doesn't have the invisible character problem, nor the compiler choke problem. The disadvantage is the requirement of Unicode, and some inconvenience of input. (the inconvenience of input can be easily solved by editor.) 〔see Unicode Popularity on Web by Google〕
Input
For inputting the section marker, you can define a abbrev, like this:
("ss" "§ ────────── ────────── ────────── ────────── ──────────")
〔see Emacs: Setup Hundreds of Abbrevs〕
Navigation
Here's lisp code that lets you navigate the new section marker.
(defun forward-section () "Move cursor forward to next occurrence of the SECTION SIGN § character." (interactive) (when (not (search-forward "§" nil t)) (goto-char (point-max)) ) ) (defun backward-section () "Move cursor backward to previous occurrence of the SECTION SIGN § character." (interactive) (when (not (search-backward "§" nil t)) (goto-char (point-min)) ) )
Here's the keys:
(global-set-key (kbd "<s-prior>") 'backward-section) ; Win+PageUp (global-set-key (kbd "<s-next>") 'forward-section) ; Win+PageDown (global-set-key (kbd "<C-M-prior>") 'backward-page) ; Ctrl+Alt+PageUp (global-set-key (kbd "<C-M-next>") 'forward-page) ; Ctrl+Alt+PageDown
Note: I have tried to use this section marker for all my code. I used it for about a year. I'm not sure it can ever be popular. There are many obstacles in adopting this:
- Unicode in source code is still foreign to most programers.
- Having Unicode in source code is probably not better supported in language than having a form feed char.
- There are many more elaborate solutions that try to solve source code markup problem, for example, org-mode Babel. Though, none are likely to be universally adopted.
- Many languages such as Perl, Java, have embedded doc system that also somewhat act as section markup.
(thanks to Miura Masahiro for the tip on inputting §. Ctrl+x 8 S 〔see Emacs: Insert Unicode Character〕 )
Emacs, form feed
Emacs Modernization
- Emacs Modernization: Simple Changes Emacs Should Adopt
- Why Emacs Keys are Painful
- Emacs: Problems of the Scratch Buffer
- Emacs Modernization: Meta Key Notation
- Emacs Menu Usability Problem
- Emacs Mode Line Problem
- Emacs cua-mode Problems
- Emacs: Inconsistency of Search Features
- Problems of grep in Emacs
- Emacs: Usability Problems of Mode Documentation
- Problems of Emacs Manual
- Emacs Manual Sucks by Examples
- Emacs: kill-buffer Induces Buffer Accumulation
- Emacs Spell Checker Problems
- Emacs: Form Feed ^L Problem
- Emacs: Single Key to Delete Whole Line
- Emacs HTML Mode Sucks
- Emacs Does Not Support Viewing Images Files In Windows
- Emacs Should Adopt HTML as Texinfo Replacement
- Emacs Should Support HTML Mail
- Problems of Emacs's “man” Command
- Emacs Lisp Mode Syntax Coloring Problem
- Emacs AutoHotkey Mode Problems
- Elisp: Syntax Table Sucks
- Emacs: Make elisp-index-search use Current Symbol
- Emacs GNU Texinfo Problems; Invalid HTML
- A Record of Frustration in IT Industry; Disappearing FSF URLs, 2006
- Emacs Manual Node Persistency Issues
- Emacs: dired-do-query-replace-regex Replace ALL (fixed)
- Problems of Emacs Supporting Obsolete Systems
- Elisp: Function to Copy/Delete a Dir Recursively (fixed)
- Thoughts on Common Lisp Scheme Lisp Based Emacs
- Text Editors Popularity and Market Research
- Text Editor's Cursor Movement Behavior (emacs, vi, Notepad++)
- Emacs: Usability Problems of Letter-Case Changing Commands
- Emacs Select Word Command Problem
- Emacs: Search Current Word 🚀
- Emacs fill-paragraph Problem