fix(org-noter): always-create-frame nil + start from PDF window (current frame split)

This commit is contained in:
2026-02-23 22:22:19 +01:00
parent f0b967bc7d
commit 3eca3349f1

View File

@@ -1232,7 +1232,6 @@ Otherwise: runs interactive ement-connect, then opens rooms after sync."
;; Emacs 31 may not autoload dired-read-dir-and-switches early enough,
;; causing "Symbol's function definition is void" when org-noter starts.
;; Ensure dired is loaded so all its internal functions are available.
(require 'dired)
(use-package! org-noter
@@ -1241,21 +1240,25 @@ Otherwise: runs interactive ement-connect, then opens rooms after sync."
(setq org-noter-notes-window-location 'horizontal-split
;; Directories to search for and create notes files
org-noter-notes-search-path (list (expand-file-name "notes/" org-directory))
;; Default note file name when creating a new session
;; Default note file name candidates
org-noter-default-notes-file-names '("notes.org")
;; Remember last position in PDF across sessions
org-noter-auto-save-last-location t
;; Insert note at precise location, not just page level
org-noter-insert-note-no-questions nil
org-noter-use-indirect-buffer nil))
org-noter-use-indirect-buffer nil
;; Split in the current frame (PDF + notes side by side), no new frame
org-noter-always-create-frame nil))
;; Smart org-noter launcher: finds the PDF window, repairs broken notes files,
;; and auto-answers org-noter's prompts so sessions start without user interaction.
;; Uses absolute NOTER_DOCUMENT paths (avoids symlink issues with file-relative-name).
;; Smart org-noter launcher: repairs broken notes files and starts from the PDF window.
;; Starting from the PDF window (not the notes file) ensures org-noter splits the
;; current frame — PDF on one side, notes on the other — instead of creating a
;; hidden new frame.
(defun my/org-noter-start ()
"Start org-noter for the PDF visible in the current frame.
Repairs any existing notes file with a wrong NOTER_DOCUMENT property,
then starts the session — no interactive prompts required."
Repairs any wrong NOTER_DOCUMENT property in the notes file, then
starts the session from the PDF window so the split appears in the
current frame."
(interactive)
(require 'org-noter)
(let* ((pdf-win (if (derived-mode-p 'pdf-view-mode)
@@ -1274,38 +1277,39 @@ then starts the session — no interactive prompts required."
(notes-dir (car org-noter-notes-search-path))
(target (expand-file-name notes-name notes-dir)))
(make-directory notes-dir t)
;; Repair existing notes file if NOTER_DOCUMENT is wrong (doesn't point to pdf-path).
;; Uses absolute path for NOTER_DOCUMENT to avoid symlink resolution issues.
(when (file-exists-p target)
(with-current-buffer (find-file-noselect target)
(let ((modified nil))
(save-excursion
(goto-char (point-min))
(while (re-search-forward
(concat "^[ \t]*:" org-noter-property-doc-file ":[ \t]*\\(.*\\)$")
nil t)
;; Repair or create notes file with correct NOTER_DOCUMENT (absolute PDF path).
;; Absolute paths avoid symlink ambiguity (~/org/ may be an iCloud symlink).
(with-current-buffer (find-file-noselect target)
(let ((modified nil))
(save-excursion
(goto-char (point-min))
(if (re-search-forward
(concat "^[ \t]*:" org-noter-property-doc-file ":[ \t]*\\(.*\\)$")
nil t)
;; Property exists — fix if it doesn't point to pdf-path
(let* ((stored (string-trim (match-string 1)))
(expanded (if (file-name-absolute-p stored)
stored
(expand-file-name stored (file-name-directory target)))))
(unless (and (file-exists-p expanded)
(file-equal-p expanded pdf-path))
;; Wrong or missing target — replace with absolute path to PDF
(replace-match (concat ":" org-noter-property-doc-file
": " pdf-path)
t t)
(setq modified t)))))
(when modified (save-buffer)))))
;; Auto-answer org-noter's two interactive prompts:
;; "What name do you want the notes to have?" -> notes-name (basename.org)
;; "Where do you want to save it?" -> target (notes-dir/basename.org)
;; org-noter will then create the heading with the correct NOTER_DOCUMENT itself.
(replace-match
(concat ":" org-noter-property-doc-file ": " pdf-path) t t)
(setq modified t)))
;; No property — insert a new org-noter heading
(goto-char (point-min))
(insert (format "* Notes: %s\n:PROPERTIES:\n:%s: %s\n:END:\n\n"
base org-noter-property-doc-file pdf-path))
(setq modified t)))
(when modified (save-buffer))))
;; Start from the PDF window. cl-letf auto-answers org-noter's prompts for
;; edge cases where it still asks (e.g. multiple candidate files).
(cl-letf* ((orig-cr (symbol-function 'completing-read))
((symbol-function 'completing-read)
(lambda (prompt collection &rest args)
(cond
((string-match-p "name" prompt) notes-name)
((string-match-p "save\\|where\\|Which" prompt) target)
((string-match-p "name" prompt) notes-name)
((string-match-p "save\\|where\\|Which" prompt) target)
(t (apply orig-cr prompt collection args))))))
(with-selected-window pdf-win
(org-noter))))))