17

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?

phils
  • 48,657
  • 3
  • 76
  • 115
Chillar Anand
  • 4,042
  • 1
  • 23
  • 52
  • 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 00:10
  • 1
    @YoungFrog, also it should be `\\s-` instead of `\\s`. That hyphen is required in elisp regexp. – Kaushal Modi Jul 26 '16 at 10:49

7 Answers7

26

Would something like this be "easier"?

(defun current-line-empty-p ()
  (save-excursion
    (beginning-of-line)
    (looking-at-p "[[:blank:]]*$")))
ideasman42
  • 8,375
  • 1
  • 28
  • 105
François Févotte
  • 5,917
  • 1
  • 24
  • 37
  • 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: https://www.gnu.org/software/emacs/manual/html_node/elisp/Char-Classes.html#Char-Classes – 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)))
PythonNut
  • 10,243
  • 2
  • 29
  • 75
5
(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)))))
Dan
  • 32,584
  • 6
  • 98
  • 168
2

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))))
ideasman42
  • 8,375
  • 1
  • 28
  • 105
Chillar Anand
  • 4,042
  • 1
  • 23
  • 52
2

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))))
npostavs
  • 9,033
  • 1
  • 21
  • 53
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.

YoungFrog
  • 3,496
  • 15
  • 27
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.

Dario
  • 83
  • 1
  • 5
  • 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). – Gilles 'SO- stop being evil' 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. – Gilles 'SO- stop being evil' Sep 10 '19 at 20:18