18

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
  • 50,977
  • 3
  • 79
  • 122
Chillar Anand
  • 4,102
  • 1
  • 24
  • 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

27

Would something like this be "easier"?

(defun current-line-empty-p ()
  (save-excursion
    (beginning-of-line)
    (looking-at-p "[[:blank:]]*$")))
ideasman42
  • 8,786
  • 1
  • 32
  • 114
François Févotte
  • 6,007
  • 1
  • 25
  • 38
  • 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,363
  • 2
  • 30
  • 76
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,980
  • 7
  • 102
  • 169
3

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,203
  • 1
  • 24
  • 53
  • Am I missing something or this can be simplified to just (= (line-beginning-position) (line-end-position)) ? – Hi-Angel Oct 05 '23 at 08:00
  • Ah, nvm, I see, the answer is considering a line with whitespace to be empty as well. Nice answer! – Hi-Angel Oct 05 '23 at 08:10
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,786
  • 1
  • 32
  • 114
Chillar Anand
  • 4,102
  • 1
  • 24
  • 52
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,526
  • 18
  • 28
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