Emacs: Select Line, between Quotes, Extend Selection

By Xah Lee. Date: . Last updated: .

This page shows many useful emacs commands for text selection.

Select Text between Quotes/Brackets

Select text inside quotes is one of the most frequently needed operation in programing languages code.

(defun xah-select-text-in-quote ()
  "Select text between the nearest left and right delimiters.
Delimiters here includes the following chars: \"<>(){}[]“”‘’‹›«»「」『』【】〖〗《》〈〉〔〕()
This command select between any bracket chars, not the inner text of a bracket. For example, if text is

 (a(b)c▮)

 the selected char is “c”, not “a(b)c”.

URL `http://ergoemacs.org/emacs/modernization_mark-word.html'
Version 2016-12-18"
  (interactive)
  (let (
        (-skipChars
         (if (boundp 'xah-brackets)
             (concat "^\"" xah-brackets)
           "^\"<>(){}[]“”‘’‹›«»「」『』【】〖〗《》〈〉〔〕()"))
        -pos
        )
    (skip-chars-backward -skipChars)
    (setq -pos (point))
    (skip-chars-forward -skipChars)
    (set-mark -pos)))

Select Current Line

This command selects current line.

If there's already a selection, extend selection downward by line.

(defun xah-select-current-line ()
  "Select current line.
URL `http://ergoemacs.org/emacs/modernization_mark-word.html'
Version 2016-07-22"
  (interactive)
  (end-of-line)
  (set-mark (line-beginning-position)))

(defun xah-select-line ()
  "Select current line. If region is active, extend selection downward by line.
URL `http://ergoemacs.org/emacs/modernization_mark-word.html'
Version 2016-07-22"
  (interactive)
  (if (region-active-p)
      (progn
        (forward-line 1)
        (end-of-line))
    (xah-select-current-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 of text between blank lines.
If region is active, extend selection downward by block.

URL `http://ergoemacs.org/emacs/modernization_mark-word.html'
Version 2017-05-27"
  (interactive)
  (if (region-active-p)
      (re-search-forward "\n[ \t]*\n" nil "move")
    (xah-select-current-block)))

(defun xah-select-current-line ()
  "Select current line.
URL `http://ergoemacs.org/emacs/modernization_mark-word.html'
Version 2016-07-22"
  (interactive)
  (end-of-line)
  (set-mark (line-beginning-position)))

Extend Selection

Here's a multi-purpose command that select different text depending on where cursor is, and if called repeatedly, expand selection.

When no selection:

(defun xah-extend-selection ()
  "Select the current word, bracket/quote expression, or expand selection.
Subsequent calls expands the selection.

when no selection,
• if cursor is on a bracket, select whole bracketed thing including bracket
• if cursor is on a quote, select whole quoted thing including quoted
• if cursor is on the beginning of line, select the line.
• else, select current word.

when there's a selection, the selection extension behavior is still experimental.
Roughly:
• if 1 line is selected, extend to next line.
• if multiple lines is selected, extend to next line.
• if a bracketed text is selected, extend to include the outer bracket. If there's no outer, select current line.

 to line, or bracket/quoted text,
or text block, whichever is the smallest.

URL `http://ergoemacs.org/emacs/modernization_mark-word.html'
Version 2017-01-15"
  (interactive)
  (if (region-active-p)
      (progn
        (let ((-rb (region-beginning)) (-re (region-end)))
          (goto-char -rb)
          (cond
           ((looking-at "\\s(")
            (if (eq (nth 0 (syntax-ppss)) 0)
                (progn
                  (message "left bracket, depth 0.")
                  (end-of-line) ; select current line
                  (set-mark (line-beginning-position)))
              (progn
                (message "left bracket, depth not 0")
                (up-list -1 t t)
                (mark-sexp))))
           ((eq -rb (line-beginning-position))
            (progn
              (goto-char -rb)
              (let ((-firstLineEndPos (line-end-position)))
                (cond
                 ((eq -re -firstLineEndPos)
                  (progn
                    (message "exactly 1 line. extend to next whole line." )
                    (forward-line 1)
                    (end-of-line)))
                 ((< -re -firstLineEndPos)
                  (progn
                    (message "less than 1 line. complete the line." )
                    (end-of-line)))
                 ((> -re -firstLineEndPos)
                  (progn
                    (message "beginning of line, but end is greater than 1st end of line" )
                    (goto-char -re)
                    (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 -re)
                        (end-of-line)))))
                 (t (error "logic error 42946" ))))))
           ((and (> (point) (line-beginning-position)) (<= (point) (line-end-position)))
            (progn
              (message "less than 1 line" )
              (end-of-line) ; select current line
              (set-mark (line-beginning-position))))
           (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)
        (set-mark (line-beginning-position)))
       ((or (looking-back "\\s_" 1) (looking-back "\\sw" 1))
        (message "left is word or symbol")
        (skip-syntax-backward "_w" )
        ;; (re-search-backward "^\\(\\sw\\|\\s_\\)" nil t)
        (mark-sexp))
       ((and (looking-at "\\s ") (looking-back "\\s " 1))
        (message "left and right both space" )
        (skip-chars-backward "\\s " ) (set-mark (point))
        (skip-chars-forward "\\s "))
       ((and (looking-at "\n") (looking-back "\n" 1))
        (message "left and right both newline")
        (skip-chars-forward "\n")
        (set-mark (point))
        (re-search-forward "\n[ \t]*\n")) ; between blank lines, select next text block
       (t (message "just mark sexp" )
          (mark-sexp))
       ;;
       ))))

You should give these commands keys. 〔►see Emacs: How to Define Keys〕.

I suggest these keybinding:

xah-extend-selection is even more useful together with commands that move cursor to brackets or quotes. 〔►see Emacs: Move Cursor to Bracket/Quote

The above commands are also in ergoemacs-mode 〔https://ergoemacs.github.io/〕 and xah-fly-keys. 〔►see Emacs: Xah Fly Keys

Enhanced Editing Commands Topic

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

Working with Brackets Topic

  1. Emacs: Select Line, between Quotes, Extend Selection
  2. Emacs: Insert Brackets by Pair
  3. Emacs: Move Cursor to Bracket/Quote
  4. Emacs: Delete Backward Char or Bracket Text
Like it? Buy Xah Emacs Tutorial. Thanks.