From b10b409f4babca6a28cdd88af3fa1149fe55c694 Mon Sep 17 00:00:00 2001 From: jao Date: Sun, 23 Feb 2020 19:01:40 +0000 Subject: signel: query --- net/signel.org | 58 +++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/net/signel.org b/net/signel.org index 7a85397..89c9b16 100644 --- a/net/signel.org +++ b/net/signel.org @@ -27,17 +27,19 @@ and a list of contact names (until i discover how to get them directly from signal-cli): #+begin_src emacs-lisp +(require 'cl-lib) + (defvar signel-cli-user "+44744xxxxxx") -(defvar signel-user-names '(("+447xxxxxxxx" . "john") - ("+346xxxxxxxx" . "anna"))) +(defvar signel-contact-names '(("+447xxxxxxxx" . "john") + ("+346xxxxxxxx" . "anna"))) #+end_src and a simple function to get a contact name given its telephone number: #+begin_src emacs-lisp -(defun signel--source-name (src) - (or (cdr (assoc src signel-contact-names)) src)) +(defun signel--contact-name (src) + (or (alist-get src signel-contact-names nil nil #'string-equal) src)) #+end_src We are also going to need the path for our signal-cli executable @@ -188,33 +190,33 @@ Once the contents of the envelope is extracted, it's trivial (and boring) to get into its components: #+begin_src emacs-lisp -(defun signel--msg-source (msg) (cdr (assoc 'source msg))) +(defun signel--msg-source (msg) (alist-get 'source msg)) (defun signel--msg-data (msg) - (cdr (assoc 'message (cdr (assoc 'dataMessage msg))))) + (alist-get 'message (alist-get 'dataMessage msg))) (defun signel--msg-timestamp (msg) - (if-let (msecs (cdr (assoc 'timestamp msg))) + (if-let (msecs (alist-get 'timestamp msg)) (format-time-string "%H:%M" (/ msecs 1000)) "")) (defun signel--msg-receipt (msg) - (cdr (assoc 'receiptMessage msg))) + (alist-get 'receiptMessage msg)) (defun signel--msg-is-receipt (msg) - (cdr (assoc 'isReceipt msg))) + (alist-get 'isReceipt msg)) (defun signel--msg-receipt-timestamp (msg) - (when-let (msecs (cdr (assoc 'when (signel--msg-receipt msg)))) + (when-let (msecs (alist-get 'when (signel--msg-receipt msg))) (format-time-string "%H:%M" (/ msecs 1000)))) (defun signel--msg-is-delivery (msg) (when-let ((receipt (signel--msg-receipt msg))) - (eq t (cdr (assoc 'isDelivery msg))))) + (alist-get 'isDelivery msg))) (defun signel--msg-is-read (msg) (when-let ((receipt (signel--msg-receipt msg))) - (eq t (cdr (assoc 'isRead msg))))) + (alist-get 'isRead msg))) #+end_src * A process output filter @@ -269,14 +271,15 @@ each /source/, using for that its name: #+begin_src emacs-lisp (defvar-local signel-user nil) -(defun signel--source-buffer (source) - (let* ((name (format "*%s" (signel--source-name source))) +(defun signel--contact-buffer (source) + (let* ((name (format "*%s" (signel--contact-name source))) (buffer (get-buffer name))) (unless buffer (setq buffer (get-buffer-create name)) (with-current-buffer buffer (signel-chat-mode) - (setq-local signel-user source))) + (setq-local signel-user source) + (insert signel-prompt))) buffer)) #+end_src @@ -300,7 +303,7 @@ what ERC does for its erc-mode): (setq-local completion-ignore-case t)) #+end_src -Note how, in ~signel--source-buffer~, we're storing the user identity +Note how, in ~signel--contact-buffer~, we're storing the user identity associated with the buffer (its /source/) in a buffer-local variable named ~signel-user~ that is set /after/ enabling ~signel-chat-mode~: order here matters because the major mode activation cleans up the values of @@ -312,7 +315,7 @@ buffer: #+begin_src emacs-lisp (defun signel--update-chat-buffer (source data stamp rec-stamp msg) - (when-let ((b (signel--source-buffer source))) + (when-let ((b (signel--contact-buffer source))) (with-current-buffer b (goto-char (point-max)) (beginning-of-line) @@ -320,7 +323,7 @@ buffer: (if data (let ((p (point))) (insert "[" stamp "] " - (signel--source-name source) + (signel--contact-name source) signel-prompt data "\n") @@ -329,7 +332,7 @@ buffer: (signel--msg-is-receipt msg))) (is-read (signel--msg-is-read msg))) (when (or rec-stamp stamp) - (insert "[" (or rec-stamp stamp) "] " + (insert "*" (or rec-stamp stamp) "* " (if is-read "(read)" "(delivered)") "\n")))) (insert signel-prompt)) @@ -409,6 +412,23 @@ and we can bind it to the return key in signal chat buffers: (define-key signel-chat-mode-map "\C-m" #'signel-send) #+end_src +And we are going sometimes to want to talk to contacts that don't have +yet said anything and have, therefore, no associated chat buffer: + +#+begin_src emacs-lisp +(defun signel-query (contact) + "Start a conversation with a signal contact." + (interactive (list (completing-read "Signal to: " + (mapcar #'cdr-safe signel-contact-names)))) + (let ((phone (alist-get contact + (cl-pairlis (mapcar #'cdr signel-contact-names) + (mapcar #'car signel-contact-names)) + nil nil #'string-equal))) + (when (not phone) + (error "Unknown contact %s" contact)) + (pop-to-buffer (signel--contact-buffer phone)))) +#+end_src + There are of course lots of rough edges and missing functionality in this incipient signel, but it's already usable and a nice demonstration of how easy it is to get the ball rolling in this lisp -- cgit v1.2.3