[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Lazy load of org-protocol

From: Max Nikulin
Subject: Lazy load of org-protocol
Date: Sat, 5 Feb 2022 18:54:37 +0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.5.0


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)))
         (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.
                       (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?

reply via email to

[Prev in Thread] Current Thread [Next in Thread]