Emacs: Move Cursor by Paragraph or Text Block
This pages shows you 2 emacs commands to move cursor by text block (paragraph) in a predictable way across major modes.
Emacs has commands
forward-paragraph 【Ctrl+↓】 and
backward-paragraph 【Ctrl+↑】. The problem with these is that the definition of “paragraph” in emacs is not predictable; it depends on what mode you are in. For example, in
text-mode, a paragraph is a text block separated by newline characters. But in
html-mode, it moves by some weird way. (copy source code of this page then paste in emacs, turn on
html-mode and try to move by paragraph.)
Technically, this is because the notion of “paragraph” in emacs is dependent on emacs's syntax table. (emacs's syntax table is a elementary system that categorize characters into semantic categories.) (info "(elisp) Syntax Tables")
The following commands let you move by paragraph in a predictable way, regardless what major mode you are in.
(defun xah-forward-block (&optional φn) "Move cursor beginning of next text block. A text block is separated by blank lines. This command similar to `forward-paragraph', but this command's behavior is the same regardless of syntax table. URL `http://ergoemacs.org/emacs/emacs_move_by_paragraph.html' Version 2016-06-15" (interactive "p") (let ((φn (if (null φn) 1 φn))) (search-forward-regexp "\n[\t\n ]*\n+" nil "NOERROR" φn))) (defun xah-backward-block (&optional φn) "Move cursor to previous text block. See: `xah-forward-block' URL `http://ergoemacs.org/emacs/emacs_move_by_paragraph.html' Version 2016-06-15" (interactive "p") (let ((φn (if (null φn) 1 φn)) (ξi 1)) (while (<= ξi φn) (if (search-backward-regexp "\n[\t\n ]*\n+" nil "NOERROR") (progn (skip-chars-backward "\n\t ")) (progn (goto-char (point-min)) (setq ξi φn))) (setq ξi (1+ ξi)))))
You can bind the emacs default keys to it:
(global-set-key (kbd "<C-up>") 'xah-backward-block) (global-set-key (kbd "<C-down>") 'xah-forward-block)
You can also bind it to page up/down keys:
(global-set-key (kbd "<prior>") 'xah-backward-block) (global-set-key (kbd "<next>") 'xah-forward-block)
This makes the 【⇞ Page △】 ＆ 【⇟ Page ▽】 keys do move by block.
A even more efficient keybinding is to combine
end-of-line commands with it. See: Emacs Lisp: Move Cursor to Beginning of Line/Block.