mirror of
https://github.com/SqrtMinusOne/dotfiles.git
synced 2025-12-10 11:13:04 +03:00
feat(emacs): more org-ql, restclient and telega chats with topics
This commit is contained in:
parent
30abb53403
commit
b2aba41920
3 changed files with 225 additions and 5 deletions
1
.config/cron/truncate.guile
Normal file
1
.config/cron/truncate.guile
Normal file
|
|
@ -0,0 +1 @@
|
|||
(job "0 * * * * " "truncate -s /home/pavel/.local/state/shepherd/shepherd.log")
|
||||
108
.emacs.d/init.el
108
.emacs.d/init.el
|
|
@ -2911,7 +2911,19 @@ Returns (<buffer> . <workspace-index>) or nil."
|
|||
|
||||
(use-package restclient
|
||||
:if (not my/remote-server)
|
||||
:straight t)
|
||||
:straight t
|
||||
:config
|
||||
(general-define-key
|
||||
:keymaps 'restclient-mode-map
|
||||
:states '(normal visual)
|
||||
"RET" #'restclient-http-send-current
|
||||
"M-RET" #'restclient-http-send-current-stay-in-window
|
||||
"y" nil
|
||||
"M-y" #'restclient-copy-curl-command)
|
||||
(general-define-key
|
||||
:keymaps 'restclient-response-mode-map
|
||||
:states '(normal visual)
|
||||
"q" #'quit-window))
|
||||
|
||||
(use-package ob-restclient
|
||||
:after (org restclient)
|
||||
|
|
@ -3516,6 +3528,50 @@ and lots of comments which are too long for my Emacs config."
|
|||
(with-eval-after-load 'org-ql
|
||||
(advice-add #'org-ql-view--format-element :override #'my/org-ql-view--format-element-override))
|
||||
|
||||
(defun my/org-ql--get-clock-data-parse-buffer ()
|
||||
(let (res)
|
||||
(org-element-map (org-element-parse-buffer) 'clock
|
||||
(lambda (clock)
|
||||
(let ((start (time-convert
|
||||
(org-timestamp-to-time (org-element-property :value clock))
|
||||
'integer))
|
||||
(end (time-convert
|
||||
(org-timestamp-to-time (org-element-property :value clock) t)
|
||||
'integer)))
|
||||
(save-excursion
|
||||
(org-back-to-heading t)
|
||||
(let* ((headline (org-element-at-point-no-context))
|
||||
(tags-val (org-ql--tags-at (point)))
|
||||
(tags (seq-filter
|
||||
#'stringp ;; to filter out `org-ql-nil'
|
||||
(append (unless (eq (car tags-val) 'org-ql-nil)
|
||||
(car tags-val))
|
||||
(unless (eq (cdr tags-val) 'org-ql-nil)
|
||||
(cdr tags-val)))))
|
||||
(filename (f-filename
|
||||
(buffer-file-name)))
|
||||
(outline-path (mapcar
|
||||
#'substring-no-properties
|
||||
(org-ql--outline-path)))
|
||||
(category (org-get-category)))
|
||||
(push
|
||||
`((:start . ,start)
|
||||
(:end . ,end)
|
||||
(:headline . ,headline)
|
||||
(:tags . ,tags)
|
||||
(:filename . ,filename)
|
||||
(:outline-path . ,outline-path)
|
||||
(:category . ,category))
|
||||
res))))))
|
||||
res))
|
||||
|
||||
(defun my/org-ql--get-clock-data ()
|
||||
(let (res)
|
||||
(dolist (file (org-agenda-files))
|
||||
(with-current-buffer (find-file-noselect file)
|
||||
(setq res (append res (my/org-ql--get-clock-data-parse-buffer)))))
|
||||
res))
|
||||
|
||||
(defun my/alist-agg (path alist value)
|
||||
"Traverse ALIST by PATH, adding VALUE to each node.
|
||||
|
||||
|
|
@ -3732,6 +3788,12 @@ VALUE is a number."
|
|||
(org-element-at-point)))))
|
||||
(my/org-ql-meeting-tasks meeting)))
|
||||
|
||||
(with-eval-after-load 'org-agenda
|
||||
(general-define-key
|
||||
:keymaps 'org-agenda-mode-map
|
||||
:states '(normal motion)
|
||||
"gm" #'my/org-ql-meeting-tasks-agenda))
|
||||
|
||||
(use-package org-habit-stats
|
||||
:straight (:host github :repo "ml729/org-habit-stats")
|
||||
:after (org)
|
||||
|
|
@ -7056,6 +7118,44 @@ base toot."
|
|||
|
||||
(setq telega-online-status-function #'my/telega-online-status)
|
||||
|
||||
(defun my/telega-switch-to-topic ()
|
||||
(interactive)
|
||||
(let* ((topics-data (gethash
|
||||
(plist-get telega-chatbuf--chat :id)
|
||||
telega--chat-topics))
|
||||
(topics-string
|
||||
(mapcar
|
||||
(lambda (topic)
|
||||
(let* ((name (plist-get (plist-get topic :info) :name))
|
||||
(unread-count (plist-get topic :unread_count))
|
||||
(name-string (with-temp-buffer
|
||||
(telega-ins--topic-title topic 'with-icon)
|
||||
(buffer-string))))
|
||||
(if (zerop unread-count)
|
||||
name-string
|
||||
(format "%-40s (%s)"
|
||||
name-string
|
||||
(propertize (format "%d" unread-count)
|
||||
'face 'telega-unread-unmuted-modeline)))))
|
||||
topics-data))
|
||||
(topics-collection (cl-loop for datum in topics-data
|
||||
for string in topics-string
|
||||
collect (cons string datum)))
|
||||
(topic (completing-read "Topic: " topics-collection nil t)))
|
||||
(telega-chat--goto-thread
|
||||
telega-chatbuf--chat
|
||||
(plist-get
|
||||
(plist-get
|
||||
(alist-get topic topics-collection nil nil #'equal)
|
||||
:info)
|
||||
:message_thread_id))))
|
||||
|
||||
(with-eval-after-load 'telega
|
||||
(general-define-key
|
||||
:states '(normal)
|
||||
:keymaps 'telega-chat-mode-map
|
||||
"T" #'my/telega-switch-to-topic))
|
||||
|
||||
(use-package google-translate
|
||||
:straight t
|
||||
:if (not my/remote-server)
|
||||
|
|
@ -7320,6 +7420,9 @@ base toot."
|
|||
(defun my/elcord-update-presence-mask-advice (r)
|
||||
(list (my/elcord-mask-buffer-name (nth 0 r)) (nth 1 r)))
|
||||
|
||||
(defun my/elcord-symlink ()
|
||||
(shell-command-to-string "bash -c 'ln -sf {app/com.discordapp.Discord,$XDG_RUNTIME_DIR}/discord-ipc-0 &'"))
|
||||
|
||||
(use-package elcord
|
||||
:straight t
|
||||
:if (and (or
|
||||
|
|
@ -7333,7 +7436,8 @@ base toot."
|
|||
(advice-add 'elcord--try-update-presence :filter-args #'my/elcord-update-presence-mask-advice)
|
||||
(add-to-list 'elcord-mode-text-alist '(telega-chat-mode . "Telega Chat"))
|
||||
(add-to-list 'elcord-mode-text-alist '(telega-root-mode . "Telega Root"))
|
||||
(elcord-mode))
|
||||
(elcord-mode)
|
||||
(my/elcord-symlink))
|
||||
|
||||
(use-package snow
|
||||
:straight (:repo "alphapapa/snow.el" :host github)
|
||||
|
|
|
|||
121
Emacs.org
121
Emacs.org
|
|
@ -4050,7 +4050,19 @@ References:
|
|||
#+begin_src emacs-lisp
|
||||
(use-package restclient
|
||||
:if (not my/remote-server)
|
||||
:straight t)
|
||||
:straight t
|
||||
:config
|
||||
(general-define-key
|
||||
:keymaps 'restclient-mode-map
|
||||
:states '(normal visual)
|
||||
"RET" #'restclient-http-send-current
|
||||
"M-RET" #'restclient-http-send-current-stay-in-window
|
||||
"y" nil
|
||||
"M-y" #'restclient-copy-curl-command)
|
||||
(general-define-key
|
||||
:keymaps 'restclient-response-mode-map
|
||||
:states '(normal visual)
|
||||
"q" #'quit-window))
|
||||
|
||||
(use-package ob-restclient
|
||||
:after (org restclient)
|
||||
|
|
@ -4884,7 +4896,55 @@ and lots of comments which are too long for my Emacs config."
|
|||
**** Aggregate clocked time
|
||||
This turned out to be kinda complicated... I want to produce a report that aggregates my clocked time. Maybe I'll extract the below into a separate package, but it's so tightly bound to my needs so I'm not sure if there's any value in it.
|
||||
|
||||
First, in order to implement the aggregation I need a function to process alists:
|
||||
Work-in-progress.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun my/org-ql--get-clock-data-parse-buffer ()
|
||||
(let (res)
|
||||
(org-element-map (org-element-parse-buffer) 'clock
|
||||
(lambda (clock)
|
||||
(let ((start (time-convert
|
||||
(org-timestamp-to-time (org-element-property :value clock))
|
||||
'integer))
|
||||
(end (time-convert
|
||||
(org-timestamp-to-time (org-element-property :value clock) t)
|
||||
'integer)))
|
||||
(save-excursion
|
||||
(org-back-to-heading t)
|
||||
(let* ((headline (org-element-at-point-no-context))
|
||||
(tags-val (org-ql--tags-at (point)))
|
||||
(tags (seq-filter
|
||||
#'stringp ;; to filter out `org-ql-nil'
|
||||
(append (unless (eq (car tags-val) 'org-ql-nil)
|
||||
(car tags-val))
|
||||
(unless (eq (cdr tags-val) 'org-ql-nil)
|
||||
(cdr tags-val)))))
|
||||
(filename (f-filename
|
||||
(buffer-file-name)))
|
||||
(outline-path (mapcar
|
||||
#'substring-no-properties
|
||||
(org-ql--outline-path)))
|
||||
(category (org-get-category)))
|
||||
(push
|
||||
`((:start . ,start)
|
||||
(:end . ,end)
|
||||
(:headline . ,headline)
|
||||
(:tags . ,tags)
|
||||
(:filename . ,filename)
|
||||
(:outline-path . ,outline-path)
|
||||
(:category . ,category))
|
||||
res))))))
|
||||
res))
|
||||
|
||||
(defun my/org-ql--get-clock-data ()
|
||||
(let (res)
|
||||
(dolist (file (org-agenda-files))
|
||||
(with-current-buffer (find-file-noselect file)
|
||||
(setq res (append res (my/org-ql--get-clock-data-parse-buffer)))))
|
||||
res))
|
||||
#+end_src
|
||||
|
||||
A function to aggregate on alists:
|
||||
#+begin_src emacs-lisp
|
||||
(defun my/alist-agg (path alist value)
|
||||
"Traverse ALIST by PATH, adding VALUE to each node.
|
||||
|
|
@ -5136,6 +5196,12 @@ I'll probably delete the below.
|
|||
(org-ql--add-markers
|
||||
(org-element-at-point)))))
|
||||
(my/org-ql-meeting-tasks meeting)))
|
||||
|
||||
(with-eval-after-load 'org-agenda
|
||||
(general-define-key
|
||||
:keymaps 'org-agenda-mode-map
|
||||
:states '(normal motion)
|
||||
"gm" #'my/org-ql-meeting-tasks-agenda))
|
||||
#+end_src
|
||||
**** Tracking habits
|
||||
Let's see how this goes.
|
||||
|
|
@ -9692,6 +9758,48 @@ And custom online status. By default it marks you online when the Emacs frame is
|
|||
|
||||
(setq telega-online-status-function #'my/telega-online-status)
|
||||
#+end_src
|
||||
|
||||
Switch to topic in forum chats.
|
||||
#+begin_src emacs-lisp
|
||||
(defun my/telega-switch-to-topic ()
|
||||
(interactive)
|
||||
(let* ((topics-data (gethash
|
||||
(plist-get telega-chatbuf--chat :id)
|
||||
telega--chat-topics))
|
||||
(topics-string
|
||||
(mapcar
|
||||
(lambda (topic)
|
||||
(let* ((name (plist-get (plist-get topic :info) :name))
|
||||
(unread-count (plist-get topic :unread_count))
|
||||
(name-string (with-temp-buffer
|
||||
(telega-ins--topic-title topic 'with-icon)
|
||||
(buffer-string))))
|
||||
(if (zerop unread-count)
|
||||
name-string
|
||||
(format "%-40s (%s)"
|
||||
name-string
|
||||
(propertize (format "%d" unread-count)
|
||||
'face 'telega-unread-unmuted-modeline)))))
|
||||
topics-data))
|
||||
(topics-collection (cl-loop for datum in topics-data
|
||||
for string in topics-string
|
||||
collect (cons string datum)))
|
||||
(topic (completing-read "Topic: " topics-collection nil t)))
|
||||
(telega-chat--goto-thread
|
||||
telega-chatbuf--chat
|
||||
(plist-get
|
||||
(plist-get
|
||||
(alist-get topic topics-collection nil nil #'equal)
|
||||
:info)
|
||||
:message_thread_id))))
|
||||
|
||||
(with-eval-after-load 'telega
|
||||
(general-define-key
|
||||
:states '(normal)
|
||||
:keymaps 'telega-chat-mode-map
|
||||
"T" #'my/telega-switch-to-topic))
|
||||
#+end_src
|
||||
|
||||
*** Google Translate
|
||||
Emacs interface to Google Translate.
|
||||
|
||||
|
|
@ -10067,6 +10175,12 @@ Some functions to override the displayed message:
|
|||
(list (my/elcord-mask-buffer-name (nth 0 r)) (nth 1 r)))
|
||||
#+end_src
|
||||
|
||||
Create a symlink for flatpak:
|
||||
#+begin_src emacs-lisp
|
||||
(defun my/elcord-symlink ()
|
||||
(shell-command-to-string "bash -c 'ln -sf {app/com.discordapp.Discord,$XDG_RUNTIME_DIR}/discord-ipc-0 &'"))
|
||||
#+end_src
|
||||
|
||||
And the package configuration:
|
||||
#+begin_src emacs-lisp
|
||||
(use-package elcord
|
||||
|
|
@ -10082,7 +10196,8 @@ And the package configuration:
|
|||
(advice-add 'elcord--try-update-presence :filter-args #'my/elcord-update-presence-mask-advice)
|
||||
(add-to-list 'elcord-mode-text-alist '(telega-chat-mode . "Telega Chat"))
|
||||
(add-to-list 'elcord-mode-text-alist '(telega-root-mode . "Telega Root"))
|
||||
(elcord-mode))
|
||||
(elcord-mode)
|
||||
(my/elcord-symlink))
|
||||
#+end_src
|
||||
*** Snow
|
||||
#+begin_src emacs-lisp
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue