16

I just want to check if the current line is empty or not (if it contains only whitespace, then I still consider it empty).

Here is my initial version:

(defun strip-text-properties(txt)
  (set-text-properties 0 (length txt) nil txt)
  txt)

(defun is-current-line-empty ()
  (interactive)
  (setq c-line (thing-at-point 'line))
  (string-match "^\s*$" (strip-text-properties c-line)))

What is the easiest way to check if current line is empty?

3
  • 3
    In a lisp string, writing \s is equivalent to writing s. Perhaps you meant "^\\s*$".
    – YoungFrog
    Sep 21 '15 at 15:23
  • 3
    As a general comment, elisp will make more sense once you start thinking in terms of actions on buffers, as opposed to (as one tends to do in other languages) doing things with strings. Isolating and extracting a string in order to perform some test is likely to (a) be inefficient, and (b) dramatically reduce the number of tools at your disposal. Elisp is really good at doing things directly on the contents of buffers.
    – phils
    Sep 22 '15 at 0:10
  • 1
    @YoungFrog, also it should be \\s- instead of \\s. That hyphen is required in elisp regexp. Jul 26 '16 at 10:49
26

Would something like this be "easier"?

(defun current-line-empty-p ()
  (save-excursion
    (beginning-of-line)
    (looking-at-p "[[:space:]]*$")))
3
  • Shouldn't space be blank? (to account for tabs)
    – ideasman42
    Nov 15 '20 at 10:04
  • @ideasman42 space accounts for all whitespace, not just space characters. That said, blank might be better here because it only accounts for horizontal whitespace rather than all whitespace. Reference: gnu.org/software/emacs/manual/html_node/elisp/…
    – eeowaa
    Nov 17 '20 at 20:06
  • :space: uses the syntax table, where :blank: is simply space or tab, which seems more accurate.
    – ideasman42
    Nov 17 '20 at 23:04
12

A simple method, close to what you have:

(defun current-line-empty-p ()
  (string-match-p "\\`\\s-*$" (thing-at-point 'line)))
5
  • I like this solution because it does not modify match-data.
    – nispio
    Apr 25 '16 at 16:08
  • 1
    You need to have \\s- instead of \s. Have you tried that solution? Jul 26 '16 at 10:51
  • Oddly, I do use it quite a bit. But I just wrote this off of memory. You are correct.
    – PythonNut
    Jul 26 '16 at 13:40
  • 1
    still missing the hyphen? :) Jul 26 '16 at 13:53
  • 1
    It was early, and I hadn't completely woken up yet.
    – PythonNut
    Jul 27 '16 at 17:57
4
(defun blank-line-p (&optional pos)
  "Returns `t' if line (optionally, line at POS) is empty or
composed only of whitespace."
  (save-excursion
    (goto-char (or pos (point)))
    (beginning-of-line)
    (= (point-at-eol)
       (progn (skip-syntax-forward " ") (point)))))
1

I suggest:

(defun blank-line-p ()
  (and (progn (skip-chars-backward " ") (bolp))
       (progn (skip-chars-forward " ") (eolp))))

(Note that the progns are in fact unnecessary because the skip functions never return nil). As Dan does in his answer, skip-syntax-* could also be used instead.

1
  • 3
    This does not identify a line containing only tabs as blank. skip-syntax-* is the right set of functions to use here. Sep 21 '15 at 21:48
1

current-indentation gives you the column following leading blanks, which can be compared against the column at the end of line:

(defun blank-line-p ()
  (= (current-indentation)
     (- (line-end-position) (line-beginning-position))))
1

This is a modification of what PythonNut answered which did not work for me (why?):

(defun current-line-blank ()
  (= 0 (string-match-p "^\\s-*$" (thing-at-point 'line))))

string-match-p returned the index of the next line whenever the current line wasn't blank. So I checked that the return value is 0.

3
  • The index of the next line? What do you mean exactly? (and welcome on emacs.SE!)
    – JeanPierre
    Sep 10 '19 at 18:41
  • @JeanPierre (thing-at-point 'line) includes the newline at the end of the line. If the current line is not blank, the regexp matches at that newline. The only time string-match-p returns nil here is on the last line of the buffer (and Dario, your version doesn't work on the last line if the buffer doesn't end with a newline). Sep 10 '19 at 20:12
  • A better fix would be to match the beginning of the string instead of matching the beginning of any line in the string. I've edited PythonNut's answer. Sep 10 '19 at 20:18
1

Here is another simple solution for it, taken from comment-dwim-2 package

(defun is-empty-line-p ()
  (string-match-p "^[[:blank:]]*$"
        (buffer-substring (line-beginning-position)
                          (line-end-position))))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.