I wrote this macro for my .emacs
file to trace its progress during loading:
(defmacro checkpoint ()
`(message "Reached line %i" (1+ `,(current-line))))
So I placed
(checkpoint)
throughout .emacs
.
The function current-line
returns a zero-based line number that obviously should be evaluated at runtime. Here's the output:
Reached line 1
Reached line 1
Reached line 1
Reached line 1
Reached line 1282
Reached line 1282
Reached line 1094
Reached line 947
Reached line 4
How can I properly expand (current-line)
in the macro?
;; -*- mode: emacs-lisp; lexical-binding: t; -*-
;; (Re)load the present file by placing point after the closing
;; parenthesis of the following expression in this comment, then pressing
;; C-x C-e (eval-last-sexp)
;; (load-file "./malformed-macro.el")
(require 'display-line-numbers)
(display-line-numbers-mode)
(require 'array) ; for current-line
(defmacro checkpoint ()
"Show that execution has reached the line containing `checkpoint'."
`(message "(checkpoint) = %i"
(1+ `,(current-line))))
;; *****************************************
;; * Actual line number in this here file: * --+
;; ***************************************** |
;; |
;; |
;; I expected (current-line) to return different values when expanded |
;; in following two lines. Image my surprise! v
(message "(1+ (current-line)) = %i"
(1+ (current-line))) ; 26
(message "(1+ (current-line)) = %i"
(1+ (current-line))) ; 28
;; I already knew there was a problem with my macro yielding the same
;; expansion when appearing on different lines, though I didn't suspect
;; (current-line) to be the culprit:
(checkpoint) ; 33
(checkpoint) ; 34
;; Here is the implementation of current-line from array.el, commented
;; out:
;; (defun array-current-line ()
;; "Return the current buffer line at point. The first line is 0."
;; (count-lines (point-min) (line-beginning-position)))
;; (define-obsolete-function-alias
;; 'current-line #'array-current-line "29.1")
;; Here I have inserted in-line the expression that current-line
;; returns:
(message "(count-lines (point-min) (line-beginning-position)) = %i"
(count-lines (point-min) (line-beginning-position))) ; 47
(message "(count-lines (point-min) (line-beginning-position)) = %i"
(count-lines (point-min) (line-beginning-position))) ; 49
;; Very interesting. We still get the same value, although the
;; expressions occur on different lines.
;; So is the problem with (point-min) or (line-beginning-position)
;; or both? Let's find out.
;; The point-min function returns "the minimum permissible value of
;; point in the current buffer. This is 1, unless narrowing (a buffer
;; restriction) is in effect."
(message "(point-min) = %S"
(point-min)) ; 61
(message "(point-min) = %S"
(point-min)) ; 63
;; point-min did indeed consistently return 1.
;; The line-beginning-position function returns "the position of the
;; first character in the current line/field."
(message "(line-beginning-position) = %S"
(line-beginning-position)) ; 70
(message "(line-beginning-position) = %S"
(line-beginning-position)) ; 72
;; It looks to me as though line-beginning-position does not behave
;; as advertised.
current-line
here - what library does that come from?