A custom identifier that is a simple incrementing number scheme
This is a sample implementation of custom Denote identifiers (Define a completely custom identifier scheme).
In its simplest form, a custom Denote identifier can be an integer that is incremented each time a new file name is produced. In the following code block, my~denote-get-identifier is the function we bind to the variable denote-get-identifier-function, which then makes Denote use the custom identifier scheme.
emacs-lisp
(setq denote-get-identifier-function #'my-denote-get-identifier)
(defun my-denote--get-all-used-ids ()
(when-let* ((ids (make-hash-table :test 'equal))
(files (denote-directory-files nil nil nil nil :has-identifier))
(file-names (mapcar #'file-name-nondirectory files))
(names (append file-names (denote--buffer-file-names))))
(dolist (name names)
(when-let* ((id (denote-retrieve-filename-identifier name)))
(puthash id t ids)))
ids))
(defun my-denote-get-identifier (initial-identifier _date)
(let ((identifiers (or denote-used-identifiers (my-denote--get-all-used-ids))))
(cond
((and initial-identifier (not (gethash initial-identifier identifiers)))
initial-identifier)
(t
(number-to-string
(let ((keys nil))
;; NOTE 2025-09-19: The `string-to-number' is done with the
;; assumption that this is always an integer. It will break
;; with the default Denote identifier scheme or, indeed,
;; anything that is not strictly numeric.
(when identifiers (maphash (lambda (key value) (push (string-to-number key) keys)) identifiers))
(if keys
(+ (apply #'max keys) 1)
1)))))))
;; And this is for testing purposes
;; (let ((denote-directory "/tmp/"))
;; (my-denote-get-identifier nil nil))
;;
;; (let* ((denote-used-identifiers (make-hash-table :test #'equal))
;; (_ (progn
;; (puthash "1" 1 denote-used-identifiers)
;; (puthash "2" 2 denote-used-identifiers)
;; (puthash "3" 3 denote-used-identifiers))))
;; (my-denote-get-identifier "1" nil))An alternative for the above:
emacs-lisp
(defun my-denote--find-first-unused-id-as-number (id)
(while (gethash id denote-used-identifiers)
(setq id (number-to-string (1+ (string-to-number id)))))
id)
(defun my-denote-generate-identifier-as-number (initial-identifier _date)
(let ((denote-used-identifiers (or denote-used-identifiers (denote--get-all-used-ids))))
(cond (;; Always use the supplied initial-identifier if possible,
;; regardless of format.
(and initial-identifier
(not (gethash initial-identifier denote-used-identifiers)))
initial-identifier)
(;; If the supplied initial-identifier is already used, but
;; it has the right format, make is unique.
(and initial-identifier
(string-match-p "[1-9][0-9]*" initial-identifier))
(my-denote--find-first-unused-id-as-number initial-identifier))
(;; Else, the supplied initial-identifier is nil or it is
;; already used or it does not match the supplied
;; format. Ignore it and generate a valid identifier with
;; the right format.
t
(my-denote--find-first-unused-id-as-number "1")))))