org-fold: Allow customizing commands where invisible edits are checked

* lisp/org-fold.el (org-fold-catch-invisible-edits-commands): New
custom option.
(org-fold-catch-invisible-edits): Mention the new custom option in the
docstring.
(org-fold-check-before-invisible-edit-maybe): New function checking
if edits are safe for `this-command'.
(org-fold--advice-edit-commands): New function advising the functions
with `org-fold-check-before-invisible-edit-maybe'.
* lisp/org.el (org-mode): Advice functions on Org startup.
(org-self-insert-command):
(org-delete-backward-char):
(org-delete-char):
(org-meta-return): Do not call `org-fold-check-before-invisible-edit'
and rely on the new advise mechanism instead.
* etc/ORG-NEWS (Commands affected by ~org-fold-catch-invisible-edits~
can now be customized): Announce the change.
* doc/org-manual.org (Catching invisible edits): Mention new
customization.
main
Ihor Radchenko 1 year ago
parent d4b66e99fd
commit ab85c1b958
No known key found for this signature in database
GPG Key ID: 6470762A7DA11D8B

@ -622,11 +622,17 @@ for this property are =folded=, =children=, =content=, and =all=.
#+cindex: edits, catching invisible
#+vindex: org-fold-catch-invisible-edits
#+vindex: org-fold-catch-invisible-edits-commands
Sometimes you may inadvertently edit an invisible part of the buffer
and be confused on what has been edited and how to undo the mistake.
Setting ~org-fold-catch-invisible-edits~ to non-~nil~ helps preventing
this. See the docstring of this option on how Org should catch
invisible edits and process them.
By default, Org prevents such edits for a limited set of user
commands. Users can control which commands are affected by
customizing ~org-fold-catch-invisible-edits-commands~.
The strategy used to decide if a given edit is dangerous is controlled
by ~org-fold-catch-invisible-edits~. See the docstring of this option
on the available strategies. Set the option to ~nil~ to disable
catching invisible edits completely.
** Motion
:PROPERTIES:

@ -51,6 +51,18 @@ encounter issues, and users are advised to update to the most recent
version of org-caldav. See [[https://github.com/dengste/org-caldav/commit/618bf4cdc9be140ca1993901d017b7f18297f1b8][this org-caldav commit]] for more information.
** New and changed options
*** Commands affected by ~org-fold-catch-invisible-edits~ can now be customized
New user option ~org-fold-catch-invisible-edits-commands~ controls
which commands trigger checking for invisible edits.
The full list of affected commands is:
- ~org-self-insert-command~
- ~org-delete-backward-char~
- ~org-delete-char~
- ~org-meta-return~
- ~org-return~ (not checked in earlier Org versions)
*** New customization ~org-image-max-width~ limiting the displayed inline image width
New custom variable ~org-image-max-width~ limits the maximum inline

@ -189,7 +189,10 @@ smart Make point visible, and do insertion/deletion if it is
Never delete a previously invisible character or add in the
middle or right after an invisible region. Basically, this
allows insertion and backward-delete right before ellipses.
FIXME: maybe in this case we should not even show?"
FIXME: maybe in this case we should not even show?
This variable only affects commands listed in
`org-fold-catch-invisible-edits-commands'."
:group 'org-edit-structure
:version "24.1"
:type '(choice
@ -199,6 +202,33 @@ smart Make point visible, and do insertion/deletion if it is
(const :tag "Show invisible part and do the edit" show)
(const :tag "Be smart and do the right thing" smart)))
(defcustom org-fold-catch-invisible-edits-commands
;; We do not add non-Org commands here by default to avoid advising
;; globally. See `org-fold--advice-edit-commands'.
'((org-self-insert-command . insert)
(org-delete-backward-char . delete-backward)
(org-delete-char . delete)
(org-meta-return . insert)
(org-return . insert))
"Alist of commands where Org checks for invisible edits.
Each element is (COMMAND . KIND), where COMMAND is symbol representing
command as stored in `this-command' and KIND is symbol `insert',
symbol `delete', or symbol `delete-backward'.
The checks are performed around `point'.
This variable must be set before loading Org in order to take effect.
Also, see `org-fold-catch-invisible-edits'."
:group 'org-edit-structure
:package-version '("Org" . "9.7")
:type '(alist
:key-type symbol
:value-type (choice
(const insert)
(const delete)
(const delete-backward))))
;;; Core functionality
;;; API
@ -903,6 +933,19 @@ The detailed reaction depends on the user option
;; Don't do the edit, make the user repeat it in full visibility
(user-error "Edit in invisible region aborted, repeat to confirm with text visible"))))))))
(defun org-fold-check-before-invisible-edit-maybe (&rest _)
"Check before invisible command by `this-command'."
(when (derived-mode-p 'org-mode)
(pcase (alist-get this-command org-fold-catch-invisible-edits-commands)
((pred null) nil)
(kind (org-fold-check-before-invisible-edit kind)))))
(defun org-fold--advice-edit-commands ()
"Advice editing commands according to `org-fold-catch-invisible-edits-commands'.
The advices are installed in current buffer."
(dolist (command (mapcar #'car org-fold-catch-invisible-edits-commands))
(advice-add command :before #'org-fold-check-before-invisible-edit-maybe)))
(provide 'org-fold)
;;; org-fold.el ends here

@ -4845,6 +4845,8 @@ The following commands are available:
(add-hook 'before-change-functions 'org-before-change-function nil 'local)
;; Check for running clock before killing a buffer
(add-hook 'kill-buffer-hook 'org-check-running-clock nil 'local)
;; Check for invisible edits.
(org-fold--advice-edit-commands)
;; Initialize cache.
(org-element-cache-reset)
(when (and org-element-cache-persistent
@ -16477,7 +16479,6 @@ either not currently on a tagged headline or on a tag."
If the cursor is in a table looking at whitespace, the whitespace is
overwritten, and the table is not marked as requiring realignment."
(interactive "p")
(org-fold-check-before-invisible-edit 'insert)
(cond
((and org-use-speed-commands
(let ((kv (this-command-keys-vector)))
@ -16549,7 +16550,6 @@ still be marked for re-alignment if the field did fill the entire column,
because, in this case the deletion might narrow the column."
(interactive "p")
(save-match-data
(org-fold-check-before-invisible-edit 'delete-backward)
(if (and (= N 1)
(not overwrite-mode)
(not (org-region-active-p))
@ -16569,7 +16569,6 @@ still be marked for re-alignment if the field did fill the entire column,
because, in this case the deletion might narrow the column."
(interactive "p")
(save-match-data
(org-fold-check-before-invisible-edit 'delete)
(cond
((or (/= N 1)
(eq (char-after) ?|)
@ -17985,7 +17984,6 @@ Calls `org-insert-heading', `org-insert-item' or
`org-table-wrap-region', depending on context. When called with
an argument, unconditionally call `org-insert-heading'."
(interactive "P")
(org-fold-check-before-invisible-edit 'insert)
(or (run-hook-with-args-until-success 'org-metareturn-hook)
(call-interactively (cond (arg #'org-insert-heading)
((org-at-table-p) #'org-table-wrap-region)

Loading…
Cancel
Save