Emacs: Move Cursor by Text Block

By Xah Lee. Date: . Last updated: .

Emacs has commands forward-paragraphCtrl+】 and backward-paragraphCtrl+】. 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)))
    (re-search-forward "\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 (re-search-backward "\n[\t\n ]*\n+" nil "NOERROR")
          (progn (skip-chars-backward "\n\t "))
        (progn (goto-char (point-min))
               (setq $i n)))
      (setq $i (1+ $i)))))

Note: these commands are in ergoemacs-mode and xah fly keys.

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)

Or, bind it to PageUp PageDown keys:

(global-set-key (kbd "<prior>") 'xah-backward-block)
(global-set-key (kbd "<next>") 'xah-forward-block)

A even more efficient keybinding is to combine beginning-of-line and end-of-line commands with it. See: Emacs: Move Cursor to Beginning of Line/Paragraph.

If you have a question, put $5 at patreon and message me on xah discord.
Or support me by Buy Xah Emacs Tutorial

Emacs Tutorial

Emacs Init

Emacs Keys

ELisp

ELisp Examples

ELisp Write Major Mode


ELisp Examples

Xah Commands

Text Transform Under Cursor

Commands Do thing-at-point

Command to Insert Things

Script Examples

Misc