Taming Emacs' text mode wrapping and indenting
To wrap long lines, or not to wrap? It's always a dilemma. Automatic wrapping is great when you're hammering away typing lots of text. But it's infuriating when you're trying to format something yourself and the editor decides it wants to line-wrap a little too early.
Although of course you can set the wrapping width, Emacs has a tendency to wrap early -- especially when you hit return. All too often, I'll be typing away at a long line, get to the end of the sentence and paragraph with the last word on the same line with the rest -- then realize that as soon as I hit return, Emacs is going to move that last word to a line by itself. Drives me nuts!
And the solution turns out to be so simple. The Return key,
"\C-m". was bound to the (newline)
function (you can find out
by typing M-x, then describe-key
, then hitting Return).
Apparently (newline)
re-wraps the current line before
inserting a line break. But I just wanted it to insert a line break.
No problem -- just bind "C-m" to (insert "\n")
.
But there's a second way, too, if you don't want to rebind: there's a magic internal emacs table you can change.
(set-char-table-range auto-fill-chars 10 nil)
But wait -- there's one other thing I want to fix in text mode.
Automatic indent is another one of those features that's very convenient ... except when it's not.
If I have some text like:
First point: - subpoint a - subpoint bthen it's handy if, when I hit Return after subpoint a, emacs indents to the right level for subpoint b. But what happens when I get to the end of that list?
First point: - subpoint a - subpoint b Second point: - subpoint c
When I hit Return after subpoint b, Emacs quite reasonably indents two spaces. If I immediately type another Return, Emacs sensibly deletes the two spaces it just inserted, opens a new line -- but then it indents that new line another two spaces.
After a blank line, I always want to start at the beginning, not indented at all.
Here's how to fix that. Define a function that will be called whenever you hit return in text mode. That function tests whether the caret comes immediately after a blank line, or at the beginning of the file. It indents except in those two cases; and in neither case does it re-wrap the current line.
;; In text mode, I don't want it auto-indenting for the first ;; line in the file, or lines following blank lines. ;; Everywhere else is okay. (defun newline-and-text-indent () "Insert a newline, then indent the next line sensibly for text" (interactive) (cond ;; Beginning of buffer, or beginning of an existing line, don't indent: ((or (bobp) (bolp)) (newline)) ;; If we're on a whitespace-only line, ((and (eolp) (save-excursion (re-search-backward "^\\(\\s \\)*$" (line-beginning-position) t))) ;; ... delete the whitespace, then add another newline: (kill-line 0) (newline)) ;; Else (not on whitespace-only) insert a newline, ;; then add the appropriate indent: (t (insert "\n") (indent-according-to-mode)) ))
Then tell emacs to call that function when it sees the Return key in text mode:
(defun text-indent-hook () (local-set-key "\C-m" 'newline-and-text-indent) ) (setq text-mode-hook 'text-indent-hook)
Finally, this is great for HTML mode too, if you get irritated at not being able to put an <a href="longurl"> all on one line:
(defun html-hook () (local-set-key "\C-m" (lambda () (interactive) (insert "\n"))) ) (setq sgml-mode-hook 'html-hook)
[ 11:29 Jan 13, 2010 More linux/editors | permalink to this entry | ]