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 Page Up Page Down 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.

Enhanced Editing Commands Topic

  1. Select Line, between Quotes, Extend Selection
  2. Copy/Cut Current Line If No Selection
  3. Copy/Cut All or Selection
  4. Paste or Paste Previous
  5. Delete Whitespace around Cursor
  6. Move Cursor to Beginning of Line/Paragraph
  7. Move Cursor by Text Block
  8. Move Cursor to Bracket/Quote
  9. Move Cursor to Punctuation
  10. Delete Text Block
  11. Toggle Comment Current Line
  12. Insert Date Time

Working with Brackets

  1. Highlight Brackets ()[]{}
  2. Insert Brackets by Pair
  3. Delete Brackets ()[]{} by Pair
  4. Select Line, between Quotes, Extend Selection
  5. Move Cursor to Bracket/Quote
  6. Change Brackets/Quotes
Patreon me $5 patreon

Or Buy Xah Emacs Tutorial

Or buy a nice keyboard: Best Keyboard for Emacs

If you have a question, put $5 at patreon and message me.