<div dir="ltr"><div><div>I'm attempting to integrate org-mode with evil-mode. I'm aware of the existing evil-org-mode, but what I'm attempting is much deeper. Rather than just adding some evil keybindings to some org functions, I want<br>
the basic evil operations to work on org files. That is, evil-mode operators, commands, and motions are org-aware.<br><br>I see that when evil-mode is in the normal state:<br><br>* the user presses 'x', which is bound to evil-delete-char<br>
* evil-delete-char calls evil-delete<br>* evil-delete calls Emacs's delete-region to perform the deletion<br><br>When my new evil-org-mode (a minor mode) is active, I need evil-delete-char to call org-delete-char to perform the deletion. Not directly, of course. The following seems to work.<br>
<br>(defun evil-org-delete-region (beg end)<br> (let ((N (- end beg)))<br> (save-excursion<br> (goto-char beg)<br> (org-delete-char N))))<br><br>(evil-define-operator evil-org-delete-char (beg end type register)<br>
"Delete next character."<br> :motion evil-forward-char<br> (interactive "<R><x>")<br> (cl-letf (((symbol-function 'delete-region) #'(lambda (beg end) (evil-org-delete-region beg end))))<br>
(evil-delete beg end type register)))<br><br>(define-key evil-org-mode-map [remap evil-delete-char] #'evil-org-delete-char)<br><br>Essentially, I remap evil-delete-char to evil-org-delete-char. This new function temporarily redefines delete-region to be evil-org-delete-region, which, in turn, calls org-delete-char. Then the subsequent cal<br>
l to evil-delete will call org-delete-char with no changes to the evil-mode source code. Great! But...<br><br>(1) This approach gets more complicated for other evil-mode functions.<br><br> * For example, evil-org-delete-backward-char-and-join requires more indirection in order to restore the function-cell value of delete-backward-char, because that's what the org-mode function needs to call.<br>
<br> * Remapping a remapped binding doesn't chain. And it appears that remapping a binding in my minor mode doesn't override the remapped binding that evil-mode does. For example, if I remap delete-backward-cha<br>
r in evil-org-mode, the evil-mode (insert state) binding (evil-delete-backward-char-and-join) still gets called.<br><br> * I can't figure out how to intercept operators like "dd" (delete whole line), in order to override their low-level Emacs calls.<br>
<br>(2) This approach isn't composable. That is, another minor mode could not integrate with evil-mode while evil-org-mode is active.<br><br><br>Questions:<br><br>(1) Is there a good, clean, composable, way of doing what I'm trying to do?<br>
<br>(2) If not, is there an acceptable change that could be made to evil-mode to support what I'm trying to do? A change that improves the ability to integrate with evil-mode in general, not just for my purpose?<br><br>
If the answer to question (1) is 'no', I'm thinking the answer to question (2) might be something along the lines of replacing evil-mode's calls to fundamental Emacs text manipulation commands (like delete-regio<br>
n) with (abnormal) hooks. Each hook would default to being the command currently being called directly, but could be made buffer local and modified by another mode to support awareness of the buffer's contents.<br> This would also allow, in theory, multiple modes to hook into the actions. Although I can't quite picture how this would work cleanly in practice.<br>
<br></div>Thank you,<br></div>--Tad<br></div>