Emacs: Select Line, between Quotes, Extend Selection 🚀
Master these text selection commands, and you almost never need to manually mark a region.
Select Text between Quotes/Brackets
Select text inside quotes is one of the most frequently needed operation in programing languages code.
put this in your Emacs Init File:
(defvar xah-brackets '("“”" "()" "[]" "{}" "<>" "<>" "()" "[]" "{}" "⦅⦆" "〚〛" "⦃⦄" "‹›" "«»" "「」" "〈〉" "《》" "【】" "〔〕" "⦗⦘" "『』" "〖〗" "〘〙" "「」" "⟦⟧" "⟨⟩" "⟪⟫" "⟮⟯" "⟬⟭" "⌈⌉" "⌊⌋" "⦇⦈" "⦉⦊" "❛❜" "❝❞" "❨❩" "❪❫" "❴❵" "❬❭" "❮❯" "❰❱" "❲❳" "〈〉" "⦑⦒" "⧼⧽" "﹙﹚" "﹛﹜" "﹝﹞" "⁽⁾" "₍₎" "⦋⦌" "⦍⦎" "⦏⦐" "⁅⁆" "⸢⸣" "⸤⸥" "⟅⟆" "⦓⦔" "⦕⦖" "⸦⸧" "⸨⸩" "⦅⦆") "A list of strings, each element is a string of 2 chars, the left bracket and a matching right bracket. Used by `xah-select-text-in-quote' and others. Version 2023-07-31") (defconst xah-left-brackets (mapcar (lambda (x) (substring x 0 1)) xah-brackets) "List of left bracket chars. Each element is a string.") (defconst xah-right-brackets (mapcar (lambda (x) (substring x 1 2)) xah-brackets) "List of right bracket chars. Each element is a string.") (defun xah-select-text-in-quote () "Select text between the nearest left and right delimiters. Delimiters here includes the following chars: \" ` and anything in `xah-brackets'. This command ignores nesting. For example, if text is (a(b)c▮) the selected char is “c”, not “a(b)c”. URL `http://xahlee.info/emacs/emacs/modernization_mark-word.html' Version: 2020-11-24 2023-07-16 2023-07-23" (interactive) (let ((xskipChars (concat "^\"`" (mapconcat #'identity xah-brackets "")))) (skip-chars-backward xskipChars) (push-mark (point) t t) (skip-chars-forward xskipChars)))
Select Current Line
This command selects current line.
If there's already a selection, extend selection downward by line.
(defun xah-select-line () "Select current line. If region is active, extend selection downward by line. If `visual-line-mode' is on, consider line as visual line. URL `http://xahlee.info/emacs/emacs/modernization_mark-word.html' Version: 2017-11-01 2021-03-19 2023-07-16" (interactive) (if (region-active-p) (if visual-line-mode (let ((xp1 (point))) (end-of-visual-line 1) (when (eq xp1 (point)) (end-of-visual-line 2))) (progn (forward-line 1) (end-of-line))) (if visual-line-mode (progn (beginning-of-visual-line) (push-mark (point) t t) (end-of-visual-line)) (progn (push-mark (line-beginning-position) t t) (end-of-line)))))
Select Current Block
This lets you select current block of text. (a block here is text between empty lines.)
If there's already a selection, extend selection downward by block.
(defun xah-select-block () "Select the current/next block plus 1 blankline. If region is active, extend selection downward by block. URL `http://xahlee.info/emacs/emacs/modernization_mark-word.html' Version: 2019-12-26 2021-04-04 2021-08-13" (interactive) (if (region-active-p) (re-search-forward "\n[ \t]*\n[ \t]*\n*" nil 1) (progn (skip-chars-forward " \n\t") (when (re-search-backward "\n[ \t]*\n" nil 1) (goto-char (match-end 0))) (push-mark (point) t t) (re-search-forward "\n[ \t]*\n" nil 1))))
Extend Selection
Here's a multi-purpose command that select different text depending on where cursor is, and if called repeatedly, extend selection.
This command is currently most useful in lisp code. Or, place cursor on a bracket and select the whole including bracket and text in between. (bracket here includes parenthesis and any type of quotation marks.)
(defun xah-extend-selection () "Select the current word, bracket/quote expression, or expand selection. Subsequent calls expands the selection. when there is no selection, • If cursor is on any type of bracket (including parenthesis, quotation mark), select whole bracketed thing including bracket • else, select current word. when there is a selection, the selection extension behavior is still experimental. But when cursor is on a any type of bracket (parenthesis, quote), it extends selection to outer bracket. URL `http://xahlee.info/emacs/emacs/modernization_mark-word.html' Version: 2020-02-04 2023-07-22 2023-07-23" (interactive) (if (region-active-p) (progn (let ((xrb (region-beginning)) (xre (region-end))) (goto-char xrb) (cond ((looking-at "\\s(") (if (eq (nth 0 (syntax-ppss)) 0) (progn ;; (message "left bracket, depth 0.") (end-of-line) ; select current line (push-mark (line-beginning-position) t t)) (progn ;; (message "left bracket, depth not 0") (up-list -1 t t) (mark-sexp)))) ((eq xrb (line-beginning-position)) (progn (goto-char xrb) (let ((xfirstLineEndPos (line-end-position))) (cond ((eq xre xfirstLineEndPos) (progn ;; (message "exactly 1 line. extend to next whole line." ) (forward-line 1) (end-of-line))) ((< xre xfirstLineEndPos) (progn ;; (message "less than 1 line. complete the line." ) (end-of-line))) ((> xre xfirstLineEndPos) (progn ;; (message "beginning of line, but end is greater than 1st end of line" ) (goto-char xre) (if (eq (point) (line-end-position)) (progn ;; (message "exactly multiple lines" ) (forward-line 1) (end-of-line)) (progn ;; (message "multiple lines but end is not eol. make it so" ) (goto-char xre) (end-of-line))))) (t (error "%s: logic error 42946" real-this-command)))))) ((and (> (point) (line-beginning-position)) (<= (point) (line-end-position))) (progn ;; (message "less than 1 line" ) (end-of-line) ; select current line (push-mark (line-beginning-position) t t))) (t ;; (message "last resort" ) nil)))) (progn (cond ((looking-at "\\s(") ;; (message "left bracket") (mark-sexp)) ; left bracket ((looking-at "\\s)") ;; (message "right bracket") (backward-up-list) (mark-sexp)) ((looking-at "\\s\"") ;; (message "string quote") (mark-sexp)) ; string quote ;; ((and (eq (point) (line-beginning-position)) (not (looking-at "\n"))) ;; (message "beginning of line and not empty") ;; (end-of-line) ;; (push-mark (line-beginning-position) t t)) ( ;; (prog2 (backward-char) (looking-at "[-_a-zA-Z0-9]") (forward-char)) (looking-back "[-_a-zA-Z0-9]" (max (- (point) 1) (point-min))) ;; (message "left is word or symbol") (skip-chars-backward "-_a-zA-Z0-9") ;; (re-search-backward "^\\(\\sw\\|\\s_\\)" nil t) (push-mark) (skip-chars-forward "-_a-zA-Z0-9") (setq mark-active t) ;; (exchange-point-and-mark) ) ((and (looking-at "[:blank:]") (prog2 (backward-char) (looking-at "[:blank:]") (forward-char))) ;; (message "left and right both space" ) (skip-chars-backward "[:blank:]") (push-mark (point) t t) (skip-chars-forward "[:blank:]")) ((and (looking-at "\n") (eq (char-before) 10)) ;; (message "left and right both newline") (skip-chars-forward "\n") (push-mark (point) t t) (re-search-forward "\n[ \t]*\n")) ; between blank lines, select next block (t ;; (message "just mark sexp" ) (mark-sexp) (exchange-point-and-mark)) ;; ))))
You should give these commands keys. [see Emacs: Define Keybinding].
I suggest these keybinding:
xah-select-block
【Alt+6】xah-select-line
【Alt+7】xah-extend-selection
【Alt+8】xah-select-text-in-quote
【Alt+9】
xah-extend-selection
is even more useful together with commands that move cursor to brackets or quotes. [see Emacs: Move Cursor to Bracket 🚀]
The above commands are also in xah-fly-keys. [see Emacs: Xah Fly Keys]
Emacs, Work with Brackets
- Emacs: Highlight Brackets
- Emacs: electric-pair-mode (Auto Insert Closing Bracket)
- Emacs: Insert Brackets by Pair 🚀
- Emacs: Delete Brackets by Pair 🚀
- Emacs: Move Cursor to Bracket 🚀
- Emacs: Jump to Matching Bracket 🚀
- Emacs: Change Brackets/Quotes 🚀
- Emacs: Navigate Lisp Code as Tree
- Emacs: Select Line, between Quotes, Extend Selection 🚀
- Emacs: Xah Elisp Mode (xah-elisp-mode.el)
Emacs Modernization
- Emacs Modernization: Simple Changes Emacs Should Adopt
- Why Emacs Keys are Painful
- Emacs: Problems of the Scratch Buffer
- Emacs M-key Notation vs Alt+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 Problems
- 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
- Emacs Lisp: Ban Syntax Table
- 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
- Emacs Lisp: 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: Toggle Letter Case 🚀
- Emacs: Select Line, between Quotes, Extend Selection 🚀
- Emacs: isearch Current Word 🚀
- Emacs fill-paragraph Problem