diff options
| -rw-r--r-- | attic/org/blog.org | 254 | ||||
| -rw-r--r-- | attic/org/completion.org | 657 | ||||
| -rw-r--r-- | attic/org/counsel.org | 337 | ||||
| -rw-r--r-- | attic/org/email.org | 391 | ||||
| -rw-r--r-- | attic/org/eww.org | 191 | ||||
| -rw-r--r-- | attic/org/exwm.org | 551 | ||||
| -rw-r--r-- | attic/org/gnus.org | 780 | ||||
| -rw-r--r-- | attic/org/init.org | 3427 | ||||
| -rw-r--r-- | attic/org/misc.org | 247 | ||||
| -rw-r--r-- | attic/org/notmuch.org | 675 | ||||
| -rw-r--r-- | attic/org/org.org | 316 | ||||
| -rw-r--r-- | attic/org/w3m.org | 191 | 
12 files changed, 0 insertions, 8017 deletions
| diff --git a/attic/org/blog.org b/attic/org/blog.org deleted file mode 100644 index 29b35f0..0000000 --- a/attic/org/blog.org +++ /dev/null @@ -1,254 +0,0 @@ -#+title: Org static blog -#+property: header-args lexical: t :tangle yes :comments yes :results silent :shebang ";; -*- lexical-binding: t -*-"  :tangle-mode (identity #o644) -#+auto_tangle: t - -* Vars and setup -  #+begin_src emacs-lisp -    (jao-load-path "org-static-blog") -    (when (> emacs-major-version 26) (use-package htmlize :ensure t)) -    (defvar jao-blog-base-dir "~/doc/jao.io") -    (defun jao-blog-dir (p) (expand-file-name p jao-blog-base-dir)) - -    (setq jao-org-blog-tag-files -          (seq-difference (directory-files (jao-blog-dir "blog") nil "tag-.*") -                          "tag-norss.html") - -          jao-org-blog-tags -          (mapcar (lambda (f) -                    (string-match "tag-\\(.+\\)\\.html" f) -                    (format "<a href=\"/blog/%s\">%s</a>" -                            f (match-string 1 f))) -                  jao-org-blog-tag-files) - -          jao-org-blog-tag-rss -          (mapcar (lambda (f) -                    (string-match "\\(.+\\)-rss\\.xml" f) -                    (format "<a href=\"/blog/%s\">%s</a>" -                            f (match-string 1 f))) -                  (directory-files (jao-blog-dir "blog") nil ".*-rss.xml")) - -          jao-org-blog-tag-names -          (mapcar (lambda (f) -                    (string-match "tag-\\(.+\\)\\.html" f) -                    (match-string 1 f)) -                  jao-org-blog-tag-files)) -  #+end_src -* HTML headers and footers -*** Header -    #+begin_src emacs-lisp -      (setq org-static-blog-page-header -            (concat -             "<meta name=\"author\" content=\"jao\">\n" -             "<meta name=\"referrer\" content=\"no-referrer\">\n" -             "<link rel=\"stylesheet\" href=\"/static/style.css\"" -             "  type=\"text/css\">\n" -             "<link rel=\"apple-touch-icon\" sizes=\"180x180\"" -             "  href=\"/static/apple-touch-icon.png\" >\n" -             "<link rel=\"icon\" type=\"image/png\"" -             "  sizes=\"32x32\" href=\"/static/favicon-32x32.png\">\n" -             "<link rel=\"icon\" type=\"image/png\"" -             "  sizes=\"16x16\" href=\"/static/favicon-16x16.png\">\n" -             "<link rel=\"icon\" href=\"/static/favicon.ico\">\n" -             "<link rel=\"manifest\" href=\"/static/site.webmanifest\">\n") - -            org-static-blog-page-preamble -            (concat -             "<div class=\"header\">" -             "  <a href=\"https://jao.io\">programming (and other) musings</a>" -             "  <div class=\"sitelinks\">" -             "    <a href=\"/blog/about.html\">about</a>" -             "    | <a href=\"/blog/hacking.html\">hacking</a>" -             "    | <a href=\"/blog/archive.html\">archive</a>" -             "    | <div class=\"dropdown\">" -             "       <a href=\"/blog/tags.html\" class=\"dropbtn\">tags</a>" -             "       <div class=\"dropdown-content\">" -             (mapconcat #'identity jao-org-blog-tags "") -             "       </div>" -             "      </div>" -             "    | <div class=\"dropdown\">" -             "       <a href=\"/blog/rss.xml\" class=\"dropbtn\">rss</a>" -             "       <div class=\"dropdown-content\">" -             (mapconcat #'identity jao-org-blog-tag-rss "") -             "       </div>" -             "      </div>" -             "  </div>" -             "</div>")) -    #+end_src -*** Footer -      #+begin_src html :tangle ~/.emacs.d/commons.html :comments no :shebang "" -      <center> -        <a rel="license" href="https://creativecommons.org/licenses/by-sa/3.0/"> -        <img alt="Creative Commons License" style="border-width:0" -             src="https://i.creativecommons.org/l/by-sa/3.0/88x31.png" /> -        </a> -        <br /> -        <span xmlns:dct="https://purl.org/dc/terms/" -              href="https://purl.org/dc/dcmitype/Text" property="dct:title" -              rel="dct:type">jao.io</span> by -        <a xmlns:cc="https://creativecommons.org/ns#" href="https://jao.io" -           property="cc:attributionName" rel="cc:attributionURL">jao</a> -        is licensed under a -        <a rel="license" href="https://creativecommons.org/licenses/by-sa/3.0/"> -          Creative Commons Attribution-ShareAlike 3.0 Unported License</a>. -      </center> -      #+end_src - -      #+begin_src emacs-lisp -        (setq org-static-blog-page-postamble -              (with-temp-buffer -                (insert-file-contents "~/.emacs.d/commons.html") -                (buffer-string))) -      #+end_src -* Package -  #+begin_src emacs-lisp -    (use-package org-static-blog -      :ensure t -      :init -      (setq org-static-blog-use-preview t -            org-static-blog-preview-link-p t -            org-static-blog-preview-start "<!-- preview-start -->" -            org-static-blog-preview-end "<!-- preview-end -->" -            org-static-blog-preview-date-first-p t -            org-static-blog-index-length 30 -            org-static-blog-preview-convert-titles t -            org-static-blog-preview-ellipsis "more ..." -            org-static-blog-enable-tags t -            org-static-blog-tags-file "tags.html" -            org-static-blog-rss-file "rss.xml" -            org-static-blog-publish-url "https://jao.io/blog/" -            org-static-blog-publish-title "programming (and other) musings" -            org-static-blog-posts-directory (jao-blog-dir "posts/") -            org-static-blog-drafts-directory (jao-blog-dir "pages/") -            org-static-blog-publish-directory (jao-blog-dir "blog/") -            org-static-blog-rss-extra "" ; "<author>mail@jao.io</author>\n" -            org-static-blog-rss-max-entries 30 -            org-static-blog-rss-excluded-tag "norss" -            org-static-blog-enable-tag-rss t -            org-export-with-toc nil -            org-export-with-section-numbers nil) - -      :config -      (defun jao-org-static-post-path (pf dt) -        (cond ((string-match-p "pages/.*\\|in-no-particular-order" pf) -               (file-name-nondirectory pf)) -              ((string-match-p "drafts/.*" pf) pf) -              ((string-match-p "^[[:digit:]]+-.*" pf) pf) -              (t (concat (format-time-string "%Y-%m-%d-" dt) -                         (file-name-nondirectory pf))))) -      (advice-add 'org-static-blog-generate-post-path :override -                  #'jao-org-static-post-path) - -      :bind (:map org-mode-map (("C-c B" . jao-transient-org-blog)))) -   #+end_src -* Commands -*** New entries -    #+begin_src emacs-lisp -      (defun jao-org-blog-publish-file (fname) -        (interactive (list (read-file-name "Publish: " -                                           nil -                                           (buffer-file-name) -                                           t -                                           (buffer-file-name)))) -        (let ((geiser-active-implementations '(guile)) -              (geiser-default-implementation 'guile)) -          (org-static-blog-publish-file fname))) - -      (defconst jao-org-static-blog--prev-beg -        "#+begin_export html\n    <!-- preview-start -->\n#+end_export ") - -      (defconst jao-org-static-blog--prev-end -        "#+begin_export html\n    <!-- preview-end -->\n#+end_export ") - -      (defun jao-org-static-blog-create-new-post (&optional draft) -        (interactive) -        (let* ((title (read-string "Title: ")) -               (file (replace-regexp-in-string "\s" "-" (downcase title))) -               (tags (completing-read-multiple "Tags: " jao-org-blog-tag-names))) -          (find-file (expand-file-name (concat file ".org") -                                       (if draft -                                           org-static-blog-drafts-directory -                                         org-static-blog-posts-directory))) -          (insert "#+title: " title "\n" -                  "#+date: " (format-time-string "<%Y-%m-%d %H:%M>") "\n" -                  "#+filetags: " -                  (mapconcat #'identity tags " ") -                  "\n\n") -          (when (member "books" tags) -            (insert jao-org-static-blog--prev-beg -                    "\n\n[[https://jao.io/img/" file ".jpg]]\n\n")) -          (save-excursion (insert jao-org-static-blog--prev-end "\n")))) -    #+end_src -*** Drafts -    #+begin_src emacs-lisp -      (defun jao-org-static-blog-update-date () -        (interactive) -        (when (y-or-n-p "Update date? ") -          (goto-char (point-min)) -          (when (re-search-forward "^#\\+date: " nil t) -            (let ((kill-whole-line nil)) (kill-line)) -            (insert (format-time-string "<%Y-%m-%d %H:%M>")) -            (save-buffer)))) - -      (defun jao-org-static-blog-create-new-draft () -        (interactive) -        (jao-org-static-blog-create-new-post t)) - -      (defun jao-org-static-blog-publish-draft () -        (interactive) -        (let* ((from (read-file-name "Post: " -                                     org-static-blog-drafts-directory -                                     nil t)) -               (to (expand-file-name (file-name-nondirectory from) -                                     org-static-blog-posts-directory))) -          (rename-file from to) -          (when-let ((b (get-buffer from))) -            (kill-buffer b)) -          (find-file to) -          (jao-org-static-blog-update-date) -          (when (y-or-n-p "Generate HTML? ") -            (jao-org-blog-publish)))) - -      (defun jao-org-static-blog-edit-draft () -        (interactive) -        (find-file (read-file-name "Edit: " -                                   org-static-blog-drafts-directory -                                   nil -                                   t))) -    #+end_src -*** Publish -    #+begin_src emacs-lisp -      (defun jao-org-blog-publish (&optional force) -          (interactive "P") -          (let ((geiser-active-implementations '(guile)) -                (geiser-default-implementation 'guile)) -            (org-static-blog-publish force))) - -      (defun jao-org-blog-republish () -        (interactive) -        (jao-org-blog-publish t)) -    #+end_src -* Transient -  #+begin_src emacs-lisp -    (defun jao-org-static-prev-begin () -      (interactive) -      (insert jao-org-static-blog--prev-beg)) - -    (defun jao-org-static-prev-end () -      (interactive) -      (insert jao-org-static-blog--prev-end)) - -    (jao-transient-major-mode+ org -      ["Insert blog snippet" -       ("s" "preview begin" jao-org-static-prev-begin) -       ("S" "preview end" jao-org-static-prev-end) -       ("T" "update date" jao-org-static-blog-update-date)] -      ["Edit blog" -       ("n" "create post" jao-org-static-blog-create-new-post) -       ("d" "create draft" jao-org-static-blog-create-new-draft) -       ("e" "edit draft" jao-org-static-blog-edit-draft)] -      ["Publish blog" -       ("D" "publish draft" jao-org-static-blog-publish-draft) -       ("f" "publish single file" jao-org-blog-publish-file) -       ("p" "publish all" jao-org-blog-publish) -       ("r" "republish" jao-org-blog-republish)]) -  #+end_src diff --git a/attic/org/completion.org b/attic/org/completion.org deleted file mode 100644 index 3a4049a..0000000 --- a/attic/org/completion.org +++ /dev/null @@ -1,657 +0,0 @@ -#+property: header-args :lexical t :tangle yes :comments yes :results silent :shebang ";; -*- lexical-binding: t -*-" :tangle-mode (identity #o644) -#+title: Completion configuration -#+auto_tangle: t - -* imenu -  #+begin_src emacs-lisp -    (use-package imenu -      :init (setq org-imenu-depth 7) -      :config -      (defun jao-imenu-hook () -        (cond ((derived-mode-p 'org-mode) (org-reveal t)) -              (outline-minor-mode (outline-show-entry)))) -      (add-hook 'imenu-after-jump-hook #'jao-imenu-hook)) -  #+end_src -* completion styles -*** completion configuration -  #+begin_src emacs-lisp -    (setq tab-always-indent 'complete -          read-extended-command-predicate #'command-completion-default-include-p -          completion-category-defaults nil -          completion-cycle-threshold nil -          completions-detailed t -          completion-show-help nil -          completion-show-inline-help nil -          completion-ignore-case t -          completion-wrap-movement t -          completion-auto-select nil -          completions-format 'one-column -          completion-styles '(basic substring partial-completion emacs22) -          completion-category-overrides -          '((file (styles partial-completion)) -            (command (styles initials substring partial-completion)) -            (symbol (styles initials substring partial-completion)) -            (variable (styles initials substring partial-completion)))) - -    ;; (setq completions-sort #'jao-completion--sort-by-length-alpha) -    (setq completions-sort #'jao-completion--sort-by-history) - -    (defun jao-completion--sort-by-alpha-length (elems) -      (sort elems (lambda (c1 c2) -                    (or (string-version-lessp c1 c2) -                        (< (length c1) (length c2)))))) - -    (defun jao-completion--sort-by-history (elems) -      (let ((hist (and (not (eq minibuffer-history-variable t)) -                       (symbol-value minibuffer-history-variable)))) -        (if hist -            (minibuffer--sort-by-position hist elems) -          (jao-completion--sort-by-alpha-length elems)))) - -  #+end_src -*** crm indicator -    #+begin_src emacs-lisp -      (defun jao-completion--crm-indicator (args) -        "Add prompt indicator to `completing-read-multiple' filter ARGS." -        (cons (concat "[CRM] " (car args)) (cdr args))) -      (advice-add #'completing-read-multiple -                  :filter-args #'jao-completion--crm-indicator) -    #+end_src -*** directory navigation -    #+begin_src emacs-lisp -      (defun jao-completion-backward-updir () -        "Delete char before point or go up a directory." -        (interactive nil mct-minibuffer-mode) -        (cond ((and (eq (char-before) ?/) -                    (eq (mct--completion-category) 'file)) -               (when (string-equal (minibuffer-contents) "~/") -                 (delete-minibuffer-contents) -                 (insert (expand-file-name "~/")) -                 (goto-char (line-end-position))) -               (save-excursion -                 (goto-char (1- (point))) -                 (when (search-backward "/" (minibuffer-prompt-end) t) -                   (delete-region (1+ (point)) (point-max))))) -              (t (call-interactively 'backward-delete-char)))) - -      (define-key minibuffer-local-filename-completion-map (kbd "DEL") -                  #'jao-completion-backward-updir) -    #+end_src -* orderless -  #+begin_src emacs-lisp -    (use-package orderless -      :ensure t -      :init -      :config -      (orderless-define-completion-style orderless+initialism -        (orderless-matching-styles '(orderless-initialism -                                     orderless-prefixes -                                     orderless-literal -                                     orderless-regexp))) - -      (defun jao-orderless--set-locally () -        (setq-local completion-styles -                    '(substring partial-completion orderless) - -                    completion-category-overrides -                    '((file (styles partial-completion orderless)) -                      (command (styles orderless+initialism))) -                    orderless-matching-styles -                    '(orderless-literal orderless-regexp orderless-prefixes))) -      (add-hook 'minibuffer-setup-hook #'jao-orderless--set-locally)) - -  #+end_src -* marginalia -  #+begin_src emacs-lisp -    (use-package marginalia -      :ensure t -      :bind (:map minibuffer-local-map ("C-M-a" . marginalia-cycle)) - -      :custom ((marginalia-align 'left) -               (marginalia-align-offset 1) -               (marginalia-field-width 200) -               (marginalia-annotators -                '(marginalia-annotators-heavy marginalia-annotators-light nil)) -               (marginalia-separator "    "))) - -    (marginalia-mode 1) -   #+end_src -* company -  #+begin_src emacs-lisp -    (use-package company -      :ensure t -      :custom ((company-backends '(company-capf -                                   ;; company-bbdb -                                   company-files -                                   company-dabbrev -                                   company-keywords)) -               (company-global-modes '(not slack-message-buffer-mode -                                           circe-channel-mode -                                           telega-chat-mode)) -               (company-format-margin-function nil) ;; #'company-text-icons-margin -               (company-idle-delay 0.2) -               (company-lighter "") -               (company-lighter-base "") -               (company-show-numbers nil) -               (company-selection-wrap-around t) -               (company-tooltip-limit 15) -               (company-tooltip-align-annotations t) -               (company-tooltip-offset-display 'lines)) ;; 'scrollbar - -      :config -      (defun jao-complete-at-point () -        "Complete using company unless we're in the minibuffer." -        (interactive) -        (if (or (not company-mode) (window-minibuffer-p)) -            (completion-at-point) -          (company-manual-begin))) - -      (defun jao-company-use-in-tab () -        (global-set-key [remap completion-at-point] #'jao-complete-at-point) -        (global-set-key [remap completion-symbol] #'jao-complete-at-point) -        (global-set-key (kbd "M-TAB") #'jao-complete-at-point)) - -      (jao-company-use-in-tab) - -      :bind (:map company-active-map - -             ("<tab>" . company-complete-common-or-cycle) -             ("TAB" . company-complete-common-or-cycle) - -             ("C-h" . company-show-doc-buffer) -             ("M-." . company-show-location) -             ("C-<return>" . company-complete-selection) -             ([remap return] . company-abort) -             ("RET" . company-abort) - -             :filter (or (not (derived-mode-p 'eshell-mode)) -                         (company-explicit-action-p)) -             ("<return>" . company-complete-selection) -             ("RET" . company-complete-selection)) -      :diminish) - -    (unless (display-graphic-p) (global-company-mode 1)) -  #+end_src -* vertico -  #+begin_src emacs-lisp -    (use-package vertico -      :ensure t -      :init -      (setq vertico-count 20 -            vertico-cycle t -            vertico-resize t -            org-refile-use-outline-path t) - -      :config - -      ;; (setq completion-in-region-function -      ;;       (lambda (&rest args) -      ;;         (apply (if (and (not window-system) vertico-mode) -      ;;                    #'consult-completion-in-region -      ;;                  #'completion--in-region) -      ;;                args))) - -      (defun jao-vertico--display-candidates (lines) -        (move-overlay vertico--candidates-ov (point-min) (point-min)) -        (overlay-put vertico--candidates-ov 'after-string (apply #'concat lines)) -        (vertico--resize-window (length lines))) - -      (advice-add 'vertico--display-candidates -                  :override #'jao-vertico--display-candidates)) - -    (use-package vertico-directory -      :after vertico -      :bind (:map vertico-map (("RET" . vertico-directory-enter) -                               ("M-<backspace>" . vertico-directory-delete-word) -                               ("<backspace>" . vertico-directory-delete-char)))) - -    (vertico-mode) - -  #+end_src -* consult -*** package -    #+begin_src emacs-lisp -      (use-package consult -        :ensure t -        :bind (("C-x M-:" . consult-complex-command) -               ("C-x b" . consult-buffer) -               ("C-x C-b" . consult-buffer) -               ("C-x 4 b" . consult-buffer-other-window) -               ("C-c b" . project-find-file) -               ("C-c h" . consult-history) -               ("C-c i" . consult-imenu) -               ("C-c I" . consult-project-imenu) -               ("C-c k" . consult-ripgrep) -               ("C-c K" . consult-git-grep) -               ("C-c L" . consult-locate) -               ;; ("C-h m" . consult-mode-command) -               ("C-c s" . consult-line) -               ("C-x r x" . consult-register) -               ("C-x r b" . consult-bookmark) -               ("C-x C-f" . jao-find-file) -               ("M-g b" . consult-bookmark) -               ("M-g m" . consult-mark) -               ("M-g e" . consult-error) -               ("M-s m" . consult-multi-occur) -               ("M-s o" . consult-outline) -               ("M-y" . consult-yank-pop) -               ("C-s" . isearch-forward) -               ("C-S-s" . consult-line) -               ("<help> a" . consult-apropos)) - -        :custom ((consult-preview-key (kbd "`"))) - -        :init -        (fset 'multi-occur #'consult-multi-occur) - -        :config - -        (defun jao-find-file (arg) -          (interactive "P") -          (call-interactively (if arg 'consult-file-externally 'find-file))) - -        (define-key consult-narrow-map (vconcat consult-narrow-key "?") -          #'consult-narrow-help) - -        (consult-customize consult-mark :preview-key 'any) -        (add-hook 'completion-list-mode-hook #'consult-preview-at-point-mode)) - -    #+end_src -*** consult-dir -    #+begin_src emacs-lisp -      (use-package consult-dir -        :ensure t -        :bind (("C-x C-d" . consult-dir) -               :map minibuffer-local-completion-map -               (("C-x C-d" . consult-dir) -                ("C-x C-j" . consult-dir-jump-file)))) -    #+end_src -*** dh-diff hunks -    #+begin_src emacs-lisp -      (defun jao-consult--diff-lines (&optional backward) -        (let ((candidates) -              (width (length (number-to-string -                              (line-number-at-pos (point-max) -                                                  consult-line-numbers-widen))))) -          (save-excursion -            (while (ignore-errors (diff-hl-next-hunk backward)) -              (let* ((str (buffer-substring (line-beginning-position) -                                            (line-end-position))) -                     (no (line-number-at-pos (point))) -                     (no (consult--line-number-prefix (point-marker) no width))) -                (push (concat no str) candidates)))) -          (if backward candidates (nreverse candidates)))) - -      (defun jao-consult-hunks () -        (interactive) -        (let ((candidates (append (jao-consult--diff-lines) -                                  (jao-consult--diff-lines t)))) -          (unless candidates (error "No changes!")) -          (consult--jump -           (consult--read candidates -                          :prompt "Go to hunk: " -                          :category 'consult--encode-location -                          :sort nil -                          :require-match t -                          :lookup #'consult--line-match -                          :state (consult--jump-state))))) - -      (with-eval-after-load "consult" -        (consult-customize '((jao-consult-hunks :preview-key any))) -        (global-set-key (kbd "C-x v c") #'jao-consult-hunks)) -  #+end_src -*** narrow helpers -    #+begin_src emacs-lisp -      (defvar jao-consult-narrow nil) - -      (defun jao-consult-initial-narrow () -        (when-let (c (cond ((eq this-command #'consult-buffer) -                            (cdr (assoc (jao-afio-current-frame) -                                        jao-consult-narrow))) -                           ((eq this-command #'consult-mode-command) ?m))) -          (setq unread-command-events (append unread-command-events `(,c 32))))) - -      (add-hook 'minibuffer-setup-hook #'jao-consult-initial-narrow) - -      (defmacro jao-consult--mode-buffers (&rest modes) -        `(lambda () -           (seq-map #'buffer-name -                    (seq-filter (lambda (b) -                                  (with-current-buffer b -                                    (derived-mode-p ,@modes))) -                                (buffer-list))))) - -      (defun jao-consult-add-buffer-source (src &optional aframe key) -        (add-to-list 'consult-buffer-sources src t) -        (when (and aframe key) -          (add-to-list 'jao-consult-narrow (cons aframe key)))) -    #+end_src -*** narrowing chats -    #+begin_src emacs-lisp -      (defvar jao-chat-buffer-source -        (list :name "chats" -              :category 'buffer -              :action #'pop-to-buffer -              :hidden t -              :narrow (cons ?c "chats") -              :items (jao-consult--mode-buffers 'erc-mode -                                                'circe-channel-mode -                                                'circe-query-mode -                                                'signel-chat-mode -                                                'slack-message-buffer-mode -                                                'slack-thread-message-buffer-mode -                                                'telega-root-mode -                                                'telega-chat-mode))) -      (with-eval-after-load "consult" -        (jao-consult-add-buffer-source 'jao-chat-buffer-source)) -    #+end_src - -*** exwm -    #+begin_src emacs-lisp :tangle no -      (with-eval-after-load "exwm" -        (defun consult-exwm-preview-fix (&rest _args) -          "Kludge to stop EXWM buffers from stealing focus during Consult previews." -          (when-let ((mini (active-minibuffer-window))) -            (select-window (active-minibuffer-window)))) - -        (advice-add #'consult--buffer-action :after #'consult-exwm-preview-fix)) - -    #+end_src -* embark -*** package -    #+begin_src emacs-lisp -      (use-package embark -        :ensure t -        :demand t -        :init -        (setq embark-quit-after-action nil -              embark-indicator #'embark-mixed-indicator -              embark-verbose-indicator-buffer-sections '(bindings) -              embark-mixed-indicator-both t -              embark-verbose-indicator-excluded-commands -              '(embark-become embark-export embark-collect) -              embark-verbose-indicator-nested t -              embark-verbose-indicator-display-action -              '((display-buffer-at-bottom) -                (window-parameters (mode-line-format . none)) -                (window-height . fit-window-to-buffer))) - -        :bind (("C-;" . embark-act) -               ("C-c ;" . embark-act) -               ("C-'" . embark-dwim) -               ("C-c '" . embark-dwim) -               (:map minibuffer-local-map -                     (("C-'" . embark-dwim) -                      ("C-c '" . embark-dwim) -                      ("C-," . embark-become) -                      ("C-c ," . embark-become) -                      ("C-o" . embark-export))))) - -      (use-package embark-consult -        :ensure t -        :after (embark consult)) - -      (with-eval-after-load 'consult -        (with-eval-after-load 'embark -          (require 'embark-consult))) - -    #+end_src -*** randomsig -    #+begin_src emacs-lisp -      (defun jao-random-sig-read (_ignored) -        "Import region as signature and edit it." -        (randomsig-message-read-sig t)) - -      (define-key embark-region-map "m" #'jao-random-sig-read) -      (define-key embark-region-map "M" #'apply-macro-to-region-lines) -    #+end_src -*** dict/say -    #+begin_src emacs-lisp -      (defun jao-say (&optional word) -        "Isn't it nice to have a computer that can talk to you?" -        (interactive "sWhat? ") -        (shell-command-to-string (format "say %s" word)) -        "") - -      (define-key embark-identifier-map "D" #'dictionary-search) -      (define-key embark-identifier-map "S" #'jao-say) -    #+end_src -*** org targets -    #+begin_src emacs-lisp -      (declare-function org-link-any-re "ol") -      (declare-function org-open-link-from-string "ol") -      (declare-function org-in-regexp "org-macs") - -      (defun jao-embark-targets--org-link () -        (when (derived-mode-p 'org-mode) -          (when (org-in-regexp org-link-bracket-re) -            (let ((lnk (match-string-no-properties 1))) -              (if (string-match-p "https?://.+" (or lnk "")) -                  (cons 'url lnk) -                (cons 'org-link (match-string-no-properties 0))))))) - -      (embark-define-keymap jao-embark-targets-org-link-map -        "Actions for org links" -        ((kbd "RET") org-open-link-from-string)) - -      (defun jao-embark-targets--gl-org-link () -        (when (org-in-regexp org-link-bracket-re) -          (cons 'gl-org-link (match-string-no-properties 0)))) - -      (embark-define-keymap jao-embark-targets-gl-org-link-map -        "Actions for exteranl org links" -        ((kbd "RET") org-open-at-point-global)) - -      (add-to-list 'embark-target-finders #'jao-embark-targets--gl-org-link) -      (add-to-list 'embark-keymap-alist -                   '(gl-org-link . jao-embark-targets-gl-org-link-map)) - -      (add-to-list 'embark-target-finders #'jao-embark-targets--org-link) -      (add-to-list 'embark-keymap-alist -                   '(org-link . jao-embark-targets-org-link-map)) - -    #+end_src -*** url targets -    #+begin_src emacs-lisp -      (declare-function w3m-anchor "w3m") - -      (defun jao-embark-targets--w3m-anchor () -        (when (not (region-active-p)) -          (when-let ((url (or (jao-url-around-point) -                              (thing-at-point 'url) -                              (and (derived-mode-p 'w3m-mode) -                                   (or (w3m-anchor) w3m-current-url)) -                              (and (derived-mode-p 'eww-mode) -                                   (eww-current-url))))) -            (when (string-match-p "^https?.*" url) -              (cons 'url url))))) - -      (add-to-list 'embark-target-finders #'jao-embark-targets--w3m-anchor) - -      (defun jao-embark-url (url) -        "Browse URL, externally if we're already in an emacs browser." -        (if (derived-mode-p 'w3m-mode 'eww-mode) -            (jao-browse-with-external-browser url) -          (browse-url url))) - -      (define-key embark-url-map (kbd "RET") #'jao-embark-url) -      (define-key embark-url-map (kbd "f") #'browse-url-firefox) -      (define-key embark-url-map (kbd "x") #'jao-rss-subscribe) -      (define-key embark-url-map (kbd "m") 'jao-browse-with-external-browser) -      (define-key embark-url-map (kbd "p") 'jao-browse-add-url-to-mpc) - -    #+end_src -*** video url targets -    #+begin_src emacs-lisp -      (defvar jao-embark-targets-video-sites -        '("youtu.be" "youtube.com" "blip.tv" "vimeo.com" "infoq.com")) - -      (defun jao-embark--video-url-rx (&optional sites) -        (format "^https?://\\(?:www\\.\\)?%s/.+" -                (regexp-opt (or sites jao-embark-targets-video-sites) t))) - -      (defvar jao-embark-targets-video-url-rx (jao-embark--video-url-rx) -        "A regular expression matching URLs that point to video streams") - -      (defun jao-embark-targets--refine-url (_ url) -        (if (string-match-p jao-embark-targets-video-url-rx url) -            (cons 'video-url url) -          (cons 'url url))) - -      (defun jao-embark-targets--play-video (player url) -        (interactive "sURL: ") -        (let ((cmd (format "%s %s" player (shell-quote-argument url)))) -          (jao-afio--goto-www) -          (start-process-shell-command player nil cmd))) - -      (defun jao-embark-targets-mpv (&optional url) -        "Play video stream with mpv" -        (interactive "sURL: ") -        (jao-embark-targets--play-video "mpv" url)) - -      (defun jao-embark-targets-vlc (&optional url) -        "Play video stream with vlc" -        (interactive "sURL: ") -        (jao-embark-targets--play-video "vlc" url)) - -      (embark-define-keymap jao-embark-targets-video-url-map -        "Actions on URLs pointing to remote video streams." -        :parent embark-url-map -        ("v" jao-embark-targets-vlc) -        ("RET" jao-embark-targets-mpv)) - -      (add-to-list 'embark-transformer-alist '(url . jao-embark-targets--refine-url)) -      (add-to-list 'embark-keymap-alist '(video-url . jao-embark-targets-video-url-map)) -      (define-key embark-url-map "v" #'jao-embark-targets-vlc) -      (define-key embark-url-map "V" #'jao-embark-targets-vlc) - -    #+end_src -*** spotify -    #+begin_src emacs-lisp -      (with-eval-after-load "consult-spotify" -        (defun jao-consult-spt-play (candidate) -          (when-let (url (espotify-candidate-url candidate)) -            (jao-spt-play-uri url))) - -        (embark-define-keymap spotify-item-keymap -          "Actions for Spotify search results" -          ("s" jao-consult-spt-play) -          ("y" espotify-yank-candidate-url) -          ("a" espotify-play-candidate-album) -          ("h" espotify-show-candidate-info)) - -        (add-to-list 'embark-keymap-alist -                     '(spotify-search-item . spotify-item-keymap))) -    #+end_src -* avy and link hints -  [[https://karthinks.com/software/avy-can-do-anything/][Avy can do anything | Karthinks]] -  #+begin_src emacs-lisp -    (use-package avy -      :ensure t -      :init (setq avy-style 'pre -                  avy-background t -                  avy-timeout-seconds 0.6 -                  avy-single-candidate-jump t) - -      :config - -      (defun avy-embark-act (pt) -        "Use Embark to act on the completion at PT." -        (save-excursion -          (goto-char pt) -          (embark-act))) -      (add-to-list 'avy-dispatch-alist '(?\; . avy-embark-act)) - -      :bind (("s-j" . avy-goto-char-timer) -             ("C-M-j" . avy-goto-char-timer))) - -    (use-package link-hint -      :ensure t -      :init (setq link-hint-avy-style 'pre) - -      :config -      (defun jao-link-hint-open-link-ext () -        (interactive) -        (let ((jao-browse-url-function jao-browse-url-external-function)) -          (link-hint-open-link))) - -      :bind (("C-l" . link-hint-open-link) -             ("C-M-l" . jao-link-hint-open-link-ext) -             ("C-S-l" . jao-link-hint-open-link-ext) -             ("C-x C-l" . recenter-top-bottom))) - -  #+end_src -* recoll -  #+begin_src emacs-lisp -    (jao-load-path "consult-recoll") - -    (defun jao-recoll-format (title url mtype) -      (let* ((u (replace-regexp-in-string "/home/jao/" "" url)) -             (u (replace-regexp-in-string -                 "\\(doc\\|org/doc\\|.emacs.d/gnus/Mail\\|var/mail\\)/" "" u))) -        (format "%s (%s, %s)" -                title -                (propertize u 'face 'jao-themes-f00) -                (propertize mtype 'face 'jao-themes-f01)))) - -    (defun jao-recoll-open-html (file) -      (jao-afio--goto-www) -      (eww-open-file file)) - -    (defun jao-recoll-consult-messages () -      (interactive) -      (consult-recoll "mime:message ")) - -    (defun jao-recoll-consult-docs () -      (interactive) -      (consult-recoll (format "dir:%s/doc " jao-org-dir))) - -    (defun jao-recoll-messages () -      (interactive) -      (jao-recoll "mime:message ")) - -    (defun jao-recoll-docs () -      (interactive) -      (jao-recoll (format "dir:%s/doc " jao-org-dir))) - -    (defun jao-recoll-notes () -      (interactive) -      (jao-recoll (format "dir:%s " jao-org-notes-dir))) - -    (defun jao-recoll-consult-notes () -      "Use consult-recoll to search notes." -      (interactive) -      (consult-recoll (format "dir:%s " jao-org-notes-dir))) - -    (defun jao-recoll-open-with-notmuch (fname) -      (let ((id (with-temp-buffer -                  (insert-file fname) -                  (goto-char (point-min)) -                  (when (re-search-forward "[Mm]essage-[Ii][Dd]: <?\\([^><]+\\)>?" -                                           nil t) -                    (match-string 1))))) -        (when id (notmuch-show (concat "id:" id))))) - -    (use-package consult-recoll -      :init (setq consult-recoll-open-fns -                  '(("application/pdf" . jao-open-doc) -                    ("message/rfc822" . jao-recoll-open-with-notmuch) -                    ("text/html" . jao-recoll-open-html)) -                  consult-recoll-search-flags nil -                  consult-recoll-format-candidate #'jao-recoll-format) -      :config -      (transient-define-prefix jao-recoll-transient () -        [["Consult recoll queries" -          ("r" "consult recoll query" consult-recoll) -          ("n" "consult recoll on notes" jao-recoll-consult-notes) -          ("d" "consult recoll on docs" jao-recoll-consult-docs) -          ("m" "consult recoll on messages" jao-recoll-consult-messages)] -         ["Recoll queries" -          ("R" "recoll query" jao-recoll) -          ("N" "recoll on notes" jao-recoll-notes) -          ("D" "consult recoll on docs" jao-recoll-docs) -          ("M" "consult recoll on messages" jao-recoll-messages)]]) - -      :bind (("s-r" . #'jao-recoll-transient))) - -  #+end_src diff --git a/attic/org/counsel.org b/attic/org/counsel.org deleted file mode 100644 index f6814ae..0000000 --- a/attic/org/counsel.org +++ /dev/null @@ -1,337 +0,0 @@ -#+title: Completion configuration using ivy, counsel and friends - -* selectrum -  #+begin_src emacs-lisp :load no -    (use-package selectrum -      :ensure t -      :init -      (defun jao-selectrum--ord-refine (&rest args) -        (let ((completion-styles '(orderless))) -          (apply #'selectrum-refine-candidates-using-completions-styles args))) - -      (defun jao-selectrum-orderless () -        (interactive) -        (setq selectrum-refine-candidates-function #'jao-selectrum--ord-refine) -        (setq selectrum-highlight-candidates-function #'orderless-highlight-matches) -        (setq orderless-skip-highlighting (lambda () selectrum-is-active))) - - -      :config -      ;; https://github.com/raxod502/selectrum/wiki/Ido,-icomplete(fido)-emulation -      (defun selectrum-fido-backward-updir () -        "Delete char before or go up directory, like `ido-mode'." -        (interactive) -        (if (and (eq (char-before) ?/) -                 (eq (selectrum--get-meta 'category) 'file)) -            (save-excursion -              (goto-char (1- (point))) -              (when (search-backward "/" (point-min) t) -                (delete-region (1+ (point)) (point-max)))) -          (call-interactively 'backward-delete-char))) - -      (defun selectrum-fido-delete-char () -        "Delete char or maybe call `dired', like `ido-mode'." -        (interactive) -        (let ((end (point-max))) -          (if (or (< (point) end) (not (eq (selectrum--get-meta 'category) 'file))) -              (call-interactively 'delete-char) -            (dired (file-name-directory (minibuffer-contents))) -            (exit-minibuffer)))) - -      (defun selectrum-fido-ret () -        "Exit minibuffer or enter directory, like `ido-mode'." -        (interactive) -        (let* ((dir (and (eq (selectrum--get-meta 'category) 'file) -                         (file-name-directory (minibuffer-contents)))) -               (current (selectrum-get-current-candidate)) -               (probe (and dir current -                           (expand-file-name (directory-file-name current) dir)))) -          (if (and probe (file-directory-p probe) (not (string= current "./"))) -              (selectrum-insert-current-candidate) -            (selectrum-select-current-candidate)))) - -      ;; (define-key selectrum-minibuffer-map (kbd "RET") 'selectrum-fido-ret) -      (define-key selectrum-minibuffer-map (kbd "DEL") 'selectrum-fido-backward-updir) -      (define-key selectrum-minibuffer-map (kbd "C-d") 'selectrum-fido-delete-char) - -      :custom ((selectrum-complete-in-buffer t) -               ;; (selectrum-display-action '(display-buffer-at-bottom)) -               (selectrum-extend-current-candidate-highlight t) -               (selectrum-fix-vertical-window-height nil) -               (selectrum-max-window-height 20) -               (selectrum-show-indices nil) -               (selectrum-count-style 'current/matches)) -      :bind (("C-R" . selectrum-repeat))) -  #+end_src -* ivy -  #+begin_src emacs-lisp -    (use-package ivy -      :ensure t -      :demand t -      :custom -      ((ivy-count-format "(%d/%d) ") -       (ivy-do-completion-in-region t) -       (ivy-height 20) -       (ivy-re-builders-alist '((counsel-ag . ivy--regex) -                                (counsel-rg . ivy--regex) -                                (counsel-yank-pop . ivy--regex) -                                (swiper . ivy--regex) -                                (swiper-isearch . ivy--regex) -                                (t . ivy--regex-fuzzy))) -       (ivy-use-virtual-buffers t) -       (ivy-virtual-abbreviate 'abbreviate) -       (ivy-wrap t)) - -      :config -      ;; used by ivy--regex-fuzzy to order results -      (use-package flx :ensure t) - -      ;; Try C-o in the minibuffer -      (use-package ivy-hydra -        :after ivy -        :ensure t -        :init (setq ivy-read-action-function #'ivy-hydra-read-action)) - -      (add-to-list 'ivy-initial-inputs-alist -                   '(gnus-summary-move-article . "")) - -      :bind (("C-R" . ivy-resume) -             ("C-x b" . ivy-switch-buffer) -             ("C-c v" . ivy-push-view) -             ("C-c V" . ivy-pop-view)) -      :diminish) -  #+end_src -* counsel -  #+begin_src emacs-lisp -    (use-package counsel -      :ensure t -      :custom ((counsel-describe-function-function 'helpful-callable) -               (counsel-describe-variable-function 'helpful-variable) -               (counsel-find-file-at-point t) -               (counsel-linux-app-format-function -                #'counsel-linux-app-format-function-name-pretty) -               (counsel-mode-override-describe-bindings nil) -               (counsel-recentf-include-xdg-list t)) -      :config -      :bind (("C-s" . swiper-isearch) -             ("C-S-s" . isearch-forward) -             ("M-x" . counsel-M-x) -             ("C-x f" . counsel-find-file) -             ("C-c k" . counsel-ag) -             ("C-c K" . counsel-rg) -             ("C-c l" . counsel-locate) -             ("C-c b" . counsel-git) -             ("C-c i" . counsel-imenu) -             ("C-c G" . counsel-search) -             ("s-r" . counsel-linux-app)) -      :diminish) -  #+end_src -* counsel add-ons -*** notmuch -    #+begin_src emacs-lisp -      (use-package counsel-notmuch -        :ensure t -        :config (with-eval-after-load "gnus-group" -                  (define-key gnus-group-mode-map "Gg" 'counsel-notmuch))) -    #+end_src -*** recoll -    #+begin_src emacs-lisp -      (require 'jao-recoll) -      (defvar jao-counsel-recoll--history nil) -      (defun jao-counsel-recoll--function (str) -        (let ((xs (counsel-recoll-function str))) -          (cl-remove-if-not (lambda (x) (string-prefix-p "file://" x)) xs))) - -      (defun jao-counsel-recoll (&optional initial-input) -        (interactive) -        (counsel-require-program "recoll") -        (ivy-read "recoll: " 'jao-counsel-recoll--function -                  :initial-input initial-input -                  :dynamic-collection t -                  :history 'jao-counsel-recoll--history -                  :action (lambda (x) -                            (when (string-match "file://\\(.*\\)\\'" x) -                              (let ((file-name (match-string 1 x))) -                                (if (string-match "pdf$" x) -                                    (jao-open-doc file-name) -                                  (find-file file-name))))) -                  :unwind #'counsel-delete-process -                  :caller 'jao-counsel-recoll)) - -      (defun jao-counsel-recoll--recoll (_s) (jao-recoll ivy-text)) - -      (ivy-set-actions 'jao-counsel-recoll -                       '(("x" jao-counsel-recoll--recoll "List in buffer"))) - -      (global-set-key (kbd "C-c R") #'jao-counsel-recoll) -    #+end_src -* ivy rich -  #+begin_src emacs-lisp -    (use-package ivy-rich -      :after (ivy counsel) -      :ensure t -      :custom ((ivy-rich-path-style 'relative) -               (ivy-rich-parse-remote-buffer nil) -               (ivy-rich-parse-remote-file-path nil)) -      :config -      (ivy-rich-modify-columns -       'ivy-switch-buffer -       '((ivy-rich-candidate (:width 80)) -         (ivy-rich-switch-buffer-indicators (:face jao-themes-f00)) -         (ivy-rich-switch-buffer-project (:width 15)) -         (ivy-rich-switch-buffer-major-mode (:width 15 :face jao-themes-f12))))) -  #+end_src -* cmap -  #+begin_src emacs-lisp -    (jao-load-path "cmap") -    (use-package cmap -      :demand t -      :bind (("C-;" . cmap-cmap) -             ("C-'" . cmap-default))) -  #+end_src -*** prompter -    #+begin_src emacs-lisp -      (defun jao-cmap--hide-help () -        (when-let ((w (get-buffer-window (help-buffer)))) -          (with-selected-window w (kill-buffer-and-window)))) - -      (defun jao-cmap--prompter (keymap) -        (let ((display-buffer-alist '(("*Help*" -                                       (display-buffer-at-bottom) -                                       (window-parameters (mode-line-format . none)) -                                       (window-height . fit-window-to-buffer))))) -          (let ((inhibit-message t)) -            (describe-keymap keymap)))) - -      (defun jao-cmap--prompter-done () -        (save-current-buffer (jao-cmap--hide-help))) - -      (setq cmap-prompter #'jao-cmap--prompter) -      (setq cmap-prompter-done #'jao-cmap--prompter-done) -    #+end_src -*** minibuffer actions -    #+begin_src emacs-lisp -      (defun jao-cmap--completion-metadata () -        (completion-metadata -         (buffer-substring-no-properties (field-beginning) (point)) -         minibuffer-completion-table -         minibuffer-completion-predicate)) - -      (defun jao-cmap--completion-category () -        (completion-metadata-get (jao-cmap--completion-metadata) 'category)) - -      (defmacro cmap-define-keymap (v d &rest b) -        `(defvar ,v (cmap-keymap ,@b) ,d)) - -      (cmap-define-keymap jao-cmap-buffer-map -        "Keymap for buffer actions." -        ("k" . kill-buffer) -        ("b" . switch-to-buffer) -        ("o" . switch-to-buffer-other-window) -        ("z" . bury-buffer) -        ("q" . kill-buffer-and-window) -        ("=" . ediff-buffers)) - -      ;; (cmap-define-keymap espotify-item-keymap -      ;;   "Actions for Spotify search results" -      ;;   ("a" espotify--play-album) -      ;;   ("h" espotify--show-info)) - -      (defvar jao-cmap--smaps -        '((command . cmap-command-map) -          ;; (espotify-search-item . espotify-item-keymap) -          (function . cmap-function-map) -          (variable . cmap-variable-map) -          (face . cmap-face-map) -          (buffer . jao-cmap-buffer-map) -          (consult-buffer . jao-cmap-buffer-map))) - -      (defun jao-cmap-target-minibuffer-candidate () -        (when (minibuffer-window-active-p (selected-window)) -          (let ((cand (ivy-state-current ivy-last)) -                (cat (jao-cmap--completion-category))) -            (when-let (m (alist-get cat jao-cmap--smaps)) -              (cons m cand))))) - -      (add-to-list 'cmap-targets #'jao-cmap-target-minibuffer-candidate) -    #+end_src -*** url / video actions -    #+begin_src emacs-lisp -      (defvar jao-cmap-video-url-rx -        (format "^https?://\\(?:www\\.\\)?%s/.+" -                (regexp-opt '("youtu.be" -                              "youtube.com" -                              "blip.tv" -                              "vimeo.com" -                              "infoq.com") -                            t)) -        "A regular expression matching URLs that point to video streams") - -      (defun jao-cmap--play-video (player url) -        (interactive "sURL: ") -        (let ((cmd (format "%s %s" player (shell-quote-argument url)))) -          (start-process-shell-command player nil cmd))) - -      (defun jao-cmap-mpv (&optional url) -        "Play video stream with mpv" -        (interactive "sURL: ") -        (jao-cmap--play-video "mpv" url)) - -      (defun jao-cmap-vlc (&optional url) -        "Play video stream with vlc" -        (interactive "sURL: ") -        (jao-cmap--play-video "vlc" url)) - -      (defun jao-cmap-target-w3m-url () -        (when-let (url (or (thing-at-point-url-at-point) -                           (w3m-anchor) -                           w3m-current-url)) -          (cons 'cmap-url-map url))) - -      (defun jao-cmap-kill (&optional x) -        "Save to kill ring" -        (interactive "s") -        (kill-new x)) - -      (defun jao-cmap-url (url) -        "Browse URL, externally if we're already in emacs-w3m" -        (if (derived-mode-p 'w3m-mode) -            (jao-browse-with-external-browser url) -          (browse-url url))) - -      (define-key cmap-url-map [return] #'jao-cmap-url) -      (define-key cmap-url-map "f" #'browse-url-firefox) -      (define-key cmap-url-map "w" #'jao-cmap-kill) - -      (defun jao-cmap-target-video-url () -        (when-let (url (jao-cmap-target-w3m-url)) -          (when (string-match-p jao-cmap-video-url-rx (cdr url)) -            (cons 'jao-cmap-video-url-map (cdr url))))) - -      (cmap-define-keymap jao-cmap-video-url-map -        "Actions on URLs pointing to remote video streams." -        ("v" . jao-cmap-vlc) -        ([return] . jao-cmap-mpv)) - -      (add-to-list 'cmap-targets #'jao-cmap-target-w3m-url) -      (add-to-list 'cmap-targets #'jao-cmap-target-video-url) -    #+end_src -* hooks -  #+begin_src emacs-lisp -    (with-eval-after-load "exwm" -      (add-to-list 'exwm-input-global-keys '([?\s-r] . counsel-linux-app))) - -    (with-eval-after-load "espotify" -      (require 'ivy-spotify) -      (defalias 'jao-spotify-album #'ivy-spotify-album) -      (defalias 'jao-spotify-track #'ivy-spotify-track) -      (defalias 'jao-spotify-artist #'ivy-spotify-artist) -      (defalias 'jao-spotify-playlist #'ivy-spotify-playlist)) -  #+end_src -* startup -  #+begin_src emacs-lisp -    (ivy-mode 1) -    (counsel-mode 1) -    (ivy-rich-mode 1) -    (ivy-rich-project-root-cache-mode 1) -  #+end_src diff --git a/attic/org/email.org b/attic/org/email.org deleted file mode 100644 index e8a8a71..0000000 --- a/attic/org/email.org +++ /dev/null @@ -1,391 +0,0 @@ -#+property: header-args:emacs-lisp :lexical t :tangle yes :comments yes :results silent :shebang ";; -*- lexical-binding: t; -*-" :tangle-mode (identity #o644) -#+title: email handling (message mode, bbdb, gnus, notmuch) - -* personal emails and others -  #+begin_src emacs-lisp -    (defvar jao-mails) -    (defvar jao-extra-mails) -    (defvar jao-mails-regexp (regexp-opt jao-mails)) -    (defvar jao-notmuch-enabled (eq jao-afio-mail-function 'notmuch)) -  #+end_src -* gnus -  #+begin_src emacs-lisp -    (setq gnus-init-file "~/.emacs.d/gnus.el" -          gnus-home-directory "~/.emacs.d/gnus" -          gnus-directory gnus-home-directory -          gnus-cache-directory (expand-file-name "cache" gnus-home-directory) -          gnus-kill-files-directory (expand-file-name "News" gnus-home-directory) -          message-directory (expand-file-name "Mail" gnus-home-directory) -          mail-source-directory (expand-file-name "Mail" gnus-home-directory)) - -    (let ((org-file (expand-file-name "gnus.org" jao-emacs-dir))) -      (when (file-newer-than-file-p org-file gnus-init-file) -        (org-babel-tangle-file org-file))) - -  #+end_src -* message mode -*** Customization -    #+begin_src emacs-lisp -      (setq message-send-mail-function 'message-send-mail-with-sendmail -            message-sendmail-envelope-from 'header -            message-sendmail-f-is-evil nil) -      (setq imap-store-password t) -      (setq password-cache-expiry nil) -      (setq message-generate-headers-first t) -      (setq message-forward-before-signature nil) -      (setq message-alternative-emails -            (regexp-opt (append jao-mails jao-extra-mails))) -      (setq message-dont-reply-to-names -            (regexp-opt (append jao-mails '("noreply@" "@noreply" -                                            "no-reply@" "@no-reply" -                                            "notifications@github")))) -      (setq message-citation-line-format "On %a, %b %d %Y, %N wrote:\n") -      (setq message-citation-line-function 'message-insert-formatted-citation-line) - -      (setq message-user-fqdn "gnus.jao.io") - -      ;; writing messages -      (setq message-kill-buffer-on-exit t) -      (setq message-max-buffers 5) -      (setq message-insert-signature t) -      (setq message-from-style 'angles -            user-mail-address (car jao-mails) -            mail-host-address system-name -            message-syntax-checks '((sender . disabled)) -            message-default-headers -            (concat -             "X-Attribution: jao\n" -             "X-Clacks-Overhead: GNU Terry Pratchett\n" -             "X-URL: <https://jao.io/>\n") -            message-hidden-headers -            '("^References:" "^Face:" "^X-Face:" "^X-Draft-From:") -            message-make-forward-subject-function 'message-forward-subject-fwd) - -      (setq message-expand-name-standard-ui t) -    #+end_src -*** Adjust Bcc -    #+begin_src emacs-lisp -      (defvar jao-message--bcc-rx (regexp-opt '("mail.io" "gnu.org"))) - -      (defun jao-message-insert-bcc () -        (let ((f (or (message-fetch-field "From") ""))) -          (when (or (string-blank-p f) (string-match-p jao-message--bcc-rx f)) -            (insert "Bcc: proton@jao.io\n")))) - -      (add-hook 'message-header-setup-hook #'jao-message-insert-bcc) -    #+end_src -*** To->From and Bcc -    #+begin_src emacs-lisp -      (defvar jao-message-to-from nil) - -      (defun jao-message-adjust-from () -        (let ((to (concat (message-fetch-field "To") (message-fetch-field "Cc")))) -          (when-let* ((tf (seq-find (lambda (tf) (string-match-p (car tf) to)) -                                    jao-message-to-from)) -                      (from (message-make-from "Jose A Ortega Ruiz" (cdr tf)))) -            (save-restriction -              (widen) -              (message-replace-header "From" from))))) - -      (when jao-notmuch-enabled -        (add-hook 'message-header-setup-hook #'jao-message-adjust-from)) -    #+end_src -*** Clean up reply addresses -    #+begin_src emacs-lisp :tangle no -      (defun jao-message--dont-reply () -        (let ((x (message-dont-reply-to-names))) -          (if (functionp x) -              x -            (lambda (mail) (unless (string-match-p x mail) mail))))) - -      (defun jao-message-strip-replies () -        (dolist (header '("To" "Cc")) -          (when-let ((v (message-fetch-field header))) -            (let* ((v (message-tokenize-header v)) -                   (vs (delq nil (mapcar (jao-message--dont-reply) v))) -                   (v (when vs (mapconcat #'string-trim vs ", ")))) -              (message-replace-header header v))))) - -      (when jao-notmuch-enabled -        (add-hook 'message-setup-hook #'jao-message-strip-replies)) - -    #+end_src -*** Encryption -    #+begin_src emacs-lisp -      ;; avoiding bogus warning -      (setq gnutls-min-prime-bits nil) -      (setq gnus-buttonized-mime-types -            '("multipart/encrypted" "multipart/signed" "multipart/alternative")) - -      (setq mm-verify-option 'always) -      (setq mm-decrypt-option 'always) - -      (setq mm-sign-option 'guided) -      (setq mm-encrypt-option 'guided) - -      (setq mml-secure-passphrase-cache-expiry (* 3600 24) -            password-cache-expiry (* 3600 24)) - -      (setq smime-CA-directory "/etc/ssl/certs/" -            smime-certificate-directory -            (expand-file-name "certs/" gnus-directory)) - -      (with-eval-after-load "mm-decode" -        ;; Tells Gnus to inline the part -        (add-to-list 'mm-inlined-types "application/pgp$") -        ;; Tells Gnus how to display the part when it is requested -        (add-to-list 'mm-inline-media-tests '("application/pgp$" -                                              mm-inline-text identity)) -        ;; Tell Gnus not to wait for a request, just display the thing -        ;; straight away. -        (add-to-list 'mm-automatic-display "application/pgp$") -        ;; But don't display the signatures, please. -        (setq mm-automatic-display (remove "application/pgp-signature" -                                           mm-automatic-display))) - -      ;; decide whether to encrypt or just sign outgoing messages -      (defvar jao-message-try-sign nil) -      (defun jao-message-maybe-sign () -        (when (and jao-message-try-sign (y-or-n-p "Sign message? ")) -          (if (y-or-n-p "Encrypt message? ") -              (let ((recipient (message-fetch-field "To"))) -                (if (or (pgg-lookup-key recipient) -                        (and (y-or-n-p (format "Fetch %s's key? " recipient)) -                             (pgg-fetch-key pgg-default-keyserver-address -                                            recipient))) -                    (mml-secure-message-encrypt-pgp) -                  (mml-secure-message-sign-pgp))) -            (mml-secure-message-sign-pgp)))) - -      ;; for ma gnus -      (eval-after-load "rfc2047" -        '(add-to-list 'rfc2047-header-encoding-alist -                      '("User-Agent" . address-mime))) -    #+end_src -*** Attach image to message -    Use ~C-c C-p~ in message-mode, and ~C-c y~. -*** Check attachment -    #+begin_src emacs-lisp -      (defvar jao-message-attachment-regexp "\\([Ww]e send\\|[Ii] send\\|attach\\)") -      (defun jao-message-check-attachment () -        "Check if there is an attachment in the message if I claim it." -        (save-excursion -          (message-goto-body) -          (when (search-forward-regexp jao-message-attachment-regexp nil t nil) -            (message-goto-body) -            (unless (or (search-forward "<#part" nil t nil) -                        (message-y-or-n-p -                         "No attachment. Send the message? " nil nil)) -              (error "No message sent"))))) -    #+end_src -*** Check Fcc/Gcc -    #+begin_src emacs-lisp -      (defun jao-message-check-gcc () -        "Ask whether to keep a copy of message." -        (save-excursion -          (save-restriction -            (message-narrow-to-headers) -            (when (and (or (message-fetch-field "Gcc") -                           (message-fetch-field "Fcc")) -                       (not (y-or-n-p "Archive? "))) -              (message-remove-header "\\(?:[BFG]cc\\)"))))) -    #+end_src -*** Check recipient -    #+begin_src emacs-lisp -      (defun jao-message-check-recipient () -        (save-excursion -          (save-restriction -            (message-narrow-to-headers) -            (when-let ((to (message-fetch-field "To"))) -              (when (string-match-p jao-mails-regexp to) -                (unless (y-or-n-p "Message is addressed to yourself.  Continue?") -                  (error "Message not sent"))))))) -    #+end_src -*** Randomsig -    #+begin_src emacs-lisp -      (with-eval-after-load "message" -        (when (require 'randomsig nil t) -          (define-key message-mode-map (kbd "C-c s") 'randomsig-replace-sig) -          (define-key message-mode-map (kbd "C-c S") 'randomsig-select-sig) -          (setq randomsig-dir (expand-file-name "~/etc/config/emacs")) -          (setq randomsig-files '("signatures.txt")) -          ;; or (setq randomsig-files (randomsig-search-sigfiles)) -          ;; or (setq randomsig-files 'randomsig-search-sigfiles) -          (setq message-signature 'randomsig-signature) -          (setq randomsig-delimiter-pattern "^%$" -                randomsig-delimiter "%"))) -    #+end_src -*** Send mail hooks -    #+begin_src emacs-lisp -      (dolist (h '(jao-message-check-gcc -                   jao-message-check-recipient -                   jao-message-maybe-sign)) -        (add-hook 'message-send-hook h)) -      (unless jao-notmuch-enabled -        (add-hook 'message-send-hook #'jao-message-check-attachment)) -    #+end_src -*** Keybindings -    #+begin_src emacs-lisp -      (with-eval-after-load "message" -        ;; (define-key message-mode-map [f7] 'mml-secure-message-sign-pgp) -        (define-key message-mode-map [f8] 'mml-secure-message-encrypt-pgp) -        (define-key message-mode-map (kbd "C-c y") #'yank-media)) -    #+end_src -* sendmail/smtp -  #+begin_src emacs-lisp -    (defun jao-sendmail-gmail () -      (setq smtpmail-auth-supported '(login cram-md5 plain)) -      (setq smtpmail-smtp-server "smtp.gmail.com") -      (setq smtpmail-smtp-service 587)) - -    (defun jao-sendmail-local () -      (setq send-mail-function 'sendmail-send-it) -      (setq smtpmail-auth-supported nil) ;; (cram-md5 plain login) -      (setq smtpmail-smtp-server "127.0.0.1") -      (setq smtpmail-smtp-service 25)) - -    (defun jao-sendmail-msmtp () -      (setq send-mail-function 'sendmail-send-it -            sendmail-program "/usr/bin/msmtp" -            mail-specify-envelope-from t -            message-sendmail-envelope-from 'header -            mail-envelope-from 'header)) - -    (jao-sendmail-local) -  #+end_src -* mailcap -  #+begin_src emacs-lisp -    (use-package mailcap -      :config -      (add-to-list 'mailcap-mime-extensions '(".JPEG" . "image/jpeg")) -      (add-to-list 'mailcap-mime-extensions '(".JPG" . "image/jpeg")) - -      (defun jao-icalendar-import-buffer () -        (let ((icalendar-import-format "%s%u%l%d")) -          (icalendar-import-buffer diary-file t nil)) -        (kill-buffer) -        (message "Event imported into diary")) - -      :custom -      ((mailcap-user-mime-data -        '((jao-icalendar-import-buffer "application/ics") -          ("viewpdf.sh %s" "application/pdf"))))) -  #+end_src -* multipart html renderer -  #+begin_src emacs-lisp -    (defun jao-w3m-html-renderer (handle) -      (let ((w3m-message-silent t) -            (mm-w3m-safe-url-regexp nil)) -        (condition-case nil -            (mm-inline-text-html-render-with-w3m handle) -          (error (delete-region (point) (point-max)) -                 (let ((shr-use-fonts nil) -                       (shr-use-colors nil)) -                   (mm-shr handle)))))) - -    (defun jao-shr-html-renderer (handle) -      (let (;; (shr-use-fonts t) -            ;; (shr-use-colors t) -            (shr-width 130)) -        (mm-shr handle))) - -    ;; (setq mm-text-html-renderer #'jao-w3m-html-renderer) -    (setq mm-text-html-renderer #'jao-shr-html-renderer) -  #+end_src -* bbdb -  #+begin_src emacs-lisp :tangle no -    (use-package bbdb -      :ensure t -      :init (setq bbdb-complete-name-allow-cycling t -                  bbdb-completion-display-record nil -                  bbdb-gui t -                  bbdb-message-all-addresses t -                  bbdb-complete-mail-allow-cycling t -                  bbdb-north-american-phone-numbers-p nil -                  bbdb-add-aka t -                  bbdb-add-name 2 -                  bbdb-message-all-addresses t -                  bbdb-mua-pop-up t ;; 'horiz -                  bbdb-mua-pop-up-window-size 0.3 -                  bbdb-layout 'multi-line -                  bbdb-mua-update-interactive-p '(query . create) -                  bbdb-mua-auto-update-p 'bbdb-select-message -                  bbdb-user-mail-address-re jao-mails-regexp -                  bbdb-auto-notes-ignore-headers -                  `(("From" . ,jao-mails-regexp) -                    ("From" . ".*@.*github\.com.*") -                    ("To" . ".*@.*github\.com.*") -                    ("Reply-to" . ".*") -                    ("References" . ".*")) -                  bbdb-auto-notes-ignore-messages -                  `(("To" . ".*@.*github\\.com.*") -                    ("From" . ".*@.*github\\.com.*") -                    ("From" . "info-list") -                    ("From" . "no-?reply\\|deploy") -                    ("X-Mailer" . "MailChimp")) -                  bbdb-accept-message-alist -                  `(("To" . ,jao-mails-regexp) -                    ("Cc" . ,jao-mails-regexp) -                    ("BCc" . ,jao-mails-regexp)) -                  bbdb-ignore-message-alist bbdb-auto-notes-ignore-messages) -      :config -      (add-hook 'message-setup-hook 'bbdb-mail-aliases) -      ;; (add-hook 'bbdb-notice-mail-hook 'bbdb-auto-notes) -      (add-hook 'bbdb-after-change-hook (lambda (arg) (bbdb-save))) -      (require 'bbdb-anniv) ;; BBDB 3.x this gets birthdays in org agenda -                            ;; and diary - clever stuff -      (add-hook 'diary-list-entries-hook 'bbdb-anniv-diary-entries) - -      (setq bbdb-file (expand-file-name "~/.emacs.d/bbdb")) -      (if jao-notmuch-enabled -          (bbdb-initialize 'message 'pgp) -        (bbdb-initialize 'message 'pgp 'gnus))) -   #+end_src -* mailboxes -  #+begin_src emacs-lisp -    (defun jao-list-mailboxes (base &rest excl) -      (let ((dir (expand-file-name base "~/var/mail"))) -        (seq-difference (directory-files dir) (append '("." "..") excl)))) - - -  #+end_src -* consult narrowing -  #+begin_src emacs-lisp -    (defvar jao-mail-consult-buffer-history nil) - -    (defun jao-mail-buffer-p (b) -      (or (member (buffer-name b) -                  '("*Calendar*" "inbox.org" "*Org Agenda*" -                    "*Fancy Diary Entries*" "diary")) -          (with-current-buffer b -            (derived-mode-p 'notmuch-show-mode -		            'notmuch-search-mode -		            'notmuch-tree-mode -		            'notmuch-hello-mode -		            'notmuch-message-mode -                            'gnus-group-mode -                            'gnus-summary-mode -                            'gnus-article-mode)))) - -    (defvar jao-mail-consult-source -      (list :name "mail buffer" -            :category 'buffer -            :hidden t -            :narrow (cons ?n "mail buffer") -            :history 'jao-mail-consult-buffer-history -            :action (lambda (b) -                      (when (not (string-blank-p (or b ""))) -                        (jao-afio--goto-mail) -                        (if (get-buffer-window b) -                            (pop-to-buffer b) -                          (pop-to-buffer-same-window b)))) -            :items (lambda () -                     (mapcar #'buffer-name -                             (seq-filter #'jao-mail-buffer-p (buffer-list)))))) - -    (jao-consult-add-buffer-source 'jao-mail-consult-source "Mail" ?n) -  #+end_src -* notmuch -  #+begin_src emacs-lisp -    (jao-load-org "notmuch") -  #+end_src diff --git a/attic/org/eww.org b/attic/org/eww.org deleted file mode 100644 index 4a9dd71..0000000 --- a/attic/org/eww.org +++ /dev/null @@ -1,191 +0,0 @@ -#+property: header-args :lexical t :tangle yes :comments yes :results silent :shebang ";; -*- lexical-binding: t -*-" :tangle-mode (identity #o644) -#+title: Web browsing using eww - -* Integration with browse-url and afio -  #+begin_src emacs-lisp -    (defun jao-eww-browse-url (url &rest r) -      "Browse URL using eww." -      (if (derived-mode-p 'eww-mode) -          (eww url) -        (jao-afio--goto-www) -        (select-window (frame-first-window)) -        (let* ((url (url-encode-url url)) -               (bf (seq-find `(lambda (b) -                                (with-current-buffer b -                                  (string= ,url -                                           (url-encode-url (eww-current-url))))) -                             (jao-eww-session--list-buffers)))) -          (cond (bf (switch-to-buffer bf)) -                ((string-match-p url "^file://") (eww-open-file url)) -                (t (eww url 4)))))) - -    (setq jao-browse-url-function #'jao-eww-browse-url) -    (setq eww-use-browse-url "^\\(gemini\\|gopher\\):") -  #+end_src -* Opening URLs -  #+begin_src emacs-lisp -    (defun jao-eww-copy-link () -      (interactive) -      (when-let (lnk (or (car (eww-links-at-point)) (eww-current-url))) -        (message "%s" lnk) -        (kill-new lnk))) - -    (defun jao-eww-browse (arg) -        (interactive "P" eww-mode) -        (setq eww-prompt-history -              (cl-remove-duplicates eww-prompt-history :test #'string=)) -        (let ((url (completing-read (if arg "eww in new buffer: " "eww: ") -                                    eww-prompt-history nil nil nil -                                    'eww-prompt-history (eww-current-url)))) -          (eww url (when arg 4)))) - -    (defun jao-eww-browse-new () -      (interactive nil eww-mode) -      (jao-eww-browse t)) - -    (defun jao-eww-reload (images) -        (interactive "P" eww-mode) -        (if images -            (let ((shr-blocked-images nil)) -              (eww-reload t)) -          (call-interactively 'eww-reload))) -  #+end_src -* Consult narrowing -  #+begin_src emacs-lisp -    (with-eval-after-load "consult" -      (defvar jao-eww-consult-history nil) -      (defvar jao-eww-buffer-source -        (list :name "eww buffer" -              :category 'eww-buffer -              :hidden t -              :narrow (cons ?e "eww") -              :annotate (lambda (c) (get-text-property 0 'url c)) -              :history 'jao-eww-consult-history -              :action (lambda (b) -                        (jao-afio--goto-www) -                        (switch-to-buffer (get-text-property 0 'buffer b))) -              :items -              (lambda () -                (seq-map (lambda (b) -                           (with-current-buffer b -                             (let ((tl (or (plist-get eww-data :title) "")) -                                   (url (or (eww-current-url) (buffer-name)))) -                               (propertize (if (string-blank-p tl) url tl) -                                           'buffer b 'url url)))) -                         (seq-filter #'jao-www--buffer-p (buffer-list)))))) -      (jao-consult-add-buffer-source 'jao-eww-buffer-source "Web" ?e)) -  #+end_src -* Images -  #+begin_src emacs-lisp -    (defun jao-eww-next-image () -      (interactive nil eww-mode) -      (when-let (p (text-property-search-forward 'image-displayer nil nil t)) -        (goto-char (prop-match-beginning p)))) -  #+end_src -* Close page and reopen -  #+begin_src emacs-lisp -    (defvar jao-eww--closed-urls ()) - -    (defun jao-eww-close () -      (interactive nil eww-mode) -      (when-let (current (eww-current-url)) -        (add-to-list 'jao-eww--closed-urls current)) -      (let ((nxt (car (jao-eww-session-invisible-buffers)))) -        (kill-current-buffer) -        (when nxt (switch-to-buffer nxt nil t)))) - -    (defun jao-eww-reopen (arg) -      (interactive "P") -      (if (> (length jao-eww--closed-urls) 0) -          (let ((url (completing-read "URL: " jao-eww--closed-urls))) -            (jao-afio--goto-www) -            (setq jao-eww--closed-urls (remove url jao-eww--closed-urls)) -            (eww url (when arg 4))) -        (message "No previously closed URLs."))) - -    (defun jao-eww-reopen-new () -      (interactive) -      (jao-eww-reopen t)) -  #+end_src -* Sessions -  #+begin_src emacs-lisp -    (use-package jao-eww-session -      :custom ((jao-eww-session-file "~/.emacs.d/cache/eww-session.eld"))) -  #+end_src -* Package -  #+begin_src emacs-lisp -    (use-package shr -      :custom ((shr-width nil) -               (shr-use-colors t) -               (shr-use-fonts t) -               (shr-max-width 130) -               (shr-blocked-images nil) -               (shr-inhibit-images t) -               (shr-max-image-proportion 1.0) -               (shr-hr-line ?โ))) - -    (use-package eww -      :demand t -      :custom ((eww-browse-url-new-window-is-tab nil) -               (eww-download-directory jao-sink-dir) -               (eww-header-line-format " %u") -               (eww-form-checkbox-selected-symbol "โ") -               (eww-buffer-name-length 180)) - -      :config -      (with-eval-after-load "org" (require 'ol-eww nil t)) - -      (defun jao-eww-buffer-name () -        (when-let ((s (or (plist-get eww-data :title) -                          (plist-get eww-data :url)))) -          (when (not (string-blank-p s)) (format "%s" s)))) -      (setq eww-auto-rename-buffer #'jao-eww-buffer-name) - -      :bind (:map eww-mode-map (("b" . eww-back-url) -                                ("B" . eww-forward-url) -                                ("d" . jao-download) -                                ("f" . link-hint-open-link) -                                ("F" . embark-on-link) -                                ("L" . eww-forward-url) -                                ("N" . jao-eww-next-image) -                                ("o" . jao-eww-browse) -                                ("O" . jao-eww-browse-new) -                                ("r" . jao-eww-reload) -                                ("s" . eww-search-words) -                                ("S" . jao-eww-browse-new) -                                ("u" . jao-eww-reopen) -                                ("U" . jao-eww-reopen-new) -                                ("w" . org-eww-copy-for-org-mode) -                                ("q" . jao-eww-close) -                                ("x" . jao-rss-subscribe) -                                ("y" . jao-eww-copy-link) -                                ("\\" . eww-view-source) -                                ("C-c C-w" . jao-eww-close) -                                ("M-i" . eww-toggle-images)))) - -  #+end_src -* Fixes for shr image rendering -  #+begin_src emacs-lisp -    (require 'shr) - -    (defun jao-shr--kill-nl (p) -      (save-excursion -        (goto-char p) -        (when (looking-at-p "\n") (delete-char 1)))) - -    (defun jao-shr-tag-img (fn &rest args) -      (let ((p (point))) -        (prog1 (apply fn args) -          (when (> (point) p) (jao-shr--kill-nl p))))) - -    (defun jao-shr-insert (fn &rest args) -      (let ((p (when (and (not (bolp)) -                          (get-text-property (1- (point)) 'image-url)) -                 (point)))) -        (prog1 (apply fn args) -          (when (and p (> (point) p)) (jao-shr--kill-nl p))))) - -    (advice-add 'shr-tag-img :around #'jao-shr-tag-img) -    (advice-add 'shr-insert :around #'jao-shr-insert) - -  #+end_src diff --git a/attic/org/exwm.org b/attic/org/exwm.org deleted file mode 100644 index 65db454..0000000 --- a/attic/org/exwm.org +++ /dev/null @@ -1,551 +0,0 @@ -#+property: header-args :lexical t :tangle yes :comments yes :results silent :shebang ";; -*- lexical-binding: t; -*-" :tangle-mode (identity #o644) -#+title: exwm configuration -#+auto_tangle: t - -* Load and basic config -  #+begin_src emacs-lisp -    (defvar jao-exwm--use-afio t) - -    (jao-load-path "exwm") - -    (use-package exwm -      :ensure t -      :init (setq exwm-debug nil -                  exwm-workspace-number 1 -                  exwm-workspace-show-all-buffers t -                  exwm-workspace-warp-cursor nil -                  exwm-layout-show-all-buffers t -                  exwm-floating-border-color -                  (if (jao-colors-scheme-dark-p) "black" "grey90"))) - -    (use-package exwm-edit :ensure t) -    (require 'exwm) -  #+end_src -* Frame(s) as workspaces -  #+begin_src emacs-lisp -    (defun jao-exwm--new-frame-p () -      (not (frame-parameter nil 'jao-frames-initialized))) - -    (defun jao-exwm--mark-frame (force) -      (prog1 (or force (jao-exwm--new-frame-p)) -        (set-frame-parameter nil 'jao-frames-initialized t))) - -    (defun jao-exwm--goto-main (&optional init) -      (interactive "P") -      (exwm-workspace-switch-create 1) -      (when (jao-exwm--mark-frame init) (jao-trisect))) - -    (defun jao-exwm--goto-mail (&optional init) -      (interactive "P") -      (exwm-workspace-switch-create 2) -      (when (jao-exwm--mark-frame init) -        (jao-afio-open-gnus))) - -    (defun jao-exwm--goto-www (&optional init) -      (interactive "P") -      (exwm-workspace-switch-create 5) -      (when (jao-exwm--mark-frame init) -        (jao-afio-open-www) -        (let ((scroll-bar-mode 'left)) -          (toggle-scroll-bar 1) -          (set-frame-parameter (window-frame) 'scroll-bar-width 12)) -        (jao-toggle-inactive-mode-line))) - -    (defun jao-exwm--goto-docs (&optional init) -      (interactive "P") -      (exwm-workspace-switch-create 4) -      (when (jao-exwm--mark-frame init) -        (jao-afio-open-doc))) - -    (defun jao-exwm-open-doc (file) -      (jao-exwm--goto-docs) -      (jao-find-or-open file)) - -    (defun jao-exwm-no-afio-setup () -      (interactive) -      (defalias 'jao-open-gnus-frame 'jao-exwm--goto-mail) -      (defalias 'jao-goto-www-frame 'jao-exwm--goto-www) -      (setq jao-open-doc-fun #'jao-exwm-open-doc) -      (setq minibuffer-follows-selected-frame t) -      (global-set-key "\C-cf" 'jao-exwm--goto-main) -      (global-set-key "\C-cg" 'jao-exwm--goto-mail) -      (global-set-key "\C-cw" 'jao-exwm--goto-www) -      (global-set-key "\C-cz" 'jao-exwm--goto-docs)) - -    (if jao-exwm--use-afio -        (setq minibuffer-follows-selected-frame nil) -      (jao-exwm-no-afio-setup)) -  #+end_src -* Tracking -  #+begin_src emacs-lisp -    (add-hook 'exwm-workspace-switch-hook 'tracking-remove-visible-buffers) -  #+end_src -* Buffer names -  #+begin_src emacs-lisp -    (defun jao-exwm--use-title-p () -      (and exwm-title (not (string-blank-p exwm-title)))) - -    (defun jao-exwm-rename-buffer/class () -      (unless (jao-exwm--use-title-p) -        (exwm-workspace-rename-buffer exwm-class-name))) - -    (defun jao-exwm-rename-buffer/title () -      (cond ((or (not exwm-instance-name) -                 (jao-exwm--use-title-p)) -             (exwm-workspace-rename-buffer exwm-title)) -            ((string= "Zathura" exwm-class-name) -             (exwm-workspace-rename-buffer -              (format "zathura: %s" (file-name-nondirectory exwm-title)))))) - -    (defun jao-exwm--set-exwm-name () -      (when (not jao-exwm--name) -        (setq jao-exwm--name jao-exwm--current-name -              jao-exwm--current-name nil))) - -    (add-hook 'exwm-mode-hook 'jao-exwm--set-exwm-name) -    (add-hook 'exwm-update-class-hook 'jao-exwm-rename-buffer/class) -    (add-hook 'exwm-update-title-hook 'jao-minibuffer-refresh) -    (add-hook 'exwm-update-title-hook 'jao-exwm-rename-buffer/title) -  #+end_src -* Float windows -  #+begin_src emacs-lisp -    (defvar jao-exwm-max-x (x-display-pixel-width)) -    (defvar jao-exwm-max-y (x-display-pixel-height)) - -    (defun jao-exwm--float-to (x y &optional w h) -      (let* ((w (or w (frame-pixel-width))) -             (h (or h (frame-pixel-height))) -             (x (if (< x 0) (- jao-exwm-max-x (- x) w) x)) -             (y (if (< y 0) (- jao-exwm-max-y (- y) h) y)) -             (p (or (frame-parameter nil 'jao-position) (frame-position)))) -        (exwm-floating-move (- x (car p)) (- y (cdr p))) -        (exwm-layout-enlarge-window-horizontally (- w (frame-pixel-width))) -        (exwm-layout-enlarge-window (- h (frame-pixel-height))) -        (set-frame-parameter nil 'jao-position (cons x y)))) - -    (defun jao-exwm--center-float (&optional w h) -      (interactive) -      (let* ((mx jao-exwm-max-x) -             (my jao-exwm-max-y) -             (w (or w (frame-pixel-width))) -             (h (or h (/ (* w my) mx)))) -        (jao-exwm--float-to (/ (- mx w) 2) (/ (- my h) 2) w h))) - -    (defun jao-exwm--setup-float () -      (set-frame-parameter nil 'jao-position nil) -      (cond ((string= "Firefox" exwm-class-name) -             (jao-exwm--center-float 900 600)) -            ((member exwm-class-name '("mpv" "vlc")) -             (jao-exwm--center-float 1200)))) - -    (defvar jao-exwm-floating-classes '("mpv" "vlc")) -    (setq jao-exwm-floating-classes nil) - -    (defun jao-exwm--maybe-float () -      (when (member exwm-class-name jao-exwm-floating-classes) -        (when (not exwm--floating-frame) -          (exwm-floating-toggle-floating)))) - -    (add-hook 'exwm-floating-setup-hook #'jao-exwm--setup-float) -    (add-hook 'exwm-manage-finish-hook #'jao-exwm--maybe-float) - -  #+end_src -* Minibuffer -  #+begin_src emacs-lisp -    (setq jao-minibuffer-frame-width 271) -    (add-hook 'exwm-workspace-switch-hook #'jao-minibuffer-refresh) -  #+end_src -* System tray -  #+begin_src emacs-lisp -    (require 'exwm-systemtray) -    (exwm-systemtray-enable) - -    (defun jao-exwm--watch-tray (sym newval op where) -      (setq jao-minibuffer-right-margin (* 2 (length newval))) -      (jao-minibuffer-refresh)) - -    (add-variable-watcher 'exwm-systemtray--list #'jao-exwm--watch-tray) -  #+end_src -* Switch to buffer / app -  #+begin_src emacs-lisp -    (defvar-local jao-exwm--name nil) -    (defvar jao-exwm--current-name nil) - -    (defun jao-exwm--check-name (name) -      (or (string= jao-exwm--name name) -          (string= (buffer-name) name) -          (string= exwm-class-name name) -          (string= exwm-title name))) - -    (defun jao-exwm-find-class-buffer (cln) -      (if (jao-exwm--check-name cln) -          (current-buffer) -        (let* ((cur-buff (current-buffer)) -               (bfs (seq-filter (lambda (b) -                                  (and (not (eq b cur-buff)) -                                       (with-current-buffer b -                                         (jao-exwm--check-name cln)))) -                                (buffer-list)))) -          (when (car bfs) (car (reverse bfs)))))) - -    (defun jao-exwm-switch-to-class/title (cln) -      (interactive) -      (when cln -        (if (jao-exwm--check-name cln) -            (current-buffer) -          (when-let ((b (jao-exwm-find-class-buffer cln))) -            (pop-to-buffer b))))) - -    (defun jao-exwm-switch-to-next-class () -      (interactive) -      (jao-exwm-switch-to-class/title exwm-class-name)) - -    (defun jao-exwm-switch-to-next-x () -      (interactive) -      (let ((bfs (seq-filter (lambda (b) (buffer-local-value 'exwm-class-name b)) -                             (buffer-list (window-frame))))) -        (when (car bfs) (switch-to-buffer (car (reverse bfs)))))) - -  #+end_src -* App runner helpers -  #+begin_src emacs-lisp -    (defun jao-exwm-run (command) -      (interactive -       (list (read-shell-command "$ " -                                 (if current-prefix-arg -                                     (cons (concat " " (buffer-file-name)) 0) -                                   "")))) -      (setq jao-exwm--current-name nil) -      (start-process-shell-command command nil command)) - -    (defmacro jao-exwm-runner (&rest args) -      `(lambda () (interactive) (start-process "" nil ,@args))) - -    (defun jao-exwm-workspace (n) -      (if jao-exwm--use-afio -          (jao-afio-goto-nth n) -        (exwm-workspace-switch-create n))) - -    (defmacro jao-def-exwm-runner (name ws class &rest args) -      `(defun ,name (&rest other-args) -         (interactive) -         ,@(when ws `((jao-exwm-workspace ,ws))) -         (if (jao-exwm-switch-to-class/title ,class) -             ,(cond ((equal ws 5) '(delete-other-windows)) -                    ((stringp (car args)) (cdr args)) -                    (t args)) -           (setq jao-exwm--current-name ,class) -           ,(if (stringp (car args)) -                `(start-process-shell-command ,(car args) -                                              "* exwm - console *" -                                              (string-join (append (list ,@args) -                                                                   other-args) -                                                           " ")) -              args)))) - -    (defmacro jao-def-exwm-toggler (name ws class &rest args) -      (let ((toggler (intern (format "%s*" name))) -            (arg (gensym))) -        `(progn (jao-def-exwm-runner ,name ,ws ,class ,@args) -                (defun ,toggler (,arg) -                  (interactive "P") -                  (if (and (not ,arg) (equal exwm-class-name ,class)) -                      (jao-afio--goto-main) -                    (,name)))))) - -    (defun jao-exwm--send-str (str) -      (dolist (k (string-to-list (kbd str))) -        (exwm-input--fake-key k))) - -  #+end_src -* Runners -  #+begin_src emacs-lisp -    (jao-def-exwm-runner jao-exwm-vlc 4 "VLC" "vlc") - -    (jao-def-exwm-runner jao-exwm-slack 0 "Slack" "slack") -    (jao-def-exwm-runner jao-exwm-signal 0 "Signal" "signal-desktop") - -    (jao-def-exwm-runner jao-exwm-proton-bridge 0 "*proton-bridge*" "protonmail-bridge") - -    ;; (jao-def-exwm-runner jao-exwm-htop 0 "htop-xterm" -    ;;                 "xterm" "-title" "htop-xterm" "-e" "htop") -    (jao-def-exwm-runner jao-exwm-htop 0 "htop" jao-term-htop) - -    ;; (jao-def-exwm-runner jao-exwm-aptitude 0 "aptitude-xterm" -    ;;                 "xterm" "-title" "aptitude-xterm" "-e" "aptitude") -    (jao-def-exwm-runner jao-exwm-aptitude 0 "aptitude" jao-term-aptitude) - -    (jao-def-exwm-runner jao-exwm-blueman 0 "Blueman-manager" "blueman-manager") -    (jao-def-exwm-runner jao-exwm-ncmpcpp 0 "ncmpcpp" "xterm" "-e" "ncmpcpp" "-p" "6669") -    (jao-def-exwm-runner jao-exwm-mpc 0 "*MPC-Status*" mpc) - -    (jao-def-exwm-runner jao-exwm-proton-vpn 0 "*pvpn*" proton-vpn-status) -    (jao-def-exwm-runner jao-exwm-enwc 0 "*ENWC*" enwc) -    (jao-def-exwm-runner jao-exwm-bluetooth 0 "*Bluetooth*" bluetooth-list-devices) -    (jao-def-exwm-runner jao-exwm-packages 0 "*Packages*" list-packages nil) -    (jao-def-exwm-runner jao-exwm-proced 0 "*Proced*" proced) - -    (jao-def-exwm-runner jao-exwm-open-with-zathura nil nil "zathura" (buffer-file-name)) -    (jao-def-exwm-runner jao-exwm-open-with-mupdf nil nil "mupdf" (buffer-file-name)) -    (jao-def-exwm-runner jao-exwm-xterm 0 nil "xterm") - -    (jao-def-exwm-toggler jao-exwm-tidal 5 "tidal-hifi" "tidal-hifi") -    (defalias 'jao-streaming-list #'jao-exwm-tidal) - -    (defun jao-exwm-import-screen (&optional area) -      (interactive "P") -      (when (not (file-directory-p "/tmp/screenshot")) -        (make-directory "/tmp/screenshot")) -      (let ((c (format "import %s %s" -                       (if area "" "-window root") -                       "/tmp/screenshot/$(date +'%g%m%d-%H%M%S').png"))) -        (start-process-shell-command "import" "* exwm - console *" c))) - -  #+end_src -* Zathura support -  #+begin_src emacs-lisp -    (defun jao-zathura--buffer-p (b) -      (string= "Zathura" (or (buffer-local-value 'exwm-class-name b) ""))) - -    (defun jao-zathura--buffers () -      (seq-filter #'jao-zathura--buffer-p (buffer-list))) - -    (defun jao-zathura--file-info (b) -      (with-current-buffer b -        (jao-zathura-file-info (or exwm-title "")))) - -    (defun jao-zathura-goto-page (page-no) -      (jao-exwm--send-str (format "%sg" page-no))) - -    (defun jao-zathura-open-doc (&optional file-name page-no height) -      (interactive) -      (let* ((file-name (expand-file-name (or file-name (buffer-file-name)))) -             (buffer (seq-find `(lambda (b) -                                    (string= ,file-name -                                             (car (jao-zathura--file-info b)))) -                               (jao-zathura--buffers))) -             (page-no (or page-no (jao-doc-view-current-page)))) -        (if jao-exwm--use-afio (jao-afio--goto-docs) (jao-exwm--goto-docs)) -        (if (not buffer) -            (jao-exwm-run (if page-no -                              (format "zathura -P %s '%s'" page-no file-name) -                            (format "zathura '%s'" file-name))) -          (pop-to-buffer buffer) -          (when page-no (jao-zathura-goto-page page-no))) -        (current-buffer))) - -    (defun jao-exwm--zathura-setup () -      (when (and (string= exwm-class-name "Zathura") -                 (not jao-doc-view--imenu-file)) -        (let ((info (jao-zathura--file-info (current-buffer)))) -          (jao-doc-view-session-mark (car info)) -          (jao-doc-view-save-session) -          (jao-doc-view--enable-imenu (car info) #'jao-zathura-goto-page)))) - -    (add-hook 'exwm-update-title-hook #'jao-exwm--zathura-setup t) - -    (defun jao-exwm-pdf-zathura-close-all () -      (interactive) -      (dolist (b (jao-zathura--buffers)) -        (ignore-errors -          (switch-to-buffer b) -          (jao-exwm--send-str "q"))) -      t) - -    (defun jao-exwm-zathura-goto-org (&optional arg) -      (interactive "P") -      (when-let ((info (jao-zathura--file-info (current-buffer)))) -        (when-let ((file (jao-org-pdf-to-org-file (car info)))) -          (let ((newp (not (file-exists-p file)))) -            (when (or arg newp) (org-store-link nil t)) -            (find-file-other-window file) -            (when newp -              (jao-org-insert-doc-skeleton) -              (org-insert-link)))))) - -    (defun jao-exwm-zathura-goto-org* () -      (interactive) -      (jao-exwm-zathura-goto-org t)) - -    (defun jao-exwm-org-store-zathura-link () -      (when-let ((info (jao-zathura--file-info (current-buffer)))) -        (let* ((file-name (car info)) -               (page (cadr info)) -               (desc (jao-doc-view-section-title page file-name))) -          (jao-org-links-store-pdf-link file-name page desc)))) - -    (defun jao-exwm-pdf-enable-zathura () -      (interactive) -      (add-hook 'kill-emacs-query-functions #'jao-exwm-pdf-zathura-close-all t) -      (setq jao-org-open-pdf-fun #'jao-zathura-open-doc) -      (setq jao-org-links-pdf-store-fun #'jao-exwm-org-store-zathura-link) -      (setq jao-open-doc-fun #'jao-zathura-open-doc)) - -    (defun jao-exwm-pdf-disable-zathura () -      (interactive) -      (define-key org-mode-map (kbd "C-c o") #'jao-org-org-goto-pdf) -      (remove-hook 'kill-emacs-query-functions #'jao-exwm-pdf-zathura-close-all) -      (setq jao-org-open-pdf-fun #'jao-find-or-open) -      (setq jao-org-links-pdf-store-fun nil) -      (setq jao-open-doc-fun #'jao-find-or-open)) - -    (defun jao-exwm-zathura-goto-pdf () -      (interactive) -      (if jao-browse-doc-use-emacs-p -          (jao-org-org-goto-pdf) -        (when-let (pdf (jao-org-org-to-pdf-file)) -          (jao-zathura-open-doc pdf)))) - -    (with-eval-after-load "org" -      (define-key org-mode-map (kbd "C-c o") #'jao-exwm-zathura-goto-pdf)) - -    (when (not jao-browse-doc-use-emacs-p) -      (jao-exwm-pdf-enable-zathura)) - -    (defun jao-exwm-select-pdf () -      (interactive) -      (let ((b (read-buffer "Document: " nil t -                            (lambda (b) -                              (let ((b (cdr b))) -                                (or (jao-zathura--buffer-p b) -                                    (member (buffer-local-value 'major-mode b) -                                            '(pdf-view-mode doc-view-mode)))))))) -        (jao-afio--goto-docs) -        (pop-to-buffer b))) - - -    (let ((viewers ["External viewers" -                    ("z" "open with zathura" jao-zathura-open-doc) -                    ("m" "open with mupdf" jao-exwm-open-with-mupdf)])) -      (jao-transient-major-mode+ pdf-view viewers) -      (jao-transient-major-mode+ doc-view viewers)) - -  #+end_src -* Firefox support -  #+begin_src emacs-lisp -    (jao-def-exwm-toggler jao-exwm-firefox 5 "Firefox" "firefox") - -    (defun jao-exwm-browse-with-firefox (&rest args) -      (jao-exwm-firefox) -      (apply #'browse-url-firefox args)) - -    (setq browse-url-secondary-browser-function #'jao-exwm-browse-with-firefox) - -    (defun jao-exwm-kill-firefox-url () -      (interactive) -      (when-let (b (jao-exwm-find-class-buffer "Firefox")) -        (let ((cb (current-buffer))) -          (switch-to-buffer b) -          (jao-exwm--send-str "yy") -          (prog1 (current-kill 1) -           (switch-to-buffer cb))))) - -  #+end_src -* Transients -  #+begin_src emacs-lisp -    (defun jao-exwm--floating-p () exwm--floating-frame) -    (defun jao-exwm--m0-5 () (interactive nil exwm-mode) (exwm-floating-move 0 -5)) -    (defun jao-exwm--m05 () (interactive nil exwm-mode) (exwm-floating-move 0 5)) -    (defun jao-exwm--m-50 () (interactive nil exwm-mode) (exwm-floating-move -5 0)) -    (defun jao-exwm--m50 () (interactive nil exwm-mode) (exwm-floating-move 5 0)) -    (defun jao-exwm--e-5 () (interactive nil exwm-mode) (exwm-layout-enlarge-window -5)) -    (defun jao-exwm--e5 () (interactive nil exwm-mode) (exwm-layout-enlarge-window 5)) -    (defun jao-exwm--eh5 () (interactive nil exwm-mode) (exwm-layout-enlarge-window 5 t)) -    (defun jao-exwm--eh-5 () (interactive nil exwm-mode) (exwm-layout-enlarge-window -5 t)) -    (defun jao-exwm--tl () (interactive nil exwm-mode) (jao-exwm--float-to 20 20)) -    (defun jao-exwm--tr () (interactive nil exwm-mode) (jao-exwm--float-to -20 20)) -    (defun jao-exwm--bl () (interactive nil exwm-mode) (jao-exwm--float-to 20 -20)) -    (defun jao-exwm--br () (interactive nil exwm-mode) (jao-exwm--float-to -20 -20)) - -    (defun jao-exwm--def-center-float () -      (interactive) -      (exwm-floating-toggle-floating) -      (jao-exwm--center-float 900 600)) - -    (transient-define-prefix jao-transient-float () -      "Operations on EXWM floating windows." -      :transient-non-suffix 'transient--do-quit-one -      [["Float" -        ("f" "float" exwm-floating-toggle-floating) -        ("F" "full" exwm-layout-toggle-fullscreen) -        ("c" "center" jao-exwm--center-float :if jao-exwm--floating-p) -        ("c" "float and resize" jao-exwm--def-center-float -         :if-not jao-exwm--floating-p) -        ("x" "hide" exwm-floating-hide :if jao-exwm--floating-p)] -       ["Slide" :if jao-exwm--floating-p -        ("k" "up" jao-exwm--m0-5 :transient t) -        ("j" "down" jao-exwm--m05 :transient t) -        ("h" "left" jao-exwm--m-50 :transient t) -        ("l" "right" jao-exwm--m50 :transient t)] -       ["Resize" :if jao-exwm--floating-p -        ("K" "up" jao-exwm--e5 :transient t) -        ("J" "down" jao-exwm--e-5 :transient t) -        ("H" "left" jao-exwm--eh5 :transient t) -        ("L" "right" jao-exwm--eh-5 :transient t)] -       ["Nudge" :if jao-exwm--floating-p -        ("t" "top-left" jao-exwm--tl) -        ("T" "top-right" jao-exwm--tr) -        ("b" "bottom-left" jao-exwm--bl) -        ("B" "bottom-right " jao-exwm--br)]]) - -    (defun jao-exwm--buffer () -      (interactive) -      (jao-buffer-same-mode 'exwm-mode nil 'exwm-workspace-switch-to-buffer)) - -  #+end_src -* Keybindings -  #+begin_src emacs-lisp -    (define-key exwm-mode-map [?\C-q] #'exwm-input-send-next-key) -    (define-key exwm-mode-map [?\s-f] #'jao-transient-float) -    (define-key exwm-mode-map (kbd "C-c o") #'jao-exwm-zathura-goto-org) -    (define-key exwm-mode-map (kbd "C-c O") #'jao-exwm-zathura-goto-org*) -    (define-key exwm-mode-map (kbd "M-o") #'other-window) -    (define-key exwm-mode-map (kbd "M-p") #'jao-prev-window) - -    (setq -     exwm-input-global-keys -     '(([?\s-0] . jao-afio--goto-scratch) -       ([?\s-1] . jao-afio--goto-main) -       ([?\s-2] . jao-afio--goto-mail) -       ([?\s-3] . jao-afio--goto-www) -       ([?\s-4] . jao-afio--goto-docs) -       ([?\s-A] . org-agenda-list) -       ([?\s-a] . jao-first-window) -       ([?\s-b] . jao-transient-org-blog) -       ;; ([?\s-d] . jao-exwm-tidal*) -       ([?\s-d] . jao-mpc-echo-current) -       ([?\s-e] . jao-exwm-firefox*) -       ([?\s-m] . jao-transient-media) -       ;; ([?\s-O] . jao-transpose-windows) -       ;; ([?\s-o] . jao-other-window) -       ;; ([?\s-P] . jao-transpose-windows-prev) -       ([?\s-O] . ace-swap-window) -       ([?\s-o] . ace-window) -       ([?\s-p] . jao-prev-window) -       ([?\s-R] . app-launcher-run-app) -       ([?\s-r] . jao-recoll-transient) -       ([?\s-s] . jao-transient-streaming) -       ([?\s-t] . vterm) -       ([?\s-w] . jao-transient-utils) -       ([?\s-z] . jao-transient-sleep) -       ([XF86AudioMute] . jao-mixer-master-toggle) -       ([XF86AudioPlay] . jao-player-toggle) -       ([XF86AudioPause] . jao-player-toggle) -       ([XF86AudioNext] . jao-player-next) -       ([XF86AudioPrev] . jao-player-previous) -       ([XF86AudioStop] . jao-player-stop) -       ([XF86AudioRaiseVolume] . jao-mixer-master-up) -       ([XF86AudioLowerVolume] . jao-mixer-master-down) -       ([XF86MonBrightnessUp] . jao-bright-up) -       ([XF86MonBrightnessDown] . jao-bright-down) -       ([?\s-\`] . jao-exwm-switch-to-next-x) -       ([s-tab] . jao-exwm-switch-to-next-class) -       ([print] . jao-exwm-import-screen) -       ([f5] . jao-weather) -       ([f6] . jao-toggle-audio-applet) -       ([f8] . jao-toggle-nm-applet) -       ([f9] . jao-bright-show))) - -    ;; (customize-set-variable 'exwm-input-global-keys exwm-input-global-keys) - -  #+end_src diff --git a/attic/org/gnus.org b/attic/org/gnus.org deleted file mode 100644 index c0c0346..0000000 --- a/attic/org/gnus.org +++ /dev/null @@ -1,780 +0,0 @@ -#+property: header-args :lexical t :tangle ~/.emacs.d/gnus.el :comments yes :results silent :shebang ";; -*- lexical-binding: t -*-" :tangle-mode (identity #o644) -#+title: Gnus - -* Feature switching vars -  #+begin_src emacs-lisp -    (defvar jao-gnus-use-local-imap nil) -    (defvar jao-gnus-use-leafnode nil) -    (defvar jao-gnus-use-gandi-imap nil) -    (defvar jao-gnus-use-pm-imap nil) -    (defvar jao-gnus-use-gmane nil) -    (defvar jao-gnus-use-nnml nil) -    (defvar jao-gnus-use-maildirs nil) -  #+end_src -* Startup and kill -  #+begin_src emacs-lisp -    ;;;;; close gnus when closing emacs, but ask when exiting -    (setq gnus-interactive-exit t) - -    (defun jao-gnus-started-hook () -      (add-hook 'before-kill-emacs-hook 'gnus-group-exit)) - -    (add-hook 'gnus-started-hook 'jao-gnus-started-hook) - -    (defun jao-gnus-after-exiting-hook () -      (remove-hook 'before-kill-emacs-hook 'gnus-group-exit)) - -    (add-hook 'gnus-after-exiting-gnus-hook 'jao-gnus-after-exiting-hook) - -    ;; define a wrapper around the save-buffers-kill-emacs -    ;; to run the new hook before: -    (defadvice save-buffers-kill-emacs -        (before my-save-buffers-kill-emacs activate) -      "Install hook when emacs exits before emacs asks to save this and that." -      (run-hooks 'before-kill-emacs-hook)) -  #+end_src -* Directories -  #+begin_src emacs-lisp -    (defun jao-gnus-dir (dir) -      (expand-file-name dir gnus-home-directory)) - -    (setq smtpmail-queue-dir (jao-gnus-dir "Mail/queued-mail/")) - -    (setq mail-source-directory (jao-gnus-dir "Mail/") -          message-directory (jao-gnus-dir "Mail/")) - -    (setq gnus-default-directory (expand-file-name "~") -          gnus-startup-file (jao-gnus-dir "newsrc") -          gnus-agent-directory (jao-gnus-dir "News/agent") -          gnus-home-score-file (jao-gnus-dir "scores") -          gnus-article-save-directory (jao-gnus-dir "saved/") -          nntp-authinfo-file (jao-gnus-dir "authinfo") -          nnmail-message-id-cache-file (jao-gnus-dir "nnmail-cache") -          nndraft-directory (jao-gnus-dir "drafts") -          nnrss-directory (jao-gnus-dir "rss")) -  #+end_src -* Looks -*** Verbosity -    #+begin_src emacs-lisp -      (setq gnus-verbose 4) -    #+end_src -*** Geometry -    #+begin_src emacs-lisp -      ;;; geometry: -      (defvar jao-gnus-use-three-panes window-system) -      (defvar jao-gnus-groups-width 50) -      (defvar jao-gnus-wide-width 190) - -      (setq gnus-use-trees nil -            gnus-generate-tree-function 'gnus-generate-horizontal-tree -            gnus-tree-minimize-window nil) - -      (when jao-gnus-use-three-panes -        (let ((side-bar '(vertical 1.0 -                                   ("inbox.org" 0.4) -                                   ("*Org Agenda*" 1.0) -                                   ("*Calendar*" 8))) -              (wide-len jao-gnus-wide-width) -              (groups-len jao-gnus-groups-width) -              (summary-len (- jao-gnus-wide-width jao-gnus-groups-width))) -          (gnus-add-configuration -           `(article -             (horizontal 1.0 -                         (vertical ,groups-len (group 1.0)) -                         (vertical ,summary-len -                                   (summary 0.25 point) -                                   (article 1.0)) -                         ,side-bar))) - -          (gnus-add-configuration -           `(group (horizontal 1.0 (group ,wide-len point) ,side-bar))) - -          (gnus-add-configuration -           `(message (horizontal 1.0 (message ,wide-len point) ,side-bar))) - -          (gnus-add-configuration -           `(reply-yank (horizontal 1.0 (message ,wide-len point) ,side-bar))) - -          (gnus-add-configuration -           `(summary -             (horizontal 1.0 -                         (vertical ,groups-len (group 1.0)) -                         (vertical ,summary-len (summary 1.0 point)) -                         ,side-bar))) - -          (gnus-add-configuration -           `(reply -             (horizontal 1.0 -                         (message ,(- wide-len 100) point) -                         (article 100) -                         ,side-bar))))) -    #+end_src -*** No blue icon -    #+begin_src emacs-lisp -      (advice-add 'gnus-mode-line-buffer-identification :override #'identity) -      (setq gnus-mode-line-image-cache nil) -    #+end_src -* Search -  #+begin_src emacs-lisp - -    (setq gnus-search-use-parsed-queries t -          gnus-search-notmuch-raw-queries-p nil -          gnus-permanently-visible-groups "^nnselect:.*" -          gnus-search-ignored-newsgroups "nndraft.*\\|nnselect.*") - -    (with-eval-after-load "gnus-search" -      (add-to-list 'gnus-search-expandable-keys "list") - -      (cl-defmethod gnus-search-transform-expression ((engine gnus-search-notmuch) -                                                      (expr (head list))) -        (format "List:%s" (gnus-search-transform-expression engine (cdr expr))))) - -    (defun jao-gnus--notmuch-engine (prefix config) -      (let ((prefix (file-name-as-directory (expand-file-name prefix "~"))) -            (config (expand-file-name config gnus-home-directory))) -        `(gnus-search-engine gnus-search-notmuch -                             (remove-prefix ,prefix) -                             (config-file ,config)))) - -    ;; (add-to-list 'gnus-parameters '("^nnselect:.*" (nnselect-rescan . t))) - -  #+end_src -* News server -  #+begin_src emacs-lisp -    (setq gnus-select-method -          (cond -           (jao-gnus-use-leafnode -            `(nntp "localhost" -                   ,(jao-gnus--notmuch-engine "var/news" "notmuch-news.config"))) -           (jao-gnus-use-gmane '(nntp "news.gmane.io")) -           (t '(nnnil "")))) - -    (setq gnus-secondary-select-methods '()) - -    (setq nnheader-read-timeout 0.02 -          gnus-save-newsrc-file nil) ; .newsrc only needed by other newsreaders -  #+end_src -* Local mail -*** nnmail params -    #+begin_src emacs-lisp -      (setq nnmail-treat-duplicates 'delete -            nnmail-scan-directory-mail-source-once nil -            nnmail-cache-accepted-message-ids t -            nnmail-message-id-cache-length 100000 -            nnmail-split-fancy-with-parent-ignore-groups nil -            nnmail-use-long-file-names t -            nnmail-crosspost t -            nnmail-resplit-incoming t -            nnmail-mail-splitting-decodes t -            nnmail-split-methods 'nnmail-split-fancy) -    #+end_src -*** nnml -    #+begin_src emacs-lisp -      (setq mail-sources -            (when jao-gnus-use-nnml -              (cons '(file :path "/var/mail/jao") -                    (when (eq jao-afio-mail-function 'gnus) -                      (mapcar (lambda (d) `(maildir :path ,(concat d "/"))) -                              (directory-files "~/var/mail" t "[^\\.]"))))) -            gnus-message-archive-group nil -            nnml-get-new-mail t -            nnml-directory message-directory) - -      (when jao-gnus-use-nnml -        (add-to-list -         'gnus-secondary-select-methods -         `(nnml "" ,(jao-gnus--notmuch-engine (jao-gnus-dir "Mail") "notmuch.config")))) - -      (defvar jao-gnus-nnml-group-params -        `(("nnml:\\(local\\|trash\\|spam\\)" -           (auto-expire . t) -           (total-expire . t) -           (expiry-wait . 1) -           (expiry-target . delete)) -          ("nnml:jao\\..*" -           (posting-style ("Bcc" "proton@jao.io") -                          ("Gcc" "nnml:jao.trove")) -           (jao-gnus--trash-group "nnml:trash") -           (jao-gnus--spam-group "nnml:spam") -           (jao-gnus--archiving-group "nnml:jao.trove")) -          ("nnml:bigml\\..*" -           (gcc-self . nil) -           (auto-expire . t) -           (total-expire . t) -           (expiry-wait . 3) -           (expiry-target . delete) -           (posting-style (address "jao@bigml.com")) -           (jao-gnus--trash-group "nnml:trash") -           (jao-gnus--spam-group "nnml:spam") -           (jao-gnus--archiving-group "nnml:bigml.trove")) -          ("nnml:bigml\\.\\(inbox\\|support\\)" -           (gcc-self . t) -           (auto-expire . t) -           (total-expire . t) -           (expiry-wait . 7) -           (expiry-target . "nnml:bigml.trove")) -          ("nnml:bigml\\.trove" -           (auto-expire . t) -           (total-expire . t) -           (expiry-target . delete) -           (expiry-wait . 365)) -          ("nnml:jao\\.drivel" -           (auto-expire . t) -           (total-expire . t) -           (expiry-wait . 3) -           (expiry-target . delete)) -          ("nnml:feeds\\.\\(.*\\)" -           (auto-expire . t) -           (total-expire . t) -           (expiry-wait . 7) -           (expiry-target . delete) -           (comment . "feeds.\\1") -           (jao-gnus--archiving-group "nnml:feeds.trove")) -          ("^nnml:feeds\\.\\(news\\)$" (expiry-wait . 2)) -          ("nnml:feeds\\.\\(trove\\|lobsters\\|philosophy\\)" -           (auto-expire . nil) -           (total-expire . nil)) -          ("nnml:feeds\\.fun" -           (mm-html-inhibit-images nil) -           (mm-html-blocked-images nil)))) - -      (when jao-gnus-use-nnml -        (dolist (p jao-gnus-nnml-group-params) -          (add-to-list 'gnus-parameters p t))) - -    #+end_src -*** leafnode -    #+begin_src emacs-lisp -      (defvar jao-gnus-image-groups '("xkcd")) - -      (defvar jao-gnus-leafnode-group-params -        `((,(format "gwene\\..*%s.*" (regexp-opt jao-gnus-image-groups)) -           (mm-html-inhibit-images nil) -           (mm-html-blocked-images nil)) -          ("\\(gmane\\|gwene\\)\\..*" -           (jao-gnus--archiving-group "nnml:feeds.trove") -           (posting-style (address "jao@gnu.org"))))) - -      (when jao-gnus-use-leafnode -        (dolist (p jao-gnus-leafnode-group-params) -          (add-to-list 'gnus-parameters p t))) - -    #+end_src -*** maildirs -      #+begin_src emacs-lisp -        (when jao-gnus-use-maildirs -          (add-to-list -           'gnus-secondary-select-methods -           `(nnmaildir "mail" -                       (directory "~/.nnmaildirs") -                       ,(jao-gnus--notmuch-engine "~/var/mail/" -                                                  "~/.notmuch-config")))) - -      #+end_src -* IMAP servers -  #+begin_src emacs-lisp -    (setq nnimap-quirks nil) - -    (when jao-gnus-use-local-imap -      (add-to-list 'gnus-secondary-select-methods -                   `(nnimap "" (nnimap-address "localhost")))) - -    (when jao-gnus-use-pm-imap -      (add-to-list 'gnus-secondary-select-methods -                   '(nnimap "pm" -                            (nnimap-address "127.0.0.1") -                            (nnimap-stream network) -                            (nnimap-server-port 1143)))) - -    (when jao-gnus-use-gandi-imap -      (add-to-list 'gnus-secondary-select-methods -                   '(nnimap "gandi" (nnimap-address "mail.gandi.net")))) -  #+end_src -* Demon and notifications -  #+begin_src emacs-lisp -    (setq mail-user-agent 'gnus-user-agent) - -    ;; synchronicity -    (setq gnus-asynchronous t) -    ;;; prefetch as many articles as possible -    (setq gnus-use-article-prefetch nil) - -    (setq gnus-save-killed-list nil) -    (setq gnus-check-new-newsgroups nil) - -    (defvar jao-gnus-tracked-groups -      (let ((feeds (thread-first -                     (directory-files mail-source-directory nil "feeds") -                     (seq-difference '("feeds.trove"))))) -        `(("nnml:bigml.inbox" "B" jao-themes-f00) -          ("nnml:bigml.bugs" "b" jao-themes-error) -          ("nnml:bigml.support" "S" default) -          ("nnml:jao.inbox" "I" jao-themes-f01) -          ("nnml:bigml.[^ibs]" "W" jao-themes-dimm) -          ("nnml:jao.[^ist]" "J" jao-themes-dimm) -          (,(format "^nnml:%s" (regexp-opt feeds)) "F" jao-themes-dimm) -          ("^gmane" "G" jao-themes-dimm) -          ("nnml:local" "l" jao-themes-dimm)))) - -    (defun jao-gnus--unread-counts () -      (seq-reduce (lambda (r g) -                    (let ((n (gnus-group-unread (car g)))) -                      (if (and (numberp n) (> n 0)) -                          (prog1 (cons (cons (car g) n) r) -                            (gnus-message 7 "%s in %s" n g)) -                        r))) -                  gnus-newsrc-alist -                  ())) - -    (defun jao-gnus--unread-label (counts rx label face) -      (let ((n (seq-reduce (lambda (n c) -                             (if (string-match-p rx (car c)) (+ n (cdr c)) n)) -                           counts -                           0))) -        (when (> n 0) `(:propertize ,(format "%s%d " label n) face ,face)))) - -    (defvar jao-gnus--notify-strs ()) - -    (defun jao-gnus--notify-strs () -      (let ((counts (jao-gnus--unread-counts))) -        (seq-filter #'identity -                    (seq-map (lambda (args) -                               (apply 'jao-gnus--unread-label counts args)) -                             jao-gnus-tracked-groups)))) - -    (defun jao-gnus--notify () -      (setq jao-gnus--notify-strs (jao-gnus--notify-strs)) -      (save-window-excursion (jao-minibuffer-refresh))) - -    (defun jao-gnus-scan () -      (interactive) -      (let ((inhibit-message t)) -        (gnus-demon-scan-mail) -        (shell-command "index-mail.sh") -        (save-window-excursion ) -        (jao-gnus--notify))) - -    (require 'gnus-demon) -    (gnus-demon-add-handler 'gnus-demon-scan-news 5 1) -    ;; (gnus-demon-remove-handler 'jao-gnus-scan) - -    (add-hook 'gnus-started-hook #'jao-gnus-scan) -    (add-hook 'gnus-summary-exit-hook #'jao-gnus--notify) -    (add-hook 'gnus-summary-exit-hook #'org-agenda-list) -    (add-hook 'gnus-after-getting-new-news-hook #'jao-gnus-scan) - -    (with-eval-after-load "jao-minibuffer" -      (jao-minibuffer-add-variable 'jao-gnus--notify-strs -20)) - -  #+end_src -* Delayed messages -  #+BEGIN_SRC emacs-lisp -    ;;; delayed messages (C-cC-j in message buffer) -    (require 'gnus-util) -    (gnus-delay-initialize) -    (setq gnus-delay-default-delay "3h") -    ;;; so that the Date is set when the message is sent, not when it's -    ;;; delayed -    (eval-after-load "message" -      '(setq message-draft-headers (remove 'Date message-draft-headers))) -  #+END_SRC -* Groups buffer -  #+begin_src emacs-lisp -    ;; (setq gnus-group-line-format " %m%S%p%P:%~(pad-right 35)c %3y %B\n") -    ;; (setq gnus-group-line-format " %m%S%p%3y%P%* %~(pad-right 30)C %B\n") -    (setq gnus-group-line-format " %m%S%p%3y%P%* %~(pad-right 30)G %B\n") -    (setq gnus-topic-line-format "%i[ %(%{%n%}%) -- %A ]%v\n") -    (setq gnus-group-uncollapsed-levels 2) -    (setq gnus-auto-select-subject 'unread) -    (setq-default gnus-large-newsgroup 2000) - -    (add-hook 'gnus-select-group-hook 'gnus-group-set-timestamp) -    (add-hook 'gnus-group-mode-hook 'gnus-topic-mode) - -    (defvar jao-gnus--expire-every 50) -    (defvar jao-gnus--get-count (1+ jao-gnus--expire-every)) - -    (defun jao-gnus-get-new-news (&optional arg) -      (interactive "p") -      (when (and jao-gnus--expire-every -                 (> jao-gnus--get-count jao-gnus--expire-every)) -        (when jao-gnus-use-pm-imap (gnus-group-catchup "nnimap:pm/spam" t)) -        (gnus-group-expire-all-groups) -        (setq jao-gnus--get-count 0)) -      (setq jao-gnus--get-count (1+ jao-gnus--get-count)) -      (gnus-group-get-new-news (max (if (= 1 jao-gnus--get-count) 4 3) -                                    (or arg 0)))) - -    ;; (define-key gnus-group-mode-map "g" 'jao-gnus-get-new-news) - -    (defun jao-gnus-restart-servers () -      (interactive) -      (message "Restarting all servers...") -      (gnus-group-enter-server-mode) -      (gnus-server-close-all-servers) -      (gnus-server-open-all-servers) -      (gnus-server-exit) -      (message "Restarting all servers... done")) - -    (define-key gnus-group-mode-map "\C-x\C-s" #'gnus-group-save-newsrc) - -    (jao-transient-major-mode gnus-group -      ["Search" -       ("zc" "consult search" consult-notmuch) -       ("zf" "consult folder search" jao-consult-notmuch-folder) -       ("g" "gnus search" gnus-group-read-ephemeral-search-group)]) - -    (defun jao-gnus--first-group () -      (when (derived-mode-p 'gnus-group-mode) -        (gnus-group-first-unread-group))) - -    (with-eval-after-load "jao-afio" -      (add-hook 'jao-afio-switch-hook #'jao-gnus--first-group)) -    #+end_src -* Summary buffer -*** Configuration -    #+begin_src emacs-lisp -      (setq gnus-face-1 'jao-gnus-face-tree) - -      (setq gnus-show-threads t -            gnus-thread-hide-subtree t -            gnus-summary-make-false-root 'adopt -            gnus-summary-gather-subject-limit 120 -            gnus-sort-gathered-threads-function 'gnus-thread-sort-by-date -            gnus-thread-sort-functions '(gnus-thread-sort-by-date)) - -      (setq gnus-summary-ignore-duplicates t -            gnus-suppress-duplicates t -            ;; gnus-summary-ignored-from-addresses jao-mails-regexp -            gnus-process-mark-toggle t -            gnus-refer-thread-use-search t -            gnus-auto-select-next 'almost-quietly) -    #+end_src -*** Search -    #+begin_src emacs-lisp -      (defun jao-gnus--maybe-reselect (&rest _i) -        (when (string-match-p "^nnselect" (or (gnus-group-name-at-point) "")) -          (save-excursion (gnus-group-get-new-news-this-group)))) - -      (advice-add 'gnus-group-select-group :before #'jao-gnus--maybe-reselect) -    #+end_src -*** Summary line -    #+begin_src emacs-lisp -      (setq gnus-not-empty-thread-mark ?โ) ; โ) ?ยท -      (setq jao-gnus--summary-line-fmt -            (concat "%%U %%*%%R %%uj " -                    "[ %%~(max-right 23)~(pad-right 23)uf " -                    " %%I%%~(pad-left 2)t ] %%s" -                    "%%-%s=" -                    "%%~(max-right 8)~(pad-left 8)&user-date;" -                    "\n")) - -      (defun jao-gnus--set-summary-line (&optional w) -        (let* ((d (if jao-gnus-use-three-panes (+ jao-gnus-groups-width 11) 12)) -               (w (- (or w (window-width)) d))) -          (setq gnus-summary-line-format (format jao-gnus--summary-line-fmt w)))) - -      (add-hook 'gnus-select-group-hook 'jao-gnus--set-summary-line) -      ;; (jao-gnus--set-summary-line 187) - -      (add-to-list 'nnmail-extra-headers 'Cc) -      (add-to-list 'nnmail-extra-headers 'BCc) -      (add-to-list 'gnus-extra-headers 'Cc) -      (add-to-list 'gnus-extra-headers 'BCc) - -      (defun gnus-user-format-function-j (headers) -        (let ((to (gnus-extra-header 'To headers))) -          (if (string-match jao-mails-regexp to) -              (if (string-match "," to) "ยฌ" "ยป") ;; "~" "=") -            (if (or (string-match jao-mails-regexp -                                  (gnus-extra-header 'Cc headers)) -                    (string-match jao-mails-regexp -                                  (gnus-extra-header 'BCc headers))) -                "ยฌ" ;; "~" -              " ")))) - -      (defconst jao-gnus--news-rx -        (concat (regexp-opt '("ElDiaro.es " -                              "ElDiario.es - ElDiario.es: " -                              "The Guardian: " -                              "Aeon | a world of ideas: " -                              ": <author>")) -                "\\|unofficial mirror of [^:]+: ")) - -      (defun gnus-user-format-function-f (headers) -        (let* ((from (gnus-header-from headers)) -               (from (gnus-summary-extract-address-component from))) -          (replace-regexp-in-string jao-gnus--news-rx "" from))) - -      (setq gnus-user-date-format-alist -            '(((gnus-seconds-today) . "%H:%M") -              ((+ 86400 (gnus-seconds-today)) . "'%H:%M") -              ;; (604800 . "%a %H:%M") ;; that's one week -              ((gnus-seconds-month) . "%a %d") -              ((gnus-seconds-year) . "%b %d") -              (t . "%b '%y"))) - -    #+end_src -*** Moving messages around -    #+BEGIN_SRC emacs-lisp -      (defvar-local jao-gnus--spam-group nil) -      (defvar-local jao-gnus--archiving-group nil) -      (defvar-local jao-gnus--archive-as-copy-p nil) - -      (defvar jao-gnus--last-move nil) -      (defun jao-gnus-move-hook (a headers c to d) -        (setq jao-gnus--last-move (cons to (mail-header-id headers)))) -      (defun jao-gnus-goto-last-moved () -        (interactive) -        (when jao-gnus--last-move -          (when (eq major-mode 'gnus-summary-mode) (gnus-summary-exit)) -          (gnus-group-goto-group (car jao-gnus--last-move)) -          (gnus-group-select-group) -          (gnus-summary-goto-article (cdr jao-gnus--last-move) nil t))) -      (add-hook 'gnus-summary-article-move-hook 'jao-gnus-move-hook) - -      (defun jao-gnus-archive (follow) -        (interactive "P") -        (if jao-gnus--archiving-group -            (progn -              (if (or jao-gnus--archive-as-copy-p -                      (not (gnus-check-backend-function -                            'request-move-article gnus-newsgroup-name))) -                  (gnus-summary-copy-article nil jao-gnus--archiving-group) -                (gnus-summary-move-article nil jao-gnus--archiving-group)) -              (when follow (jao-gnus-goto-last-moved))) -          (gnus-summary-mark-as-read) -          (gnus-summary-delete-article))) - -      (defun jao-gnus-archive-tickingly () -        (interactive) -        (gnus-summary-tick-article) -        (jao-gnus-archive) -        (when jao-gnus--archive-as-copy-p -          (gnus-summary-mark-as-read))) - -      (defun jao-gnus-show-tickled () -        (interactive) -        (gnus-summary-limit-to-marks "!")) - -      (make-variable-buffer-local -       (defvar jao-gnus--trash-group nil)) - -      (defun jao-gnus-trash () -        (interactive) -        (gnus-summary-mark-as-read) -        (if jao-gnus--trash-group -            (gnus-summary-move-article nil jao-gnus--trash-group) -          (gnus-summary-delete-article))) - -      (defun jao-gnus-move-to-spam () -        (interactive) -        (gnus-summary-mark-as-read) -        (gnus-summary-move-article nil jao-gnus--spam-group)) - -      (define-key gnus-summary-mode-map "Ba" 'jao-gnus-archive) -      (define-key gnus-summary-mode-map "BA" 'jao-gnus-archive-tickingly) -      (define-key gnus-summary-mode-map "Bl" 'jao-gnus-goto-last-moved) - -      (define-key gnus-summary-mode-map (kbd "B DEL") 'jao-gnus-trash) -      (define-key gnus-summary-mode-map (kbd "B <backspace>") 'jao-gnus-trash) -      (define-key gnus-summary-mode-map "Bs" 'jao-gnus-move-to-spam) -      (define-key gnus-summary-mode-map "/!" 'jao-gnus-show-tickled) -      (define-key gnus-summary-mode-map [f7] 'gnus-summary-force-verify-and-decrypt) -    #+END_SRC -*** Saving emails -    #+BEGIN_SRC emacs-lisp -      (setq gnus-default-article-saver 'gnus-summary-save-article-mail) -      (defvar jao-gnus-file-save-directory (expand-file-name "~/tmp")) -      (defun jao-gnus-file-save (newsgroup headers &optional last-file) -        (expand-file-name (format "%s.eml" (mail-header-subject headers)) -                          jao-gnus-file-save-directory)) -      (setq gnus-mail-save-name 'jao-gnus-file-save) -    #+END_SRC -*** arXiv capture -    #+begin_src emacs-lisp -      (use-package org-capture -        :config -        (add-to-list 'org-capture-templates -                     '("X" "arXiv" entry (file "notes/physics/arxiv.org") -                       "* %:subject\n  %i" :immediate-finish t) -                     t) -        (org-capture-upgrade-templates org-capture-templates)) - -      (defun jao-gnus-arXiv-capture () -        (interactive) -        (gnus-summary-select-article-buffer) -        (gnus-article-goto-part 0) -        (forward-paragraph) -        (setq-local transient-mark-mode 'lambda) -        (set-mark (point)) -        (goto-char (point-max)) -        (org-capture nil "X")) -    #+end_src -* Article buffer -*** Config, headers -    #+begin_src emacs-lisp -      (setq mail-source-delete-incoming t) -      (setq gnus-gcc-mark-as-read t) -      (setq gnus-treat-display-smileys nil) -      (setq gnus-treat-fill-long-lines nil) -      (setq gnus-treat-fill-article nil) -      (setq gnus-treat-fold-headers nil) -      (setq gnus-treat-strip-leading-blank-lines t) -      (setq gnus-article-auto-eval-lisp-snippets nil) -      (setq gnus-posting-styles '((".*" (name "Jose A. Ortega Ruiz")))) -      (setq gnus-single-article-buffer nil) -      (setq gnus-article-update-lapsed-header 60) -      (setq gnus-article-update-date-headers 60) - -      (eval-after-load "gnus-art" -        '(setq -          gnus-visible-headers -          (concat -           gnus-visible-headers -           "\\|^List-[iI][Dd]:\\|^X-Newsreader:\\|^X-Mailer:\\|User-Agent:\\|X-User-Agent:"))) -    #+end_src -*** HTML email (washing, images) -    #+begin_src emacs-lisp -      (setq  gnus-button-url 'browse-url-generic -             gnus-inhibit-images t -             mm-discouraged-alternatives nil ;; '("text/html" "text/richtext") -             mm-inline-large-images 'resize) - -      ;; no html in From: (washing articles from arxiv feeds) and cleaning up -      ;; addresses -      (require 'shr) -      (defvar jao-gnus--from-rx -        (concat "From: \\\"?\\(  " jao-gnus--news-rx "\\)")) - -      (defun jao-gnus-remove-anchors () -        (save-excursion -          (goto-char (point-min)) -          (cond ((re-search-forward jao-gnus--from-rx nil t) -                 (replace-match "" nil nil nil 1)) -                ((re-search-forward "[gq].+ updates on arXiv.org: " nil t) -                 (replace-match "") -                 (let ((begin (point))) -                   (when (re-search-forward "^\\(To\\|Subject\\):" nil t) -                     (beginning-of-line) -                     (let ((shr-width 10000)) -                       (shr-render-region begin (1- (point)))))))))) - -      (add-hook 'gnus-part-display-hook 'jao-gnus-remove-anchors) - -      (defvar-local jao-gnus--images nil) - -      (defun jao-gnus--init-images () -        (with-current-buffer gnus-article-buffer -          (setq jao-gnus--images nil))) - -      (add-hook 'gnus-select-article-hook #'jao-gnus--init-images) - -      (defun jao-gnus-show-images () -        (interactive) -        (save-window-excursion -          (gnus-summary-select-article-buffer) -          (save-excursion -            (setq jao-gnus--images (not jao-gnus--images)) -            (if jao-gnus--images -                (gnus-article-show-images) -              (gnus-article-remove-images))))) -    #+end_src -*** Follow links and enclosures -    #+begin_src emacs-lisp -      (defun jao-gnus-follow-link (&optional external) -        (interactive "P") -        (when (eq major-mode 'gnus-summary-mode) -          (gnus-summary-select-article-buffer)) -        (save-excursion -          (goto-char (point-min)) -          (when (or (search-forward-regexp "^Via: h" nil t) -                    (search-forward-regexp "^URL: h" nil t) -                    (and (search-forward-regexp "^Link$" nil t) -                         (not (beginning-of-line)))) -            (if external -                (jao-browse-with-external-browser) -              (browse-url (jao-url-around-point)))))) - -      (defun jao-gnus-open-enclosure () -        (interactive) -        (save-window-excursion -          (gnus-summary-select-article-buffer) -          (save-excursion -            (goto-char (point-min)) -            (when (search-forward "Enclosure:") -              (forward-char 2) -              (when-let ((url (thing-at-point-url-at-point))) -                (jao-browse-add-url-to-mpc url)))))) -    #+end_src -* Add-ons -*** notmuch integration -    #+begin_src emacs-lisp -      (require 'jao-notmuch-gnus) - -      (jao-notmuch-gnus-auto-tag) - -      (defun jao-gnus-toggle-todo () -        (interactive) -        (jao-notmuch-gnus-toggle-tags '("todo"))) - -      (define-key gnus-summary-mode-map (kbd "C-c T") #'jao-notmuch-gnus-tag-message) -      (define-key gnus-summary-mode-map (kbd "C-c t") #'jao-notmuch-gnus-show-tags) -      (define-key gnus-summary-mode-map (kbd "C-c C-t") #'jao-gnus-toggle-todo) - -      (with-eval-after-load "notmuch-show" -        (define-key gnus-group-mode-map "z" #'jao-gnus-consult-notmuch) -        (define-key gnus-group-mode-map "Z" #'notmuch) -        (define-key notmuch-show-mode-map -                    (kbd "C-c C-c") -                    #'jao-notmuch-gnus-goto-message)) - -      (defun jao-gnus-notmuch-export (query) -        (notmuch-tree query nil nil "* consult-notmuch results *")) - -      (setq consult-notmuch-export-function #'jao-gnus-notmuch-export) - -      (with-eval-after-load "notmuch-tree" -        (define-key notmuch-tree-mode-map -                    (kbd "C-<return>") -                    #'jao-notmuch-gnus-goto-message)) - -    #+end_src -*** gnus-icalendar -    #+begin_src emacs-lisp -      (require 'ol-gnus) -      (use-package gnus-icalendar -        :demand t -        :init (setq gnus-icalendar-org-capture-file -                    (expand-file-name "inbox.org" org-directory) -                    gnus-icalendar-org-capture-headline '("Appointments")) -        :config (gnus-icalendar-org-setup)) -    #+end_src -*** bbdb -    #+begin_src emacs-lisp -      (with-eval-after-load "bbdb" -        (bbdb-initialize 'gnus 'message 'pgp 'mail) -        (bbdb-mua-auto-update-init 'gnus) -        (with-eval-after-load "gnus-sum" -          (define-key gnus-summary-mode-map ":" 'bbdb-mua-annotate-sender) -          (define-key gnus-summary-mode-map ";" 'bbdb-mua-annotate-recipients))) -    #+end_src -*** randomsig -    #+begin_src emacs-lisp -      (with-eval-after-load "randomsig" -        (with-eval-after-load "gnus-sum" -          (define-key gnus-summary-save-map "-" 'gnus/randomsig-summary-read-sig))) -    #+end_src -* Keyboard shortcuts -  #+begin_src emacs-lisp -    (define-key gnus-article-mode-map "i" 'jao-gnus-show-images) -    (define-key gnus-summary-mode-map "i" 'jao-gnus-show-images) -    (define-key gnus-article-mode-map "\M-g" 'jao-gnus-follow-link) -    (define-key gnus-summary-mode-map "\M-g" 'jao-gnus-follow-link) -    (define-key gnus-summary-mode-map "v" 'scroll-other-window) -    (define-key gnus-summary-mode-map "V" 'scroll-other-window-down) -    (define-key gnus-summary-mode-map "X" 'jao-gnus-arXiv-capture) -    (define-key gnus-summary-mode-map "e" 'jao-gnus-open-enclosure) -    (define-key gnus-summary-mode-map "\C-l" nil) - -  #+end_src diff --git a/attic/org/init.org b/attic/org/init.org deleted file mode 100644 index fcd69fb..0000000 --- a/attic/org/init.org +++ /dev/null @@ -1,3427 +0,0 @@ -#+property: header-args :lexical t :tangle yes :comments yes :results silent :shebang ";; -*- lexical-binding: t -*-" :tangle-mode (identity #o644) - -* Packages -*** Use package -    #+begin_src emacs-lisp -    (unless (package-installed-p 'use-package) -      (package-refresh-contents) -      (package-install 'use-package)) -    (require 'use-package) -    #+end_src -*** ELPA Keyring -    #+begin_src emacs-lisp -    (use-package gnu-elpa-keyring-update :ensure t) -    #+end_src -*** Loading .el newer than .elc files, and eln stuff -    #+begin_src emacs-lisp -      (setq load-prefer-newer t) -      (setq comp-async-report-warnings-errors nil -            warning-suppress-types '((comp))) -    #+end_src -* Initialisation -*** Paths -    #+begin_src emacs-lisp -      (defvar jao-local-lisp-dir "~/lib/elisp" -        "Directory for external elisp libraries and repos") - -      (defvar jao-data-dir (expand-file-name "data" jao-emacs-dir) -        "Directory containing static data, such as images.") - -      (defun jao-data-file (file) (expand-file-name file jao-data-dir)) - -      (defvar jao-org-dir (expand-file-name "~/org")) - -      (defvar jao-sink-dir -        (file-name-as-directory (expand-file-name "~/doc/sink")) -        "Directory used for downloads and such.") - -      (defvar jao-site-dir (expand-file-name "site" jao-emacs-dir)) -      (defun jao-site-el (basename &optional gpg) -        (expand-file-name (concat basename ".el" (when gpg ".gpg")) jao-site-dir)) - -      (defun jao-load-site-el (basename &optional gpg) -        (let ((lf (jao-site-el basename gpg))) -          (if (file-exists-p lf) -              (load lf) -            (message "Attempted to load non existing %s" lf)))) - -      (defun jao-exec-path (file) -        (let ((fn (expand-file-name file))) -          (add-to-list 'exec-path fn nil) -          (setenv "PATH" (concat fn ":" (getenv "PATH"))))) - -      (defun jao-load-path (subdir) -        "Add to load path a subdir of `jao-local-lisp-dir'" -        (let ((path (expand-file-name subdir jao-local-lisp-dir))) -          (when (file-directory-p path) (add-to-list 'load-path path)))) -    #+end_src -*** Load and info path initialisation -    #+begin_src emacs-lisp -      (add-to-list 'load-path jao-site-dir) -      (add-to-list 'load-path jao-local-lisp-dir) -      (add-to-list 'load-path (expand-file-name "custom" jao-emacs-dir)) -      (add-to-list 'load-path "/usr/local/share/emacs/site-lisp/") - -      (let ((libd (expand-file-name "lib" jao-emacs-dir))) -        (add-to-list 'load-path libd) -        (dolist (f (directory-files libd t "^[^.]+$")) -          (when (file-directory-p f) (add-to-list 'load-path f)))) - -      (defvar jao-info-dir (expand-file-name "~/doc/info")) -      (require 'info) -      (add-to-list 'Info-directory-list jao-info-dir) -    #+end_src -*** Custom location of custom.el and co. -    #+begin_src emacs-lisp -      (setq custom-file (jao-site-el "custom")) -      ;; (load custom-file) -      (setq custom-unlispify-tag-names nil) -      (setq custom-buffer-done-kill t) -      (setq custom-raised-buttons nil) -    #+end_src -*** Preamble (pre.el) -    #+begin_src emacs-lisp -    (jao-load-site-el "pre") -    #+end_src -*** Session and history -    #+BEGIN_SRC emacs-lisp -      (setq backup-directory-alist (quote (("." . "~/.emacs.d/backups")))) -      (setq delete-old-versions t -            kept-new-versions 3 -            kept-old-versions 2) - -      (require 'saveplace) -      (setq save-place-file (expand-file-name "~/.emacs.d/cache/places")) -      (save-place-mode 1) - -      (setq recentf-save-file (expand-file-name "~/.emacs.d/cache/recentf") -            recentf-max-saved-items 2000 -            recentf-exclude '("/home/jao/\\.emacs\\.d/elpa.*/.*" -                              ".*/.git/COMMIT_EDITMSG")) -      (require 'recentf) -      (recentf-mode 1) - -      ;; Command history -      (setq savehist-file (expand-file-name "~/.emacs.d/cache/history")) -      (require 'savehist) -      (savehist-mode t) -      (setq savehist-additional-variables -            '(kill-ring search-ring regexp-search-ring) -            savehist-ignored-variables -            '(ido-file-history)) -    #+END_SRC -*** yes/no, bell, startup message -    #+BEGIN_SRC emacs-lisp -      ;;; change yes/no for y/n -      (if (version< emacs-version "28") -          (fset 'yes-or-no-p 'y-or-n-p) -        (setq use-short-answers t)) -      (setq inhibit-startup-message t) -      (setq visible-bell t) -    #+END_SRC -*** Server -    #+begin_src emacs-lisp -      (setenv "EDITOR" "emacsclient") -      ;; (unless (daemonp) (server-start)) -    #+end_src -* System utilities -*** Tramp -    #+begin_src emacs-lisp -      (setq tramp-mode nil) -    #+end_src -*** Sleep/awake -    #+begin_src emacs-lisp -      (use-package jao-sleep) -      (jao-sleep-dbus-register) -    #+end_src -*** Process runners -    #+begin_src emacs-lisp -      (use-package jao-shell -        :demand t -        :config (jao-shell-def-exec jao-trayer "trayer.sh") -        :bind (("s-r" . jao-shell-exec))) - -    #+end_src -*** App launcher -    #+begin_src emacs-lisp -      (jao-load-path "app-launcher") -      (use-package app-launcher -        :bind (("s-R" . app-launcher-run-app))) -    #+end_src -*** Brightness control -    #+begin_src emacs-lisp -      (jao-shell-def-exec jao-bright-set-up "brightnessctl" "-q" "s" "5%+") -      (jao-shell-def-exec jao-bright-set-down "brightnessctl" "-q" "s" "5%-") - -      (defun jao-bright-show () -        (interactive) -        (message "%s" (thread-first (jao-shell-string "brightnessctl") -                        (split-string "\n") -                        (cadr) -                        (string-trim)))) - -      (defun jao-bright-up () -        (interactive) -        (jao-shell-string "brightnessctl -q s 5%%+") -        (jao-bright-show)) - -      (defun jao-bright-down () -        (interactive) -        (jao-shell-string "brightnessctl -q s 5%%-") -        (jao-bright-show)) -     #+end_src -*** Keyboard -    #+begin_src emacs-lisp -      (use-package repeat -        :config (setq repeat-echo-function #'repeat-echo-mode-line)) -      (when (> emacs-major-version 27) (repeat-mode)) - -      (defun jao-kb-toggle (&optional lyt) -        (interactive) -        (shell-command-to-string (or lyt -                                     (if (jao-kb-toggled-p) -                                         "setxkbmap us" -                                       "setxkbmap us -variant intl")))) - -      (defun jao-kb-toggled-p () -        (not (string-empty-p -              (shell-command-to-string "setxkbmap -query|grep variant")))) - -      (set-keyboard-coding-system 'latin-1) -      (set-language-environment "UTF-8") -      ;; must be set after current-language-environment -      (customize-set-variable 'default-input-method "catalan-prefix") -      ;; http://mbork.pl/2022-03-07_Transient_input_method -      (customize-set-variable 'default-transient-input-method "TeX") - -      (defun jao--set-kb-system (frame) -        (select-frame frame) -        (set-keyboard-coding-system 'latin-1) -        t) -      (add-to-list 'after-make-frame-functions 'jao--set-kb-system) - -      (setq echo-keystrokes 1 -            suggest-key-bindings nil) -    #+end_src -*** Transient -    #+begin_src emacs-lisp -      (use-package transient -        :init (setq transient-show-popup t) ;; 2.0 -        :demand t -        :config -        (transient-bind-q-to-quit)) - -      (defmacro jao-transient-major-mode (mode &rest suffix) -        (declare (indent defun)) -        (let ((mode (intern (format "%s-mode" mode))) -              (mmap (intern (format "%s-mode-map" mode))) -              (name (intern (format "jao-transient-%s" mode)))) -          `(progn -             (transient-define-prefix ,name () -               ,(format "Transient ops for %s" mode) -               [,(format "Operations for %s" mode) :if-derived ',mode ,@suffix]) -             (define-key ,mmap (kbd "s-SPC") #',name)))) - -      (defmacro jao-transient-major-mode+1 (mode suffix) -        (declare (indent defun)) -        (let ((name (intern (format "jao-transient-%s" mode)))) -          (if (fboundp name) -              `(transient-append-suffix ',name '(0 -1) ,suffix) -            `(jao-transient-major-mode ,mode ,suffix)))) - -      (defmacro jao-transient-major-mode+ (mode &rest suffixes) -        (declare (indent defun)) -        `(progn ,@(mapcar (lambda (s) `(jao-transient-major-mode+1 ,mode ,s)) -                          suffixes))) - -    #+end_src -*** Disk -    #+begin_src emacs-lisp -      (when (featurep 'multisession) -        (use-package jao-dirmon)) -    #+end_src -* Crypto -*** PGP, EPG, passwords -    #+begin_src emacs-lisp -      (setq epg-pinentry-mode 'loopback) -      (setq auth-source-debug nil) - -      (require 'auth-source) -      (add-to-list 'auth-source-protocols '(local "local")) -      (setq auth-sources '("~/.emacs.d/authinfo.gpg" "~/.netrc")) - -      (use-package epa-file -        :init (setq epa-file-cache-passphrase-for-symmetric-encryption t) -        :config (epa-file-enable)) -      (require 'epa-file) - -      (defun jao--get-user/password (h) -        (let ((item (car (auth-source-search :type 'netrc :host h :max 1)))) -          (when item -            (let ((user (plist-get item :user)) -                  (pwd (plist-get item :secret))) -              (list user (when pwd (funcall pwd))))))) -    #+end_src -*** pass -    #+begin_src emacs-lisp -      (use-package password-store :ensure t -        :bind (("C-c p" . jao-transient-password))) - -      (transient-define-prefix jao-transient-password () -        [[("c" "copy secret" password-store-copy) -          ("C" "copy field" password-store-copy-field)] -         [("i" "insert entry" password-store-insert) -          ("e" "edit entry" password-store-edit) -          ("g" "generate password" password-store-generate)] -         [("d" "delete entry" password-store-remove) -          ("r" "rename entry" password-store-rename)]]) - -    #+end_src -*** Pinentry -    #+begin_src emacs-lisp -      (use-package pinentry :ensure t) -      (pinentry-start) -    #+end_src -* Fonts and colour themes -*** Widgets -    #+begin_src emacs-lisp -      (setq widget-image-enable nil -            widget-link-prefix "" -            widget-link-suffix "" -            widget-button-prefix " " -            widget-button-suffix " " -            widget-push-button-prefix "" -            widget-push-button-suffix "") -    #+end_src -*** Fonts -***** fontsets -      See [[https://emacs.stackexchange.com/questions/251/line-height-with-unicode-characters/5386#5386][fonts - Line height with unicode characters]] for a good -      discussion. -      #+begin_src emacs-lisp -        (defun jao--set-fontsets (_f) -          (set-fontset-font t 64257 "Quivira" nil) -          (set-fontset-font t 'egyptian "Noto Sans Egyptian Hieroglyphs" nil) -          (set-fontset-font t 'hangul "NanumGothicCoding" nil) -          (set-fontset-font t 'unicode (face-attribute 'default :family) nil) -          (set-fontset-font t 'unicode-bmp (face-attribute 'default :family) nil) -          (set-fontset-font t 'symbol "Symbola-10" nil) -          (set-fontset-font t 'greek "GFS Didot" nil) -          (set-fontset-font t 'mathematical "FreeSerif" nil) -          (set-fontset-font t 'emoji "Noto Color Emoji" nil) -          ;; boxes -          (set-fontset-font t '(9472 . 9599) "Source Code Pro" nil) -          ;; variation selector-16 -          (set-fontset-font t 65039 "BabelStone Modern-1" nil)) - -        (jao--set-fontsets nil) -        (add-to-list 'after-make-frame-functions 'jao--set-fontsets) - -      #+end_src -***** nobreak char display -      #+begin_src emacs-lisp -        (setq nobreak-char-display nil) -      #+end_src -***** list-fonts-display -      #+begin_src emacs-lisp -        (defun list-fonts-display (&optional matching) -          "Display a list of font-families available via font-config, in a new buffer. -           If the optional argument MATCHING is non-nil, only -           font families matching that regexp are displayed; -           interactively, a prefix argument will prompt for the -           regexp.  The name of each font family is displayed -           using that family, as well as in the default font (to -           handle the case where a font cannot be used to display -           its own name)." -          (interactive -           (list -            (and current-prefix-arg -                 (read-string "Display font families matching regexp: ")))) -          (let (families) -            (with-temp-buffer -              (shell-command "fc-list : family" t) -              (goto-char (point-min)) -              (while (not (eobp)) -                (let ((fam (buffer-substring (line-beginning-position) -                                             (line-end-position)))) -                  (when (or (null matching) (string-match matching fam)) -                    (push fam families))) -                (forward-line))) -            (setq families -                  (sort families -                        (lambda (x y) (string-lessp (downcase x) (downcase y))))) -            (let ((buf (get-buffer-create "*Font Families*"))) -              (with-current-buffer buf -                (erase-buffer) -                (dolist (family families) -                  ;; We need to pick one of the comma-separated names to -                  ;; actually use the font; choose the longest one because some -                  ;; fonts have ambiguous general names as well as specific -                  ;; ones. -                  (let ((family-name -                         (car (sort (split-string family ",") -                                    (lambda (x y) (> (length x) (length y)))))) -                        (nice-family (replace-regexp-in-string "," ", " family))) -                    (insert (concat (propertize nice-family -                                                'face (list :family family-name)) -                                    " (" nice-family ")")) -                    (newline))) -                (goto-char (point-min))) -              (display-buffer buf)))) -      #+end_src -*** Vertical separator -    #+begin_src emacs-lisp -      (unless (display-graphic-p) -        (set-display-table-slot standard-display-table -                                'vertical-border -                                (make-glyph-code ?โ))) -    #+end_src -*** Themes -    #+begin_src emacs-lisp -      (defun jao-colors-scheme-dark-p () -        (equal "dark" (getenv "JAO_COLOR_SCHEME"))) - -      (setq custom-theme-directory -            (expand-file-name "lib/themes" jao-emacs-dir)) - -      (require 'jao-themes) - -      (defvar jao-theme-dark 'jao-dark) -      (defvar jao-theme-light 'jao-light) -      (defvar jao-theme-term-dark 'modus-vivendi) -      (defvar jao-theme-term-light 'jao-light) - -      (defun jao-themes-setup () -        (let* ((dark (jao-colors-scheme-dark-p)) -               (theme (cond ((and dark window-system) jao-theme-dark) -                            (dark jao-theme-term-dark) -                            (window-system jao-theme-light) -                            (t jao-theme-term-light)))) -          (load-theme theme t) -          (modify-all-frames-parameters `((font . ,jao-themes-default-face))))) - -      (unless (eq window-system 'pgtk) (jao-themes-setup)) - -      (global-font-lock-mode 1) -    #+end_src -* Help system -*** Help buffers and shortcuts -    #+begin_src emacs-lisp -      (setq help-window-select t -            help-link-key-to-documentation t) - -      (use-package find-func -        :bind (("C-h C-v" . find-variable) -               ("C-h C-f" . find-function) -               ("C-h C-k" . find-function-on-key) -               ("C-h C-l" . find-library))) -    #+end_src -*** eldoc -    #+begin_src emacs-lisp -      (use-package eldoc -        :init (setq eldoc-mode-line-string nil -                    eldoc-echo-area-use-multiline-p t -                    eldoc-echo-area-prefer-doc-buffer nil -                    eldoc-display-functions '(eldoc-display-in-echo-area)) -        :config (global-eldoc-mode 1) -        :diminish ((eldoc-mode . ""))) -   #+end_src -*** Bookmarks -    #+begin_src emacs-lisp -    (setq bookmark-default-file "~/.emacs.d/emacs.bmk" -          bookmark-set-fringe-mark nil) - -    #+end_src -*** Man pages -    #+begin_src emacs-lisp -      (setq Man-notify-method 'pushy) ;; pushy - same window -    #+end_src -*** Recoll -    #+begin_src emacs-lisp -      (use-package jao-recoll) -    #+end_src -* Window manager helpers -*** transparency -    #+begin_src emacs-lisp -      (defvar jao-transparent-only-bg (> emacs-major-version 28)) - -      (defvar jao-frames-default-alpha -        (cond ((eq window-system 'pgtk) 80) -              (jao-transparent-only-bg 88) -              (t 85))) - -      (defvar jao-transparent-frame (< jao-frames-default-alpha 100)) - -      (defun jao-transparent-p () jao-transparent-frame) - -      (defun jao-alpha-parameters (&optional level) -        (let ((level (or level jao-frames-default-alpha))) -          (if jao-transparent-only-bg -              `((alpha-background . ,level) (alpha)) -            `((alpha . ,(cons level level)) (alpha-background))))) - -      (defun jao-set-transparency (&optional level all) -        (interactive "nOpacity (0-100): ") -        (let ((level (or level jao-frames-default-alpha))) -          (setq jao-transparent-frame (< level 100)) -          (if all -                (modify-all-frames-parameters (jao-alpha-parameters level)) -              (modify-frame-parameters nil (jao-alpha-parameters level))))) - -      (defun jao-toggle-transparency (&optional all) -        (interactive "P") -        (let ((level (if jao-transparent-frame 100 jao-frames-default-alpha))) -          (jao-set-transparency level all))) - -    #+end_src -*** exwm -    #+begin_src emacs-lisp -      (defvar jao-exwm-enabled nil) -      (defun jao-exwm-enabled-p () jao-exwm-enabled) - -      (defun jao-exwm-enable () -        (require 'jao-custom-exwm) -        (setq jao-exwm-enabled t) -        (display-time-mode -1) -        (exwm-enable) -        (setq jao-frames-default-alpha 88) -        (jao-set-transparency) -        (x-change-window-property "_XMONAD_TRAYPAD" "" nil nil nil nil 0) -        (jao-trisect t)) -    #+end_src -*** xmonad -    #+begin_src emacs-lisp -      (defvar jao-xmonad-enabled (string= "xmonad" (or (getenv "wm") ""))) -      (defun jao-xmonad-enabled-p () jao-xmonad-enabled) - -      (defun jao-xmonad-enable () -        (setq jao-browse-doc-use-emacs-p t) -        (setq jao-wallpaper-random-wake t) -        ;; (jao-set-transparency) -        (jao-trisect) -        (message "Welcome to xmonad")) - -      (when jao-xmonad-enabled -        (add-hook 'after-init-hook #'jao-xmonad-enable t)) - -    #+end_src -*** sway -    When starting emacs inside a sway session, we use ~-f -    jao-sway-enable~ and don't load any separate configuration file. - -    #+begin_src emacs-lisp -      (defun jao-swaymsg (msg) -        (shell-command (format "swaymsg '%s' >/dev/null" msg))) - -      (defmacro jao-def-swaymsg (name msg) -        `(defun ,(intern (format "jao-sway-%s" name)) () -           (interactive) -           (jao-swaymsg ,msg))) -      (jao-def-swaymsg firefox "[app_id=firefox] focus") - -      (defvar jao-sway-enabled -        (and (eq window-system 'pgtk) (not jao-xmonad-enabled))) - -      (defun jao-sway-set-wallpaper (f) -        (jao-swaymsg (format "output * bg %s fill" f)) -        (make-symbolic-link f "~/.wallpaper.sway" t)) - -      (defun jao-sway-run-or-focus (cmd &optional ws) -        (if (jao-shell-running-p "firefox") -            (jao-swaymsg (format "[app_id=%s] focus" cmd)) -          (jao-swaymsg (format "workspace %s" (or ws 2))) -          (start-process-shell-command cmd nil cmd))) - -      (defun jao-sway-run-or-focus-tidal () -        (interactive) -        (if (jao-shell-running-p "tidal-hifi") -            (jao-swaymsg "[app_id=tidal-hifi] scratchpad show") -          (start-process-shell-command "tidal-hifi" nil "tidal-hifi &") -          (jao-sway-run-or-focus-tidal))) - -      (defun jao-sway-run-or-focus-firefox () -        (interactive) -        (jao-sway-run-or-focus "firefox")) - -      (defun jao-sway-enable () -        (setq jao-browse-doc-use-emacs-p t) -        (setq jao-wallpaper-random-wake nil) -        (jao-trisect) -        (jao-set-transparency 85) -        (jao-themes-setup) -        ;; (display-time-mode 1) -        (global-set-key (kbd "s-f") #'jao-sway-run-or-focus-firefox) -        (defalias 'jao-streaming-list #'jao-sway-run-or-focus-tidal) -        (message "Welcome to sway")) - -      (when jao-sway-enabled -        (defalias 'x-change-window-property #'ignore) -        (add-hook 'after-init-hook #'jao-sway-enable)) - -    #+end_src -*** wallpaper -    #+begin_src emacs-lisp -      (defvar jao-wallpaper-dir "~/.wallpapers/") - -      (defvar jao-wallpaper-random-candidates -        '("wallpaper.jpg" "wallpaper2.jpg")) - -      (defvar jao-wallpaper-random-candidates-light -        '("wallpaper.jpg" "wallpaper2.jpg")) - -      (defvar jao-wallpaper-random-wake t -        "Set to t for getting a new wallpaper on awaking from sleep") - -      (defun jao-set-wallpaper (&optional path) -        (interactive) -        (let ((current (format "~/.wallpaper.%s" -                               (if (jao-colors-scheme-dark-p) "dark" "light")))) -          (when-let ((f (or path -                            (read-file-name "Image: " -                                            jao-wallpaper-dir -                                            (file-symlink-p current) -                                            t)))) -            (make-symbolic-link (expand-file-name f) current t) -            (if jao-sway-enabled -                (jao-sway-set-wallpaper (expand-file-name f)) -              (shell-command (format "xwallpaper --zoom %s" f)))))) - -      (defun jao-set-random-wallpaper () -        (interactive) -        (when (or (called-interactively-p 'interactive) -                  jao-wallpaper-random-wake) -          (let* ((ws (if (jao-colors-scheme-dark-p) -                         jao-wallpaper-random-candidates -                       jao-wallpaper-random-candidates-light)) -                 (f (seq-random-elt ws))) -            (jao-set-wallpaper (expand-file-name f jao-wallpaper-dir)) -            (message "%s" f)))) - -      (add-to-list 'jao-sleep-awake-functions #'jao-set-random-wallpaper) -    #+end_src -*** screensaver and lock -    #+begin_src emacs-lisp -      (defun jao-screensaver-enabled () -        (string= (jao-shell-string "xdg-screensaver status") "enabled")) - -      (defun jao-screensaver-toggle () -        (interactive) -        (let ((wid (jao-shell-string "xdotool getwindowfocus"))) -          (if (jao-screensaver-enabled) -              (jao-shell-string "xdg-screensaver suspend" wid) -            (jao-shell-string "xdg-screensaver resume" wid)) -          (jao-notify (format "Using '%s'" -                              (jao-shell-string "xdotool getwindownames" wid)) -                      (format "Screensaver %s" -                              (jao-shell-string "xdg-screensaver status"))))) - -      (jao-shell-def-exec jao-xlock-screen "xdg-screensaver" "activate") -      (jao-shell-def-exec jao-suspend "sudo" "systemctl" "suspend") -      (jao-shell-def-exec jao-poweroff "sudo" "systemctl" "poweroff") - -      (defun jao-lock-screen () -        (interactive) -        (if jao-sway-enabled -            (shell-command "swaylock -i ~/.lockimage") -          (jao-xlock-screen))) - -      (transient-define-prefix jao-transient-sleep () -        ["Sleep" -         ("l" "lock screen" jao-lock-screen) -         ("z" "sleep" jao-suspend) -         ("u" "enable/disable screensaver" jao-screensaver-toggle) -         ("poof" "power-off" jao-poweroff)]) - -    #+end_src -*** mouse -    #+begin_src emacs-lisp -      (dolist (k '([mouse-3] -                   [down-mouse-3] -                   [drag-mouse-3] -                   [double-mouse-3] -                   [mouse-4] -                   [down-mouse-4] -                   [drag-mouse-4] -                   [double-mouse-4] -                   [triple-mouse-4] -                   [mouse-5] -                   [down-mouse-5] -                   [drag-mouse-5] -                   [double-mouse-5] -                   [triple-mouse-5])) -        (global-unset-key k)) -    #+end_src -*** X clipboard -    #+BEGIN_SRC emacs-lisp -      (setq select-enable-clipboard t -            select-enable-primary t -            selection-timeout 100) -    #+END_SRC -*** pop-up frames -    #+begin_src emacs-lisp -      (defun jao-open-in-x-frame (&optional width height) -        (interactive) -        (make-frame `((window-system . x) -                      (name . "emacs popup") -                      (width . ,(or width (window-width))) -                      (height . ,(or height (window-height))))) -        (define-key (current-local-map) "q" #'delete-frame)) -    #+end_src -*** xmobar -    #+begin_src emacs-lisp -      (defun jao-xmobar-kill () -        (interactive) -        (shell-command "killall xmobar-exwm")) - -      (defun jao-xmobar-restart () -        (interactive) -        (jao-xmobar-kill) -        (start-process "" nil "xmobar-exwm" "-d")) - -    #+end_src -* Mode line and minibuffer -*** Time display -    #+begin_src emacs-lisp -      (setq display-time-world-list -            '(("Europe/Paris" "Barcelona") -              ("America/Los_Angeles" "Los Angeles") -              ("America/New_York" "New York") -              ("Europe/London" "London") -              ("Asia/Calcutta" "Bangalore") -              ("Asia/Tokyo" "Tokyo"))) - -      (defun jao-time--pdt-hour () -        (jao-time-at-zone "%H" "America/Los_Angeles")) - -      (defun jao-time--chicago-hour () -        (jao-time-at-zone "%H" "America/Chicago")) - -      (defun jao-time-at-zone (format zone) -        (set-time-zone-rule zone) -        (prog1 (format-time-string format) -          (set-time-zone-rule nil))) - -      (defun jao-time-echo-la-time () -        (interactive) -        (message (jao-time-at-zone "LA %H:%M" "America/Los_Angeles"))) - -      (defun jao-time-echo-times () -        (interactive) -        (let ((msg (format "%s (%s)" -                           (format-time-string "%a, %e %B - %H:%M") -                           (jao-time-at-zone "%H:%M" "America/Los_Angeles")))) -          (jao-notify msg "" (jao-data-file "clock-world-icon.png")))) - -      (defun jao-time-to-epoch (&optional s) -        "Transform a time string to an epoch integer in milliseconds." -        (interactive) -        (let ((s (or s (read-string "Time string: " (thing-at-point 'string))))) -          (message "%s = %s" -                   s -                   (round (* 1000 (time-to-seconds (parse-time-string s))))))) - -      (defun jao-epoch-to-time (&optional v) -        "Transform an epoch, given in milliseconds, to a time string." -        (interactive) -        (let ((v (or v (read-number "Milliseconds: " (thing-at-point 'number))))) -          (message "%s = %s" v -                   (format-time-string "%Y-%m-%d %H:%M:%S" -                                       (seconds-to-time (/ v 1000.0)))))) - -      (setq display-time-day-and-date nil -            display-time-24hr-format nil -            display-time-default-load-average nil -            display-time-format " %a %e %H:%M") - -    #+end_src -*** Minibuffer -    #+begin_src emacs-lisp -      (defvar jao-modeline-in-minibuffer (and window-system t)) - -      (use-package jao-minibuffer -        :init -        (if (jao-colors-scheme-dark-p) -            (setq jao-minibuffer-active-buffer-line-color "azure4" -                  jao-minibuffer-inactive-buffer-line-color "grey25") -          (setq jao-minibuffer-active-buffer-line-color "burlywood3" -                jao-minibuffer-inactive-buffer-line-color "grey65")) -        :commands (jao-minibuffer-add-variable -		   jao-minibuffer-refresh -                   jao-minibuffer-mode)) - -      (use-package jao-mode-line -        :commands (jao-mode-line-add-to-minibuffer -                   jao-mode-line-remove-from-minibuffer)) - -      (setq enable-recursive-minibuffers t) -      (require 'mb-depth) -      (minibuffer-depth-indicate-mode 1) -      (require 'minibuf-eldef) -      (setq minibuffer-eldef-shorten-default t) -      (minibuffer-electric-default-mode 1) - -      (jao-minibuffer-mode 1) - -      (when jao-modeline-in-minibuffer -        (add-hook 'display-time-hook #'jao-minibuffer-refresh) -        (add-hook 'after-init-hook -                  (lambda () (jao-mode-line-add-to-minibuffer 90)))) -    #+end_src -*** Mode line format -    #+begin_src emacs-lisp -      (setq line-number-display-limit-width 250) -      (setq mode-line-position-column-format '(" %c") -            mode-line-position-line-format '(" %l,%c")) -      (setq mode-line-percent-position -            '(" %l" (:eval (format "/%d" (line-number-at-pos (point-max)))))) -      (line-number-mode -1) -      (column-number-mode 1) -    #+end_src -*** Mode line toggle -    #+begin_src emacs-lisp -      (use-package jao-mode-line -        :init -        (when (and window-system (not jao-modeline-in-minibuffer)) -          (add-to-list 'after-make-frame-functions #'jao-mode-line-hide-inactive) -          (add-hook 'after-init-hook #'jao-toggle-inactive-mode-line)) -        :demand t -        :bind (("<home>" . jao-mode-line-toggle-inactive) -               ("<end>" . jao-mode-line-toggle) -               ("<insert>" . jao-mode-line-echo))) -    #+end_src -*** Diminish -    #+BEGIN_SRC emacs-lisp -      (use-package diminish :ensure t) -      (when (require 'use-package-diminish nil 'noerror) -        (eval-after-load "simple" '(diminish 'auto-fill-function " ยง")) -        (eval-after-load "autorevert" '(diminish 'auto-revert-mode ""))) -    #+END_SRC -*** Battery -    #+begin_src emacs-lisp -      (use-package battery -        :init (setq battery-load-low 15 -                    battery-load-critical 8 -                    battery-mode-line-limit 40 -                    battery-echo-area-format -                    "%L %r %B (%p%% load, remaining time %t)" -                    battery-mode-line-format " %b%p ")) ;; " ๐%b%p " -      (display-battery-mode 1) -      (with-eval-after-load "jao-minibuffer" -        (unless jao-modeline-in-minibuffer -          (jao-minibuffer-add-variable 'battery-mode-line-string 80))) -    #+end_src -* Notifications -*** alert -    #+BEGIN_SRC emacs-lisp -      (use-package alert -        :ensure t -        :init -        (setq alert-default-style 'message ;; 'libnotify -              alert-hide-all-notifications nil)) -    #+END_SRC -*** jao-notify -    #+begin_src emacs-lisp -      (require 'jao-notify) -    #+end_src -*** tracking -    #+begin_src emacs-lisp -      (use-package tracking -        :demand t -        :init (setq tracking-position 'before-modes -                    tracking-frame-behavior nil -                    tracking-most-recent-first nil -                    tracking-max-mode-line-entries 10 -                    tracking-sort-faces-first t -                    tracking-shorten-modes '()) -        :config -        (setq erc-track-enable-keybindings nil) - -        (defun jao-tracking-next-buffer () -          (interactive) -          (tracking-next-buffer) -          (jao-tracking-update-minibuffer)) - -        :bind (("C-c C-SPC" . jao-tracking-next-buffer))) - -      (use-package jao-tracking -        :demand t -        :init (setq jao-tracking-bkg -                    (if (jao-colors-scheme-dark-p) "grey20" "grey93"))) -      #+end_src -*** tmr -    #+begin_src emacs-lisp -      (use-package tmr -        :ensure t -        :init -        (setq tmr-sound-file "/usr/share/sounds/freedesktop/stereo/message.oga" -              tmr-descriptions-list '("tea is ready"))) -    #+end_src -* Calendar, diary, weather -*** Diary -    #+BEGIN_SRC emacs-lisp -      (setq diary-file (expand-file-name "diary" jao-org-dir) -            diary-display-function 'diary-fancy-display -            diary-mail-addr "jao@localhost" -            diary-comment-start ";;" -            diary-comment-end "") - -      (add-hook 'diary-list-entries-hook 'diary-sort-entries t) -    #+END_SRC -*** Calendar -    #+begin_src emacs-lisp -      (setq appt-display-format nil) -      (appt-activate 1) -      (setq calendar-latitude 55.9533 -            calendar-longitude -3.1883 -            calendar-location-name "Edinburgh, Scotland" -            calendar-mark-diary-entries-flag t -            calendar-date-echo-text '(format "ISO date: %s" -                                             (calendar-iso-date-string -                                              (list month day year)))) - -      (setq calendar-holidays -            '((holiday-fixed 1 1 "New Year's Day") -              (holiday-fixed 4 1 "April Fools' Day") -              (holiday-float 5 0 2 "Mother's Day") -              (holiday-fixed 3 19 "Father's Day") -              (holiday-float 11 4 4 "Thanksgiving") -              (holiday-fixed 12 25 "Christmas") -              (holiday-chinese-new-year) -              (solar-equinoxes-solstices) -              (holiday-sexp calendar-daylight-savings-starts -                            (format "Daylight Saving Time Begins %s" -                                    (solar-time-string -                                     (/ calendar-daylight-savings-starts-time -                                        (float 60)) -                                     calendar-standard-time-zone-name))) -              (holiday-sexp calendar-daylight-savings-ends -                            (format "Daylight Saving Time Ends %s" -                                    (solar-time-string -                                     (/ calendar-daylight-savings-ends-time -                                        (float 60)) -                                     calendar-daylight-time-zone-name))))) - -      (add-to-list 'display-buffer-alist -                   `(,(regexp-quote diary-fancy-buffer) -                     (display-buffer-at-bottom) -                     (window-parameters (mode-line-format . none)) -                     (window-height . fit-window-to-buffer))) - -      (defun jao-diary--select () -        (switch-to-buffer diary-fancy-buffer)) - -      (add-hook 'diary-fancy-display-mode-hook #'jao-diary--select) -      (setq org-calendar-insert-diary-entry-key nil -            org-agenda-diary-file 'diary-file) - -    #+end_src -*** Weather -***** winttr -      #+begin_src emacs-lisp -        (defun jao-weather (&optional wide) -          (interactive "P") -          (if (not wide) -              (message "%s" -                       (jao-shell-string "curl -s" -                                         "https://wttr.in/?format=%l++%m++%C+%c+%t+%w++%p")) -            (jao-afio--goto-scratch) -            (if-let ((b (get-buffer "*wttr*"))) -                (progn (pop-to-buffer b) -                       (term-send-string "clear;curl wttr.in\n")) -              (jao-exec-in-term "curl wttr.in" "*wttr*")))) -        (global-set-key (kbd "<f5>") #'jao-weather) -      #+end_src -*** Timers -    #+BEGIN_SRC emacs-lisp -    (put 'list-timers 'disabled nil) -    #+END_SRC -* Files, dired and scratch buffer -*** so-long -    #+begin_src emacs-lisp -      (setq large-file-warning-threshold (* 200 1024 1024)) - -      (use-package so-long -        :ensure t -        :diminish) -      (global-so-long-mode 1) -    #+end_src -*** Persistent scratch -    #+BEGIN_SRC emacs-lisp -      (use-package persistent-scratch -        :ensure t -        :config (persistent-scratch-setup-default)) -    #+END_SRC -*** Automatically uncompress -  #+BEGIN_SRC emacs-lisp -    (require 'jka-compr) -    (auto-compression-mode 1) -  #+END_SRC -*** wgrep -    #+begin_src emacs-lisp -      (use-package wgrep :ensure t) -      (require 'wgrep) -    #+end_src -*** dired -    - [[https://www.masteringemacs.org/article/working-multiple-files-dired][Working with multiple files in dired - Mastering Emacs]] -    #+begin_src emacs-lisp -      (use-package dired -        :init -        (setq dired-recursive-deletes 'top -              dired-recursive-copies 'top -              dired-listing-switches "-alhF --group-directories-first" -              ls-lisp-dirs-first t -              dired-dwim-target t -              dired-kill-when-opening-new-dired-buffer t -              dired-mouse-drag-files t -              wdired-create-parent-directories t) - -        (put 'dired-find-alternate-file 'disabled nil) -        :hook (dired-mode . turn-on-gnus-dired-mode) -        :bind (:map dired-mode-map -                    ("C-c C-r" . wdired-change-to-wdired-mode) -                    ("C-M-m" . gnus-dired-attach))) - -      (use-package dired-x :demand t) - -      (use-package find-dired -        :init (setq find-ls-option '("-print0 | xargs -0 ls -ld" . "-ld")) -        :bind ("C-c D" . find-name-dired)) - -      (use-package dired-git-info -        :ensure t -        :bind (:map dired-mode-map (")" . dired-git-info-mode))) - -      #+end_src -* General editing -*** Executable scripts -    #+begin_src emacs-lisp -      (add-hook 'after-save-hook -                'executable-make-buffer-file-executable-if-script-p) -    #+end_src -*** Long lines -    [[https://200ok.ch/posts/2020-09-29_comprehensive_guide_on_handling_long_lines_in_emacs.html][Comprehensive guide on handling long lines in Emacs - 200ok]] -    #+begin_src emacs-lisp -      (when (version<= "27.1" emacs-version) -        (setq bidi-inhibit-bpa t)) -    #+end_src -*** Spaces, tabs, kill -    #+begin_src emacs-lisp -      (setq kill-whole-line t) -      (setq-default indent-tabs-mode nil) -      (setq indent-tabs-width 4) -      (setq-default default-tab-width 8) -      (setq tab-always-indent t) -      (setq kill-read-only-ok t) -      (setq view-read-only nil) -    #+end_src -*** Whitespace and filling column -    #+begin_src emacs-lisp -      (add-hook 'write-file-functions 'delete-trailing-whitespace) -      (setq-default indicate-empty-lines nil) -      (setq fill-column 78) -      (setq comment-auto-fill-only-comments nil) - -      (use-package whitespace -        :init -        (setq whitespace-style '(face tabs trailing ;; lines-tail -                                 empty  missing-newline-at-eof) -              whitespace-line-column 80) -        :hook (prog-mode . whitespace-mode) -        :diminish) - -      (use-package display-fill-column-indicator -        :init (setq-default display-fill-column-indicator-column 80) -        :hook (prog-mode . display-fill-column-indicator-mode)) - -    #+end_src -*** Visible mode -    #+begin_src emacs-lisp -      (use-package visible-mode -        :bind (("s-v" . visible-mode))) -    #+end_src -*** Changes -    #+begin_src emacs-lisp -      (use-package goto-chg -        :ensure t -        :bind (("C-." . goto-last-change) -               ("C-c ." . goto-last-change) -               ("C-c ," . goto-last-change-reverse))) -    #+end_src -*** Eval-and-replace -    #+BEGIN_SRC emacs-lisp -      (defun fc-eval-and-replace () -        "Replace the preceding sexp with its value." -        (interactive) -        (backward-kill-sexp) -        (condition-case nil -            (prin1 (eval (read (current-kill 0))) -                   (current-buffer)) -          (error (message "Invalid expression") -                 (insert (current-kill 0))))) - -       (global-set-key "\C-ce" 'fc-eval-and-replace) -    #+END_SRC -*** Skeletons and autoinsert -    #+begin_src emacs-lisp -      (use-package autoinsert -        :config -        (setq auto-insert-directory "~/.emacs.d/autoinsert/" -              auto-insert t -              auto-insert-query t) -        (setf (alist-get 'html-mode auto-insert-alist nil t) nil)) -      (add-hook 'find-file-hooks #'auto-insert) - -      (use-package jao-skel -        :demand t -        :config -        (require 'jao-skel-geiser) -        (require 'jao-skel-lisp) -        (require 'jao-skel-haskell) -        (require 'jao-skel-latex)) -    #+end_src -*** Undo -    f   to go forward -    b   to go backward - -    n   to go to the node below when you at a branching point -    p   to go to the node above - -    a   to go back to the last branching point -    e   to go forward to the end/tip of the branch - -    #+begin_src emacs-lisp -      (use-package vundo -        :ensure t -        :config -        (set-face-attribute 'vundo-default nil :family "Symbola") -        (setq vundo-glyph-alist vundo-unicode-symbols) -        :bind (("C-?" . vundo))) - -    #+end_src -*** Completion -    #+begin_src emacs-lisp -      (use-package jao-custom-completion) -    #+end_src -* Buffers -*** cursor and mark -    #+begin_src emacs-lisp -      (transient-mark-mode -1) -      (blink-cursor-mode -1) -      (setq cursor-in-non-selected-windows nil) -    #+end_src -*** uniquifiy -    #+begin_src emacs-lisp -      (require 'uniquify) -      (setq uniquify-buffer-name-style 'forward -            uniquify-trailing-separator-p t) -    #+end_src -*** autosave -    #+begin_src emacs-lisp -    (setq auto-save-list-file-prefix "~/.emacs.d/auto-save-list/.saves-" -          auto-save-no-message t -          kill-buffer-delete-auto-save-files t) - -    (setq lock-file-name-transforms -          '(("\\`/.*/\\([^/]+\\)\\'" "/tmp/emacs-lock/\\1" t))) -    #+end_src -*** autorevert -    #+BEGIN_SRC emacs-lisp -      (setq auto-revert-check-vc-info nil) -      (setq auto-revert-verbose nil) -      (setq auto-revert-avoid-polling t) -      (setq auto-revert-mode-text "") -      (require 'autorevert) -      (global-auto-revert-mode 1) -    #+END_SRC -*** attached buffers -    #+begin_src emacs-lisp -      (defun jao-display-buffer-below-selected (buffer alist) -        (delete-other-windows-vertically) -        (display-buffer-below-selected buffer alist)) - -      (defun jao-attached-buffer-entry (name-rx height) -        `(,name-rx (display-buffer-reuse-window -                    jao-display-buffer-below-selected) -                   (window-height . ,(or height 25)))) - -      (defmacro jao-with-attached-buffer (name-rx height &rest body) -        (declare (indent defun)) -        `(let ((display-buffer-alist '(,(jao-attached-buffer-entry name-rx height)))) -           ,@body)) - -      (defun jao-define-attached-buffer (name-rx &optional height) -        (add-to-list 'display-buffer-alist -                     (jao-attached-buffer-entry name-rx height))) - -     #+end_src -*** images -    #+begin_src emacs-lisp -      (setq image-use-external-converter t) -      (setq widget-image-enable nil) -    #+end_src -*** same mode -    #+begin_src emacs-lisp -      (defun jao-buffer-same-mode (&optional mode pre-fn switch-fn) -        (interactive) -        (let* ((mode (or mode major-mode)) -               (modes (if (symbolp mode) (list mode) mode)) -               (pred `(lambda (b) -                        (let ((b (get-buffer (if (consp b) (car b) b)))) -                          (member (buffer-local-value 'major-mode b) -                                  ',modes)))) -               (buff (read-buffer "Buffer: " nil t pred))) -          (when pre-fn (funcall pre-fn)) -          (if switch-fn (funcall switch-fn buff) (pop-to-buffer buff)))) -      (global-set-key (kbd "C-c C-b") #'jao-buffer-same-mode) -    #+end_src -*** projects -    #+begin_src emacs-lisp -      (use-package project -        :bind (("C-x C-p" . project-prefix-map))) -    #+end_src -*** buffer quit function (the triple ESC) -    #+begin_src emacs-lisp -      (setq buffer-quit-function (lambda () t)) -    #+end_src -*** pulsar -    #+begin_src emacs-lisp -      (use-package pulsar -        :ensure t -        :diminish -        :custom ((pulsar-pulse-functions -                  '(ace-window -                    backward-page -                    delete-other-windows -                    delete-window -                    forward-page -                    jao-prev-window -                    move-to-window-line-top-bottom -                    org-backward-heading-same-level -                    org-forward-heading-same-level -                    org-next-visible-heading -                    org-previous-visible-heading -                    other-window -                    outline-backward-same-level -                    outline-forward-same-level -                    outline-next-visible-heading -                    outline-previous-visible-heading -                    outline-up-heading -                    recenter-top-bottom -                    reposition-window -                    scroll-down-command -                    scroll-up-command)) -                 (pulsar-pulse t) -                 (pulsar-delay 0.1) -                 (pulsar-iterations 10) -                 (pulsar-face 'pulsar-yellow) -                 (pulsar-highlight-face 'pulsar-face)) -        :hook ((jao-afio-switch . pulsar-pulse-line))) - -      (pulsar-global-mode) - -    #+end_src -* Windows -*** scrolling -    #+begin_src emacs-lisp -      (setq scroll-preserve-screen-position 'always -            scroll-conservatively most-positive-fixnum -            scroll-margin 4 -            scroll-step 2 -            redisplay-skip-fontification-on-input t) -    #+end_src -*** splitting and switch -    #+begin_src emacs-lisp -      (setq split-height-threshold 80 -            split-width-threshold 144 -            display-buffer-avoid-small-windows 20) - -      (setq switch-to-buffer-preserve-window-point nil -            switch-to-buffer-obey-display-actions t -            switch-to-prev-buffer-skip 'this) ;; don't switch to a -                                              ;; buffer already visible in -                                              ;; this frame - -      (global-set-key (kbd "C-x _") #'delete-other-windows-vertically) -    #+end_src -*** first window -    #+begin_src emacs-lisp -      (defvar jao-first-window--from nil) - -      (defun jao-first-window () -        "Go to previous windows in frame, remembering where we were." -        (interactive) -        (let ((cb (current-buffer))) -          (if (eq (get-buffer-window cb) (select-window (frame-first-window))) -              (when jao-first-window--from (pop-to-buffer jao-first-window--from)) -            (setq jao-first-window--from cb)))) - -      (defun jao-prev-window () -        "Go to previous window." -        (interactive) -        (other-window -1)) - -      (global-set-key (kbd "C-x p") #'jao-prev-window) -      (global-set-key (kbd "s-a") #'jao-first-window) -      (global-set-key (kbd "M-a") #'jao-first-window) - -    #+end_src -*** ace window -    #+begin_src emacs-lisp -      (use-package ace-window -        :ensure t -        :demand t -        :init (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l) -                    aw-char-position 'top-left -                    aw-ignore-current nil -                    aw-dispatch-when-more-than 2 -                    aw-leading-char-style 'path -                    aw-display-mode-overlay t -                    aw-scope 'frame) -        :config - -        (defun jao-ace-consult-buffer-other-window (w) -          (interactive) -          (aw-switch-to-window w) -          (consult-buffer)) - -        (setf (alist-get ?b aw-dispatch-alist) -              '(jao-ace-consult-buffer-other-window "Consult buffer")) - -        (setf (alist-get ?B aw-dispatch-alist) -              (alist-get ?u aw-dispatch-alist)) - - -        :bind (("M-o" . ace-window) -               ("M-O" . ace-swap-window) -               ("C-x 4 t" . ace-swap-window))) - -    #+end_src -*** window navigation (custom) -    #+begin_src emacs-lisp -      (defun jao-nth-window (n) -        (if (zerop n) -            'jao-first-window -          `(lambda () -             (interactive) -             (select-window (frame-first-window)) -             (dotimes (x ,n) (other-window 1))))) - -      (defun jao-prev-window () -        "Go to previous window" -        (interactive) -        (other-window -1)) - -      (defun jao-next-window () -        "Go to previous window" -        (interactive) -        ;; next-window-any-frame -        (other-window 1)) - -      (global-set-key (kbd "C-x p") 'jao-prev-window) -      (global-set-key (kbd "C-x o") 'other-window) -      (mapc (lambda (n) -              (global-set-key (format "\C-c%s" (1+ n)) (jao-nth-window n))) -            '(0 1 2 3 4 5 6 7 8)) - -      ;; transposing windows -      (defun transpose-windows (arg) -        "Transpose the buffers shown in two windows." -        (interactive "p") -        (let ((selector (if (>= arg 0) 'next-window 'previous-window))) -          (while (/= arg 0) -            (let ((this-win (window-buffer)) -                  (next-win (window-buffer (funcall selector)))) -              (set-window-buffer (selected-window) next-win) -              (set-window-buffer (funcall selector) this-win) -              (select-window (funcall selector))) -            (setq arg (if (plusp arg) (1- arg) (1+ arg)))))) - -      (define-key ctl-x-4-map (kbd "t") 'transpose-windows) -    #+end_src - -    #+RESULTS: -    : transpose-windows -*** winner mode -    #+begin_src emacs-lisp -      (winner-mode 1) -    #+end_src -* Frames -*** Frame geometry -    #+begin_src emacs-lisp -      (setq frame-resize-pixelwise t) -      (modify-all-frames-parameters -       `((horizontal-scroll-bars . nil) -         (vertical-scroll-bars . nil) -         (scroll-bar-width . 0) -         (menu-bar . nil))) -    #+end_src -*** Frame layout, title, etc. -    #+begin_src emacs-lisp -      (setq frame-title-format '("%b")) -      (use-package fringe) -      (fringe-mode) - -      (menu-bar-mode -1) - -      ;; (setting it to nil avoids mouse wrapping after other-frame) -      (setq focus-follows-mouse t) - -      (use-package scroll-bar) -      (set-scroll-bar-mode nil) -      (use-package tool-bar) -      (tool-bar-mode -1) - -      (defun jao-trisect (&optional force) -        (interactive) -        (let ((fw (frame-width))) -          (delete-other-windows) -          (cond ((or force (>= fw 240)) -                 (let ((w (- (/ fw 3)))) -                   (delete-other-windows) -                   (split-window-horizontally w) -                   (split-window-horizontally w) -                   (balance-windows))) -                ((> fw 162) -                 (split-window-horizontally) -                 (switch-to-buffer (other-buffer)))))) - -      (defun jao-bisect () -        (interactive) -        (jao-trisect t) -        (next-window) -        (delete-window)) -    #+end_src -*** afio -    #+begin_src emacs-lisp -      (use-package jao-afio) - -      (defun jao-xmonad-goto-1 () -        (shell-command "sendCommand 1")) - -      (defun jao-afio--goto-scratch-1 () -        (interactive) -        (jao-afio-goto-scratch t)) - -      (jao-afio-setup 'jao-afio--goto-scratch-1 t) - -      (defun jao-current--frame-id () -        (propertize (if (and (jao-exwm-enabled-p) -                             (not (bound-and-true-p jao-exwm--use-afio))) -                        (format "F%s" exwm-workspace-current-index) -                      (format "%s" (jao-afio-current-no))) -                    'face 'font-lock-warning-face)) - -      (add-hook 'jao-afio-switch-hook #'tracking-remove-visible-buffers) -      (jao-minibuffer-add-variable '(jao-current--frame-id) 100) - -      (defun jao-afio--set-mode-line () -        (when (and window-system (fboundp 'jao-mode-line-hide-inactive)) -          (if (string= "Docs" (jao-afio-current-frame)) -              (jao-mode-line-show-inactive nil) -            (jao-mode-line-hide-inactive nil)))) - -      (unless jao-modeline-in-minibuffer -        (add-hook 'jao-afio-switch-hook #'jao-afio--set-mode-line)) -    #+end_src -* Writing and writing modes -*** Copyright notices -    #+begin_src emacs-lisp -      (setq copyright-year-ranges t) -      (add-hook 'write-file-functions 'copyright-update) -    #+end_src -*** Indent on yank -    #+begin_src emacs-lisp -      ;;; indent on yank -      (defvar jao-auto-indent-modes -        '(emacs-lisp-mode ;; clojure-mode -          scheme-mode objc-mode -          tuareg-mode c-mode c++-mode -          tcl-mode sql-mode -          perl-mode cperl-mode -          java-mode jde-mode -          LaTeX-mode TeX-mode)) - -      (defadvice yank (after indent-region activate) -        (if (member major-mode jao-auto-indent-modes) -            (indent-region (region-beginning) (region-end) nil))) -    #+end_src -*** Org mode -    #+begin_src emacs-lisp -      (use-package jao-custom-org) -    #+end_src -*** Blog -    #+begin_src emacs-lisp -      (use-package jao-custom-blog) -    #+end_src -*** Text-ish mode settings -    #+begin_src emacs-lisp -      ;;; SENTENCES separated by just one space -      (setq sentence-end "[.?!][]\"')]*\\($\\|\t\\| \\)[ \t\n]*") -      (setq sentence-end-double-space t) -      ;;; copy rectangle -      (defun kill-rectangle-save (start end) -        "Save the region-rectangle as the last killed one." -        (interactive "r") -        (require 'rect)           ; Make sure killed-rectangle is defvar'ed. -        (setq killed-rectangle (extract-rectangle start end)) -        (message "Rectangle saved")) - -      ;; text mode, autoinserts and write hooks -      ;;; misc -      (setq default-major-mode 'text-mode) - -      (add-hook 'text-mode-hook 'turn-on-auto-fill) -    #+end_src -*** Dictionaries -    #+begin_src emacs-lisp -      (defun jao-word-definition-lookup () -        "Look up the word under cursor in a browser." -        (interactive) -        (require 'thingatpt) -        (browse-url -         (concat "http://www.wordnik.com/words/" -                 ;; "http://www.answers.com/main/ntquery?s=" -                 (thing-at-point 'word)))) - -      (use-package dictionary -        :init (setq dictionary-use-single-buffer t -                    dictionary-server "localhost") -        :commands (dictionary-search -                   dictionary-match-words -                   dictionary-lookup-definition -                   dictionary -                   dictionary-mouse-popup-matching-words -                   dictionary-popup-matching-words -                   dictionary-tooltip-mode -                   global-dictionary-tooltip-mode) -        :bind (("C-c d" . dictionary-search))) - -      (setq ispell-personal-dictionary -            (expand-file-name "~/.emacs.d/ispell.dict")) - -      (use-package wordreference -        :ensure t -        :init (setq wordreference-target-lang "es" -                    wordreference-source-lang "en") -        :bind (("C-c D" . wordreference-search))) - -    #+end_src -*** Markdown -    #+BEGIN_SRC emacs-lisp -      (use-package markdown-mode -        :ensure t) - -      (use-package markdown-toc -        :ensure t) - -      (dolist (ext '("\\.md$" "\\.markdown$")) -        (add-to-list 'auto-mode-alist (cons ext 'markdown-mode))) -    #+END_SRC -*** TeX and LaTex -    #+begin_src emacs-lisp -      (use-package tex-site -        :ensure auctex -        :init -        (setq TeX-auto-save t) -        (setq TeX-parse-self t) -        (setq TeX-a4-paper t) -        (setq TeX-auto-local ".tex-auto-local") -        ;; Preferred view format: dvi, ps, pdf, pdfs -        (setq TeX-view-format "pdf") -        (setq-default TeX-master "../main") ; nil to ask -        (setq TeX-view-program-selection -              ;;  '((output-dvi "open") -              ;;    (output-pdf "open") -              ;;    (output-html "open")) -              '(((output-dvi has-no-display-manager) "dvi2tty") -                ((output-dvi style-pstricks) "dvips and gv") -                (output-dvi "xdvi") -                (output-pdf "xdg-open") -                (output-html "xdg-open"))) -        ;; to make RefTeX faster for large documents, try these: -        (setq reftex-enable-partial-scans t) -        (setq reftex-save-parse-info t) -        (setq reftex-use-multiple-selection-buffers t) -        ;; to integrate with AUCTeX -        (setq reftex-plug-into-AUCTeX t) -        (setq reftex-ref-style-default-list -              '("Hyperref" "Varioref" "Fancyref")) -        (setq LaTeX-command "latex -shell-escape") -        (setq LaTeX-biblatex-use-Biber t) -        (setq bibtex-dialect 'biblatex) -        :config -        (add-hook 'TeX-after-compilation-finished-functions -                  #'TeX-revert-document-buffer) -        (add-hook 'LaTeX-mode-hook 'turn-on-reftex) -        ) - -      ;; (use-package ebib -      ;;  :ensure t -      ;;  :config (setq ebib-bibtex-dialect 'biblatex)) - -      ;; for M-x biblio-lookup -      ;; (use-package biblio :ensure t) -    #+end_src -* Browsing -*** Variables -    #+begin_src emacs-lisp -      (defvar jao-browse-doc-use-emacs-p t) -      (defvar jao-browse-url-function nil) -      (defvar jao-browse-url-external-function nil) -    #+end_src -*** URL around point -    #+begin_src emacs-lisp -      (defun jao-url-around-point (&optional current-url) -        (or (and (fboundp 'w3m-anchor) (w3m-anchor)) -            (shr-url-at-point nil) -            (ffap-url-at-point) -            (thing-at-point 'url) -            (when current-url -              (or (and (fboundp 'w3m-anchor) (w3m-anchor)) -                  (and (derived-mode-p 'eww-mode) (plist-get eww-data :url)))))) - -      (defun jao--url-prompt () -        (let* ((def (jao-url-around-point t)) -               (prompt (concat "URL" (if def (format " (%s): " def) ": ")))) -          (read-string prompt nil nil def))) -    #+end_src -*** Downloads using wget -    #+BEGIN_SRC emacs-lisp -      (defun jao-wget--get-title (filename) -        (let ((fn (file-name-base filename))) -          (if (string-blank-p fn) -              (plist-get eww-data :title) -            (subst-char-in-string ?- ?  (capitalize fn))))) - -      (defun jao-wget (url &optional user pwd) -        "Download URL using wget." -        (let* ((def (file-name-nondirectory url)) -               (pmt (format "Save %s to: " url)) -               (read-file-name-function nil) -               (dest (expand-file-name -                      (read-file-name pmt jao-sink-dir nil nil def))) -               (title (jao-wget--get-title dest)) -               (src-url (jao-url-around-point t)) -               (auth (when (and user pwd) -                       `(,(format "--http-user=%s" user) -                         ,(format "--http-password=%s" pwd))))) -          (switch-to-buffer-other-window (get-buffer-create "*downloads*")) -          (erase-buffer) -          (kill-new (format "[[doc:%s][%s]] (from [[%s][here]])" -                            (file-name-nondirectory dest) -                            (read-string "Title: " title) -                            (or src-url (file-name-directory url)))) -          (apply 'make-term `("downloads" "wget" nil ,@auth "-O" ,dest ,url)))) - -      (defun jao-download (url &optional pws) -        "Download URL using wget" -        (interactive (list (jao--url-prompt))) -        (when url -          (let ((usr (and pws (read-string "Login name: "))) -                (pwd (and pws (read-passwd "Password: ")))) -            (jao-wget url usr pwd)))) - -      (with-eval-after-load "embark" -        (define-key embark-url-map (kbd "d") #'jao-download)) - -    #+END_SRC -*** Video -    #+BEGIN_SRC emacs-lisp -      (defvar jao-video--url-rx -        (format "^https?://\\(?:www\\.\\)?%s/.+" -                (regexp-opt '("youtu.be" -                              "youtube.com" -                              "blip.tv" -                              "vimeo.com" -                              "infoq.com") -                            t))) - -      (defvar jao-video--ext-rx -        (format "^https?://.+/.+\\.%s" (regexp-opt '("mp3" "webm" "mp4")))) - -      (defun jao-video--url-p (url) -        (or (string-match-p jao-video--url-rx url) -            (string-match-p jao-video--ext-rx url))) - -      (defun jao--remote-run (url prg) -        (let ((args (format "%s %s" prg (shell-quote-argument url)))) -          (start-process-shell-command prg nil args))) - -      (defun jao--mpv (url &rest args) (jao--remote-run url "mpv")) -      (defun jao--vlc (url &rest args) (jao--remote-run url "vlc")) - -      (defvar jao--video-player 'jao--mpv) - -      (defun jao-view-video (url) -        "Tries to stream a video from the current or given URL" -        (interactive (list (jao--url-prompt))) -        (when url (funcall jao--video-player url))) - -      (defun jao-maybe-view-video (url &rest _ignored) -        (interactive) -        (if (y-or-n-p "View video (y) or web page (n)? ") -            (jao-view-video url) -          (funcall jao-browse-url-function url))) - -    #+END_SRC -*** Web browsers -    #+begin_src emacs-lisp -      (defun jao-www--buffer-p (b) -        (with-current-buffer b -          (or (derived-mode-p 'w3m-mode 'eww-mode) -              (and (boundp 'exwm-class-name) -                   (member (buffer-local-value 'exwm-class-name b) -                           '("vlc" "mpv")))))) - -      (use-package jao-custom-eww) -    #+end_src -*** Browse URL -    #+begin_src emacs-lisp -      (require 'browse-url) - -      (setq browse-url-generic-program "~/bin/firehog") - -      (defun jao-browse-with-external-browser (&rest url) -        "Browse with external hogging" -        (interactive "s") -        (let ((url (or (car url) (jao-url-around-point)))) -          (if (not url) -              (message "No URL at point") -            (when (and (jao-exwm-enabled-p) (fboundp 'jao-exwm-firefox)) -              (jao-exwm-firefox)) -            (when (and jao-sway-enabled (fboundp 'jao-sway-firefox)) -              (jao-sway-firefox)) -            (browse-url-generic url)))) -      (setq jao-browse-url-external-function 'jao-browse-with-external-browser) - -      (defun jao--fln (url) -        (shell-quote-argument -         (if (string-match "^[^:]*:/*?\\(/?[^/].*\\)" url) -             (match-string-no-properties 1 url) -           url))) - -      (defun jao--browse-doc (url search &optional no-add) -        (let* ((url (substring-no-properties url)) -               (file (jao--fln url))) -          (when file -            (unless (file-exists-p file) -              (error "File %s does not exist" file)) -            (jao-open-doc file)))) - -      (defun jao--make-file-rx (exts) -        (format "file:/?/?.+\\.%s$" (regexp-opt exts))) - -      (defvar jao--see-exts -        (jao--make-file-rx '("jpg" "jpeg" "png" "mov" "wmv" "avi" "mp4"))) - -      (defvar jao--doc-exts -        (jao--make-file-rx '("ps" "ps.gz" "pdf" "dvi" "djvu" "chm"))) - -      (defvar jao-browse-url-wget-exts -        '("ps" "pdf" "dvi" "djvu" "zip" "gz" "tgz" "mp4" "mp3" "flv")) - -      (defvar jao-browse-external-domains -        '("github.com" "gitlab.com" "slack.com" "meet.google.com" -          "twitter.com" "t.com" "linkedin.com" "bigml.com")) - -      (defvar jao-browse--external-regexp -        (format "https?://.*%s\\(/.*\\)?" -                (regexp-opt jao-browse-external-domains))) - -      (defun jao-wget--regexp () -        (concat "^http[s]?://.+\\(\\." -          (mapconcat 'identity jao-browse-url-wget-exts "\\|\\.") -          "\\)\\'")) - -      (defun jao--see (url &rest _r) -        (start-process-shell-command "see" nil (format "see %s" (jao--fln url)))) - -      (defun jao--find-file-other-window (url &rest _) -        (find-file-other-window (jao--fln url))) - -      (use-package elpher :ensure t) - -      (defun jao-elpher--browse (url &rest _) (elpher-go url)) - -      (defvar jao-browse--sound-rx -        (format "^https?://.*/.*\\.%s" (regexp-opt '("mp4" "mp3" "flv")))) - -      (defun jao-browse-add-url-to-mpc (url &rest _) -        "Add the given URL to mpc's playing list, or just play it." -        (let ((p (yes-or-no-p (format "Play %s right now?" url)))) -          (when p (jao-mpc-clear)) -          (jao-mpc-add-url url) -          (if p (jao-mpc-play) (message "%s added to mpc queue" url)))) - -      (defun jao-browse-url-browse (&rest args) -        (apply jao-browse-url-function args)) - -      (setq browse-url-handlers -            `(("^\\(gemini\\|gopher\\)://.*" . jao-elpher--browse) -              (,jao--doc-exts . jao--browse-doc) -              (,jao--see-exts . jao--see) -              ("^file://?.+\\.html?$" . ,jao-browse-url-function) -              ("^file://?" . jao--find-file-other-window) -              (,jao-browse--external-regexp . ,jao-browse-url-external-function) -              ("^https?://.*\\.gotomeeting\\.com\\.*" . browse-url-chrome) -              (,jao-browse--sound-rx . jao-browse-add-url-to-mpc) -              (,(jao-wget--regexp) . jao-download) -              (jao-video--url-p . jao-maybe-view-video) -              ("." . jao-browse-url-browse))) - -      (when (< emacs-major-version 28) -        (setf (alist-get 'jao-video--url-p browse-url-handlers nil t) nil) -        (setq browse-url-browser-function browse-url-handlers)) - -    #+end_src -*** Subscribe rss using r2e -    #+begin_src emacs-lisp -      (autoload 'View-quit "view") - -      (defun jao-rss--find-url () -        (save-excursion -          (when (derived-mode-p 'w3m-mode 'eww-mode) -            (if (fboundp 'w3m-view-source) (w3m-view-source) (eww-view-source))) -          (goto-char (point-min)) -          (when (re-search-forward -                 "type=\"application/\\(?:atom\\|rss\\)\\+xml\" +" nil t) -            (let ((url (save-excursion -                         (when (re-search-forward -                                "href=\"\\([^\n\"]+\\)\"" nil t) -                           (match-string-no-properties 1)))) -                  (title (when (re-search-forward -                                "\\(?:title=\"\\([^\n\"]+\\)\" +\\)" nil t) -                           (match-string-no-properties 1)))) -              (cond ((derived-mode-p 'w3m-view-mode) (w3m-view-source)) -                    ((string-match-p ".*\\*eww-source\\b.*" (buffer-name)) -                     (View-quit))) -              (when url (cons url (or title ""))))))) - -      (defun jao-rss2e-append (name url mbox) -        (with-current-buffer (find-file-noselect "~/.config/rss2email.cfg") -          (goto-char (point-max)) -          (insert "[feed." name "]\nurl = " url) -          (insert "\nto = " mbox "+" name "@localhost") -          (insert "\nmaildir-mailbox = " mbox "\n\n") -          (save-buffer))) - -      (defun jao-rss--feeds-dirs () -        (mapcar (lambda (d) (cadr (split-string d "\\."))) -                (directory-files "~/.emacs.d/gnus/Mail/" nil "^feeds"))) - -      (defun jao-rss-subscribe (url) -        "Subscribe to a given RSS URL.  If URL not given, look for it." -        (interactive (list (or (jao-url-around-point) -                               (jao-rss--find-url) -                               (read-string "Feed URL: ")))) -        (let* ((url+title (if (consp url) url (list url))) -               (url (car url+title)) -               (title (cdr url+title)) -               ;; (cats (cons "prog" (jao-notmuch--subtags "feeds"))) -               (cats (jao-rss--feeds-dirs))) -          (if url -              (let ((url (if (string-match "^feed:" url) (substring url 5) url))) -                (when (y-or-n-p (format "Subscribe to <%s>? " url)) -                  (let* ((name (read-string "Feed name: " title)) -                         (cat (completing-read "Category: " cats nil t)) -                         (subs (format "r2e add %s '%s' feeds.%s@localhost" -                                       name url cat))) -                    ;; (jao-rss2e-append name url cat) -                    (shell-command-to-string subs) -                    (shell-command (format "r2e run %s" name))))) -            (message "No feeds found")))) -    #+end_src -* Email -  #+begin_src emacs-lisp -    (setq jao-afio-mail-function 'notmuch) -    (use-package jao-custom-email) -    (use-package jao-custom-notmuch) -  #+end_src -* PDFs and other docs -*** doc-view -    #+begin_src emacs-lisp -      (use-package doc-view -        :init -        (setq doc-view-cache-directory "~/.emacs.d/cache/docview" -              doc-view-resolution 110 -              doc-view-continuous t -              doc-view-conversion-refresh-interval 1) - -        :bind (:map doc-view-mode-map -                    ("j" . doc-view-next-line-or-next-page) -                    ("J" . doc-view-scroll-up-or-next-page) -                    ("k" . doc-view-previous-line-or-previous-page) -                    ("K" . doc-view-scroll-down-or-previous-page))) - -      (use-package jao-doc-view -        :bind (:map doc-view-mode-map -                    ("b" . jao-doc-view-back) -                    ("B" . jao-doc-view-forward) -                    ("S" . jao-doc-view-save-session) -                    ("u" . jao-doc-view-visit-url))) -    #+end_src -*** pdf-tools -    #+begin_src emacs-lisp -      (use-package pdf-tools -        :ensure t -        :demand t -        :init -        (add-hook 'after-init-hook -                  (lambda () -                    (setq pdf-view-midnight-colors -                          (cons (frame-parameter nil 'foreground-color) -                                (frame-parameter nil 'background-color))))) - -        :config (pdf-tools-install) - -        :diminish ((pdf-view-midnight-minor-mode . "")) - -        :bind (:map pdf-view-mode-map -                    (("C-c C-d" . pdf-view-midnight-minor-mode) -                     ("j" . pdf-view-next-line-or-next-page) -                     ("J" . pdf-view-scroll-up-or-next-page) -                     ("k" . pdf-view-previous-line-or-previous-page) -                     ("K" . pdf-view-scroll-down-or-previous-page)))) - -    #+end_src -*** zathura -    #+begin_src emacs-lisp -      (defun jao-zathura-file-info (title) -        (when (string-match "\\(.+\\) \\[\\(.+\\) (\\([0-9]+\\)/\\([0-9]+\\))\\]" -                            title) -          (list (expand-file-name (match-string 1 title)) -                (string-to-number (match-string 3 title)) -                (string-to-number (match-string 4 title)) -                (match-string 2 title)))) - -      (defun jao-zathura-goto-org (&optional title) -        (when-let* ((title (or title (jao-shell-string "xdotool" -                                                       "getactivewindow" -                                                       "getwindowname"))) -                    (info (jao-zathura-file-info title)) -                    (file (jao-org-pdf-to-org-file (car info))) -                    (page (cadr info)) -                    (pageno (or (car (last info)) page))) -          (ignore-errors (jao-afio--goto-docs)) -          (let* ((exists (file-exists-p file)) -                 (fn (file-name-nondirectory file)) -                 (lnk (format "[[doc:%s::%d][Page %s]]" fn page pageno))) -            (find-file file) -            (unless exists (jao-org-insert-doc-skeleton)) -            (if (or (not exists) (y-or-n-p "Insert link?")) -                (insert lnk "\n") -              (kill-new lnk) -              (message "Link to %s (%s) killed" file page))))) - -      (defun jao-zathura-open (file page) -        (let ((id (jao-shell-string (format "xdotool search --name %s" -                                            (file-name-nondirectory file))))) -          (if (string-blank-p id) -              (progn -                (when jao-xmonad-enabled -                  (jao-shell-exec "xdotool set_destktop 2")) -                (jao-shell-exec (format "zathura %s -P %s" file (or page 1)))) -            (let* ((page (if page (format " && xdotool type %dg" page) "")) -                   (cmd (format "xdotool windowactivate %s%s" id page))) -              (jao-shell-string cmd))))) - -    #+end_src -*** open pdfs -    #+begin_src emacs-lisp -      (use-package saveplace-pdf-view -        :ensure t -        :demand t -        :after doc-view) - -      (setq jao-open-doc-fun 'jao-find-or-open) -      (setq jao-org-open-pdf-fun 'jao-find-or-open) - -      (defun jao-find-or-open (file &optional page height) -        (if (and jao-browse-doc-use-emacs-p window-system) -            (let* ((buffs (buffer-list)) -                   (b (catch 'done -                        (while buffs -                          (when (string-equal (buffer-file-name (car buffs)) file) -                            (throw 'done (car buffs))) -                          (setq buffs (cdr buffs)))))) -              (jao-afio--goto-docs) -              (if b (pop-to-buffer b) (find-file file)) -              (when page (jao-doc-view-goto-page page height))) -          (jao-zathura-open file page))) - -      (defun jao-open-doc (&optional file page height) -        (interactive) -        (when-let (file (or file -                            (read-file-name "Document: " -                                            (concat jao-org-dir "/doc/")))) -          (funcall jao-open-doc-fun file page height))) - -      (defun jao-select-pdf () -        (interactive) -        (jao-buffer-same-mode '(pdf-view-mode doc-view-mode) -                              #'jao-afio--goto-docs)) -    #+end_src -*** epub -    #+begin_src emacs-lisp -      (use-package nov -        :ensure t -        :after doc-view -        :init (setq nov-variable-pitch t -                    nov-text-width 80) -        :config (add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))) - -    #+end_src -*** transient -    #+begin_src emacs-lisp -      (defun jao-org-pdf-goto-org-linking () -        (interactive) -        (jao-org-pdf-goto-org 4)) - -      (jao-transient-major-mode doc-view -        ["Notes" -         ("o" "notes file" jao-org-pdf-goto-org) -         ("O" "notes file, linking" jao-org-pdf-goto-org-linking)] -        ["Navigation" -         ("b" "back jump" jao-doc-view-back) -         ("B" "forward jump" jao-doc-view-back) -         ("u" "visit URL" jao-doc-view-visit-url)] -        ["Slices" -         ("cb" "bounding box" doc-view-set-slice-from-bounding-box) -         ("cm" "using mouse" doc-view-set-slice-using-mouse)] -        ["Session" -         ("s" "load session" jao-afio-open-pdf-session) -         ("S" "save session" jao-doc-view-save-session) -         ("d" "visit cache directory" doc-view-dired-cache)]) - -      (with-eval-after-load "pdf-view" -        (jao-transient-major-mode pdf-view -          ["Notes" -           ("o" "notes file" jao-org-pdf-goto-org) -           ("O" "notes file, linking" jao-org-pdf-goto-org-linking)] -          ["Navigation" -           ("b" "back jump" pdf-history-backward) -           ("f" "forward jump" pdf-history-forward)] -          ["Session" -           ("s" "load session" jao-afio-open-pdf-session) -           ("S" "save session" jao-doc-view-save-session)])) - -      ;; (transient-get-suffix 'jao-transient-pdf-view '(0 -1)) - -  #+end_src -* Shells and terms -*** shell modes -    #+begin_src emacs-lisp -      (setq sh-basic-offset 2) -      ;; translates ANSI colors into text-properties, for eshell -      (autoload 'ansi-color-for-comint-mode-on "ansi-color" nil t) -      (add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on) -    #+end_src -*** vterm -    #+begin_src emacs-lisp -      (defvar jao-use-vterm nil) - -      (use-package vterm -        :ensure t -        :demand t -        :commands (vterm vterm-mode) -        :init (setq vterm-kill-buffer-on-exit t -                    vterm-copy-exclude-prompt t -                    jao-use-vterm t) -        :config (jao-define-attached-buffer "\\*vterm\\*" 0.5) -        :bind (:map vterm-mode-map ("C-c C-c" . vterm-send-C-c))) - -      (defun jao-exec-in-vterm (cmd bname) -        (if (string-blank-p (or cmd "")) -            (vterm) -          (let ((vterm-shell cmd) -                (vterm-kill-buffer-on-exit t) -                (buff (generate-new-buffer bname))) -            (switch-to-buffer buff) -            (vterm-mode)))) - -    #+end_src -*** term -    #+begin_src emacs-lisp -      (defvar-local jao-term--cmd nil) - -      (defun jao-term--find (cmd) -        (seq-find (lambda (b) -                    (with-current-buffer b -                      (and (derived-mode-p 'term-mode 'vterm-mode) -                           (string= (or jao-term--cmd "") cmd)))) -                  (buffer-list))) - -      (defun jao-exec-in-term (cmd &optional name) -        (if jao-use-vterm -            (jao-exec-in-vterm cmd name) -          (ansi-term "bash" name) -          (set-process-sentinel (get-buffer-process (current-buffer)) -                                (lambda (process event) -                                  (when (string= event "finished\n") -                                    (kill-buffer (process-buffer process))))) -          (term-send-string nil (concat cmd " ; exit\n")))) - -      (defmacro jao-def-exec-in-term (name cmd &rest prelude) -        `(defun ,(intern (format "jao-term-%s" name)) (&optional term) -           (interactive "P") -           ,@prelude -           (let ((jao-use-vterm (if term (not jao-use-vterm) jao-use-vterm))) -             (if-let ((b (jao-term--find ,cmd))) -                 (pop-to-buffer b) -               (jao-exec-in-term ,cmd ,(format "*%s*" name)) -               (setq-local jao-term--cmd ,cmd))))) - -    #+end_src -*** eshell -***** Basic custom -      #+begin_src emacs-lisp -        (use-package eshell -          :init -          (setq eshell-directory-name "~/.emacs.d/eshell") -          (setq eshell-hist-ignoredups 'erase) - -          (defun jao-eshell--outline () -            (setq-local outline-regexp eshell-prompt-regexp)) - -          :hook (eshell-mode . jao-eshell--outline)) -      #+end_src -***** Colors -      #+begin_src emacs-lisp -        (autoload 'ansi-color-apply "ansi-color") -        ;; (add-hook 'eshell-preoutput-filter-functions 'ansi-color-filter-apply) -        (add-hook 'eshell-preoutput-filter-functions 'ansi-color-apply) - -        (use-package eshell-syntax-highlighting -          :after esh-mode -          :ensure t -          :config -          ;; Enable in all Eshell buffers. -          (eshell-syntax-highlighting-global-mode +1)) -      #+end_src -***** Visual commands -      #+begin_src emacs-lisp -        (require 'em-term) -        ;;; commands using ansi scape seqs -        (dolist (c '("editor" "more" "wget" "dict" "vim" "links" "w3m" "guile" -                     "ssh" "autossh" "zmore" "pager" "aptitude" "su" "htop" "top" -                     "screen" "whizzml" "iex" "spt")) -          (add-to-list 'eshell-visual-commands c)) - -        (setq eshell-visual-subcommands '(("git" "log" "diff" "show") -                                          ("sudo" "vim") -                                          ("rebar3" "shell")) -              eshell-destroy-buffer-when-process-dies nil -              eshell-escape-control-x t) - -        (use-package eshell-vterm :ensure t) - -        (when jao-use-vterm (eshell-vterm-mode)) - -      #+end_src -***** bol -      #+begin_src emacs-lisp -        (defun jao-eshell-maybe-bol () -          (interactive) -          (let ((p (point))) -            (eshell-bol) -            (if (= p (point)) -                (beginning-of-line)))) -      #+end_src -***** Prompt -      #+BEGIN_SRC emacs-lisp -      ;; tracking git repos -      (defun jao-eshell--git-dirty () -        (shell-command-to-string "git diff-index --quiet HEAD -- || echo -n '*'")) - -      (use-package git-ps1-mode -        :ensure t -        :init (setq git-ps1-mode-showupstream "1" -                    git-ps1-mode-showdirtystate "1")) - -      (defun jao-eshell--git-info () -        (if (fboundp 'git-ps1-mode-get-current) -            (git-ps1-mode-get-current) -          (let ((desc (shell-command-to-string "git branch --no-color"))) -            (when (string-match "^* \\(\\<.+\\>\\)" desc) -              (format "%s%s" (match-string 1 desc) (jao-eshell--git-dirty)))))) - -      (defun jao-eshell--git-current-branch (suffix) -        (let ((desc (or (jao-eshell--git-info) ""))) -          (cond ((and (string-empty-p desc) suffix) (format " (%s)" suffix)) -                ((string-empty-p (or suffix "")) (format " (%s)" desc)) -                (t (format " (%s %s)" desc suffix))))) - -      (defun jao-eshell--virtualenv () -        (let ((venv (getenv "VIRTUAL_ENV"))) -          (when (and venv (string-match ".*/\\([^/]+\\)/$" venv)) -            (match-string-no-properties 1 venv)))) - -      (defun jao-eshell-prompt-function () -        (let* ((venv (jao-eshell--virtualenv)) -               (venv (if venv (format "%s" venv) ""))) -          (concat (abbreviate-file-name (eshell/pwd)) -                  (jao-eshell--git-current-branch venv) -                  (if (= (user-uid) 0) " # " " $ ")))) - -      (setq eshell-prompt-function 'jao-eshell-prompt-function) -      #+END_SRC -***** in-term -      #+begin_src emacs-lisp -        (defun eshell/in-term (prog &rest args) -          (switch-to-buffer -           (apply #'make-term (format "in-term %s %s" prog args) prog nil args)) -          (term-mode) -          (term-char-mode)) -      #+end_src -***** Dir navigation -      #+BEGIN_SRC emacs-lisp -      (use-package eshell-up -        :ensure t -        :config (setq eshell-up-print-parent-dir t)) - -      (use-package eshell-autojump :ensure t) -      #+END_SRC -***** Completion -      #+begin_src emacs-lisp -        (defun jao-eshell-completion-capf () -          (let* ((b (save-excursion (eshell-bol) (point))) -                 (c (bash-completion-dynamic-complete-nocomint b (point) t))) -            (when (and c (listp c)) -              (append c '(:exclusive no))))) - -        (defun jao-eshell--set-up-completion () -          (setq-local completion-styles '(basic partial-completion) -                      completion-at-point-functions -                      '(jao-eshell-completion-capf -                        pcomplete-completions-at-point t))) - -        (use-package bash-completion -          :ensure t -          :hook (eshell-mode . jao-eshell--set-up-completion)) -      #+end_src -***** History -      #+BEGIN_SRC emacs-lisp -        (setq eshell-history-size 10000) -        ;;; Fix eshell history completion to allow !$ -        ;; This is done by advising eshell-history-reference to expand !$ -        ;; into !!:$ which works... -        (defadvice jao-eshell-history-reference (before ben-fix-eshell-history) -          "Fixes eshell history to allow !$ as abbreviation for !!:$" -          (when (string= (ad-get-arg 0) "!$") (ad-set-arg 0 "!!:$"))) -        (ad-activate 'jao-eshell-history-reference) -      #+END_SRC -      This is needed if we want ! to expand in emacs >= 27 -      #+BEGIN_SRC emacs-lisp -        (add-hook 'eshell-expand-input-functions #'eshell-expand-history-references) -      #+END_SRC -***** Toggle -      #+begin_src emacs-lisp - -        (use-package jao-eshell-here -          :demand t -          :config (jao-define-attached-buffer "^\\*eshell" 0.5) -          :bind (("<f1>" . jao-eshell-here-toggle) -                 ("C-<f1>" . jao-eshell-here-toggle-new))) - -      #+end_src -***** Workarounds -      #+begin_src emacs-lisp -        ;; at some point, bash completion started insertig the TAB -        ;; after the commands ends -        (defun jao-eshell--clean-prompt () -          (eshell-bol) -          (ignore-errors (kill-line))) - -        (add-hook 'eshell-after-prompt-hook 'jao-eshell--clean-prompt) -      #+end_src -***** Keybindings -      #+begin_src emacs-lisp -        (defun jao-eshell--kbds () -          (define-key eshell-mode-map "\C-a" 'jao-eshell-maybe-bol) -          (define-key eshell-mode-map "\C-ci" 'consult-outline)) -        ;; Eshell mode is sillily re-creating its mode map -        ;; in every buffer in emacs < 28. -        (if (> emacs-major-version 27) -            (jao-eshell--kbds) -          (add-hook 'eshell-mode-hook #'jao-eshell--kbds)) -      #+end_src -* Version control and CI -*** General options -    #+begin_src emacs-lisp -    (setq vc-follow-symlinks t) -    (setq auto-revert-check-vc-info nil) -    #+end_src -*** Diff fringe indicators (diff-hl) -    #+begin_src emacs-lisp -      (use-package diff-hl -        :ensure t -        :custom ((diff-hl-draw-borders nil) -                 (diff-hl-side 'right) -                 (diff-hl-margin-symbols-alist -                  '((insert . "+") -                    (delete . "-") -                    (change . "~") -                    (unknown . "?") -                    (ignored . "i")))) -        :config -        (map-keymap (lambda (_k cmd) -                      (put cmd 'repeat-map 'diff-hl-command-map)) -                    diff-hl-command-map) -        (add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh) -        (when (jao-colors-scheme-dark-p) (diff-hl-margin-mode 1))) - -      (global-diff-hl-mode 1) - -    #+end_src -*** Git config files: more informative diffs -    See [[https://protesilaos.com/codelog/2021-01-26-git-diff-hunk-elisp-org/][Informative diff hunks for Emacs Lisp and Org | Protesilaos Stavrou]] -    #+begin_src config :tangle ~/.config/git/attributtes :comments no -      *.clj  diff=lisp -      *.cljc  diff=lisp -      *.cljs  diff=lisp -      *.lisp  diff=lisp -      *.el    diff=lisp -      *.org   diff=org -    #+end_src -    #+begin_src gitconfig :tangle ~/.config/git/config -      [diff "lisp"] -	xfuncname = "^(((;;;+ )|\\(|([ \t]+\\(((cl-|el-patch-)?def(un|var|macro|method|custom)|gb/))).*)$" -      [diff "org"] -	xfuncname = "^(\\*+ +.*)$" -    #+end_src -*** Magit and forge -    #+begin_src emacs-lisp -      (use-package magit -        :ensure t -        :commands magit-status -        :init -        (setq magit-status-initial-section nil -              magit-define-global-key-bindings nil -              magit-completing-read-function 'magit-builtin-completing-read -              magit-display-buffer-function -              'magit-display-buffer-fullcolumn-most-v1 -              magit-delete-by-moving-to-trash nil -              magit-last-seen-setup-instructions "1.4.0" -              magit-log-edit-confirm-cancellation t -              magit-omit-untracked-dir-contents t -              magit-process-connection-type nil -              magit-push-always-verify nil -              magit-repository-directories -              '(("/home/jao/usr/bigml" . 2) -                ("/home/jao/usr/jao" . 2) -                ("/home/jao/lib/elisp" . 3) -                ("/usr/local/src" . 1)) -              magit-save-repository-buffers 'dontask -              magit-section-visibility-indicator '("โฆ" . t) -              magit-status-buffer-switch-function 'switch-to-buffer -              magit-status-show-hashes-in-headers t) -        :config - -        (use-package forge -          :ensure t -          :demand t -          :init -          (setq forge-topic-list-limit (cons 100 -1) -                forge-pull-notifications nil)) - -        (add-hook 'magit-status-sections-hook #'forge-insert-assigned-pullreqs t) -        (add-hook 'magit-status-sections-hook #'forge-insert-assigned-issues t) - -        :bind (("<f2>" . magit-status) -               (:map forge-topic-mode-map ("M-w" . copy-region-as-kill)))) - -      (use-package code-review -        :ensure t -        :after forge -        :bind (:map magit-status-mode-map -                    ("C-c C-r" . code-review-forge-pr-at-point))) - - -    #+end_src -*** Eldoc for magit status/log buffers -    [[https://tsdh.org/posts/2021-06-21-using-eldoc-with-magit.html][Using Eldoc with Magit]]. -    #+begin_src emacs-lisp -      (defun jao-magit-eldoc-for-commit (_callback) -        (when-let ((commit (magit-commit-at-point))) -          (with-temp-buffer -            (magit-git-insert "show" -                              "--format=format:%an <%ae>, %ar" -                              (format "--stat=%d" (window-width)) -                              commit) -            (goto-char (point-min)) -            (put-text-property (point-min) (line-end-position) 'face 'bold) -            (buffer-string)))) - -      (defun jao-magit-eldoc-setup () -        (add-hook 'eldoc-documentation-functions -                  #'jao-magit-eldoc-for-commit nil t) -        (eldoc-mode 1)) - -      (add-hook 'magit-log-mode-hook #'jao-magit-eldoc-setup) -      (add-hook 'magit-status-mode-hook #'jao-magit-eldoc-setup) - -      (with-eval-after-load "eldoc" -        (eldoc-add-command 'magit-next-line) -        (eldoc-add-command 'magit-previous-line) -        (eldoc-add-command 'magit-section-forward) -        (eldoc-add-command 'magit-section-backward)) -    #+end_src -*** Other git packages -    #+begin_src emacs-lisp -      (use-package git-timemachine :ensure t) - -      ;; git config --local git-link.remote / git-link.branch -      (use-package git-link :ensure t) - -      (use-package git-modes :ensure t) - -    #+end_src -*** Jenkins -    [[https://github.com/rmuslimov/jenkins.el][GitHub - rmuslimov/jenkins.el: Jenkins plugin for emacs]] -    #+BEGIN_SRC emacs-lisp -      (use-package jenkins -        :ensure t -        :init -        ;; one also needs jenkins-api-token, jenkins-username and jenkins-url -        ;; optionally: jenkins-colwidth-id, jenkins-colwidth-last-status -        (setq jenkins-colwidth-name 35) -        :config -        (defun jao-jenkins-first-job (&rest _) -          (interactive) -          (goto-char (point-min)) -          (when (re-search-forward "^- Job" nil t) -            (goto-char (match-beginning 0)))) -        (add-hook 'jenkins-job-view-mode-hook #'jao-jenkins-first-job) -        (advice-add 'jenkins-job-render :after #'jao-jenkins-first-job) - -        (defun jenkins-refresh-console-output () -          (interactive) -          (let ((n (buffer-name))) -            (when (string-match "\\*jenkins-console-\\([^-]+\\)-\\(.+\\)\\*$" n) -              (jenkins-get-console-output (match-string 1 n) (match-string 2 n)) -              (goto-char (point-max))))) - -        :bind (:map jenkins-job-view-mode-map -                    (("n" . next-line) -                     ("p" . previous-line) -                     ("f" . jao-jenkins-first-job) -                     ("RET" . jenkins--show-console-output-from-job-screen)) -                    :map jenkins-console-output-mode-map -                    (("n" . next-line) -                     ("p" . previous-line) -                     ("g" . jenkins-refresh-console-output)))) -    #+END_SRC -* Programming -*** Automatic modes -    #+BEGIN_SRC emacs-lisp -      (add-to-list 'auto-mode-alist '("\\.mix\\'" . hexl-mode)) -      (add-to-list 'auto-mode-alist '("\\.m4\\'" . m4-mode)) -      (add-to-list 'auto-mode-alist '("\\.am\\'" . makefile-mode)) -      (add-to-list 'auto-mode-alist '("\\.pl\\'\\|\\.pm\\'" . cperl-mode)) -    #+END_SRC -*** Smart scan -    #+begin_src emacs-lisp -      (use-package smartscan -        :ensure t -        :commands smartscan-mode -        :init (add-hook 'prog-mode-hook #'smartscan-mode) -        :diminish) -    #+end_src -*** Paredit and parens -    #+begin_src emacs-lisp -      (require 'paren) -      (show-paren-mode t) -      (setq show-paren-context-when-offscreen t) - -      (use-package paredit -        :ensure t -        :commands paredit-mode -        :hook ((pie-mode . paredit-mode) -               (scheme-mode . paredit-mode) -               (clojure-mode . paredit-mode) -               (emacs-lisp-mode . paredit-mode) -               (eval-expression-minibuffer-setup . paredit-mode) -               (lisp-interaction-mode . disable-paredit-mode)) -        :diminish ((paredit-mode . " รพ"))) -    #+end_src -*** Diff/Ediff -    #+BEGIN_SRC emacs-lisp -      (setq ediff-split-window-function 'split-window-horizontally) -      (setq ediff-make-buffers-readonly-at-startup nil) -      (setq ediff-window-setup-function 'ediff-setup-windows-plain) -      (setq ediff-keep-variants nil) -    #+END_SRC -*** Compilation -***** Compilation mode options -      #+begin_src emacs-lisp -      (require 'compile) -      (setq compilation-scroll-output t) -      (setq compilation-error-regexp-alist -            (remove 'omake compilation-error-regexp-alist)) -      ;; (add-hook 'compilation-mode-hook #'visual-line-mode) -      #+end_src -***** Mode line (no "Compiling"!) -      #+BEGIN_SRC emacs-lisp -        (require 'compile) -        (diminish 'compilation-minor-mode " โก") -        (when (< emacs-major-version 27) -          (setcdr (assq 'compilation-in-progress minor-mode-alist) '(" โก"))) -        (when (> emacs-major-version 26) -          (setcdr (assq 'compilation-in-progress mode-line-modes) '("โก "))) -      #+END_SRC -***** Colorizing compilation buffer -      #+begin_src emacs-lisp -        (setq compilation-message-face 'default) -        (require 'ansi-color) -        (defun endless/colorize-compilation () -          "Colorize from `compilation-filter-start' to `point'." -          (let ((inhibit-read-only t)) -            (ansi-color-apply-on-region -             compilation-filter-start (point)))) - -        (add-hook 'compilation-filter-hook #'endless/colorize-compilation) -      #+end_src -***** Compilation commands -      #+begin_src emacs-lisp -        (use-package jao-compilation -          :commands jao-compilation-setup -          :bind (("C-c C" . compile) -                 ("C-c c" . jao-compile))) -        (jao-compilation-setup) -      #+end_src -***** Next error -      #+begin_src emacs-lisp -        (setq next-error-find-buffer-function -              #'next-error-buffer-on-selected-frame -              next-error-verbose t) -      #+end_src -*** Flymake -    #+begin_src emacs-lisp -      (use-package flymake -        :ensure t -        :custom ((flymake-mode-line-format '(" " flymake-mode-line-counters))) -        :hook ((haskell-mode . flymake-mode)) -        :config (jao-define-attached-buffer "^\\*Flymake diagnostics .*\\*\\'") -        :bind (:map flymake-mode-map (("s-f n" . flymake-goto-next-error) -                                      ("s-f p" . flymake-goto-prev-error) -                                      ("s-f i" . flymake-show-diagnostic) -                                      ("s-f f" . flymake-show-diagnostics-buffer) -                                      ("s-f l" . consult-flymake)))) -    #+end_src -*** Workarounds -    #+begin_src emacs-lisp -      (setq c-type-finder-time-slot nil) -    #+end_src -*** Outline minor mode -    #+begin_src emacs-lisp -      (setq outline-minor-mode-cycle t) - -      (defvar jao-outline-minor-mode-map -        (let ((map (make-keymap))) -          (define-key map (kbd "C-c C-n") #'outline-next-visible-heading) -          (define-key map (kbd "C-c C-p") #'outline-previous-visible-heading) -          (define-key map (kbd "C-c o") 'consult-outline) -          map)) - -      (define-minor-mode jao-outline-minor-mode -        "Minor outline mode for programming languages" -        :lighter "" -        (if jao-outline-minor-mode -            (progn (setq-local outline-level #'outline-level -                               outline-regexp (format "[%s]\\{3,\\} " -                                                      comment-start) -                               outline-default-state 4) -                   (outline-minor-mode 1)) -          (outline-minor-mode -1))) - -    #+end_src -* Programming languages -*** Elisp -    #+begin_src emacs-lisp -      (add-hook 'emacs-lisp-mode-hook #'jao-outline-minor-mode) - -      (use-package edit-list :ensure t) -      (use-package package-lint :ensure t) - -      (defun elisp-disassemble (function) -        (interactive (list (function-called-at-point))) -        (disassemble function)) - -      (defun elisp-pp (sexp) -        (with-output-to-temp-buffer "*Pp Eval Output*" -          (pp sexp) -          (with-current-buffer standard-output -            (emacs-lisp-mode)))) - -      (defun elisp-macroexpand (form) -        (interactive (list (form-at-point 'sexp))) -        (elisp-pp (macroexpand form))) - -      (defun elisp-macroexpand-all (form) -        (interactive (list (form-at-point 'sexp))) -        (elisp-pp (macroexpand-all form))) - -      (defun elisp-find-definition (name) -        (interactive (list (thing-at-point 'symbol))) -        (cond (name -               (let ((symbol (intern-soft name)) -                     (search (lambda (fun sym) -                               (let* ((r (save-excursion (funcall fun sym))) -                                      (buffer (car r)) -                                      (point (cdr r))) -                                 (cond ((not point) -                                        (error "Found no definition for %s in %s" -                                               name buffer)) -                                       (t -                                        (switch-to-buffer buffer) -                                        (goto-char point) -                                        (recenter 1))))))) -                 (cond ((fboundp symbol) -                        (xref-push-marker-stack) -                        (funcall search 'find-function-noselect symbol)) -                       ((boundp symbol) -                        (xref-push-marker-stack) -                        (funcall search 'find-variable-noselect symbol)) -                       (t -                        (message "Symbol not bound: %S" symbol))))) -              (t (message "No symbol at point")))) - - -      (defun elisp-bytecompile-and-load () -        (interactive) -        (or buffer-file-name -            (error "The buffer must be saved in a file first")) -        (require 'bytecomp) -        ;; Recompile if file or buffer has changed since last compilation. -        (when  (and (buffer-modified-p) -                    (y-or-n-p (format "save buffer %s first? " (buffer-name)))) -          (save-buffer)) -        (let ((filename (expand-file-name buffer-file-name))) -          (with-temp-buffer -            (byte-compile-file filename t)))) - -      (use-package elisp-mode -        :bind (:map emacs-lisp-mode-map -                    (("C-c C-M" . emacs-lisp-macroexpand) -                     ("C-c C-m" . elisp-macroexpand-all) -                     ("C-c C-k" . elisp-bytecompile-and-load) -                     ;; ("C-c C-p" . pp-eval-last-sexp) -                     ("M-." . elisp-find-definition) -                     ("M-," . pop-tag-mark) -                     ("C-c <" . lc-show-package-summary)))) -    #+end_src -*** Erlang -    #+begin_src emacs-lisp -      (use-package erlang -        :disabled t -        :ensure t -        :custom ((inferior-erlang-machine-options '("shell")) -                 (inferior-erlang-machine "rebar3") -                 (inferior-erlang-shell-type nil) -                 (erlang-indent-level 4)) - -        ;; :bind (:map erlang-mode-map (("C-c C-z" . jao-vterm-repl-pop-to-repl))) - -        :init -        ;; (require 'jao-vterm-repl) -        ;; (add-to-list 'auto-mode-alist '("^rebar\\.config\\`" . erlang-mode)) -        ;; (jao-vterm-repl-register "rebar.config" "rebar3 shell" "^[0-9]+> ") - -        :config -        ;; (defun jao-erlang-current-module () -        ;;   (when (save-excursion (goto-char (point-min)) -        ;;                         (re-search-forward "^-module(\\([^)]+\\))" nil t)) -        ;;     (match-string-no-properties 1))) - -        ;; (defun jao-erlang-compile (arg) -        ;;   (interactive "P") -        ;;   (save-some-buffers) -        ;;   (when-let ((mname (jao-erlang-current-module))) -        ;;     (with-current-buffer (jao-vterm-repl) -        ;;       (vterm-send-string (format "c(%s).\n" mname)) -        ;;       (sit-for 0) -        ;;       (setq compilation-last-buffer (current-buffer)) -        ;;       (when arg (jao-vterm-repl-pop-to-repl))))) - -        ;; (setq erlang-shell-function #'jao-vterm-repl -        ;;       erlang-shell-display-function #'jao-vterm-repl-pop-to-repl -        ;;       erlang-compile-function #'jao-erlang-compile) -        ) -    #+end_src -*** Idris -    #+begin_src emacs-lisp -      (use-package idris-mode -        :ensure t -        :custom ((idris-interpreter-path "idris2") -                 (idris-pretty-printer-width 80) -                 (idris-repl-history-file "~/.emacs.d/cache/idris-history.eld") -                 (idris-stay-in-current-window-on-compiler-error t))) -      (jao-define-attached-buffer "^\\*idris.*") -    #+end_src -*** Clojure -    #+begin_src emacs-lisp -      (use-package clojure-mode -        :ensure t -        :config -        (defun jao-clojure--fix-things () -          (setq-local completion-styles '(basic partial-completion emacs22)) -          (eldoc-mode 1) -          (setq mode-name "ฮป")) -        :hook (clojure-mode . jao-clojure--fix-things)) - -      (use-package cider -        :ensure t -        :commands cider-mode -        :init (setq cider-annotate-completion-candidates t -                    cider-auto-select-error-buffer nil -                    cider-auto-select-test-report-buffer nil -                    cider-eldoc-display-for-symbol-at-point t -                    cider-eldoc-ns-function #'identity ;; #'cider-last-ns-segment -                    cider-enrich-classpath nil -                    cider-lein-parameters "repl :headless :host localhost" -                    cider-mode-line  " รท" -                    cider-prompt-for-symbol nil -                    cider-repl-history-file -                    (expand-file-name "~/.emacs.d/cache/cider.history") -                    cider-repl-pop-to-buffer-on-connect nil -                    cider-repl-use-pretty-printing t -                    cider-show-error-buffer 'except-in-repl -                    cider-test-show-report-on-success nil -                    cider-use-fringe-indicators nil -                    cider-use-overlays nil -                    clojure-docstring-fill-column 72 -                    nrepl-prompt-to-kill-server-buffer-on-quit nil) -        :bind (("<f3>" . cider-selector))) - -      (with-eval-after-load "cider-test" -        (advice-add 'cider-scale-background-color :override -                    (lambda () (frame-parameter nil 'background-color))) -        (setq cider-test-items-background-color -              (frame-parameter nil 'background-color))) - -      (use-package cider-macroexpansion -        :after cider -        :diminish " ยต") - -    #+end_src -*** Geiser -    #+begin_src emacs-lisp -      (defun jao-org--set-geiser-impl () (setq-local geiser-repl--impl 'guile)) -      (add-hook 'org-mode-hook #'jao-org--set-geiser-impl) - -      (jao-load-path "geiser/geiser/elisp") -      (use-package geiser -        :init -        (setq geiser-repl-history-filename "~/.emacs.d/cache/geiser-history" -              geiser-repl-startup-time 20000 -              geiser-debug-auto-display-images-p t -              geiser-log-verbose-p t -              geiser-active-implementations '(guile) -              geiser-default-implementation 'guile)) - -      (jao-load-path "geiser/guile") -      (use-package geiser-guile) - -      ;; (jao-load-path "geiser/mit") -      ;; (use-package geiser-mit) - -      ;; (jao-load-path "geiser/chicken") -      ;; (use-package geiser-chicken) - -      ;; (jao-load-path "geiser/chibi") -      ;; (use-package geiser-chibi) - -      ;; (jao-load-path "geiser/chez") -      ;; (use-package geiser-chez -      ;;   :init (setq geiser-chez-binary "scheme")) - -      ;; (jao-load-path "geiser/gambit") -      ;; (use-package geiser-gambit) - -      ;; (jao-load-path "geiser/gauche") -      ;; (use-package geiser-gauche) - -      (jao-define-attached-buffer "^\\* ?Geiser .*\\*" 0.4) -      (jao-define-attached-buffer "^\\* Guile REPL \\*" 0.4) - -    #+end_src -*** Haskell -***** packages -      #+begin_src emacs-lisp -        (use-package haskell-mode -          :ensure t -          :custom -          ((inferior-haskell-find-project-root t) -           (haskell-check-remember-last-command-p nil) -           (haskell-font-lock-symbols nil) -           (haskell-interactive-popup-errors nil) -           (haskell-process-auto-import-loaded-modules t) -           (haskell-process-log t) -           (haskell-process-suggest-remove-import-lines t) -           (haskell-process-suggest-hoogle-imports t) -           (haskell-process-type 'cabal-repl) -           (haskell-process-use-presentation-mode t) -           (haskell-stylish-on-save nil)) - -          :config -          (defun jao-haskell-hoogle (query) -            (interactive (hoogle-prompt)) -            (haskell-hoogle query t)) - -          (put 'haskell-process-args-cabal-repl -               'safe-local-variable -               (apply-partially #'seq-every-p #'stringp)) - -          (require 'haskell-doc) -          (dolist (h '(interactive-haskell-mode -                       haskell-doc-mode -                       haskell-decl-scan-mode -                       haskell-indentation-mode -                       haskell-auto-insert-module-template)) -            (add-hook 'haskell-mode-hook h)) - -          :bind (:map haskell-mode-map -                      (("C-c C-d" . jao-haskell-hoogle) -                       ("C-c h" . haskell-hoogle-lookup-from-local) -                       ("C-c C-c" . haskell-compile)))) - -        (require 'haskell) - -        (diminish 'interactive-haskell-mode " ฮป") -        (diminish haskell-doc-mode) -        (diminish haskell-decl-scan-mode) - -        (jao-define-attached-buffer "\\*hoogle\\*.*") - -        ;; needs cabal install apply-refact -        (use-package hlint-refactor -          :ensure t -          :after (haskell-mode) -          :diminish "" -          :hook (haskell-mode . hlint-refactor-mode)) -      #+end_src -***** transient -      #+begin_src emacs-lisp -        (jao-transient-major-mode haskell -          ["Imports" -           ("in" "Navigate imports" haskell-navigate-imports) -           ("if" "Format imports" haskell-mode-format-imports) -           ("is" "Sort imports" haskell-sort-imports) -           ("ia" "Align imports" haskell-align-imports)] -          ["Code" -           ("c" "Compile" haskell-compile) -           ("s" "stylish on buffer" haskell-mode-stylish-buffer)] -          ["Hoogle" -           ("h" "Hoogle" jao-haskell-hoogle) -           ("H" "Hoogle from local server" haskell-hoogle-lookup-from-local)]) -      #+end_src -*** Pie -    #+begin_src emacs-lisp -      (jao-load-path "pie") -      (use-package pie -        :demand t -        :commands (pie-mode)) -    #+end_src -*** Lisp -    #+begin_src emacs-lisp :tangle no -      (use-package sly -        :ensure t -        :init (setq inferior-lisp-program "sbcl") -        :config (sly-setup)) - -      (use-package sly-quicklisp -        :after (sly) -        :ensure t) -    #+end_src -*** Prolog -    #+BEGIN_SRC emacs-lisp -      (use-package ediprolog :ensure t) - -      (use-package prolog -        :ensure t -        :commands (run-prolog prolog-mode mercury-mode) -        :init (progn -                (setq prolog-system 'swi) -                (add-to-list 'auto-mode-alist '("\\.pl$" . prolog-mode)) -                (setq prolog-consult-string '((t "[%f]."))) -                (setq prolog-program-name -                      '(((getenv "EPROLOG") (eval (getenv "EPROLOG"))) -                        (eclipse "eclipse") -                        (mercury nil) -                        (sicstus "sicstus") -                        (swi "swipl") -                        (t "prolog"))))) -    #+END_SRC -*** Racket -    #+begin_src emacs-lisp -      (use-package racket-mode -        :ensure t -        :init (setq racket-show-functions '(racket-show-echo-area) -                    racket-documentation-search-location 'local) -        :config -        (jao-define-attached-buffer "\\`\\*Racket REPL") -        (jao-define-attached-buffer "\\`\\*Racket Describe" 0.5) -        (add-hook 'racket-mode-hook #'paredit-mode) -        (require 'racket-xp) -        (add-hook 'racket-mode-hook #'racket-xp-mode) -        :bind (:map racket-xp-mode-map (("C-c C-S-d" . racket-xp-documentation) -                                        ("C-c C-d" . racket-xp-describe)))) - -    #+end_src -*** Python -***** Virtual envs (with eshell support) -      See also [[https://github.com/porterjamesj/virtualenvwrapper.el][the docs]]. -      #+begin_src emacs-lisp -        (use-package virtualenvwrapper -          :ensure t -          :config -          (venv-initialize-eshell) -          (jao-compilation-env "VIRTUAL_ENV")) -      #+end_src -* Text/data formats -*** YAML -    #+begin_src emacs-lisp -      (use-package yaml-mode :ensure t) -    #+end_src -*** JSON -    #+BEGIN_SRC emacs-lisp -      (use-package json-mode :ensure t) -      ;; (use-package json-navigator :ensure nil) -    #+END_SRC -* Graphics -*** Images -    #+begin_src emacs-lisp -      (setq image-use-external-converter t) -    #+end_src -*** Gnuplot -    #+BEGIN_SRC emacs-lisp -      (use-package gnuplot -        :ensure t -        :commands (gnuplot-mode gnuplot-make-buffer) -        :init (add-to-list 'auto-mode-alist '("\\.gp$" . gnuplot-mode))) -    #+END_SRC -* Network -*** nm applet -    #+begin_src emacs-lisp -      (jao-shell-def-exec jao-nm-applet "nm-applet") - -      (defun jao-toggle-nm-applet () -        (interactive) -        (if (jao-shell-running-p "nm-applet") -            (jao-shell-string "killall nm-applet") -          (jao-nm-applet))) -    #+end_src -*** enwc -      #+begin_src emacs-lisp -        (use-package enwc -          :ensure t -          :custom ((enwc-default-backend 'nm) -                   (enwc-wired-device "wlp164s0") -                   (enwc-wireless-device "wlp164s0") -                   (enwc-display-mode-line nil))) -       #+end_src - -*** bluetooth -    #+BEGIN_SRC emacs-lisp -    (use-package bluetooth :ensure t) -    #+END_SRC -*** vpn -    #+begin_src emacs-lisp -      (use-package jao-mullvad :demand t) -    #+end_src -*** ssh -    #+begin_src emacs-lisp -      (use-package tramp) -      (defun jao-tramp-hosts () -        (seq-uniq -         (mapcan (lambda (x) -                   (remove nil (mapcar 'cadr (apply (car x) (cdr x))))) -                 (tramp-get-completion-function "ssh")) -         #'string=)) - -      (defun jao-ssh () -        (interactive) -        (let ((h (completing-read "Host: " (jao-tramp-hosts)))) -          (jao-afio-goto-scratch) -          (jao-exec-in-term (format "ssh %s" h) (format "*ssh %s*" h)))) -    #+end_src -* Chats -*** circe -    #+begin_src emacs-lisp -      (defvar jao-libera-channels '()) -      (defvar jao-oftc-channels '()) -      (defvar jao-bitlbee-channels '()) - -      (use-package circe -        :ensure t -        :bind (:map circe-channel-mode-map -                    (("C-c C-a" . lui-track-jump-to-indicator))) -        :init -        (setq circe-chat-buffer-name "{target}" -              circe-default-realname "https://jao.io" -              circe-default-part-message "" -              circe-default-quit-message "" -              circe-ignore-list nil -              circe-server-coding-system '(undecided . undecided) -              circe-server-killed-confirmation 'ask-and-kill-all -              circe-server-auto-join-default-type :after-auth -              circe-format-say "({nick}) {body}" -              circe-format-self-say "(jao) {body}" -              circe-new-buffer-behavior 'ignore -              circe-new-buffer-behavior-ignore-auto-joins t -              circe-nickserv-ghost-style 'after-auth -              circe-prompt-string ": " -              circe-completion-suffix ", " -              circe-reduce-lurker-spam t - -              circe-nick-next-function -              (lambda (old) -                (replace-regexp-in-string "-" "`" (circe-nick-next old))) - -              circe-lagmon-mode-line-format-string "" ;;  "%.0f " -              circe-lagmon-mode-line-unknown-lag-string "" ;; "? " -              circe-lagmon-timer-tick 120 -              circe-lagmon-reconnect-interval 180 - -              lui-max-buffer-size 30000 -              lui-fill-column 80 -              lui-time-stamp-position 'right -              lui-time-stamp-format "%H:%M" -              lui-flyspell-p nil - -              lui-track-indicator (if window-system 'fringe 'bar) -              lui-track-behavior 'before-tracking-next-buffer) -        :config - -        (define-minor-mode jao-circe-user-number-mode "" -          :lighter (:eval (format " [%s]" (length (circe-channel-nicks))))) - -        (add-hook 'circe-channel-mode-hook #'jao-circe-user-number-mode) - -        (defun circe-command-RECOVER (&rest ignore) -          "Recover nick" -          (let* ((fn (jao--get-user/password "freenode")) -                 (u (car fn)) -                 (p (cadr fn))) -            (circe-command-MSG "nickserv" (format "IDENTIFY %s %s" u p)) -            (circe-command-MSG "nickserv" (format "GHOST %s" u)) -            (circe-command-MSG "nickserv" (format "RELEASE %s" u)) -            (circe-command-NICK u))) - -        (defun circe-command-NNICKS (&rest _) -          "Echo number of nicks" -          (circe-display-server-message -           (format "%d nicks in this channel" (length (circe-channel-nicks))))) - -        (advice-add 'circe-command-NAMES :after #'circe-command-NNICKS) - -        (setq circe-network-options -              (let ((up (jao--get-user/password "libera")) -                    (oup (jao--get-user/password "oftc")) -                    (bup (jao--get-user/password "bitlbee"))) -                `(("Libera Chat" -                   :nick ,(car up) :channels ,jao-libera-channels -                   :tls t :sasl-username ,(car up) :sasl-password ,(cadr up)) -                  ("OFTC" :nick ,(car oup) :channels ,jao-oftc-channels -                   :nickserv-password ,(cadr oup) -                   :tls t :sasl-username ,(car oup) :sasl-password ,(cadr oup)) -                  ("Bitlbee" -                   :host "127.0.0.1" :nick ,(car bup) -                   :channels ,jao-bitlbee-channels -                   :lagmon-disabled t -                   :nickserv-password ,(cadr bup) :user ,(car bup))))) - -        (jao-shorten-modes 'circe-channel-mode -                           'circe-server-mode -                           'circe-query-mode) - -        (enable-lui-track) -        (circe-lagmon-mode) -        (enable-circe-display-images)) -    #+end_src -*** slack -    [[https://github.com/jackellenberger/emojme#finding-a-slack-token][How to get a token]]: It's easyish! Open and sign into the slack -    customization page, e.g. https://my.slack.com/customize, right -    click anywhere > inspect element. Open the console and paste: - -         =window.prompt("your api token is: ", TS.boot_data.api_token)= - -    Lately things are iffy.  We've needed to add the ~:override~ to -    slack-counts update, and it might be needed to replace -    ~slack-conversations-view~ by ~slack-conversations-history~ - -    #+begin_src emacs-lisp -      (use-package slack -        :commands (slack-start) -        :init -        (setq slack-alert-icon (jao-data-file "slack.svg") -              slack-buffer-emojify nil -              slack-buffer-create-on-notify t -              slack-display-team-name t -              slack-typing-visibility 'never ;; 'buffer, 'frame -              slack-profile-image-file-directory "/tmp/slack-imgs/" -              slack-image-file-directory "/tmp/slack-imgs/" -              slack-file-dir "~/var/download/slack/" -              slack-prefer-current-team t -              slack-message-tracking-faces '(warning) -              slack-log-level 'warn -              slack-message-custom-notifier (lambda (msg room team) room)) -        :bind (:map slack-mode-map (("@" . slack-message-embed-mention) -                                    ("#" . slack-message-embed-channel)) -               :map slack-message-buffer-mode-map -               (("C-c C-e" . slack-message-edit) -                ("C-c C-a" . slack-file-upload))) -        :config -        (dolist (f (list slack-file-dir slack-image-file-directory)) -          (when (not (file-exists-p f)) (make-directory f))) - -        (jao-shorten-modes 'slack-message-buffer-mode -                           'slack-thread-message-buffer-mode) -        (jao-tracking-faces 'warning) - -        (jao-define-attached-buffer "\\*Slack .+ Edit Message [0-9].+" 20)) -    #+end_src -*** telegram -    #+begin_src emacs-lisp -      (use-package telega -        :ensure t -        :custom -        (telega-use-tracking-for '(unmuted) ;; '(or unmuted mention) -         telega-rainbow-color-custom-for nil -         telega-msg-rainbow-title nil -         telega-sticker-set-download t) -        :config -        (define-key global-map (kbd "C-c C-t") telega-prefix-map) -        (setq telega-chat-show-avatars nil -              telega-chat-prompt-format ">> " -              telega-root-show-avatars nil -              telega-emoji-use-images nil -              telega-temp-dir "/tmp/telega" -              telega-symbol-checkmark "ยท" -              telega-symbol-heavy-checkmark "ร" -              telega-symbol-verified "*" -              telega-symbol-horizontal-bar -              (propertize "-" 'face 'jao-themes-f00) -              telega-symbol-vertical-bar -              (propertize "|ย " 'face 'jao-themes-dimm) -              telega-mode-line-string-format -              '(:eval (telega-mode-line-unread-unmuted)) -              telega-use-images (display-graphic-p)) -        (with-eval-after-load "tracking" -          (jao-shorten-modes 'telega-chat-mode) -          (jao-tracking-faces 'telega-tracking)) -        (telega-mode-line-mode 1)) -    #+end_src -*** startup -    #+begin_src emacs-lisp -      (defun jao-chats (&optional p) -        (interactive "P") -        (when (or p (y-or-n-p "Connect to slack? ")) -          (slack-start)) -        (when (or p (y-or-n-p "Connect to telegram? ")) -          (telega)) -        (when (or p (y-or-n-p "Connect to libera? ")) -          (unless (get-buffer "irc.libera.chat:6697") -            (circe "Libera Chat")))) - -      (defun jao-all-chats () (interactive) (jao-chats t)) - -      (defun jao-chats-telega () -        (interactive) -        (jao-buffer-same-mode '(telega-root-mode telega-chat-mode))) - -      (defun jao-chats-slack () -        (interactive) -        (jao-buffer-same-mode 'slack-message-buffer-mode)) - -      (defun jao-chats-irc () -        (interactive) -        (jao-buffer-same-mode '(circe-channel-mode circe-query-mode erc-mode))) - -     #+end_src -* Multimedia -*** mixer -    #+begin_src emacs-lisp -      (defun jao-mixer-get-level (&optional dev) -        (interactive) -        (let* ((dev (or dev "Master")) -               (s (shell-command-to-string (format "amixer sget %s" dev))) -               (s (car (last (split-string s "\n" t))))) -          (when (string-match ".*Front .*\\[\\([0-9]+\\)%\\] .*" s) -            (let ((level (match-string 1 s))) -              (message "%s level: %s%%" dev level) -              (string-to-number level))))) - -      (defun jao-mixer-set (dev v) -        (jao-shell-string "amixer sset" dev v) -        (jao-mixer-get-level dev)) - -      (defun jao-mixer-master-toggle () -        (interactive) -        (jao-mixer-set "Master" "toggle")) - -      (defun jao-mixer-master-up () -        (interactive) -        (jao-mixer-set "Master" "10%+")) - -      (defun jao-mixer-master-down () -        (interactive) -        (jao-mixer-set "Master" "10%-")) - -      (defun jao-mixer-capture-up () -        (interactive) -        (jao-mixer-set "Capture" "10%+")) - -      (defun jao-mixer-capture-down () -        (interactive) -        (jao-mixer-set "Capture" "10%-")) - -      (jao-shell-def-exec jao-audio-applet "pasystray") - -      (defun jao-toggle-audio-applet () -        (interactive) -        (if (string-empty-p (jao-shell-string "pidof pasystray")) -            (jao-audio-applet) -          (jao-shell-string "killall pasystray"))) - -      (global-set-key (kbd "<f4>") #'jao-toggle-audio-applet) - -    #+end_src -*** mpris -    #+begin_src emacs-lisp -      (defun jao-mpris-lyrics (&optional force) -        (interactive "P") -        (jao-show-lyrics force #'jao-mpris-artist-title)) - -      (use-package jao-mpris :demand t) - -      (defalias 'jao-streaming-list #'ignore) -      (defalias 'jao-streaming-like #'ignore) -      (defalias 'jao-streaming-dislike #'ignore) -      (defalias 'jao-streaming-lyrics #'jao-mpris-lyrics) -      (defalias 'jao-streaming-toggle #'jao-mpris-play-pause) -      (defalias 'jao-streaming-next #'jao-mpris-next) -      (defalias 'jao-streaming-prev #'jao-mpris-previous) -      (defalias 'jao-streaming-current #'jao-mpris-show-osd) -      (defalias 'jao-streaming-seek #'jao-mpris-seek) -      (defalias 'jao-streaming-seek-back #'jao-mpris-seek-back) -      (defalias 'jao-streaming-volume #'jao-mpris-vol) -      (defalias 'jao-streaming-volume-down #'jao-mpris-vol-down) - -      (jao-mpris-register "playerctld" -                          :session (if jao-modeline-in-minibuffer -10 70)) - -    #+end_src -*** mpc -    #+begin_src emacs-lisp -      (use-package jao-mpc -        :demand t -        :commands jao-mpc-setup) - -      (defvar jao-mopidy-port 6669) -      (defvar jao-mpc-last-port nil) - -      (defun jao-mpc-toggle-port () -        (interactive) -        (setq jao-mpc-last-port (unless jao-mpc-last-port jao-mopidy-port) -              jao-mpc-port jao-mpc-last-port)) - -      (jao-mpc-setup jao-mopidy-port (if jao-modeline-in-minibuffer -10 70)) - -      (defun jao-mpc-pport (&optional mop) -        (cond ((or mop (jao-mpc--playing-p jao-mopidy-port)) jao-mopidy-port) -              ((jao-mpc--playing-p) nil) -              (t jao-mpc-last-port))) - -      (defmacro jao-defun-play (name &optional mpc-name) -        (let ((arg (gensym))) -          `(defun ,(intern (format "jao-player-%s" name)) (&optional ,arg) -             (interactive "P") -             (,(intern (format "jao-mpc-%s" (or mpc-name name))) -              (setq jao-mpc-last-port (jao-mpc-pport ,arg)))))) - -      (jao-defun-play toggle) -      (jao-defun-play next) -      (jao-defun-play previous) -      (jao-defun-play stop) -      (jao-defun-play echo echo-current) -      (jao-defun-play list show-playlist) -      (jao-defun-play info lyrics-track-data) -      (jao-defun-play browse show-albums) -      (jao-defun-play select-album) - -      (defun jao-player-seek (delta) (jao-mpc-seek delta (jao-mpc-pport))) - -      (defalias 'jao-player-connect 'jao-mpc-connect) -      (defalias 'jao-player-play 'jao-mpc-play) -    #+end_src -*** transients -    #+begin_src emacs-lisp - -      (require 'jao-lyrics) -      (setq jao-lyrics-info-function #'jao-player-info) - -      (defun jao-player-volume-delta (raise) -        (jao-player-vol-delta (if raise 5 -5)) -        (sit-for 0.05) -        (jao-player-show-volume)) - -      (defun jao-player-volume-raise () -        (interactive) -        (jao-player-volume-delta t)) - -      (defun jao-player-volume-lower () -        (interactive) -        (jao-player-volume-delta nil)) - -      (defun jao-player-show-volume () -        (interactive) -        (jao-notify "Volume" (format "%s%%" (jao-player-volume)))) - -      (defun jao-player-seek-10 () (interactive) (jao-player-seek 10)) -      (defun jao-player-seek--10 () (interactive) (jao-player-seek -10)) - -      (defun jao-streaming-clear () (interactive) (jao-mpc-clear jao-mopidy-port)) - -      (defun jao-streaming-echo-current () -        (interactive) -        (jao-mpc-echo-current jao-mopidy-port)) - -      (defun jao-streaming-show-playlist () -        (interactive) -        (jao-mpc-show-playlist jao-mopidy-port)) - -      (defun jao-player-level-cap () (interactive) (jao-mixer-level "Capture")) - -      (use-package jao-random-album :demand t) - -      (jao-def-exec-in-term "aptitude" "aptitude" (jao-afio--goto-scratch)) -      (jao-def-exec-in-term "htop" "htop" (jao-afio--goto-scratch)) - -      (transient-define-prefix jao-transient-streaming () -        [:description -         (lambda () (format "Streaming using %s" jao-mpris-player)) -         ;; ["Search" -         ;;  ("a" "album" jao-streaming-album) -         ;;  ("A" "artist" jao-streaming-artist) -         ;;  ("t" "track" jao-streaming-track) -         ;;  ("P" "playlist" jao-streaming-playlist)] -         ["Play" -          ("s" "toggle" jao-streaming-toggle) -          ("n" "next" jao-streaming-next) -          ("p" "previous" jao-streaming-prev)] -         ["Seek & shout" -          ("f" "seek fwd" jao-streaming-seek :transient t) -          ("F" "seek bwd" jao-streaming-seek-back :transient t) -          ("u" "up" jao-streaming-volume :transient t) -          ("d" "down" jao-streaming-volume-down :transient t)] -         ["Browse" -          ("l" "playing list" jao-streaming-list) -          ("L" "lyrics" jao-streaming-lyrics) -          ("w" "currently playing" jao-streaming-current)] -         ["Act" -          ("k" "like" jao-streaming-like) -          ("K" "dislike" jao-streaming-dislike)]]) - -      (transient-define-prefix jao-transient-media () -        [["Play" -          ("m" "toggle" jao-player-toggle) -          ("n" "next" jao-player-next) -          ("p" "previous" jao-player-previous) -          ("s" "select album" jao-player-select-album)] -         ["Seek and search" -          ("f" "seek fwd" jao-player-seek-10 :transient t) -          ("F" "seek bwd" jao-player-seek--10 :transient t) -          ("a" "search album" jao-mpc-search-and-select-album)] -         ["Browse" -          ("b" "browse" jao-player-browse) -          ("l" "show play list" jao-player-list) -          ("L" "show lyrics" jao-show-lyrics) -          ("w" "now playing" jao-player-echo)] -         ["Master volume" -          ("d" "master down" jao-mixer-master-down :transient t) -          ("u" "master up" jao-mixer-master-up :transient t) -          ("M" "master toggle" jao-mixer-master-toggle) -          ("v" "show" jao-mixer-get-level)] -         ["Capture volume" -          ("D" "capture down" jao-mixer-capture-down :transient t) -          ("U" "capture up" jao-mixer-capture-up :transient t) -          ("V" "show" jao-player-level-cap)] -         ["Utilities" -          ("c" "reconnect to mpd" jao-player-connect) -          ("N" "next random album" jao-random-album-next) -          ("r" (lambda () -                 (concat (if jao-random-album-p "dis" "en") "able random album")) -           jao-random-album-toggle) -          ("P" (lambda () -                 (concat "Toggle to " -                         (if (equal jao-mpc-last-port jao-mopidy-port) -                             "mpd" "mopidy"))) -           jao-mpc-toggle-port)]]) - -      (global-set-key (kbd "s-m") #'jao-transient-media) - -    #+end_src -* General transients -  #+begin_src emacs-lisp -    (defun jao-list-packages () -      (interactive) -      (jao-afio--goto-scratch-1) -      (package-list-packages)) - -    (defun jao-window-system-p () -      (or jao-exwm-enabled jao-xmonad-enabled jao-sway-enabled)) - -    (transient-define-prefix jao-transient-utils () -      "Global operations in X11." -      [["Notes" -        ("n" "capture note" jao-org-notes-open-or-create) -        ("/" "search notes" jao-org-notes-open) -        ("\\" "grep notes" jao-org-notes-grep)] -       ["Documents" :if jao-window-system-p -        ("d" "go to doc" jao-select-pdf) -        ("D" "open to doc" jao-open-doc)] -       ["Packages" -        ("a" "aptitude" jao-term-aptitude) -        ("l" "packages" jao-list-packages)] -       ["Monitors" -        ("p" "htop" jao-term-htop) -        ("v" "vpn status" jao-mullvad-status) -        ("m" "set tmr" tmr)] -       ["Network" -        ("S" "ssh" jao-ssh) -        ("b" "bluetooth" bluetooth-list-devices) -        ("c" "connect chats" jao-all-chats) -        ("N" "network interfaces" enwc)] -       ["Chats" -        ("t" "telegram" jao-chats-telega) -        ("s" "slack" jao-chats-slack) -        ("i"  "irc" jao-chats-irc) -        ("T" "telegram rooster" telega)] -       ["Window system" :if jao-window-system-p -        ("w" "set wallpaper" jao-set-wallpaper) -        ("W" "set radom wallpaper" jao-set-random-wallpaper) -        ("x" "restart xmobar" jao-xmobar-restart :if jao-exwm-enabled-p) -        ("x" "kill xmobar" jao-xmobar-kill :if jao-xmonad-enabled-p)] -       ["Helpers" -        ("r" "org reveal" org-reveal) -        ("k" (lambda () (concat "keyboard" (when (jao-kb-toggled-p) "*"))) -         jao-kb-toggle :if jao-window-system-p) -        ("M" (lambda () (concat "minibuffer" (when jao-minibuffer-mode "*"))) -         jao-minibuffer-mode)]]) - -    (global-set-key (kbd "s-w") #'jao-transient-utils) -  #+end_src -* Key bindings -  #+begin_src emacs-lisp -    (global-set-key "\C-cj" #'join-line) -    (global-set-key "\C-cn" #'next-error) -    (global-set-key "\C-cq" #'auto-fill-mode) -    (global-set-key "\C-xr\M-w" #'kill-rectangle-save) -    (global-set-key "\C-c\C-z" #'comment-or-uncomment-region) -    (global-set-key "\C-z" #'comment-or-uncomment-region) -    (global-set-key (kbd "C-c W") #'jao-open-in-x-frame) -  #+end_src -* Last minute (post.el) -  #+begin_src emacs-lisp -    (jao-load-site-el "post") -  #+end_src diff --git a/attic/org/misc.org b/attic/org/misc.org deleted file mode 100644 index 6d8d82d..0000000 --- a/attic/org/misc.org +++ /dev/null @@ -1,247 +0,0 @@ -* corfu -  #+begin_src emacs-lisp -    (use-package corfu -      :ensure t -      :demand t -      :init (setq corfu-echo-documentation 0.25 -                  corfu-cycle t -                  corfu-count 15 -                  corfu-quit-no-match t -                  corfu-auto t -                  corfu-commit-predicate nil -                  corfu-preview-current nil -                  corfu-preselect-first t -                  corfu-min-width 20 -                  corfu-max-width 100) -      :config - -      ;; show eldoc string immediately after accepted completion too -      (with-eval-after-load "eldoc" -        (eldoc-add-command-completions "corfu-")) - -      (defun jao-corfu-enable-no-auto () -        (setq-local corfu-auto nil) -        (corfu-mode 1)) - -      (defmacro jao-corfu-no-auto (mode) -        (let ((mode-name (intern (format "%s-mode" mode))) -              (hook-name (intern (format "%s-mode-hook" mode)))) -          `(with-eval-after-load ',mode -             (add-to-list 'corfu-excluded-modes ',mode-name) -             (add-hook ',hook-name #'jao-corfu-enable-no-auto)))) - -      (jao-corfu-no-auto eshell) -      ;; (add-to-list 'corfu-excluded-modes 'notmuch-message-mode) - -      (defun jao-corfu--active-p () -        (and (>= corfu--index 0) (/= corfu--index corfu--preselect))) - -      (defun jao-corfu-quit-or-insert () -        (interactive) -        (if (jao-corfu--active-p) (corfu-insert) (corfu-quit))) - -      (defun jao-corfu-quit-or-previous () -        (interactive) -        (if (jao-corfu--active-p) -            (corfu-previous) -          (corfu-quit) -          (previous-line))) - -      :bind (:map corfu-map -                  ("C-<return>" . corfu-insert) -                  ("\r" . jao-corfu-quit-or-insert) -                  ("C-p" . jao-corfu-quit-or-previous))) - -    (defun corfu-in-minibuffer () -      (when (not (bound-and-true-p vertico--input)) (corfu-mode 1))) - -    (when (display-graphic-p) -      (add-hook 'minibuffer-setup-hook #'corfu-in-minibuffer 1) -      (global-corfu-mode 1)) - -  #+end_src -* erc -*** package -  #+begin_src emacs-lisp -    (use-package erc -      :init -      (setq erc-modules -            '(autojoin -              button -              dcc -              fill -              irccontrols -              match -              move-to-prompt -              netsplit -              networks -              noncommands -              notify -              pcomplete -              ring -              services -              stamp -              track -              truncate)) - -      (setq erc-auto-query 'bury -            erc-autojoin-channels-alist `(("libera.chat" ,@jao-libera-channels)) -            erc-away-nickname "jao" -            erc-button-buttonize-nicks t -            erc-common-server-suffixes '(("libera.chat$" . "lb")) -            erc-current-nick-highlight-type 'nick-or-keyword -            erc-email-userid (car jao-mails) -            erc-fill-column 84 -            erc-fill-prefix "     " -            erc-format-nick-function 'erc-format-@nick -            erc-header-line-face-method t -            erc-header-line-format nil ;; "%l %o" -            erc-header-line-uses-tabbar-p nil -            erc-hide-list '("JOIN" "PART" "QUIT") -            erc-hide-timestamps nil -            erc-input-line-position -1 -            erc-insert-timestamp-function 'erc-insert-timestamp-right -            erc-join-buffer 'bury -            erc-kill-buffer-on-part t -            erc-kill-queries-on-quit t -            erc-log-channels-directory nil -            erc-mode-line-away-status-format "(a)" -            erc-mode-line-format "%t" -            erc-nick "jao" -            erc-notice-highlight-type 'all -            erc-notice-prefix "- " -            erc-notify-signoff-hook 'erc-notify-signoff -            erc-notify-signon-hook 'erc-notify-signon -            erc-pcomplete-nick-postfix "," -            erc-rename-buffers t -            erc-server-send-ping-timeout 60 -            erc-prompt ":" -            erc-prompt-for-nickserv-password nil -            erc-use-auth-source-for-nickserv-password t -            erc-prompt-for-password nil -            erc-public-away-p t -            erc-server "irc.libera.chat" -            erc-server-coding-system '(utf-8 . undecided) -            erc-server-reconnect-attempts 10 -            erc-server-reconnect-timeout 10 -            erc-timestamp-format "%H:%M" -            erc-timestamp-only-if-changed-flag t -            erc-timestamp-right-column 84 -            erc-user-full-name "https://jao.io" -            erc-user-mode "+i" -            erc-whowas-on-nosuchnick t) - -      :config - -      (define-minor-mode ncm-erc-mode "" nil -        (:eval (format " [%s]" (hash-table-count erc-channel-users)))) - -      (add-hook 'erc-mode-hook (lambda () (ncm-erc-mode 1))) -      (add-hook 'erc-mode-hook (lambda () (auto-fill-mode -1)))) -    #+end_src -*** no angles -   #+begin_src emacs-lisp -    (defun jao-erc--no-angles (old-func &rest args) -      (let ((msg (apply old-func args))) -        (replace-regexp-in-string "^<\\([^>]+\\)>" "(\\1)" msg))) - -    (with-eval-after-load "erc" -      (modify-syntax-entry ?\( "." erc-mode-syntax-table) -      (modify-syntax-entry ?\) "." erc-mode-syntax-table) -      (advice-add 'erc-format-privmessage :around #'jao-erc--no-angles) -      (advice-add 'erc-format-my-nick :around #'jao-erc--no-angles)) -    #+end_src -*** tracking -    #+begin_src emacs-lisp -     (defun jao-erc-track-shorten (names) -       (let ((names (erc-track-shorten-names names))) -         (mapcar (lambda (n) (string-remove-prefix "#" n)) names))) - -     (setq erc-track-exclude-server-buffer t -           erc-track-exclude-types '("NICK" "JOIN" "PART" "QUIT" "MODE" "KICK") -           erc-track-remove-disconnected-buffers t -           erc-track-shorten-aggressively t ;; 'max -           erc-track-shorten-function #'jao-erc-track-shorten -           erc-track-switch-direction 'importance -           erc-track-visibility nil ;; t all, nil only selected frame -           erc-track-position-in-mode-line nil -           erc-track-enable-keybindings nil ;; 'ask -           erc-track-faces-priority-list '(erc-error-face -                                           erc-current-nick-face -                                           erc-pal-face -                                           erc-direct-msg-face -                                           erc-nick-msg-face -                                           erc-default-face -                                           erc-action-face -                                           erc-notice-face)) -     (defun jao-track-erc-buffers () -       (dolist (e erc-modified-channels-alist) -         (tracking-add-buffer (car e) (list (cddr e))))) - -     (with-eval-after-load "erc-track" -       (require 'tracking nil t) -       (add-hook 'exwm-workspace-switch-hook #'erc-modified-channels-update) -       (add-hook 'erc-track-list-changed-hook #'jao-track-erc-buffers)) - -     (jao-shorten-modes 'erc-mode) -     (jao-tracking-faces 'erc-error-face -                         'erc-pal-face -                         'erc-current-nick-face -                         'erc-direct-msg-face) -    #+end_src -*** commands (/recover &co.) -    #+begin_src emacs-lisp -     (defun erc-cmd-RECOVER (&rest ignore) -       "Recover nick" -       (let ((fn (jao--get-user/password "freenode"))) -         (erc-cmd-MSG (format "nickserv IDENTIFY %s %s" (car fn) (cadr fn))) -         (erc-cmd-MSG (format "nickserv GHOST %s" (car fn))) -         (erc-cmd-MSG (format "nickserv RELEASE %s" (car fn))) -         (erc-cmd-NICK (car fn)))) -    #+end_src -*** startup -    #+begin_src emacs-lisp -    (defun jao-erc (&optional yes) -      (interactive "P") -      ;; (when (or yes (y-or-n-p "Connect to bitlbee using ERC? ")) -      ;;   (erc-select :server "localhost")) -      (when (or yes (y-or-n-p "Connect to libera using ERC? ")) -        (erc-select :server "irc.libera.chat"))) -    #+end_src -* dtache -  #+begin_src emacs-lisp -    (use-package dtache -      :ensure t -      :hook (after-init . dtache-setup)) - -    (use-package dtache-eshell -      :after dtache -      :hook (eshell-mode . dtache-eshell-mode)) - -    (use-package dtache-consult -      :after (consult dtache) -      :bind ([remap dtache-open-session] . dtache-consult-session)) -  #+end_src -* cdlatex -  #+begin_src emacs-lisp -    (use-package cdlatex -      :ensure t -      :hook ((org-mode . org-cdlatex-mode)) -      :diminish ((cdlatex-mode . " ยฃ") -                 (org-cdlatex-mode . " ยฃ"))) -  #+end_src -* maps -  #+begin_src emacs-lisp -    (use-package osm -      :ensure t -      :init -      (with-eval-after-load 'org (require 'osm-ol)) -      :config -      (transient-define-prefix jao-transient-osm () -        ["Open Street Maps" -         ("s" "search" osm-search) -         ("g" "goto" osm-goto) -         ("b" "jump to bookmark" osm-bookmark-jump) -         ("t" "server" osm-server)]) -      :bind ("C-c M" . #'jao-transient-osm)) -  #+end_src diff --git a/attic/org/notmuch.org b/attic/org/notmuch.org deleted file mode 100644 index 0368ac1..0000000 --- a/attic/org/notmuch.org +++ /dev/null @@ -1,675 +0,0 @@ -#+property: header-args:emacs-lisp :lexical t :tangle yes :comments yes :results silent :shebang ";; -*- lexical-binding: t; -*-" :tangle-mode (identity #o644) -#+title: notmuch configuration - -* minibuffer -  #+begin_src emacs-lisp -    (defvar jao-notmuch-minibuffer-string "") - -    (defvar jao-notmuch-minibuffer-queries -      '((:name "" :query "tag:new and not tag:draft" :face jao-themes-f00) -        (:name "B" :query "tag:new and tag:bigml and tag:inbox" :face default) -        (:name "b" :query "tag:new and tag:bigml and tag:bugs" -               :face jao-themes-error) -        (:name "S" :query "tag:new and tag:bigml and tag:support" :face default) -        (:name "W" -               :query "tag:new and tag:bigml and not tag:\"/support|bugs|inbox/\"" -               :face default) -        (:name "I" -               :query "tag:new and tag:jao and tag:inbox" -               :face jao-themes-warning) -        (:name "J" -               :query "tag:new and tag:jao and not tag:\"/local|hacking|draft|inbox|prog|words/\"" -               :face default) -        (:name "H" :query "tag:new and tag:hacking and not tag:\"/emacs/\"") -        (:name "E" :query "tag:new and tag:\"/emacs/\"") -        (:name "l" :query "tag:new and tag:local") -        (:name "F" :query "tag:new and tag:feeds and not tag:\"/emacs/\""))) - -    (defun jao-notmuch-notify () -      (let ((cnts (notmuch-hello-query-counts jao-notmuch-minibuffer-queries))) -        (setq jao-notmuch-minibuffer-string -              (mapconcat (lambda (c) -                           (propertize (format "%s%s" -                                               (plist-get c :name) -                                               (plist-get c :count)) -                                       'face (or (plist-get c :face) -                                                 'jao-themes-dimm))) -                         cnts -                         " ")) -        (jao-minibuffer-refresh))) - -    (when jao-notmuch-enabled -      (jao-minibuffer-add-variable 'jao-notmuch-minibuffer-string -20)) -  #+end_src -* saved searches -  #+begin_src emacs-lisp -    (defvar jao-notmuch--new "tag:\"/^(unread|new)$/\"") -    (defvar jao-notmuch--newa (concat jao-notmuch--new " AND ")) - -    (defun jao-notmuch--q (d0 d1 &optional k qs st) -      (let ((q (or (when qs (mapconcat #'identity qs " AND ")) -                   (concat jao-notmuch--newa -                           (mapconcat (lambda (d) (when d (concat "tag:" d))) -                                      (list d0 d1) " AND "))))) -        (list :name (concat d0 (when (and d1 (not (string= "" d1))) "/") d1) -              :key k :query q :search-type (or st 'tree) -              :sort-order 'oldest-first))) - -    (defun jao-notmuch--qn (d0 d1 k qs &optional st) -      (jao-notmuch--q d0 d1 k (cons jao-notmuch--new qs) st)) - -    (defun jao-notmuch--sq (tag &optional k d0 d1) -      (jao-notmuch--qn (or d0 "feeds") (or d1 tag) k (list (concat "tag:" tag)))) - -    (defvar jao-notmuch--shared-tags -      '("new" "unread" "flagged" "signed" "sent" "attachment" "forwarded" -        "encrypted" "gmane" "gnus" "feeds" "rss" "mce" "trove" "prog" "emacs")) - -    (defun jao-notmuch--subtags (tag &rest excl) -      (let* ((cmd (concat "notmuch search --output=tags tag:" tag)) -             (ts (split-string (shell-command-to-string cmd)))) -        (seq-difference ts (append jao-notmuch--shared-tags (cons tag excl))))) - -    (defvar jao-notmuch-feed-searches-news -      (mapcar #'jao-notmuch--sq '("news" "fun" "words" "computers"))) - -    (defvar jao-notmuch-feed-searches-hack -      (mapcar #'jao-notmuch--sq -              '("xmobar" "geiser" "mdk" "mailutils" "notmuch"))) - -    (defvar jao-notmuch-feed-searches-lang -      (append (mapcar #'jao-notmuch--sq -                      '( "lobsters" "clojure"  "lisp" "scheme" -                        "haskell" "idris" "erlang" "pharo")) -              `(,(jao-notmuch--qn "feeds" "prog" "fp" -                                  '("tag:prog" "not tag:\"/emacs/\""))))) - -    (defvar jao-notmuch-feed-searches-sci -      (mapcar #'jao-notmuch--sq -              '("philosophy" "math" "physics" "sci" "gr-qc" "quant-ph"))) - -    (defvar jao-notmuch-feed-searches -      (append jao-notmuch-feed-searches-news -              jao-notmuch-feed-searches-hack -              jao-notmuch-feed-searches-lang -              jao-notmuch-feed-searches-sci)) - -    (defvar jao-notmuch-bigml-searches -      `(,(jao-notmuch--q "bigml" "inbox" "bi") -        ,(jao-notmuch--q "bigml" "alba" "ba") -        ,(jao-notmuch--q "bigml" "support" "bs") -        ,(jao-notmuch--q "bigml" "bugs" "bb") -        ,(jao-notmuch--q "bigml" "drivel" "bd") -        ,(jao-notmuch--q "bigml" "lists" "bl"))) - -    (defvar jao-notmuch-inbox-searches -      `(,(jao-notmuch--q "jao" "inbox" "ji") -        ,(jao-notmuch--q "jao" "bills" "jb") -        ,(jao-notmuch--q "jao" "drivel" "jd") -        ,(jao-notmuch--q "jao" "mdk" "jm") -        ,(jao-notmuch--qn "jao" "hacking" "jh" -                          '("tag:hacking" "not tag:\"/emacs/\"")) -        ,(jao-notmuch--qn "jao" "local" "jl" '("tag:local")))) - -    (defvar jao-notmuch-mark-searches -      `(,(jao-notmuch--q "jao" "drafts" "d" '("tag:draft")) -        ,(jao-notmuch--q "bml" "flagged" "rb" '("tag:flagged" "tag:bigml")) -        ,(jao-notmuch--q "jao" "flagged" "rj" '("tag:flagged" "tag:jao")) -        ,(jao-notmuch--q "feeds" "flagged" "rf" '("tag:flagged" "tag:feeds")))) - -    (defvar jao-notmuch-emacs-searches -      `(,(jao-notmuch--sq "emacs" "ee" "emacs" "feeds") -        ,(jao-notmuch--sq "emacs-help" "eh" "emacs" "help") -        ,(jao-notmuch--sq "emacs-github" "eg" "emacs" "github") -        ,(jao-notmuch--sq "emacs-devel" "ed" "emacs" "devel") -        ,(jao-notmuch--sq "emacs-bugs" "eb" "emacs" "bugs") -        ,(jao-notmuch--sq "emacs-diffs" "ec" "emacs" "diffs") -        ,(jao-notmuch--sq "emacs-orgmode" "eo" "emacs" "org"))) - -    (setq notmuch-saved-searches -          (append jao-notmuch-inbox-searches -                  jao-notmuch-bigml-searches -                  jao-notmuch-mark-searches -                  jao-notmuch-feed-searches -                  jao-notmuch-emacs-searches)) - -    (defvar jao-notmuch-dynamic-searches -      `(,(jao-notmuch--q "bml" "today" "tb" '("tag:bigml" "date:24h..")) -        ,(jao-notmuch--q "jao" "today" "tj" -                         '("tag:jao" "date:24h.." -                           "not tag:\"/(feeds|spam|local)/\"")))) - -    (defvar jao-notmuch-new-searches -      `(,(jao-notmuch--q "new" nil "nn" '("tag:new" "not tag:draft")) -        ,(jao-notmuch--q "unread" nil "nu" '("tag:unread")) -        (:query "*" :name "messages"))) - -    (defun jao-notmuch-tree-widen-search () -      (interactive) -      (when-let ((query (notmuch-tree-get-query))) -        (let ((notmuch-show-process-crypto (notmuch-tree--message-process-crypto))) -          (notmuch-tree-close-message-window) -          (notmuch-tree (string-replace jao-notmuch--newa "" query))))) - -    (defun jao-notmuch-widen-searches (searches &optional extra) -      (mapcar (lambda (s) -                (let* ((q (plist-get s :query)) -                       (qs (string-replace jao-notmuch--newa "" q))) -                  (plist-put (copy-sequence s) :query (concat qs extra)))) -              searches)) - -    (defvar jao-notmuch-widened-searches -      (jao-notmuch-widen-searches notmuch-saved-searches)) - -    (defvar jao-notmuch-flagged-searches -      (let ((s (seq-difference notmuch-saved-searches -                               jao-notmuch-mark-searches))) -        (jao-notmuch-widen-searches s " AND tag:flagged"))) - -    (defun jao-notmuch-jump-search (&optional widen) -      (interactive "P") -      (let ((notmuch-saved-searches -             (if widen jao-notmuch-widened-searches notmuch-saved-searches))) -        (notmuch-jump-search))) - -  #+end_src -* tags -  #+begin_src emacs-lisp -    (setq notmuch-archive-tags '("+trove" "-new" "-inbox") -          notmuch-show-mark-read-tags '("-new" "-unread") -          notmuch-tag-formats -          (let ((d `(:foreground ,(face-attribute 'jao-themes-dimm :foreground))) -                (e `(:foreground ,(face-attribute 'jao-themes-error :foreground) -                     :weight bold))) -            `(("unread") -              ("signed") -              ("new" "N") -              ("replied" "โฉ" (propertize tag 'face '(:family "Fira Code"))) -              ("sent" "S") -              ("attachment" "๐") -              ("deleted" "๐" (propertize tag 'face '(:underline nil ,@e))) -              ;; ("attachment" "+") -              ;; ("deleted" "xxx" (propertize tag 'face '(:underline nil ,@e))) -              ("flagged" "!" (propertize tag 'face ',e)) -              ("jao" "j") -              ("bigml" "b") -              ("feeds" "f") -              ("gmane" "g"))) -          notmuch-tag-deleted-formats -          '(("unread") -            ("new") -            (".*" (notmuch-apply-face tag 'notmuch-tag-deleted)))) - -    (with-eval-after-load "notmuch-tag" -      (advice-add #'notmuch-read-tag-changes -                  :filter-return (lambda (x) (mapcar #'string-trim x)))) -  #+end_src -* package -  #+begin_src emacs-lisp -    (add-to-list 'load-path "/usr/local/share/emacs/site-lisp/") - -    (use-package notmuch -      :init -      (setq notmuch-address-use-company t -            notmuch-address-command (if jao-notmuch-enabled 'internal 'as-is) -            notmuch-always-prompt-for-sender t -            notmuch-draft-folder "local" -            notmuch-draft-quoted-tags '("part") -            notmuch-address-internal-completion '(received nil) -            notmuch-fcc-dirs -            '(("\\(support\\|education\\)@bigml.com" . nil) -              (".*@bigml.com" . "bigml/trove +bigml +sent -new -unread") -              (".*" . "jao/trove +jao +sent +trove -new -unread")) -            notmuch-maildir-use-notmuch-insert t) - -      :config - -      (add-hook 'message-send-hook #'notmuch-mua-attachment-check) - -      (when jao-notmuch-enabled -        (define-key message-mode-map (kbd "C-c C-d") #'notmuch-draft-postpone) -        (setq message-directory "~/var/mail/" -              message-auto-save-directory "/tmp" -              mail-user-agent 'message-user-agent)) - -      :bind (:map notmuch-common-keymap -             (("E" . jao-notmuch-open-enclosure) -              ("B" . notmuch-show-resend-message) -              ("b" . jao-notmuch-browse-urls)))) - -    (use-package jao-notmuch :demand t) - -  #+end_src -* hello -  #+begin_src emacs-lisp -    (defun jao-notmuch-hello--insert-searches (searches title) -      (when-let (searches (notmuch-hello-query-counts searches)) -        (let* ((cnt (when title -                      (seq-reduce (lambda (c q) -                                    (+ c (or (plist-get q :count) 0))) -                                  searches -                                  0))) -               (title (if title (format "[ %d %s ]\n\n" cnt title) "\n"))) -          (widget-insert (propertize title 'face 'jao-themes-f00)) -          (let ((notmuch-column-control 1.0) -                (start (point))) -            (notmuch-hello-insert-buttons searches) -            (indent-rigidly start (point) notmuch-hello-indent)) -          cnt))) - -    (defun jao-notmuch-hello-insert-inbox-searches () -      (jao-notmuch-hello--insert-searches jao-notmuch-inbox-searches "inbox")) - -    (defun jao-notmuch-hello-insert-bigml-searches () -      (jao-notmuch-hello--insert-searches jao-notmuch-bigml-searches "bigml")) - -    (defun jao-notmuch-hello-insert-mark-searches () -      (jao-notmuch-hello--insert-searches jao-notmuch-mark-searches "marks") -      (jao-notmuch-hello--insert-searches jao-notmuch-flagged-searches nil)) - -    (defun jao-notmuch-hello-insert-feeds-searches () -      (let ((sect "feeds")) -        (dolist (s `(,jao-notmuch-feed-searches-news -                     ,jao-notmuch-feed-searches-hack -                     ,jao-notmuch-feed-searches-lang -                     ,jao-notmuch-feed-searches-sci)) -          (let ((i (funcall #'jao-notmuch-hello--insert-searches s sect))) -            (setq sect (unless i sect)))))) - -    (defun jao-notmuch-hello-insert-emacs-searches () -      (jao-notmuch-hello--insert-searches jao-notmuch-emacs-searches "emacs")) - -    (defun jao-notmuch-hello-insert-dynamic-searches () -      (jao-notmuch-hello--insert-searches jao-notmuch-dynamic-searches "dynamic") -      (jao-notmuch-hello--insert-searches jao-notmuch-new-searches nil)) - -    (defun jao-notmuch-refresh-agenda () -      (interactive) -      (save-window-excursion (org-agenda-list)) -      (let ((b (current-buffer))) -        (pop-to-buffer "*Calendar*") -        (goto-char (point-min)) -        (calendar-goto-today) -        (pop-to-buffer b))) - -    (defun jao-notmuch-hello-first () -      (interactive) -      (let ((inhibit-message t)) -        (beginning-of-buffer) -        (widget-forward 1))) - -    (defun jao-notmuch-refresh-hello (&optional agenda) -      (interactive "P") -      (ignore-errors -        (when (and (string= "Mail" (jao-afio-current-frame)) -                   (derived-mode-p 'notmuch-hello-mode)) -          (when (not (string-blank-p jao-notmuch-minibuffer-string)) -            (let ((notmuch-hello-auto-refresh nil)) (notmuch-hello))) -          (when agenda (jao-notmuch-refresh-agenda)) -          (unless (widget-at) (jao-notmuch-hello-first))))) - -    (defvar jao-notmuch-hello--sec-rx "^\\(\\[ [0-9]+\\|All tags:.+\\)") - -    (defun jao-notmuch-hello-next-section () -      (interactive) -      (when (re-search-forward jao-notmuch-hello--sec-rx  nil t) -        (widget-forward 1))) - -    (defun jao-notmuch-hello-prev-section () -      (interactive) -      (beginning-of-line) -      (unless (looking-at-p jao-notmuch-hello--sec-rx) -        (re-search-backward jao-notmuch-hello--sec-rx nil t)) -      (when (re-search-backward jao-notmuch-hello--sec-rx  nil t) -        (end-of-line) -        (widget-forward 1))) - -    (defun jao-notmuch-hello-next () -      (interactive) -      (if (widget-at) -          (widget-button-press (point)) -        (jao-notmuch-hello-next-section))) - -    (use-package notmuch-hello -      :init -      (setq notmuch-column-control t -            notmuch-hello-sections '(jao-notmuch-hello-insert-bigml-searches -                                     jao-notmuch-hello-insert-inbox-searches -                                     jao-notmuch-hello-insert-feeds-searches -                                     jao-notmuch-hello-insert-emacs-searches -                                     jao-notmuch-hello-insert-mark-searches -                                     jao-notmuch-hello-insert-dynamic-searches -                                     notmuch-hello-insert-alltags) -            notmuch-hello-hide-tags nil -            notmuch-hello-thousands-separator "," -            notmuch-hello-auto-refresh t -            notmuch-show-all-tags-list nil -            notmuch-show-logo nil -            notmuch-show-empty-saved-searches nil) - -      :hook ((notmuch-hello-refresh . jao-notmuch-notify) -             (jao-afio-switch . jao-notmuch-refresh-hello)) - -      :bind (:map notmuch-hello-mode-map -             (("a" . jao-notmuch-refresh-agenda) -              ("j" . jao-notmuch-jump-search) -              ("n" . jao-notmuch-hello-next) -              ("p" . widget-backward) -              ("S" . consult-notmuch) -              ("g" . jao-notmuch-refresh-hello) -              ("." . jao-notmuch-hello-first) -              ("SPC" . widget-button-press) -              ("[" . jao-notmuch-hello-prev-section) -              ("]" . jao-notmuch-hello-next-section)))) - -  #+end_src -* show -  #+begin_src emacs-lisp -    (defun jao-notmuch-open-enclosure (add) -      (interactive "P") -      (with-current-notmuch-show-message -       (goto-char (point-min)) -       (if (not (search-forward "Enclosure:" nil t)) -           (user-error "No enclosure in message body") -         (re-search-forward "https?://" nil t) -         (if-let (url (thing-at-point-url-at-point)) -             (progn -               (message "%s %s ..." (if add "Adding" "Playing") url) -               (unless add (jao-mpc-clear)) -               (jao-mpc-add-url url) -               (unless add (jao-mpc-play))) -           (error "Found an enclosure, but not a link!"))))) - -    (defconst jao-mail-clean-rx -      (regexp-opt '("ElDiario.es - ElDiario.es: " "The Guardian: " -                    "The Conversation โ Articles (UK): "))) - -    (defun jao-mail-clean-address (args) -      (when-let ((address (car args))) -        (list (if (string-match ".+ updates on arXiv.org: \\(.+\\)" address) -                  (with-temp-buffer -                    (insert (match-string 1 address)) -                    (let ((shr-width 1000)) -                      (shr-render-region (point-min) (point-max))) -                    (replace-regexp-in-string "\"" "" (buffer-string))) -                (replace-regexp-in-string jao-mail-clean-rx "" address))))) - -    (use-package notmuch-show -      :init -      (setq gnus-blocked-images "." -            notmuch-message-headers -            '("To" "Cc" "Date" "Reply-To" "List-Id" "X-RSS-Feed") -            notmuch-show-only-matching-messages t -            notmuch-show-part-button-default-action 'notmuch-show-view-part -            notmuch-wash-signature-lines-max 0 -            notmuch-wash-wrap-lines-length 80 -            notmuch-wash-citation-lines-prefix 10 -            notmuch-wash-citation-lines-suffix 20 -            notmuch-show-text/html-blocked-images "." -            notmuch-show-header-line #'jao-notmuch-message-header-line) - -      :config - -      (advice-add 'notmuch-clean-address :filter-args #'jao-mail-clean-address) - -      :bind -      (:map notmuch-show-mode-map -       (("h" . jao-notmuch-goto-tree-buffer) -        ("TAB" . jao-notmuch-show-next-button) -        ([backtab] . jao-notmuch-show-previous-button) -        ("RET" . jao-notmuch-show-ret)))) -  #+end_src -* search -  #+begin_src emacs-lisp -    (use-package notmuch-search -      :init (setq notmuch-search-result-format -                  '(("date" . "%12s ") -                    ("count" . "%-7s ") -                    ("authors" . "%-35s") -                    ("subject" . " %-100s") -                    (jao-notmuch-format-tags . "  (%s)")) -                  notmuch-search-buffer-name-format "*%s*" -                  notmuch-saved-search-buffer-name-format "*%s*") -      :bind (:map notmuch-search-mode-map -             (("RET" . notmuch-tree-from-search-thread) -              ("M-RET" . notmuch-search-show-thread)))) - -  #+end_src -* tree -  #+begin_src emacs-lisp -    (defun jao-notmuch-tree--forward (&optional prev) -      (interactive) -      (forward-line (if prev -1 1)) -      (when prev (forward-char 2)) -      (jao-notmuch-tree-scroll-or-next)) - -    (defun jao-notmuch-tree--backward () -      (interactive) -      (jao-notmuch-tree--forward t)) - -    (defun jao-notmuch--via-url () -      (when (window-live-p notmuch-tree-message-window) -        (with-selected-window notmuch-tree-message-window -          (goto-char (point-min)) -          (when (re-search-forward "^Via: http" nil t) -            (thing-at-point-url-at-point))))) - -    (defun jao-notmuch-browse-url (ext) -      (interactive "P") -      (when-let (url (or (jao-notmuch--via-url) -                         (car (last (jao-notmuch-message-urls))))) -        (funcall (if ext browse-url-secondary-browser-function #'browse-url) -                 url))) - -    (defun jao-notmuch-adjust-tree-fonts (&optional family) -      (let ((fg (face-attribute 'jao-themes-dimm :foreground)) -            (family (or family "Source Code Pro"))) -        (dolist (f '(notmuch-tree-match-tree-face -                     notmuch-tree-no-match-tree-face)) -          (if family -              (set-face-attribute f nil :family family :foreground fg) -            (set-face-attribute f nil :foreground fg))))) - -    (use-package notmuch-tree -      :init -      (setq notmuch-tree-result-format -            `(("date" . "%12s  ") -              (jao-notmuch-format-author . 25) -              (jao-notmuch-format-msg-ticks . ,jao-mails-regexp) -              (jao-notmuch-format-tree-and-subject . "%>-85s") -              (jao-notmuch-format-tags . "  (%s)")) -            notmuch-unthreaded-result-format notmuch-search-result-format -            consult-notmuch-result-format -            `((jao-notmuch-format-msg-ticks . ,jao-mails-regexp) -              ("date" . "%12s  ") -              ("authors" . "%-35s") -              ("subject" . " %-100s") -              (jao-notmuch-format-tags . "  (%s)")) -            ;; notmuch-tree-thread-symbols -            ;; '((prefix . "โ") (top . "โ") (top-tee . "โฌ") -            ;;   (vertical . "โ") (vertical-tee . "โ") (bottom . "โฐ") -            ;;   (arrow . "")) -            notmuch-tree-thread-symbols -            '((prefix . " ") (top . " ") (top-tee . " ") -              (vertical . " ") (vertical-tee . " ") (bottom . " ") -              (arrow . ""))) -      :config - -      (jao-notmuch-adjust-tree-fonts -       (when (string-prefix-p "Hack" jao-themes-default-face) "Source Code Pro")) - -      (jao-notmuch-tree-setup "T") - -      (defun jao-notmuch-before-tree (&rest args) -        (when (string= (buffer-name) "*notmuch-hello*") -          (split-window-right 40) -          (other-window 1))) - -      (defvar jao-notmuch--visits 0) - -      (defun jao-notmuch-after-tree-quit (&optional both) -        (when (and (not (derived-mode-p 'notmuch-tree-mode 'notmuch-hello-mode)) -                   (save-window-excursion (other-window -1) -                                          (derived-mode-p 'notmuch-hello-mode))) -          (delete-window) -          (jao-notmuch-refresh-hello (= 0 (mod (cl-incf jao-notmuch--visits) 10))))) - -      (advice-add 'notmuch-tree :before #'jao-notmuch-before-tree) -      (advice-add 'notmuch-tree-quit :after #'jao-notmuch-after-tree-quit) - -      :bind (:map notmuch-tree-mode-map -                  (("b" . jao-notmuch-browse-urls) -                   ("d" . jao-notmuch-tree-toggle-delete) -                   ("D" . jao-notmuch-tree-toggle-delete-thread) -                   ("h" . jao-notmuch-goto-message-buffer) -                   ("H" . jao-notmuch-click-message-buffer) -                   ("i" . jao-notmuch-toggle-images) -                   ("K" . jao-notmuch-tag-jump-and-next) -                   ("k" . jao-notmuch-tree-read-thread) -                   ("n" . jao-notmuch-tree-next) -                   ("N" . jao-notmuch-tree--forward) -                   ("O" . notmuch-tree-toggle-order) -                   ("o" . jao-notmuch-tree-widen-search) -                   ("p" . jao-notmuch-tree-previous) -                   ("P" . jao-notmuch-tree--backward) -                   ("r" . notmuch-tree-reply) -                   ("R" . notmuch-tree-reply-sender) -                   ("s" . jao-notmuch-tree-toggle-spam) -                   ("u" . jao-notmuch-tree-toggle-flag) -                   ("v" . notmuch-tree-scroll-message-window) -                   ("V" . notmuch-tree-scroll-message-window-back) -                   ("x" . jao-notmuch-arXiv-capture) -                   ("<" . jao-notmuch-tree-beginning-of-buffer) -                   (">" . jao-notmuch-tree-end-of-buffer) -                   ("\\" . notmuch-tree-view-raw-message) -                   ("." . jao-notmuch-toggle-mime-parts) -                   ("=" . jao-notmuch-tree-toggle-message) -                   ("RET" . jao-notmuch-tree-show-or-scroll) -                   ("SPC" . jao-notmuch-tree-scroll-or-next) -                   ("M-g" . jao-notmuch-browse-url) -                   ("M-u" . jao-notmuch-tree-reset-tags)))) -  #+end_src -* org mode -  Stolen and adapted from [[https://gist.github.com/fedxa/fac592424473f1b70ea489cc64e08911][Fedor Bezrukov]]. -  #+begin_src emacs-lisp -    (defvar jao-org-notmuch-last-subject nil) -    (defun jao-org-notmuch-last-subject () jao-org-notmuch-last-subject) - -    (defun jao-notmuch--add-tags (tags) -      (if (derived-mode-p 'notmuch-show-mode) -          (notmuch-show-add-tag tags) -        (notmuch-tree-add-tag tags))) - -    (defun org-notmuch-store-link () -      "Store a link to a notmuch mail message." -      (cl-case major-mode -        ((notmuch-show-mode notmuch-tree-mode) -         ;; Store link to the current message -         (let* ((id (notmuch-show-get-message-id)) -                (link (concat "notmuch:" id)) -                (subj (notmuch-show-get-subject)) -                (description (format "Mail: %s" subj))) -           (setq jao-org-notmuch-last-subject subj) -           (when (y-or-n-p "Archive message? ") -             (jao-notmuch--add-tags '("+trove"))) -           (when (y-or-n-p "Flag message as todo? ") -             (jao-notmuch--add-tags '("+flagged"))) -           (org-store-link-props -	    :type "notmuch" -	    :link link -	    :description description))) -        (notmuch-search-mode -         ;; Store link to the thread on the current line -         (let* ((id (notmuch-search-find-thread-id)) -                (link (concat "notmuch:" id)) -                (subj (notmuch-search-find-subject)) -                (description (format "Mail: %s" subj))) -           (setq jao-org-notmuch-last-subject subj) -           (org-store-link-props -            :type "notmuch" -            :link link -            :description description))))) - -    (with-eval-after-load "org" -      (org-link-set-parameters "notmuch" -                               :follow 'notmuch-show -                               :store 'org-notmuch-store-link)) -  #+end_src -* arXiv -    #+begin_src emacs-lisp -      (use-package org-capture -        :config -        (add-to-list 'org-capture-templates -                     '("X" "arXiv" entry (file "notes/physics/arxiv.org") -                       "* %(jao-org-notmuch-last-subject)\n %i" -                       :immediate-finish t) -                     t) -        (org-capture-upgrade-templates org-capture-templates)) - -      (defun jao-notmuch-arXiv-capture () -        (interactive) -        (save-window-excursion -          (jao-notmuch-goto-message-buffer) -          (save-excursion -            (goto-char (point-min)) -            (re-search-forward "\\[ text/html \\]") -            (forward-paragraph) -            (setq-local transient-mark-mode 'lambda) -            (set-mark (point)) -            (goto-char (point-max)) -            (org-capture nil "X")))) - -    #+end_src -* html render -  #+begin_src emacs-lisp -    (when jao-notmuch-enabled (setq mm-text-html-renderer 'shr)) -  #+end_src -* consult -  #+begin_src emacs-lisp -    (jao-load-path "consult-notmuch") -    (require 'consult-notmuch) -    (consult-customize consult-notmuch :preview-key 'any) - -    (defvar jao-consult-notmuch-history nil) - -    (defvar jao-mailbox-folders '("bigml" "jao")) - -    (defun jao-consult-notmuch-folder (&optional tree folder) -      (interactive "P") -      (let ((folder (if folder -                        (file-name-as-directory folder) -                      (completing-read "Group: " -                                       jao-mailbox-folders -                                       nil nil nil -                                       jao-consult-notmuch-history -                                       "."))) -             (folder (replace-regexp-in-string "/\\(.\\)" ".\\1" folder)) -             (init (read-string "Initial query: ")) -             (init (format "folder:/%s/ %s" folder init))) -        (if tree (consult-notmuch-tree init) (consult-notmuch init)))) - -    (with-eval-after-load "notmuch-hello" -      (define-key notmuch-hello-mode-map "f" #'jao-consult-notmuch-folder)) -  #+end_src -* link hint -  #+begin_src emacs-lisp -    (with-eval-after-load "link-hint" -      (defun jao-link-hint--notmuch-next-part (&optional bound) -        (when-let (p (next-single-property-change (point) :notmuch-part nil bound)) -          (and (< p (or bound (point-max))) p))) - -      (defun jao-link-hint--notmuch-part-p () -        (and (get-text-property (point) :notmuch-part) -             (when-let (b (button-at (point))) (button-label b)))) - -      (link-hint-define-type 'notmuch-part -        :next #'jao-link-hint--notmuch-next-part -        :at-point-p #'jao-link-hint--notmuch-part-p -        :vars '(notmuch-show-mode) -        :open #'push-button -        :open-message "Toggled" -        :open-multiple t) - -      (push 'link-hint-notmuch-part link-hint-types)) - -  #+end_src diff --git a/attic/org/org.org b/attic/org/org.org deleted file mode 100644 index bcce3e1..0000000 --- a/attic/org/org.org +++ /dev/null @@ -1,316 +0,0 @@ -#+property: header-args :lexical t :tangle yes :comments yes :results silent :shebang ";; -*- lexical-binding: t" :tangle-mode (identity #o644) -#+title: Org (and related) mode configuration - -* General configuration -  #+begin_src emacs-lisp -    (use-package org -      :ensure t -      :custom ((org-export-backends '(ascii html latex texinfo))) -      :init -      (defalias 'jao-open-gnus-frame 'jao-afio--goto-mail) - -      (setq org-adapt-indentation t -            org-catch-invisible-edits 'smart -            org-complete-tags-always-offer-all-agenda-tags t -            org-cycle-separator-lines 0 ;; no blank lines when all colapsed -            org-deadline-warning-days 14 -            org-default-notes-file (expand-file-name "inbox.org" org-directory) -            org-directory jao-org-dir -            org-display-remote-inline-images 'download ;; 'skip 'cache -            org-ellipsis " .." ;; โด -            org-email-link-description-format "Email %c: %s" -            org-enforce-todo-dependencies t -            org-fast-tag-selection-single-key 'expert -            ;; org-list-demote-modify-bullet '(("+" . "-") ("-" . "+") ("*" . "+")) -            org-link-frame-setup -            '((gnus . (lambda (&optional x) (jao-open-gnus-frame))) -              (file . find-file-other-window)) -            org-log-done nil -            org-modules '(bibtex info eww eshell git-link) -            org-odd-levels-only t -            org-outline-path-complete-in-steps nil -            org-refile-allow-creating-parent-nodes 'confirm -            org-refile-targets '((nil :maxlevel . 5) -                                 (org-agenda-files :maxlevel . 5)) -            org-refile-use-outline-path 'file -            org-return-follows-link t -            org-reverse-note-order t -            org-special-ctrl-a/e t -            org-src-fontify-natively t -            org-startup-folded t -            org-tag-alist nil -            org-tags-column -75 -            org-todo-keywords -            '((sequence "TODO(t)" "STARTED(s!)" "|" "DONE(d!)") -              (sequence "REPLY(r)" "WAITING(w!)" "|" "DONE(d!)") -              (sequence "TOREAD(T)" "READING(R!)" "|" "READ(a!)") -              (sequence "|" "CANCELLED(x!)" "SOMEDAY(o!)" "DONE(d!)")) -            org-use-fast-todo-selection t -            org-use-speed-commands nil ;; t and then ? to see help -            org-gnus-prefer-web-links nil)) -    (require 'org) -  #+end_src -* Agenda -  #+begin_src emacs-lisp -    (setq ;; org-agenda-custom-commands -          ;; '(("w" todo "WAITING" nil) -          ;;   ("W" agenda "" ((org-agenda-ndays 21)))) -          org-agenda-files (mapcar (lambda (f) -                                     (expand-file-name f jao-org-dir)) -                                  '("inbox.org" "bigml.org")) -          org-agenda-block-separator " " -          org-agenda-breadcrumbs-separator "โข" -          org-agenda-current-time-string "โข" ;; "*" -          org-agenda-time-grid -          '((daily today require-timed) -            (800 1000 1200 1400 1600 1800 2000) "" "ยท") -          org-agenda-include-diary t -          org-agenda-include-inactive-timestamps t -          org-agenda-inhibit-startup nil -          org-agenda-restore-windows-after-quit t -          org-agenda-show-all-dates t -          org-agenda-skip-deadline-if-done t -          org-agenda-skip-scheduled-if-done nil -          org-agenda-span 14 -          org-agenda-start-on-weekday nil -          org-agenda-window-setup 'current-window) -  #+end_src -* Capture templates -  #+BEGIN_SRC emacs-lisp -    (setq  org-capture-templates -           '(("t" "TODO" entry -              (file+headline "inbox.org" "Todo") -              "* TODO %?\n  %i%a" :prepend t) -             ("r" "REPLY" entry -              (file+headline "inbox.org" "Todo") -              "* REPLY %:subject%?\n  %t\n %i%a" :prepend t) -             ("a" "Appointment" entry -              (file+olp "inbox.org" "Appointments") -              "* %^T %?\n  %a" :time-prompt t) -             ("i" "Inbox note" entry (file+headline "inbox.org" "Notes") -              "* %a\n  %i%?(added on: %u)" :prepend t))) -    ;; (org-capture-upgrade-templates org-capture-templates) -  #+END_SRC -* MIME and file apps -  #+BEGIN_SRC emacs-lisp -    (setq org-file-apps -          '((system . mailcap) -            (".*\\.djvu" . system) -            (t . emacs))) -  #+END_SRC -* Appearance -  #+begin_src emacs-lisp -    ;; Show hidden emphasis markers -    (use-package org-appear -      :ensure t -      :hook (org-mode . org-appear-mode)) - -    ;; #+caption: Image caption. -    ;;  #+attr_org: :width 100 -    ;;  [[file:path/to/image.png]] - -    (setq org-startup-indented nil -          org-pretty-entities nil -          org-hide-emphasis-markers t -          org-hide-leading-stars t -          org-startup-with-inline-images t -          org-image-actual-width '(300)) - -    (use-package org-modern -      :ensure t -      :init (setq org-modern-label-border 1)) - -    ;; (unless (display-graphic-p) (global-org-modern-mode 1)) - -  #+end_src -* LaTeX -  #+begin_src emacs-lisp -    (use-package org-fragtog -      :after org -      :ensure t -      :hook ((org-mode . org-fragtog-mode))) - -    (require 'org-fragtog) - -    (setq org-format-latex-options -          `(:foreground default -                        :background -                        ,(if (jao-colors-scheme-dark-p) "black" "white") -                        :scale 1.25 -                        :html-foreground "black" -                        :html-background "Transparent" -                        :html-scale 1.0 -                        :matchers ("begin" "$1" "$" "$$" "\\(" "\\[")) -          org-preview-latex-image-directory -          (expand-file-name "~/.emacs.d/cache/ltximg/") -          org-latex-hyperref-template nil -          org-highlight-latex-and-related '(latex script entities)) - -    (require 'ox-latex) -  #+end_src - -* Export (minted) - -  #+begin_src emacs-lisp -    (setq org-latex-listings 'minted -          org-latex-packages-alist '(("" "minted")) -          org-latex-pdf-process -          '("pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f" -            "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f")) -  #+end_src - -* Babel and literate programming -  - [[http://cachestocaches.com/2018/6/org-literate-programming][Literate Programming with Org-mode]] -  - [[http://howardism.org/Technical/Emacs/literate-devops.html][Literate DevOps]] - -  #+begin_src emacs-lisp -    (setq org-src-window-setup 'other-window) ;; current-window -    (require 'org-tempo nil t) ;; <s TAB for 9.2 and later - -    (use-package poly-org :ensure t) - -    (use-package ob-prolog -      :ensure t -      :after org) - -    (org-babel-do-load-languages -     'org-babel-load-languages -     '((calc . t) -       (clojure . t) -       ;; (elixir . t) -       (emacs-lisp .t) -       (gnuplot .t) -       (haskell . t) -       (makefile . t) -       (ocaml . t) -       (org . t) -       (python . t) -       (scheme .t) -       (shell . t) -       (prolog . t))) -  #+end_src - -* Org cliplink (link from clipboard) -  [[https://github.com/rexim/org-cliplink][GitHub - rexim/org-cliplink: Insert org-mode links from clipboard]] - -  #+BEGIN_SRC emacs-lisp -    (use-package org-cliplink -      :ensure t -      :bind (:map org-mode-map ("C-c C-f" . org-cliplink)) -      :config -      (add-to-list 'org-capture-templates -                   '("k" "Cliplink capture task" entry -                     (file+headline "inbox.org" "Todo") -                     "* TODO %(org-cliplink-capture) %?" :prepend t) -                   t)) -  #+END_SRC - -* Notes -  #+begin_src emacs-lisp -    (use-package jao-org-notes -      :commands (jao-org-notes-setup) -      :config -      (defun jao-org-notes-note-p () -        (string-prefix-p jao-org-notes-dir (buffer-file-name))) - -      (defun jao-org-notes-recoll () -        "Use consult-recoll to search notes." -        (interactive) -        (consult-recoll (format "dir:%s " jao-org-notes-dir))) - -      (jao-transient-major-mode org -        ["Notes" -         ("o" "find and open note" jao-org-notes-open) -         ("c" "open or create note" jao-org-notes-open-or-create) -         ("\\" "grep notes" jao-org-notes-grep) -         ("r" "recoll notes" jao-org-notes-recoll)] -        ["Current note" :if jao-org-notes-note-p -         ("i" "insert link" jao-org-notes-insert-link) -         ("t" "insert tags" jao-org-notes-insert-tags) -         ("v" "show backlinks" jao-org-notes-backlinks)])) - -    (jao-org-notes-setup "n") -  #+end_src -* Links -  #+begin_src emacs-lisp -    (require 'ol-eshell nil t) -    ;; (require 'ol-bbdb nil t) -    (require 'ol-info nil t) -    (setq org-link-abbrev-alist '(("jao.io" "https://jao.io/"))) - -    (defun jao-org-link-at-point (&optional copy) -      (when (thing-at-point-looking-at "\\[\\[\\([^]]+\\)\\]\\[[^]]+\\]\\]") -        (when copy (kill-ring-save (match-beginning 1) (match-end 1))) -        (match-string-no-properties 1))) - -    (defun jao-org-copy-link-at-point () -      (interactive) -      (message "%s" (or (jao-org-link-at-point t) "No link at point"))) - -    (defun jao-org-insert-link (url title) -      (insert (format "[[%s][%s]]" url title))) - -    (defun jao-insert-eww-link () -      "Look for last eww buffer and insert an org link to it." -      (interactive) -      (when-let (b (car (jao-eww-session--list-buffers))) -        (let ((lnk (with-current-buffer b -                     (format "[[%s][%s]]" -                             (eww-current-url) -                             (jao-eww-buffer-title))))) -          (insert lnk)))) - -    (use-package jao-org-links -      :commands jao-org-links-setup -      :bind (("C-c T" . jao-org-insert-doc))) - -    (jao-org-links-setup jao-sink-dir) - -    (with-eval-after-load "pdf-view" -      (define-key pdf-view-mode-map (kbd "C-c o") #'jao-org-pdf-goto-org) -      (define-key pdf-view-mode-map (kbd "C-c O") #'jao-org-pdf-goto-org*)) - -    (with-eval-after-load "doc-view" -      (define-key doc-view-mode-map (kbd "C-c o") #'jao-org-pdf-goto-org) -      (define-key doc-view-mode-map (kbd "C-c O") #'jao-org-pdf-goto-org*)) - -    #+end_src -* eldoc -  #+begin_src emacs-lisp -    (defun jao-org-eldoc--hook () -      (set (make-local-variable 'eldoc-documentation-function) -           'jao-org-link-at-point) -      (eldoc-mode)) -    (add-hook 'org-mode-hook 'jao-org-eldoc--hook) -  #+end_src -* savedoc -  #+begin_src emacs-lisp -    (defun jao-org--show-if-hidden () -      (when (outline-invisible-p) -        (save-excursion -          (outline-previous-visible-heading 1) -          (org-show-subtree)))) -    (add-hook 'org-mode-hook 'jao-org--show-if-hidden t) -  #+end_src -* Keybindings -    #+begin_src emacs-lisp -      (define-key mode-specific-map [?a] 'org-agenda) -      (define-key org-mode-map "\C-cv" 'jao-org-copy-link-at-point) -      (define-key org-mode-map [(control ?c) tab] 'org-force-cycle-archived) -      (define-key org-mode-map [(f7)] 'org-archive-to-archive-sibling) -      (define-key org-mode-map "\C-cE" 'jao-insert-eww-link) -      (define-key org-mode-map "\C-cW" 'jao-insert-eww-link) -      (define-key org-mode-map "\C-c'" 'org-edit-src-code) -      (define-key org-mode-map "\C-cO" 'outline-hide-other) -      (global-set-key "\C-cr" 'org-capture) -      (global-set-key "\C-c\C-l" 'org-store-link) -      ;; (global-set-key "\C-cL" 'org-insert-link-global) -      (global-set-key "\C-cO" 'org-open-at-point-global) - -      (jao-transient-major-mode+ org -        ["Links" -         ("le" "insert current eww link" jao-insert-eww-link) -         ("lf" "insert link from clipboard" org-cliplink) -         ("lc" "copy link at point" jao-org-copy-link-at-point)]) - -    #+end_src diff --git a/attic/org/w3m.org b/attic/org/w3m.org deleted file mode 100644 index 3689c8e..0000000 --- a/attic/org/w3m.org +++ /dev/null @@ -1,191 +0,0 @@ -#+property: header-args :lexical t :tangle yes :comments no :results silent -#+title: Customizations for emacs-w3m -#+auto_tangle: t - -* browse-url and afio -  #+begin_src emacs-lisp -    (defun jao-w3m-find-url (url) -      (let* ((url (w3m-canonicalize-url url)) -             (fn `(lambda (b) -                    (with-current-buffer b -                      (string= ,url (w3m-canonicalize-url w3m-current-url)))))) -        (when-let (b (seq-find fn (w3m-list-buffers))) -          (pop-to-buffer b)))) - -    (defun jao-w3m-browse-url (url &rest r) -      (jao-afio--goto-www) -      (select-window (frame-first-window)) -      (or (jao-w3m-find-url url) -          (w3m-goto-url-new-session url))) - -    (defun jao-w3m-download (arg) -      (interactive "P") -      (jao-download (w3m-anchor) arg)) - -    (setq jao-afio-use-w3m t) -    (setq jao-browse-url-function 'jao-w3m-browse-url) -  #+end_src -* Org integration -  #+begin_src emacs-lisp -    (defun jao-w3m-get-link () -      (let ((wb (w3m-alive-p))) -        (when wb -          (let ((url (with-current-buffer wb w3m-current-url)) -                (title (w3m-buffer-title wb))) -            (cons url title))))) - -    (defun jao-insert-w3m-link () -      (interactive) -      (let ((link (jao-w3m-get-link))) -        (when link (insert "[[" (car link) "][" (cdr link) "]]")))) - -    (with-eval-after-load "org" -      (require 'ol-w3m nil t) -      (define-key org-mode-map "\C-cW" 'jao-insert-w3m-link)) -  #+end_src -* notmuch integration -  #+begin_src emacs-lisp -    (defvar-local jao-notmuch--showing-images nil) - -    (defun jao-notmuch--setup-w3m-images (&optional activate) -      (when (eq mm-text-html-renderer 'w3m) -        (setq-local w3m-ignored-image-url-regexp -                    (unless jao-notmuch--showing-images -                      notmuch-show-text/html-blocked-images)) -        (when activate -          (setq-local scroll-margin 0) -          (w3m-toggle-inline-images (if jao-notmuch--showing-images t 'turnoff))))) - -    (defun jao-notmuch--w3m-toggle-images () -      (save-window-excursion -        (when (or (derived-mode-p 'notmuch-show-mode) -                  (jao-notmuch-goto-message-buffer nil t)) -          (goto-char (point-min)) -          (when (re-search-forward "^\\[ text/html " nil t) -            (when (looking-at-p "(hidden)") -              (notmuch-show-toggle-part-invisibility)) -            (forward-line 1) -            (setq jao-notmuch--showing-images (not jao-notmuch--showing-images)) -            (jao-notmuch--setup-w3m-images t))))) - -    (add-hook 'notmuch-show-mode-hook #'jao-notmuch--setup-w3m-images) -  #+end_src -* Capture page -  #+begin_src emacs-lisp -    (defun jao-w3m-capture-page () -      (interactive) -      (let* ((title (w3m-current-title)) -             (url w3m-current-url) -             (html (y-or-n-p "Save as HTML (y) or PS (n)? ")) -             (basename (concat (read-string "File name: ") -                               (if html ".html" ".ps"))) -             (name (expand-file-name basename jao-sink-dir))) -        (if html -            (progn -              (w3m-view-source) -              (write-region (point-min) (point-max) name nil nil nil t) -              (w3m-view-source)) -          (progn -            (split-window-horizontally 85) -            (w3m-redisplay-this-page) -            (ps-print-buffer name) -            (delete-other-windows) -            (w3m-redisplay-this-page))) -        (kill-new (format "[[doc:%s][%s]] ([[%s][original]])" -                          basename title url)))) -   #+end_src -* Consult narrowing -  #+begin_src emacs-lisp -    (with-eval-after-load "w3m-util" -      (with-eval-after-load "consult" -        (defvar jao-consult-w3m-buffer-history nil) -        (defun jao-www--item (b) -          (with-current-buffer b -            (propertize (or w3m-current-title (buffer-name)) -                        'buffer b -                        'url (or w3m-current-url (buffer-name))))) -        (defvar jao-consult-w3m-source -          (list :name "www buffer" -                :category 'www-buffer -                :hidden t -                :narrow (cons ?w "www") -                :annotate (lambda (b) (when b (get-text-property 0 'url b))) -                :history 'jao-consult-w3m-buffer-history -                :items (lambda () -                         (seq-map #'jao-www--item -                                  (seq-filter #'jao-www--buffer-p (buffer-list)))) -                :action (lambda (b) -                          (jao-afio--goto-www) -                          (switch-to-buffer (get-text-property 0 'buffer b))))) -        (jao-consult-add-buffer-source 'jao-consult-w3m-source "Web" ?w))) -  #+end_src -* Package -  #+begin_src emacs-lisp -    (use-package w3m -      :ensure t -      :custom ((w3m-key-binding 'info) -               (w3m-display-mode 'dual-pane)) -      :init -      (setq w3m-add-user-agent nil -            w3m-confirm-leaving-secure-page nil -            w3m-cookie-accept-bad-cookies t -            w3m-cookie-accept-domains '(".github.com" -                                        ".librarything.com" -                                        ".goodreads.com" -                                        ".sr.ht" -                                        ".gnu.org" -                                        ".codeberg.org" -                                        "codeberg.org" -                                        ".bookshop.org" -                                        ".reddit.com") -            w3m-cookie-reject-domains '(".") -            w3m-default-save-directory "~/var/download" -            w3m-do-cleanup-temp-files nil -            w3m-external-view-temp-directory "/tmp" -            w3m-fill-column 110 -            w3m-goto-article-function 'jao-w3m-browse-url -            w3m-form-input-textarea-buffer-lines 40 -            w3m-history-minimize-in-new-session t -            w3m-history-reuse-history-elements nil -            w3m-image-no-idle-timer t -            w3m-make-new-session t -            w3m-profile-directory "~/.w3m" -            w3m-redisplay-pages-automatically-p nil -            w3m-resize-images t -            w3m-safe-url-regexp nil -            w3m-search-default-engine "duckduckgo" ; "google-en" -            w3m-select-buffer-horizontal-window nil -            w3m-select-buffer-window-ratio '(20 . 40) -            w3m-session-load-last-sessions t -            w3m-session-load-crashed-sessions 'ask -            w3m-show-graphic-icons-in-header-line nil -            w3m-show-graphic-icons-in-mode-line nil -            w3m-use-tab nil -            w3m-use-tab-line nil -            w3m-use-title-buffer-name t -            w3m-use-cookies t -            w3m-use-filter nil -            w3m-use-favicon nil -            w3m-use-header-line nil -            w3m-use-refresh nil -            w3m-use-symbol t) - -      :config -      :bind (:map w3m-mode-map -                  (("+" . w3m-zoom-in-image) -                   ("-" . w3m-zoom-out-image) -                   ("C-c C-@" . tracking-next-buffer) -                   ("C-c C-SPC" . tracking-next-buffer) -                   ("C-c C-b" . nil) -                   ("C-c c" . jao-w3m-capture-page) -                   ("b" . w3m-view-previous-page) -                   ("B" . w3m-view-next-page) -                   ("c" . w3m-print-this-url) -                   ("d" . jao-w3m-download) -                   ("D" . w3m-download) -                   ("f" . w3m-lnum-follow) -                   ("v" . jao-view-video) -                   ("w" . org-w3m-copy-for-org-mode) -                   ("x" . jao-rss-subscribe) -                   ("y" . w3m-print-current-url)))) -  #+end_src | 
