(define-command-global org-capture ()
(let* ((url (quri:url-encode (buffer-url)))
(title (quri:url-encode (buffer-title)))
(body (quri:url-encode (%copy)))
(org-protocol-uri
(format nil
"'org-protocol://capture?template=w&url=~a&title=~a&body=~a'"
url title body)))
(format *error-output* "Sending to Emacs:~%~a~%" org-protocol-uri)
(uiop:run-program
(list "timeout" "--signal=9" "5m" "emacsclient"
org-protocol-uri))))
;; For most users, (list "emacsclient" org-protocol-uri) may be adequate.
;; Helper functions
(defun buffer-url ()
"Returns the URL of the current buffer."
(quri:render-uri (url (current-buffer))))
(defun buffer-title ()
"Returns the title of the current buffer."
(title (current-buffer)))
I had a similar idea myself the other day. I actually wrote something very similar if only I had known earlier you had done all the dirty work haha. My version is pretty similar but offers storing links as well as opening org-capture. As well as a nice prompt interface in case you wanna access more than one template.
(defun get-org-templates ()
(read-from-string (uiop:run-program
(list "timeout" "--signal=9" "5m" "emacsclient" "--eval"
"org-capture-templates")
:output :string)))
(defun template-description (template)
(make-instance 'prompter:suggestion
:value (first template)
:attributes `(("Key" ,(first template))
("Description" ,(second template))
("Template" ,(car (last template))))))
(defun make-org-template-source ()
"Create a prompt source based on the currently running emacs's
org-templates"
(make-instance 'prompter:source
:name "Emacs Capture Templates"
:constructor (mapcar #'template-description
;; Ensure that we are not listing prefix keys
;; e.g. m in the me
(remove-if-not #'cddr (get-org-templates)))))
(define-command-global org-capture (&optional (buffer (nyxt:current-buffer)))
"Call org-protocol whith the type of capture using the BUFFER for
context."
(org-protocol "capture" buffer))
(define-command-global org-protocol
(&optional (protocol "store-link") (buffer (nyxt:current-buffer)))
"Using the supported org-protocol type PROTOCOL execute it against the
given BUFFER's current url."
(let ((url (render-url (nyxt:url buffer)))
(title (title buffer))
(body (quri:url-encode (%copy)))
(protocol-str (format nil "org-protocol://~a?" protocol))
(capture-template (when (equal protocol "capture")
(format nil "template=~a&"
(first (prompt :prompt "Select a capture template"
:sources (list (make-org-template-source))))))))
(uiop:launch-program (list "emacsclient"
;; nyxt:*open-program* would also be an alternative
(str:concat
protocol-str
capture-template
(format nil "url=~a&title=~a&body=~a"
url title body))))))
Stole the idea of using timeout which I had never even thought of
It’s actually a little better than this gif shows since it removes the blank templates now.
Hi.
I am trying to get org-capture working with Nyxt. USing your code I am getting an error that NYXT-USER::%COPY is undefined. Is this code working for you?
Sorry, I stopped using Nyxt years ago.
OK. Thanks for the reply. Appreciate it. Maybe I can take your code and run with it if that's OK.
Of course. Good luck.