all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Lazy load of org-protocol
@ 2022-02-05 11:54 Max Nikulin
  2022-02-05 18:27 ` Jim Porter
  0 siblings, 1 reply; 15+ messages in thread
From: Max Nikulin @ 2022-02-05 11:54 UTC (permalink / raw)
  To: emacs-orgmode

Hi.

I would prefer to avoid
    (require 'org-protocol)
in emacs init file and to postpone loading till invocation of 
emacsclient with org-protocol URI.

The problem is a hack in org-protocol. URIs are actually treated as 
(relative) file names and magic is achieved in an advice for 
`server-visit-files' function. So the advice must be installed in advance.

My first idea was to avoid such magic and to create autoload function 
org-protocol-from-argv with body similar to that advice. If it were 
possible to get arguments from `command-line-args-left' then invocation 
would look like

    emacsclient --eval '(org-protocol-from-argv)' 
'org-protocol:/store-link?url=u1&title=t1'

Unfortunately it is against design of emacs server protocol. If --eval 
option is given than everything other is considered as independent 
expressions. At the lower level there is no way to transfer `argv` as a 
list from client to server process.

It seems, it works if I add another advice to init.el that loads 
org-protocol on demand:

(defadvice server-visit-files (before org-protocol-lazy-load activate)
   (and (not (featurep 'org-protocol))
        (memq nil
	     (mapcar (lambda (loc)
		       ;; loc: (file-name . (line . column))
		       (not (string-match-p "\\(?:^\\|[/\\\\]\\)org-protocol:" (car 
loc))))
		     (ad-get-arg 0)))
        (progn
	 (require 'org-protocol)
	 ;; copy of org-protocol-detect-protocol-server advice,
          ;; move to a dedicated function
	 (let ((flist (if org-protocol-reverse-list-of-files
			  (reverse  (ad-get-arg 0))
			(ad-get-arg 0)))
	       (client (ad-get-arg 1)))
	   (catch 'greedy
	     (dolist (var flist)
	       ;; `\' to `/' on windows.  FIXME: could this be done any better?
	       (let ((fname  (expand-file-name (car var))))
		 (setq fname (org-protocol-check-filename-for-protocol
			      fname (member var flist)  client))
		 (if (eq fname t) ;; greedy? We need the t return value.
		     (progn
		       (ad-set-arg 0 nil)
		       (throw 'greedy t))
		   (if (stringp fname) ;; probably filename
		       (setcar var fname)
		     (ad-set-arg 0 (delq var (ad-get-arg 0))))))))))))

I hope, copy of original advice may be avoided by moving its body to a 
separate function in org-protocol.

Do you have have better ideas how to avoid eager loading of org-protocol 
from init file?



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Lazy load of org-protocol
  2022-02-05 11:54 Lazy load of org-protocol Max Nikulin
@ 2022-02-05 18:27 ` Jim Porter
  2022-02-06 16:42   ` Max Nikulin
  0 siblings, 1 reply; 15+ messages in thread
From: Jim Porter @ 2022-02-05 18:27 UTC (permalink / raw)
  To: Max Nikulin, emacs-orgmode

On 2/5/2022 3:54 AM, Max Nikulin wrote:
> I would prefer to avoid
>     (require 'org-protocol)
> in emacs init file and to postpone loading till invocation of 
> emacsclient with org-protocol URI.
> 
> The problem is a hack in org-protocol. URIs are actually treated as 
> (relative) file names and magic is achieved in an advice for 
> `server-visit-files' function. So the advice must be installed in advance.
> 
> My first idea was to avoid such magic and to create autoload function 
> org-protocol-from-argv with body similar to that advice. If it were 
> possible to get arguments from `command-line-args-left' then invocation 
> would look like
> 
>     emacsclient --eval '(org-protocol-from-argv)' 
> 'org-protocol:/store-link?url=u1&title=t1'
> 
> Unfortunately it is against design of emacs server protocol. If --eval 
> option is given than everything other is considered as independent 
> expressions. At the lower level there is no way to transfer `argv` as a 
> list from client to server process.

I've thought a bit about how to improve this too. One further issue with 
the current implementation is that when emacsclient invokes the 
alternate editor (usually to start the "main" emacs instance), 
org-protocol: links no longer work correctly. That's because only the 
emacsclient itself (through `server-visit-files') knows what to do with 
them.

I think the problem really starts in emacsclient's command line 
handling. You can see this in other situations too. For example, Emacs 
can be configured as your system's mailto: URL handler. (The file 
etc/emacsclient-mail.desktop in the Emacs repo does this.) The command 
to use for a new Emacs instance is simple:

   emacs -f message-mailto %u

However, doing this for emacsclient is harder:

   emacsclient --alternate-editor= --create-frame --eval 
"(message-mailto \\"%u\\")"

There's no problem with "--alternate-editor=" and "--create-frame", but 
the fact that emacsclient requires evaling the function call that way 
is: if %u holds a string with quotation marks, this will break, and 
worse, could even result in arbitrary code being executed. (In practice, 
this is probably rare, since URLs are generally URL-encoded, and so 
don't have literal quotes in them.)

As a result, I think a good first step might be to add support for 
"--funcall" to emacsclient, just like the regular emacs binary. (The 
"-f" shorthand won't work though, since emacsclient already uses that 
for "--server-file"). This would simplify the `message-mailto' case 
above and would also allow org-protocol to do something similar:

   emacsclient --funcall org-protocol-capture %u

Then, so long as `org-protocol-capture' has an autoload, this would Just 
Work, and org-protocol.el would be lazily loaded. Hopefully, this could 
also be forwarded onto the alternate editor so that when the user open 
an org-protocol: URL when Emacs is closed, it still handles the URL 
correctly.

That said, in the short term, you could try out something like:

   emacsclient --eval "(org-protocol-capture \\"%u\\")"

Of course, that has the quoting issues I mentioned above, but it could 
be helpful for developing a proof of concept.

- Jim


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Lazy load of org-protocol
  2022-02-05 18:27 ` Jim Porter
@ 2022-02-06 16:42   ` Max Nikulin
  2022-02-06 19:40     ` Jim Porter
  0 siblings, 1 reply; 15+ messages in thread
From: Max Nikulin @ 2022-02-06 16:42 UTC (permalink / raw)
  To: emacs-orgmode

On 06/02/2022 01:27, Jim Porter wrote:
> On 2/5/2022 3:54 AM, Max Nikulin wrote:
> etc/emacsclient-mail.desktop in the Emacs repo does this.) The command 
> to use for a new Emacs instance is simple:
> 
>    emacs -f message-mailto %u
> 
> However, doing this for emacsclient is harder:
> 
>    emacsclient --alternate-editor= --create-frame --eval 
> "(message-mailto \\"%u\\")"
> 
> There's no problem with "--alternate-editor=" and "--create-frame", but 
> the fact that emacsclient requires evaling the function call that way 
> is: if %u holds a string with quotation marks, this will break, and 
> worse, could even result in arbitrary code being executed. (In practice, 
> this is probably rare, since URLs are generally URL-encoded, and so 
> don't have literal quotes in them.)

Thank you for suggesting another use case.

Quoting issues was the reason why I started to search a better way. 
There should be an easy and safe means to pass argument from command 
line to evaluated expressions similar to shell
     sh -c 'echo "$1"' example 'Hello, World!'

Some people could not even choose proper quotes for shell command:
https://www.reddit.com/r/emacs/comments/hhbcg7/emacsclient_eval_with_command_line_arguments/
https://stackoverflow.com/questions/8848819/emacs-eval-ediff-1-2-how-to-put-this-line-in-to-shell-script
First recipe and the accepted answer in second source solves the obvious 
problem but they miss escaping for elisp expression. Another answer on 
stackoverflow is more accurate, it suggests
     quoted1=${1//\\/\\\\}; quoted1=${quoted1//\"/\\\"}
I suppose, these links is a good illustration that substitution of 
arbitrary argument into lisp expression is harder than it should be to 
help users to avoid security issues.

> As a result, I think a good first step might be to add support for 
> "--funcall" to emacsclient, just like the regular emacs binary. (The 
> "-f" shorthand won't work though, since emacsclient already uses that 
> for "--server-file"). This would simplify the `message-mailto' case 
> above and would also allow org-protocol to do something similar:
> 
>    emacsclient --funcall org-protocol-capture %u

No, --funcall is just a sugar for --eval '(func)' that does not contain 
arbitrary input, but func has no access to other arguments and it is the 
real problem.

I think, the solution is to add -arg command to emacs server protocol 
that pushes its argument to a list and extend -exec command that would 
make such list available as argv or as `command-line-args-left' for 
evaluated expression. Of course, emacsclient option parser should be 
modified as well to support --arg option
      emacsclient --eval '(func)' --arg 1 2 3
      emacsclient --eval '(func)' --arg -- 1 2 3
and maybe even for multiple eval+arg pairs
      emacsclient --eval '(f1)' --arg 'a1' --eval '(f2)' --arg 'a2' 'a3'

The proper place to discuss idea is emacs-devel list, but I am afraid 
that without a patch it will be just buried.

>    emacsclient --eval "(org-protocol-capture \\"%u\\")"

Due to quoting issues a small wrapper may be safer (modulo -a, -c)

     emacsclient --eval "(require 'org-protocol)"
     emacsclient -- "$@"



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Lazy load of org-protocol
  2022-02-06 16:42   ` Max Nikulin
@ 2022-02-06 19:40     ` Jim Porter
  2022-02-07 14:57       ` Max Nikulin
  0 siblings, 1 reply; 15+ messages in thread
From: Jim Porter @ 2022-02-06 19:40 UTC (permalink / raw)
  To: emacs-orgmode

On 2/6/2022 8:42 AM, Max Nikulin wrote:
> On 06/02/2022 01:27, Jim Porter wrote:
>> As a result, I think a good first step might be to add support for 
>> "--funcall" to emacsclient, just like the regular emacs binary. (The 
>> "-f" shorthand won't work though, since emacsclient already uses that 
>> for "--server-file"). This would simplify the `message-mailto' case 
>> above and would also allow org-protocol to do something similar:
>>
>>    emacsclient --funcall org-protocol-capture %u
> 
> No, --funcall is just a sugar for --eval '(func)' that does not contain 
> arbitrary input, but func has no access to other arguments and it is the 
> real problem.

Oh right, of course. The emacsclient case with `(message-mailto \"%u\")' 
threw me off, but `message-mailto' works differently depending on 
whether you pass it an arg or not.

> I think, the solution is to add -arg command to emacs server protocol 
> that pushes its argument to a list and extend -exec command that would 
> make such list available as argv or as `command-line-args-left' for 
> evaluated expression. Of course, emacsclient option parser should be 
> modified as well to support --arg option
>       emacsclient --eval '(func)' --arg 1 2 3
>       emacsclient --eval '(func)' --arg -- 1 2 3
> and maybe even for multiple eval+arg pairs
>       emacsclient --eval '(f1)' --arg 'a1' --eval '(f2)' --arg 'a2' 'a3'

I think something like this could work, so long as the arguments can be 
forwarded correctly in the alternate editor case. If I understand how 
emacsclient handles --eval, I think that might work, but it would still 
require writing Lisp functions that know how to handle argv or 
`command-line-args-left'. I'm also not totally sure how safe/sensible 
that is when the arguments aren't from the invocation of emacs itself, 
but from emacsclient (and thus, the args could be updated multiple times 
throughout a session). It probably wouldn't actually break anything, but 
it does seem a bit surprising to me...

Maybe another option would be to add an --apply argument that really 
*does* consume the other command-line args and turns them into a 
properly-quoted function call. Roughly speaking, it would turn this:

   emacs --apply func foo bar baz

into this:

   (apply #'func '(foo bar baz))

This would work effectively like how I momentarily thought --funcall 
works. Then you could say:

   emacsclient --apply org-protocol-capture %u
   # or ...
   emacs --apply org-protocol-capture %u

This would also mean that the `message-mailto' function from Gnus 
doesn't need to care about `command-line-args-left' anymore, which would 
simplify it somewhat. And this could be useful in general for 
programmatically interacting with Emacs, since users would be able to 
pass arbitrary strings to Emacs Lisp functions without having to worry 
(as much) about sanitizing the strings first.

> The proper place to discuss idea is emacs-devel list, but I am afraid 
> that without a patch it will be just buried.

I don't know if an actual patch would be a strict prerequisite for 
posting to emacs-devel, but it's probably wise to have a clear, detailed 
proposal first. I think it's easier to get everyone on board with an 
idea if it's easy for them to see how all the details work up-front.

- Jim


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Lazy load of org-protocol
  2022-02-06 19:40     ` Jim Porter
@ 2022-02-07 14:57       ` Max Nikulin
  2022-02-07 19:06         ` Jim Porter
  2022-02-08 10:44         ` Emacs-orgmode Digest, Vol 192, Issue 8 Tianshu Wang
  0 siblings, 2 replies; 15+ messages in thread
From: Max Nikulin @ 2022-02-07 14:57 UTC (permalink / raw)
  To: emacs-orgmode

On 06/02/2022 09:40, Tianshu Wang wrote:
> 
> (defadvice server-execute (before enable-org-protocol activate)
>   (unless (featurep 'org-protocol) (require 'org-protocol)))

Thank you, such approach, unlike mine example, does not have code 
duplication. On the other hand it loads org-protocol on any remote 
command, not only for "files" representing org-protocol URIs. Maybe 
defadvice in org-protocol.el should be changed by newer advice-add with 
a function containing body of the old advice.

On 07/02/2022 02:40, Jim Porter wrote:
> On 2/6/2022 8:42 AM, Max Nikulin wrote:
>> On 06/02/2022 01:27, Jim Porter wrote:
> 
>> I think, the solution is to add -arg command to emacs server protocol 
>> that pushes its argument to a list and extend -exec command that would 
>> make such list available as argv or as `command-line-args-left' for 
>> evaluated expression. Of course, emacsclient option parser should be 
>> modified as well to support --arg option
>>       emacsclient --eval '(func)' --arg 1 2 3
>>       emacsclient --eval '(func)' --arg -- 1 2 3
>> and maybe even for multiple eval+arg pairs
>>       emacsclient --eval '(f1)' --arg 'a1' --eval '(f2)' --arg 'a2' 'a3'
> 
> I think something like this could work, so long as the arguments can be 
> forwarded correctly in the alternate editor case. If I understand how 
> emacsclient handles --eval, I think that might work, but it would still 
> require writing Lisp functions that know how to handle argv or 
> `command-line-args-left'. I'm also not totally sure how safe/sensible 
> that is when the arguments aren't from the invocation of emacs itself, 
> but from emacsclient (and thus, the args could be updated multiple times 
> throughout a session). It probably wouldn't actually break anything, but 
> it does seem a bit surprising to me...

Of course, I mean let-bind of `argv' and `command-line-args-left' just 
for processing of the passed expression, not setq that would change them 
globally.

> Maybe another option would be to add an --apply argument that really 
> *does* consume the other command-line args and turns them into a 
> properly-quoted function call. Roughly speaking, it would turn this:
> 
>    emacs --apply func foo bar baz
> 
> into this:
> 
>    (apply #'func '(foo bar baz))

You have almost managed to sell this idea to me. However even --apply is 
just sugar for

     emacsclient --eval "(apply #'func command-line-args-left)" --arg 1 2

So it is --apply option that may require to write a dedicated function 
if --arg is not implemented. Another limitation of --apply is that the 
function must accept string arguments only, no lists or even integers or 
boolean.

> This would work effectively like how I momentarily thought --funcall 
> works. Then you could say:
> 
>    emacsclient --apply org-protocol-capture %u
>    # or ...
>    emacs --apply org-protocol-capture %u

Just because of there were a couple of recent threads related to calling 
conventions for subprotocol handlers, it is better to provide a bit more 
"real" example

     emacsclient --eval '(org-protocol-check-filename-for-protocol (pop 
command-line-args-left) nil nil)' --args %u



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Lazy load of org-protocol
  2022-02-07 14:57       ` Max Nikulin
@ 2022-02-07 19:06         ` Jim Porter
  2022-02-09 16:46           ` Max Nikulin
  2022-02-08 10:44         ` Emacs-orgmode Digest, Vol 192, Issue 8 Tianshu Wang
  1 sibling, 1 reply; 15+ messages in thread
From: Jim Porter @ 2022-02-07 19:06 UTC (permalink / raw)
  To: emacs-orgmode

On 2/7/2022 6:57 AM, Max Nikulin wrote:
>> Maybe another option would be to add an --apply argument that really 
>> *does* consume the other command-line args and turns them into a 
>> properly-quoted function call. Roughly speaking, it would turn this:
>>
>>    emacs --apply func foo bar baz
>>
>> into this:
>>
>>    (apply #'func '(foo bar baz))
> 
> You have almost managed to sell this idea to me. However even --apply is 
> just sugar for
> 
>      emacsclient --eval "(apply #'func command-line-args-left)" --arg 1 2
> 
> So it is --apply option that may require to write a dedicated function 
> if --arg is not implemented. Another limitation of --apply is that the 
> function must accept string arguments only, no lists or even integers or 
> boolean.

Yeah, `--arg' does have greater flexibility in that regard, but it comes 
at the cost of verbosity and some slight behavioral differences with the 
equivalent in the main emacs executable. For emacs itself, any elements 
of `command-line-args-left' that aren't consumed by a function will get 
opened as files, but I don't think that would be the case with 
emacsclient. Does this difference matter? Probably not. However, 
avoiding `command-line-args-left' just feels intuitively "cleaner" to 
me. Still, I think `--arg' should work and be backwards-compatible, so I 
don't mind it, even if I prefer the simplicity of `--apply'.

On a related note, there is still an issue with `--eval' in some cases. 
It fails to work with emacsclient when invoking an alternate editor:

   emacsclient --alternate-editor emacs --eval '(message "hi")'

If Emacs isn't already running, that will open a new buffer named 
'(message "hi")'. I think that's just a bug in how emacsclient handles 
`--eval', though fixing it would make org-protocol links work more 
reliably (if they used `--eval' as proposed, that is).

- Jim


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Emacs-orgmode Digest, Vol 192, Issue 8
  2022-02-07 14:57       ` Max Nikulin
  2022-02-07 19:06         ` Jim Porter
@ 2022-02-08 10:44         ` Tianshu Wang
  1 sibling, 0 replies; 15+ messages in thread
From: Tianshu Wang @ 2022-02-08 10:44 UTC (permalink / raw)
  To: emacs-orgmode


Max Nikulin writes:

> Thank you, such approach, unlike mine example, does not have code
> duplication. On the other hand it loads org-protocol on any remote
> command, not only for "files" representing org-protocol URIs. Maybe
> defadvice in org-protocol.el should be changed by newer advice-add with
> a function containing body of the old advice.

Yes, I replaced the original code with advice-add (not fully tested).

(advice-add 'server-execute :before
            (defun enable-org-protocol (&rest r)
              (unless (featurep 'org-protocol) (require 'org-protocol))))

--
Tianshu Wang


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] lisp/org-capture.el: Add hook & hook options to org-capture (Valentin Herrmann)
       [not found] <mailman.61.1644253327.32758.emacs-orgmode@gnu.org>
@ 2022-02-08 19:02 ` No Wayman
  2022-02-09  4:10   ` Ihor Radchenko
  2022-02-10 19:32   ` Greg Minshall
  0 siblings, 2 replies; 15+ messages in thread
From: No Wayman @ 2022-02-08 19:02 UTC (permalink / raw)
  To: emacs-orgmode; +Cc: emacs-orgmode-request


I've implemented what you're proposing here (and much more) in a 
package you may find useful a couple years ago. I pitched adopting 
some of the ideas into org-mode proper and was willing to do the 
work. My proposal was met with enthusiastic silence:

https://www.github.com/progfolio/doct


> - :prepend            Normally newly captured information will 
> be appended at
> -                     the target location (last child, last 
> table line,
> -                     last list item...).  Setting this property 
> will
> -                     change that.
> + :prepend               Normally newly captured information 
> will be appended at
> +                        the target location (last child, last 
> table line,
> +                        last list item...).  Setting this 
> property will
> +                        change that.

Are the white space changes to unrelated properties necessary?
   
> +(defcustom org-capture-before-view-hook nil
> +  "Hook that is run right after the capture buffer is made 
> current.
> +The buffer is still narrowed."
> +  :group 'org-capture
> +  :version "28.1"
> +  :type 'hook)
> +

This functionality is already provided by `org-capture-mode-hook'. 
Instead of introducing another hook, that can be utilized. An 
illustration using doct's :hook keyword which runs functions 
during org-capture-mode-hook:

Yodel[1] Report 2022-02-08 14:16:58
===================================

--8<---------------cut here---------------start------------->8---
(yodel
  :save "org-capture-mode-hook-example"
  :packages*
  doct
  :post*
  (require 'org-capture)
  (require 'doct)
  (let ((org-capture-templates
        (doct
         `("test"
           :keys "t"
           :file "/tmp/test.org"
           :template "* test"
           :immediate-finish t
           :hook (lambda nil
             (message "%S narrowed?: %S"
                      (current-buffer)
                      (buffer-narrowed-p)))))))
    (org-capture nil "t")))
--8<---------------cut here---------------end--------------->8---

STDOUT
======

> Loading 
> /tmp/org-capture-mode-hook-example/straight-bootstrap-snippet.el 
> (source)...
> Clipboard pasted as level 1 subtree
> #<buffer CAPTURE-test.org> narrowed?: t

Environment
===========

- emacs version: GNU Emacs 29.0.50 (build 1, x86_64-pc-linux-gnu, 
  GTK+ Version 3.24.31, cairo version 1.17.4)
 of 2022-01-13
- system type: gnu/linux

Packages
========

- doct 
  https://github.com/progfolio/doct/commit/9ed9b8c7f7e2ea2d2fb739d65ae4626a1cf16b9f

[1] https://www.github.com/progfolio/yodel

> +
> +        (run-hooks 'org-capture-before-view-hook)
> +        (if-let ((bvh (org-capture-get :before-view-hook)))
> +            (funcall bvh))

This pattern implies that functions added via template keywords 
will be run after the equivalent global hooks. That should be 
documented. This pattern could be improved by let-binding each 
hook and adding the templates functions. e.g.

>(let ((org-capture-mode-hook
>       (append org-capture-mode-hook (org-capture-get :hook t))))
>  (run-hooks 'org-capture-mode-hook))

Note the use of the non-nil LOCAL argument in org-capture-get.
You want to ensure you're accessing the correct plist in the case 
of overlapping capture processes.
 
>    ;; FIXME: This does not do the right thing, we need to remove 
>    the
>    ;; new stuff by hand it is easy: undo, then kill the buffer
> -  (let ((org-note-abort t)
> -	(org-capture-before-finalize-hook nil))
> +  (let ((org-note-abort t))
>      (org-capture-finalize)))
>  
>  (defun org-capture-goto-last-stored ()

Why was org-capture-before-finalize-hook bound to nil here and 
what is the reason for changing that?




^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] lisp/org-capture.el: Add hook & hook options to org-capture (Valentin Herrmann)
  2022-02-08 19:02 ` [PATCH] lisp/org-capture.el: Add hook & hook options to org-capture (Valentin Herrmann) No Wayman
@ 2022-02-09  4:10   ` Ihor Radchenko
  2022-02-09  7:11     ` No Wayman
  2022-02-10 19:32   ` Greg Minshall
  1 sibling, 1 reply; 15+ messages in thread
From: Ihor Radchenko @ 2022-02-09  4:10 UTC (permalink / raw)
  To: No Wayman; +Cc: emacs-orgmode-request, emacs-orgmode

No Wayman <iarchivedmywholelife@gmail.com> writes:

> I've implemented what you're proposing here (and much more) in a 
> package you may find useful a couple years ago. I pitched adopting 
> some of the ideas into org-mode proper and was willing to do the 
> work. My proposal was met with enthusiastic silence:
>
> https://www.github.com/progfolio/doct

I think Nicolas gave some reasonable comments, didn't he? He suggested
to incorporate some of the ideas into the existing Org mode code.

https://orgmode.org/list/87wo66t8i7.fsf@gmail.com

Best,
Ihor


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] lisp/org-capture.el: Add hook & hook options to org-capture (Valentin Herrmann)
  2022-02-09  4:10   ` Ihor Radchenko
@ 2022-02-09  7:11     ` No Wayman
  2022-03-20 10:43       ` Ihor Radchenko
  0 siblings, 1 reply; 15+ messages in thread
From: No Wayman @ 2022-02-09  7:11 UTC (permalink / raw)
  To: Ihor Radchenko; +Cc: emacs-orgmode-request, emacs-orgmode


Ihor Radchenko <yantar92@gmail.com> writes:

> No Wayman <iarchivedmywholelife@gmail.com> writes:
>
>> I've implemented what you're proposing here (and much more) in 
>> a 
>> package you may find useful a couple years ago. I pitched 
>> adopting 
>> some of the ideas into org-mode proper and was willing to do 
>> the 
>> work. My proposal was met with enthusiastic silence:
>>
>> https://www.github.com/progfolio/doct
>
> I think Nicolas gave some reasonable comments, didn't he? He 
> suggested
> to incorporate some of the ideas into the existing Org mode 
> code.
>
> https://orgmode.org/list/87wo66t8i7.fsf@gmail.com
>
> Best,
> Ihor

I believe you're referring to:

https://list.orgmode.org/87y2qlgq33.fsf@nicolasgoaziou.fr/

He had some reasonable questions about the design, but said he 
only uses very basic capture templates, and could not comment 
beyond that on the design. The hope was that people who use more 
of org-capture's features would chime in. That didn't happen.

Of course doct's features could be added to org-capture in a 
piecemeal fashion, but I'm not too keen on contributing anything 
non-trivial to Org these days. Too much back and forth coupled 
with discussion that can stall due to lack of interest. 
e.g.

https://list.orgmode.org/87h7e6dluc.fsf@gmail.com/
https://list.orgmode.org/87tuit73ij.fsf@gmail.com/





^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Lazy load of org-protocol
  2022-02-07 19:06         ` Jim Porter
@ 2022-02-09 16:46           ` Max Nikulin
  2022-02-09 19:22             ` Jim Porter
  0 siblings, 1 reply; 15+ messages in thread
From: Max Nikulin @ 2022-02-09 16:46 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 3869 bytes --]

On 08/02/2022 17:44, Tianshu Wang wrote:
> Max Nikulin writes:
> 
>> Thank you, such approach, unlike mine example, does not have code 
>> duplication. On the other hand it loads org-protocol on any remote 
>> command, not only for "files" representing org-protocol URIs.
>> Maybe defadvice in org-protocol.el should be changed by newer
>> advice-add with a function containing body of the old advice.
> 
> Yes, I replaced the original code with advice-add (not fully tested).

Sorry, I was not clear enough. I meant a patch similar to the attached 
one. It is not tested for greedy subprotocols. It allows to check 
arguments to decide if it is necessary to load org-protocol:

(defun org-protocol-lazy-load (args)
   (if (or (featurep 'org-protocol)
	  (not (delq nil
		     (mapcar (lambda (loc)
			       ;; loc: (file-name . (line . column))
			       (string-match-p "\\(?:^\\|[/\\\\]\\)org-protocol:" (car loc)))
			     (car args)))))
       args
     (require 'org-protocol)
     (org-protocol-detect-protocol-server args)))

(server-start)

(advice-add 'server-visit-files :filter-args #'org-protocol-lazy-load)


On 08/02/2022 02:06, Jim Porter wrote:
> On 2/7/2022 6:57 AM, Max Nikulin wrote:
>>> Maybe another option would be to add an --apply argument that really 
>>> *does* consume the other command-line args and turns them into a 
>>> properly-quoted function call. Roughly speaking, it would turn this:
>>>
>>>    emacs --apply func foo bar baz
>>>
>>> into this:
>>>
>>>    (apply #'func '(foo bar baz))
>>
>> You have almost managed to sell this idea to me. However even --apply 
>> is just sugar for
>>
>>      emacsclient --eval "(apply #'func command-line-args-left)" --arg 1 2
>>
>> So it is --apply option that may require to write a dedicated function 
>> if --arg is not implemented. Another limitation of --apply is that the 
>> function must accept string arguments only, no lists or even integers 
>> or boolean.
> 
> Yeah, `--arg' does have greater flexibility in that regard, but it comes 
> at the cost of verbosity and some slight behavioral differences with the 
> equivalent in the main emacs executable. For emacs itself, any elements 
> of `command-line-args-left' that aren't consumed by a function will get 
> opened as files, but I don't think that would be the case with 
> emacsclient. Does this difference matter? Probably not. However, 
> avoiding `command-line-args-left' just feels intuitively "cleaner" to 
> me. Still, I think `--arg' should work and be backwards-compatible, so I 
> don't mind it, even if I prefer the simplicity of `--apply'.

It is not a problem to implement --apply in addition to --arg. It may 
just mean
     --eval '(apply-from-command-line-args-left)'

     emacs --batch -l apply-from-command-line-args-left.el \
         --eval '(apply-from-command-line-args-left)' \
         message 'test %S, %S' Hello 'World!'

(defun apply-from-command-line-args-left ()
   (let* ((name (car command-line-args-left))
	 (func (symbol-function (intern name))))
     (if func
       (apply func (cdr command-line-args-left))
      (error (format "Symbol's function definition is void: %s" name)))))

OK, I forgot to set the variable to nil.

> On a related note, there is still an issue with `--eval' in some cases. 
> It fails to work with emacsclient when invoking an alternate editor:
> 
>    emacsclient --alternate-editor emacs --eval '(message "hi")'
> 
> If Emacs isn't already running, that will open a new buffer named 
> '(message "hi")'. I think that's just a bug in how emacsclient handles 
> `--eval', though fixing it would make org-protocol links work more 
> reliably (if they used `--eval' as proposed, that is).

     emacsclient --alternate-editor '' --eval '(message "hi")'

But it makes it harder to use it during debugging when -Q -L 
~/src/org-mode/lisp options are required.

[-- Attachment #2: 0001-org-protocol.el-New-style-advice.patch --]
[-- Type: text/x-patch, Size: 2217 bytes --]

From 8a4f8db239d004513be35249ed71e222381b0162 Mon Sep 17 00:00:00 2001
From: Max Nikulin <manikulin@gmail.com>
Date: Wed, 9 Feb 2022 23:25:28 +0700
Subject: [PATCH] org-protocol.el: New-style advice

lisp/org-protocol.el (org-protocol-detect-protocol-server): Use
`advice-add' instead of deprecated `defadvice'.

Advice as a function allows to call it from another similar advice
loading `org-protocol' on demand.
---
 lisp/org-protocol.el | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/lisp/org-protocol.el b/lisp/org-protocol.el
index 7c4de03bc..fb41e3c0f 100644
--- a/lisp/org-protocol.el
+++ b/lisp/org-protocol.el
@@ -687,25 +687,29 @@ to deal with new-style links.")
                     (throw 'fname t))))))))
       fname)))
 
-(defadvice server-visit-files (before org-protocol-detect-protocol-server activate)
+(defun org-protocol-detect-protocol-server (args)
   "Advice server-visit-flist to call `org-protocol-modify-filename-for-protocol'."
-  (let ((flist (if org-protocol-reverse-list-of-files
-                   (reverse  (ad-get-arg 0))
-                 (ad-get-arg 0)))
-        (client (ad-get-arg 1)))
+  (let* ((files (nth 0 args))
+         (client (nth 1 args))
+         (flist (if org-protocol-reverse-list-of-files
+                    (reverse files)
+                  files)))
     (catch 'greedy
       (dolist (var flist)
 	;; `\' to `/' on windows.  FIXME: could this be done any better?
         (let ((fname  (expand-file-name (car var))))
           (setq fname (org-protocol-check-filename-for-protocol
-		       fname (member var flist)  client))
+		       fname (member var flist) client))
           (if (eq fname t) ;; greedy? We need the t return value.
               (progn
-                (ad-set-arg 0 nil)
+                (setcar args nil)
                 (throw 'greedy t))
             (if (stringp fname) ;; probably filename
                 (setcar var fname)
-              (ad-set-arg 0 (delq var (ad-get-arg 0))))))))))
+              (setcar args (delq var files))))))))
+  args)
+
+(advice-add 'server-visit-files :filter-args #'org-protocol-detect-protocol-server)
 
 ;;; Org specific functions:
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: Lazy load of org-protocol
  2022-02-09 16:46           ` Max Nikulin
@ 2022-02-09 19:22             ` Jim Porter
  2022-02-10 14:44               ` Max Nikulin
  0 siblings, 1 reply; 15+ messages in thread
From: Jim Porter @ 2022-02-09 19:22 UTC (permalink / raw)
  To: emacs-orgmode

On 2/9/2022 8:46 AM, Max Nikulin wrote:
> It is not a problem to implement --apply in addition to --arg.
[snip]

For the purposes of this issue, I think either solution would probably 
work. It probably depends on what people think on emacs-devel.

>> On a related note, there is still an issue with `--eval' in some 
>> cases. It fails to work with emacsclient when invoking an alternate 
>> editor:
>>
>>    emacsclient --alternate-editor emacs --eval '(message "hi")'
>>
>> If Emacs isn't already running, that will open a new buffer named 
>> '(message "hi")'. I think that's just a bug in how emacsclient handles 
>> `--eval', though fixing it would make org-protocol links work more 
>> reliably (if they used `--eval' as proposed, that is).
> 
>      emacsclient --alternate-editor '' --eval '(message "hi")'
> 
> But it makes it harder to use it during debugging when -Q -L 
> ~/src/org-mode/lisp options are required.

Right, invoking the main Emacs instance as a daemon (i.e. when 
--alternate-editor is the empty string) works pretty differently from 
invoking the main Emacs instance directly (i.e. when --alternate-editor 
is "emacs" or somesuch). In the former case, emacsclient starts "emacs 
--daemon" and then tries to reconnect to the daemon; in the latter, it 
just takes the arguments passed to emacsclient and forwards them (well, 
some of them) to emacs. The end result is that it runs "emacs '(message 
"hi")'", which isn't correct.

It'd be nice to fix the behavior of "--alternate-editor emacs" so it 
passes the --eval flag along too. This might be tricky though, since the 
semantics of --eval aren't quite the same for emacs and emacsclient. For 
emacs, --eval means that just the next argument is Lisp code; for 
emacsclient, --eval means that *all* subsequent (positional) arguments 
are Lisp code.

In practice though, I don't think fixing this is actually *required* to 
fix the issue of how org-protocol is handled. It only causes issues for 
the subset of people who use "--alternate-editor emacs" or something 
similar.

- Jim


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Lazy load of org-protocol
  2022-02-09 19:22             ` Jim Porter
@ 2022-02-10 14:44               ` Max Nikulin
  0 siblings, 0 replies; 15+ messages in thread
From: Max Nikulin @ 2022-02-10 14:44 UTC (permalink / raw)
  To: emacs-orgmode

On 10/02/2022 02:22, Jim Porter wrote:
> On 2/9/2022 8:46 AM, Max Nikulin wrote:
> 
>>> On a related note, there is still an issue with `--eval' in some 
>>> cases. It fails to work with emacsclient when invoking an alternate 
>>> editor:
>>>
>>>    emacsclient --alternate-editor emacs --eval '(message "hi")'
>>>
>>> If Emacs isn't already running, that will open a new buffer named 
>>> '(message "hi")'. I think that's just a bug in how emacsclient 
>>> handles `--eval', though fixing it would make org-protocol links work 
>>> more reliably (if they used `--eval' as proposed, that is).
>>
>>      emacsclient --alternate-editor '' --eval '(message "hi")'
>>
>> But it makes it harder to use it during debugging when -Q -L 
>> ~/src/org-mode/lisp options are required.
> 
> Right, invoking the main Emacs instance as a daemon (i.e. when 
> --alternate-editor is the empty string) works pretty differently from 
> invoking the main Emacs instance directly (i.e. when --alternate-editor 
> is "emacs" or somesuch). In the former case, emacsclient starts "emacs 
> --daemon" and then tries to reconnect to the daemon; in the latter, it 
> just takes the arguments passed to emacsclient and forwards them (well, 
> some of them) to emacs. The end result is that it runs "emacs '(message 
> "hi")'", which isn't correct.

It looks like a bug. I believed that other application may be specified 
as --alternate-editor, so --eval arguments should not be passed to it.

Actually I do not like --alternate-editor option at all. It is a single 
string, not an array of executable and options. It allows quotes but 
does not support escaping.

On linux a solution is to start emacs daemon from systemd session as a 
socket-activated application.



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] lisp/org-capture.el: Add hook & hook options to org-capture (Valentin Herrmann)
  2022-02-08 19:02 ` [PATCH] lisp/org-capture.el: Add hook & hook options to org-capture (Valentin Herrmann) No Wayman
  2022-02-09  4:10   ` Ihor Radchenko
@ 2022-02-10 19:32   ` Greg Minshall
  1 sibling, 0 replies; 15+ messages in thread
From: Greg Minshall @ 2022-02-10 19:32 UTC (permalink / raw)
  To: No Wayman; +Cc: emacs-orgmode-request, emacs-orgmode

fwiw...

> I've implemented what you're proposing here (and much more) in a 
> package you may find useful a couple years ago. I pitched adopting 
> some of the ideas into org-mode proper and was willing to do the 
> work. My proposal was met with enthusiastic silence:
> 
> https://www.github.com/progfolio/doct

i've been using doct for a while, and have been very happy with it.

(thanks for implementing it.)

cheers, Greg


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] lisp/org-capture.el: Add hook & hook options to org-capture (Valentin Herrmann)
  2022-02-09  7:11     ` No Wayman
@ 2022-03-20 10:43       ` Ihor Radchenko
  0 siblings, 0 replies; 15+ messages in thread
From: Ihor Radchenko @ 2022-03-20 10:43 UTC (permalink / raw)
  To: No Wayman; +Cc: emacs-orgmode-request, emacs-orgmode

No Wayman <iarchivedmywholelife@gmail.com> writes:

>> I think Nicolas gave some reasonable comments, didn't he? He 
>> suggested
>> to incorporate some of the ideas into the existing Org mode 
>> code.
>>
>> https://orgmode.org/list/87wo66t8i7.fsf@gmail.com
>
> I believe you're referring to:
>
> https://list.orgmode.org/87y2qlgq33.fsf@nicolasgoaziou.fr/
>
> He had some reasonable questions about the design, but said he 
> only uses very basic capture templates, and could not comment 
> beyond that on the design. The hope was that people who use more 
> of org-capture's features would chime in. That didn't happen.

I just pinged that thread again. Note that I strongly support adding
doct to Org.

> Of course doct's features could be added to org-capture in a 
> piecemeal fashion, but I'm not too keen on contributing anything 
> non-trivial to Org these days. Too much back and forth coupled 
> with discussion that can stall due to lack of interest. 
> e.g.

> https://list.orgmode.org/87h7e6dluc.fsf@gmail.com/
> https://list.orgmode.org/87tuit73ij.fsf@gmail.com/

I cannot comment on the lexical binding thing. I do not really know
lexical binding internals enough to judge what kind of problem that
patch is trying to solve. However, Bastien commented on the second
patch. I do find it useful as well. I think the only problem with that
patch is that it is not listed in updates.orgmode.org and Bastien missed
your last reply.

Best,
Ihor



^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2022-03-20 10:43 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-02-05 11:54 Lazy load of org-protocol Max Nikulin
2022-02-05 18:27 ` Jim Porter
2022-02-06 16:42   ` Max Nikulin
2022-02-06 19:40     ` Jim Porter
2022-02-07 14:57       ` Max Nikulin
2022-02-07 19:06         ` Jim Porter
2022-02-09 16:46           ` Max Nikulin
2022-02-09 19:22             ` Jim Porter
2022-02-10 14:44               ` Max Nikulin
2022-02-08 10:44         ` Emacs-orgmode Digest, Vol 192, Issue 8 Tianshu Wang
     [not found] <mailman.61.1644253327.32758.emacs-orgmode@gnu.org>
2022-02-08 19:02 ` [PATCH] lisp/org-capture.el: Add hook & hook options to org-capture (Valentin Herrmann) No Wayman
2022-02-09  4:10   ` Ihor Radchenko
2022-02-09  7:11     ` No Wayman
2022-03-20 10:43       ` Ihor Radchenko
2022-02-10 19:32   ` Greg Minshall

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.