diff --git a/config.el b/config.el index 85f15e1..baa50e0 100644 --- a/config.el +++ b/config.el @@ -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))))))