org-icomplete
is a function that calls ido-completing-read
(icr). Instead, I want it to call my function: ido-completing-path-like-read
(icplr). This would be easily implemented as advice, except that icplr calls icr, so another advice needs to be applied to icplr to resore the original definition of icr before it is called, to prevent an infinite recursion.
I implemented this in two ways, one of which works, and one of which doesn't - icplr goes into an infinite recursion, calling itself instead of icr. Why does the one not working, not work?
Works:
(defadvice org-icompleting-read (around ido-path-like-completion activate)
(let ((sh/orig-ido-completing-read (symbol-function 'ido-completing-read)))
(unwind-protect
(progn
(defadvice ido-completing-path-like-read
(around save-ido-completing-read activate)
(setf (symbol-function 'ido-completing-read)
sh/orig-ido-completing-read)
ad-do-it
)
(setf (symbol-function 'ido-completing-read)
(symbol-function 'ido-completing-path-like-read))
ad-do-it
)
(setf (symbol-function 'ido-completing-read)
sh/orig-ido-completing-read)
(ad-remove-advice 'ido-completing-path-like-read 'around 'save-ido-completing-read)
))
)
Does not work:
(defadvice org-icompleting-read (around ido-path-like-completion activate)
(let ((sh/orig-ido-completing-read (symbol-function 'ido-completing-read)))
(unwind-protect
(progn
(setf (symbol-function 'ido-completing-read)
(symbol-function 'ido-completing-path-like-read))
(defadvice ido-completing-path-like-read
(around save-ido-completing-read activate)
(setf (symbol-function 'ido-completing-read)
sh/orig-ido-completing-read)
ad-do-it
)
ad-do-it
)
(setf (symbol-function 'ido-completing-read)
sh/orig-ido-completing-read)
(ad-remove-advice 'ido-completing-path-like-read 'around 'save-ido-completing-read)
))
)
Edit
I want to make it clear that all the mentioned functiond: ido-completing-path-like-read, ido-completing-read, and org-icompleting-read are to be treated (and two of them in fact are) library functions, the definitions of which I do not control.
While I'm open to suggestions for alternative patterns here and would appreciate those, I will only accept an answer that actually answers my question: Why does the first code work and the second doesn't? Thanks for understanding.
To anyone who may come searching:
The reason that the first one works and the second one doesn't, is not the order of applying advice - it is the order of applying the inner advice relative to:
(setf (symbol-function 'ido-completing-read)
(symbol-function 'ido-completing-path-like-read))
The reason this matters is, that if this statement is executed before the advice, then the symbol 'ido-completing-read
will not be advised, whereas the symbol 'ido-completing-path-like-read
copy will be. If however advice is applied first, then both symbols will refer to the advised versions.
I'm not sure this completely makes sense. I imagined (which is why this conundrum) that the function objects have some additional information attached to them, and advice we applied by way of manipulating this additional information.
Turns out that this is a more basic mechanism - the functions are actually wrapped ad-hoc...
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments