(feat): Protect region targeted by org-roam-insert (#974)

Co-authored-by: Jethro Kuan <jethrokuan95@gmail.com>
This commit is contained in:
Leo Vivier 2020-07-27 20:16:39 +02:00 committed by GitHub
parent f2c1500beb
commit 6345d0c22e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 113 additions and 56 deletions

View file

@ -1,5 +1,15 @@
# Changelog # Changelog
## 1.2.2 (TBD)
### Breaking Changes
### Features
-[#974](https://github.com/org-roam/org-roam/pull/974) Protect region targeted by `org-roam-insert`
### Bugfixes
## 1.2.1 (27-07-2020) ## 1.2.1 (27-07-2020)
This release consisted of a big deal of refactoring and bug fixes. Notably, we fixed several catastrophic failures on db builds with bad setups (#854), and modularized tag and title extractions. This release consisted of a big deal of refactoring and bug fixes. Notably, we fixed several catastrophic failures on db builds with bad setups (#854), and modularized tag and title extractions.

View file

@ -31,6 +31,7 @@
;;; Code: ;;; Code:
;;;; Library Requires ;;;; Library Requires
(require 'org-capture) (require 'org-capture)
(require 'org-roam-macs)
(require 'dash) (require 'dash)
(require 's) (require 's)
(require 'cl-lib) (require 'cl-lib)
@ -320,26 +321,35 @@ the capture)."
(defun org-roam-capture--finalize () (defun org-roam-capture--finalize ()
"Finalize the `org-roam-capture' process." "Finalize the `org-roam-capture' process."
(unless org-note-abort (let* ((finalize (org-roam-capture--get :finalize))
(pcase (org-roam-capture--get :finalize) ;; In case any regions were shielded before, unshield them
('find-file (region (when-let ((region (org-roam-capture--get :region)))
(when-let ((file-path (org-roam-capture--get :file-path))) (org-roam-unshield-region (car region) (cdr region))))
(org-roam--find-file file-path) (beg (car region))
(run-hooks 'org-roam-capture-after-find-file-hook))) (end (cdr region)))
('insert-link (unless org-note-abort
(when-let* ((mkr (org-roam-capture--get :insert-at)) (pcase finalize
(buf (marker-buffer mkr))) ('find-file
(with-current-buffer buf (when-let ((file-path (org-roam-capture--get :file-path)))
(when-let ((region (org-roam-capture--get :region))) ;; Remove previously selected text. (org-roam--find-file file-path)
(delete-region (car region) (cdr region))) (run-hooks 'org-roam-capture-after-find-file-hook)))
(let ((path (org-roam-capture--get :file-path)) ('insert-link
(desc (org-roam-capture--get :link-description))) (when-let* ((mkr (org-roam-capture--get :insert-at))
(if (eq (point) (marker-position mkr)) (buf (marker-buffer mkr)))
(insert (org-roam--format-link path desc)) (with-current-buffer buf
(org-with-point-at mkr (when region
(insert (org-roam--format-link path desc)))))))))) (delete-region (car region) (cdr region)))
(org-roam-capture--save-file-maybe) (let ((path (org-roam-capture--get :file-path))
(remove-hook 'org-capture-after-finalize-hook #'org-roam-capture--finalize)) (desc (org-roam-capture--get :link-description)))
(if (eq (point) (marker-position mkr))
(insert (org-roam--format-link path desc))
(org-with-point-at mkr
(insert (org-roam--format-link path desc))))))))))
(when region
(set-marker beg nil)
(set-marker end nil))
(org-roam-capture--save-file-maybe)
(remove-hook 'org-capture-after-finalize-hook #'org-roam-capture--finalize)))
(defun org-roam-capture--install-finalize () (defun org-roam-capture--install-finalize ()
"Install `org-roam-capture--finalize' if the capture is an Org-roam capture." "Install `org-roam-capture--finalize' if the capture is an Org-roam capture."

View file

@ -77,6 +77,28 @@ to look.
(s-replace "\\" "\\\\") (s-replace "\\" "\\\\")
(s-replace "\"" "\\\""))) (s-replace "\"" "\\\"")))
;;; Shielding regions
(defun org-roam-shield-region (beg end)
"Shield REGION against modifications.
REGION must be a cons-cell containing the marker to the region
beginning and maximum values."
(when (and beg end)
(add-text-properties beg end
'(font-lock-face org-roam-link-shielded
read-only t)
(marker-buffer beg))
(cons beg end)))
(defun org-roam-unshield-region (beg end)
"Unshield the shielded REGION."
(when (and beg end)
(let ((inhibit-read-only t))
(remove-text-properties beg end
'(font-lock-face org-roam-link-shielded
read-only t)
(marker-buffer beg)))
(cons beg end)))
(provide 'org-roam-macs) (provide 'org-roam-macs)
;;; org-roam-macs.el ends here ;;; org-roam-macs.el ends here

View file

@ -960,6 +960,13 @@ Return nil if the file does not exist."
This face is used for links without a destination." This face is used for links without a destination."
:group 'org-roam-faces) :group 'org-roam-faces)
(defface org-roam-link-shielded
'((t :inherit (warning org-link)))
"Face for Org-roam links that are shielded.
This face is used on the region target by `org-roam-insertion'
during an `org-roam-capture'."
:group 'org-roam-faces)
;;;; org-roam-backlinks-mode ;;;; org-roam-backlinks-mode
(define-minor-mode org-roam-backlinks-mode (define-minor-mode org-roam-backlinks-mode
"Minor mode for the `org-roam-buffer'. "Minor mode for the `org-roam-buffer'.
@ -1420,42 +1427,50 @@ If DESCRIPTION is provided, use this as the link label. See
`org-roam--get-title-path-completions' for details." `org-roam--get-title-path-completions' for details."
(interactive "P") (interactive "P")
(unless org-roam-mode (org-roam-mode)) (unless org-roam-mode (org-roam-mode))
(let* ((region (and (region-active-p) ;; Deactivate the mark on quit since `atomic-change-group' prevents it
;; following may lose active region, so save it (unwind-protect
(cons (region-beginning) (region-end)))) ;; Group functions together to avoid inconsistent state on quit
(region-text (when region (atomic-change-group
(buffer-substring-no-properties (car region) (cdr region)))) (let* (region-text
(completions (--> (or completions beg end
(org-roam--get-title-path-completions)) (_ (when (region-active-p)
(if filter-fn (setq beg (set-marker (make-marker) (region-beginning)))
(funcall filter-fn it) (setq end (set-marker (make-marker) (region-end)))
it))) (setq region-text (buffer-substring-no-properties beg end))))
(title-with-tags (org-roam-completion--completing-read "File: " completions (completions (--> (or completions
:initial-input region-text)) (org-roam--get-title-path-completions))
(res (cdr (assoc title-with-tags completions))) (if filter-fn
(title (or (plist-get res :title) (funcall filter-fn it)
title-with-tags)) it)))
(target-file-path (plist-get res :path)) (title-with-tags (org-roam-completion--completing-read "File: " completions
(description (or description region-text title)) :initial-input region-text))
(link-description (org-roam--format-link-title (if lowercase (res (cdr (assoc title-with-tags completions)))
(downcase description) (title (or (plist-get res :title)
description)))) title-with-tags))
(if (and target-file-path (target-file-path (plist-get res :path))
(file-exists-p target-file-path)) (description (or description region-text title))
(progn (link-description (org-roam--format-link-title (if lowercase
(when region ;; Remove previously selected text. (downcase description)
(delete-region (car region) (cdr region))) description))))
(insert (org-roam--format-link target-file-path link-description))) (cond ((and target-file-path
(let ((org-roam-capture--info `((title . ,title-with-tags) (file-exists-p target-file-path))
(slug . ,(funcall org-roam-title-to-slug-function title-with-tags)))) (when region-text
(org-roam-capture--context 'title)) (delete-region beg end)
(setq org-roam-capture-additional-template-props (list :region region (set-marker beg nil)
:insert-at (point-marker) (set-marker end nil))
:link-description link-description (insert (org-roam--format-link target-file-path link-description)))
:finalize 'insert-link)) (t
(org-roam--with-template-error 'org-roam-capture-templates (let ((org-roam-capture--info `((title . ,title-with-tags)
(org-roam-capture--capture)))) (slug . ,(funcall org-roam-title-to-slug-function title-with-tags))))
res)) (org-roam-capture--context 'title))
(setq org-roam-capture-additional-template-props (list :region (org-roam-shield-region beg end)
:insert-at (point-marker)
:link-description link-description
:finalize 'insert-link))
(org-roam--with-template-error 'org-roam-capture-templates
(org-roam-capture--capture)))))
res))
(deactivate-mark)))
;;;###autoload ;;;###autoload
(defun org-roam-insert-immediate (arg &rest args) (defun org-roam-insert-immediate (arg &rest args)