#+title: Miscellaneous config bits that i don't use anymore * portability macros #+begin_src emacs-lisp (defmacro jao-syscase (clauses) (let ((cls (assoc system-type clauses))) (when cls `(progn ,@(cdr cls))))) (defmacro jao-d-l (darw linux) `(jao-syscase ((darwin ,darw) (gnu/linux ,linux)))) (defmacro jao-when-darwin (&rest body) `(jao-syscase ((darwin ,@body)))) (defmacro jao-when-linux (&rest body) `(jao-syscase ((gnu/linux ,@body)))) #+end_src * outlines #+begin_src emacs-lisp (use-package bicycle :ensure t :after outline :bind (:map outline-minor-mode-map ("C-" . bicycle-cycle) ("S-" . bicycle-cycle-global)) :diminish ((hs-minor-mode . "") (outline-minor-mode . ""))) #+end_src * elixir *** packages #+begin_src emacs-lisp (use-package elixir-mode :ensure t :custom (lsp-clients-elixir-server-executable (expand-file-name "~/usr/share/elixir-ls/language_server.sh")) ;; :bind (:map elixir-mode-map (("C-c C-z" . jao-vterm-repl-pop-to-repl))) ) (use-package mix :ensure t :hook (elixir-mode . mix-minor-mode) ;; :init (jao-vterm-repl-register "mix.exs" "iex -S mix" "^iex([0-9]+)> ") :diminish ((mix-minor-mode . ""))) (use-package exunit :ensure t) #+end_src *** hydra #+begin_src emacs-lisp (major-mode-hydra-define elixir-mode nil ("Doc" (("dd" lsp-describe-thing-at-point "Describe thing at point")) "Xref" (("xd" xref-find-definitions "Definitions") ("xo" xref-find-definitions-other-window "-> other win") ("xr" xref-find-references "References")) "LSP" (("lg" lsp-goto-implementation "Implementation") ("lf" lsp-format-buffer "Format buffer") ("ls" lsp-describe-session "Describe session")) "LSP modes" (("Tl" lsp-lens-mode "Lens mode" :toggle t) ("Td" lsp-modeline-diagnostics-mode "Modeline diagnostics" :toggle t) ("Tb" lsp-headerline-breadcrumb-mode "Header breadcrumb" :toggle t) ("Ti" lsp-toggle-trace-io "Trace I/O" :toggle lsp-print-io)) "Mix" (("me" mix-execute-task "Execute mix task") ("mt" mix-test "Run tests") ("mc" mix-compile "Compile") ("mm" jao-elixir-pop-to-iex "Pop to iex")) "Mix subproject" (("Me" (lambda () (interactive) (mix-execute-task nil t)) "Execute task") ("Mt" (lambda () (interactive) (mix-compile nil t)) "Compile") ("Mt" (lambda () (interactive) (mix-test nil t)) "Run tests")) "Tests" (("tt" exunit-verify-single "Run single test") ("tr" exunit-rerun "Re-run tests") ("ta" exunit-verify "Run test suites") ("tA" exunit-verify-all "Run all test suites")))) #+end_src * mpdel #+BEGIN_SRC emacs-lisp (jao-load-path "libmpdel") (jao-load-path "mpdel") (jao-load-path "navigel") (use-package navigel :init (setq navigel-display-messages nil)) (defun jao-mpdel-dup-dir-p (dir) (and (libmpdel-directory-p dir) (string-match-p "\\[.+\\]\\b" (or (libmpdel--directory-path dir) "")))) (defun jao-mpdel--filter (dirs) (cl-remove-if 'jao-mpdel-dup-dir-p dirs)) (use-package libmpdel :init (setq libmpdel-port 6669)) (use-package mpdel :diminish :init (setq mpdel-browser-list-clean-up-function 'identity mpdel-browser-top-level-entries '(directories empty-line stored-playlists current-playlist empty-line "Spotify/Top Lists/Top artists/Personal" "Spotify/Playlists/Featured" empty-line search-album search-artist search-title)) (defun jao-mpdel--show-osd (data song ml) (let* ((no (1+ (string-to-number (or (cdr (assq 'song data)) "0")))) (to (or (cdr (assq 'playlistlength data)) "0")) (album (or (libmpdel-album-name song) "")) (artist (or (libmpdel-artist-name song) "")) (tms (split-string (or (cdr (assq 'time data)) "0/0") ":")) (tm (format "%s/%s" (libmpdel-time-to-string (car tms)) (libmpdel-time-to-string (cadr tms)))) (title (format "%s %s/%s. %s" tm no to (or (libmpdel-entity-name song) "")))) (if ml (message "%s %s - %s (%s)" tm title artist album) (jao-notify (format "%s (%s)" artist album) title jao-notify-audio-icon)))) (defun jao-mpdel-show-osd (&optional ml) (interactive "P") (let ((song (libmpdel-current-song))) (when song (libmpdel-send-command "status" `(lambda (data) (jao-mpdel--show-osd data ,song ,ml)))))) (defun jao-mpdel-search (&optional type) (interactive (list (completing-read "Search by: " '("album" "artist" "title")))) (let* ((func (cond ((string= type "album") 'mpdel-core-search-by-album) ((string= type "artist") 'mpdel-core-search-by-artist) ((string= type "title") 'mpdel-core-search-by-title))) (thing (read-from-minibuffer (format "Search for %s: " type)))) (mpdel-core-open (libmpdel-search-criteria-create :type type :what thing))))) (use-package mpdel-browser) (defalias 'mpdel-pop-to-browser 'mpdel-browser-open) (mpdel-mode) (define-key mpdel-browser-mode-map (kbd "n") #'next-line) (define-key mpdel-browser-mode-map (kbd "p") #'previous-line) #+END_SRC * emms *** configuration #+BEGIN_SRC emacs-lisp (use-package emms :pin gnu :ensure t :init (setq emms-score-file "~/.emacs.d/score" emms-stream-bookmarks-file "~/.emacs.d/streams" emms-history-file "~/.emacs.d/cache/emms-history" emms-cache-file "~/.emacs.d/cache/emms-cache" emms-show-format "%s") (setq emms-source-file-default-directory "~/var/lib/music/" emms-player-list '(emms-player-mpd) emms-player-mpd-server-name "localhost" emms-player-mpd-server-port "6600" emms-player-mpd-music-directory emms-source-file-default-directory) (setq emms-volume-change-function 'emms-volume-mpd-change emms-volume-change-amount 10 emms-info-ogginfo-coding-system 'utf-8) ;; from http://www.shellarchive.co.uk/index.html#%20Prettify%20emms (setq emms-browser-info-genre-format "%i· %n" emms-browser-info-artist-format "%i· %n" emms-browser-info-album-format "%i◨ %n" emms-browser-info-title-format "%i♪ %n") (setq emms-last-played-format-alist '(((emms-last-played-seconds-today) . "Today at %H:%M") (604800 . "%a at %H:%M") ((emms-last-played-seconds-month) . "%d") ((emms-last-played-seconds-year) . "%m-%d") (t . ""))) :hook ((emms-player-started . emms-player-mpd-show)) :config (eval-after-load "emms-info" '(add-to-list 'emms-info-functions 'emms-info-mpd))) (emms-all) (emms-mode-line -1) (emms-playing-time 1) (emms-playing-time-disable-display) (use-package jao-emms-random-album :after emms :commands (jao-emms-random-album-next) :init (setq jao-emms-random-album-notify-icon jao-notify-audio-icon)) (use-package jao-emms-info-track :after emms :init (setq jao-emms-show-icon jao-notify-audio-icon) :config (jao-emms-info-setup 50)) (use-package jao-emms-lyrics :after emms :init (setq jao-lyrics-info-function 'jao-emms-lyrics-track-data)) (defvar jao-emms-random-album-notify--pause-icon "/usr/share/icons/Tango/scalable/actions/media-playback-pause.svg") (defun jao-emms--show-status (s status) (jao-notify (format "%s%s%s" (cadr s) (cdr (assoc (car s) status)) (caddr s)) "emms" (if (string= "pause" (cdr (assoc "state" status))) jao-emms-random-album-notify--pause-icon jao-notify-audio-icon))) (defun jao-emms--osd-status (s &optional pref suff) (emms-player-mpd-get-status (list s (or pref "") (or suff "")) 'jao-emms--show-status)) #+END_SRC *** helper functions #+begin_src emacs-lisp (defun jao-emms-volume-delta (d) (funcall emms-volume-change-function d)) (defun jao-emms-show-volume () (jao-emms--osd-status "volume" "Volume " "%")) (defalias 'jao-emms-update-cache 'emms-player-mpd-update-all-reset-cache) (defun jao-emms-load-streams () (interactive) (emms-play-playlist (expand-file-name "~/var/lib/music/streams.list"))) (defun jao-emms-search () (interactive) (let ((by (completing-read "Search by: " '("artist" "composer" "performer" "title" "album" "names")))) (if (string= "names" by) (emms-browser-search-by-names) (emms-browser-search (list (intern (concat "info-" by))))))) (defun jao-emms-echo () (interactive) (emms-show) (jao-emms-update-echo-string) (emms-show)) #+end_src *** Media global aliases #+begin_src emacs-lisp (defalias 'jao-player-connect 'emms-player-mpd-connect) (defalias 'jao-player-toggle 'emms-pause) (defalias 'jao-player-next 'emms-next) (defalias 'jao-player-previous 'emms-previous) (defalias 'jao-player-stop 'emms-stop) (defalias 'jao-player-start 'emms-start) (defalias 'jao-player-seek-forward 'emms-seek-forward) (defalias 'jao-player-seek-backward 'emms-seek-backward) (defalias 'jao-player-play 'emms-start) (defalias 'jao-player-search 'jao-emms-search) (defalias 'jao-player-vol-delta 'jao-emms-volume-delta) (defalias 'jao-player-volume 'jao-emms-show-volume) (defalias 'jao-player-osd 'jao-emms-show-osd) (defalias 'jao-player-echo 'jao-emms-echo) (defalias 'jao-player-list 'emms-playlist-mode-go) (defalias 'jao-player-browse 'emms-browser) (defalias 'jao-player-random-album 'jao-emms-random-album-next) #+end_src * enwc #+BEGIN_SRC emacs-lisp (use-package enwc :ensure t :init (setq enwc-default-backend 'nm enwc-backend 'nm enwc-display-mode-line nil enwc-wired-device "enp3s0f0" enwc-wireless-device "wlp1s0")) #+END_SRC * frm #+begin_src emacs-lisp (use-package jao-frm :init (setq jao-frm-mail-command 'jao-open-gnus-frame)) (defun jao-frm--formatter (mbox n) (apply #'format "%s/%s: %s" `(,@(last (split-string mbox "/") 2) ,n))) (defun jao-frm--show () (interactive) (jao-frm-show-mail-numbers #'jao-frm--formatter)) (global-set-key [(f12)] 'jao-frm--show) (global-set-key [(f8)] 'jao-frm) #+end_src * mu4e #+begin_src emacs-lisp (jao-load-path "mu4e") (use-package mu4e :init (setq mu4e-attachment-dir (expand-file-name "~/var/download/attachments") mu4e-change-filenames-when-moving nil mu4e-completing-read-function 'completing-read mu4e-display-update-status-in-modeline nil mu4e-get-mail-command "run-mb.sh || [ $? -eq 1 ]" mu4e-headers-show-threads t mu4e-headers-sort-direction 'ascending mu4e-headers-visible-columns 100 mu4e-headers-visible-lines 12 mu4e-hide-index-messages t mu4e-index-cleanup t ;; don't do a full cleanup check mu4e-index-lazy-check t ;; don't consider up-to-date dirs mu4e-maildir "~/var/mail/" mu4e-split-view 'horizontal ;; 'vertical mu4e-update-interval 300 mu4e-use-fancy-chars nil mu4e-user-mail-address-list jao-mails mu4e-view-show-addresses t mu4e-view-show-images t mu4e-maildir-shortcuts '((:maildir "/jao/inbox" :key ?j) (:maildir "/bigml/inbox" :key ?b)) jao-mu4e-uninteresting-mail-query (concat "flag:unread AND NOT flag:trashed" " AND NOT (maildir:/bigml/inbox OR maildir:/bigml/bugs OR" " maildir:/bigml/support OR maildir:/jao/inbox)") jao-mu4e-interesting-mail-query (concat "flag:unread AND NOT flag:trashed" " AND (maildir:/bigml/inbox OR maildir:/bigml/bugs OR" " maildir:/bigml/support OR maildir:/jao/inbox)") mu4e-bookmarks `((:name "Inbox" :query ,jao-mu4e-interesting-mail-query :key ?i) (:name "Other messages" :query ,jao-mu4e-uninteresting-mail-query :key 117) (:name "Today's messages" :query "date:today..now" :key 116) (:name "Last 7 days" :query "date:7d..now" :hide-unread t :key 119) (:name "Messages with PDFs" :query "mime:application/pdf OR mime:x-application/pdf" :key 112))) :config (defun jao-mu4e--maildir (msg) (when msg (let ((md (mu4e-message-field msg :maildir))) (when (string-match "/\\([^/]+\\)/.*" md) (match-string 1 md))))) (defun jao-mu4e--refile-folder (msg) (let ((md (jao-mu4e--maildir msg))) (if (string= md "trove") "/trove/jao" (format "/trove/%" md)))) (setq mu4e-sent-folder #'jao-mu4e--refile-folder) (setq mu4e-drafts-folder "/trove/drafts") (setq mu4e-trash-folder "/trash") (setq mu4e-refile-folder 'jao-mu4e--refile-folder) (setq mu4e-contexts nil) (setq mu4e-view-show-images t) (when (fboundp 'imagemagick-register-types) (imagemagick-register-types)) (define-key mu4e-view-mode-map [remap mu4e-view-verify-msg-popup] 'epa-mail-verify) ;; View html message in browser (type aV) (add-to-list 'mu4e-view-actions '("ViewInBrowser" . mu4e-action-view-in-browser) t)) #+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 ("" . #'company-complete-common-or-cycle) ("TAB" . #'company-complete-common-or-cycle) ("C-h" . #'company-show-doc-buffer) ("M-." . #'company-show-location) :filter (or (not (derived-mode-p 'eshell-mode)) (company-explicit-action-p)) ("" . #'company-complete-selection) ("RET" . #'company-complete-selection)) :diminish) (global-company-mode 1) #+end_src * notmuch-addr #+begin_src emacs-lisp (when (jao-load-path "notmuch-addr") (with-eval-after-load 'notmuch-address (jao-corfu-no-auto notmuch-message) (defun jao-notmuch-message-corfu-setup () (setq-local corfu-quit-no-match nil corfu-commit-predicate t orderless-component-separator " +")) (add-hook 'notmuch-message-mode-hook #'jao-notmuch-message-corfu-setup) (require 'notmuch-addr) (notmuch-addr-setup))) #+end_src * rcirc #+begin_src emacs-lisp :load no (use-package rcirc :init (setq rcirc-server-alist `(("irc.libera.chat" :encryption tls :port 6697 :channels ,jao-irc-channels)) rcirc-default-user-full-name "http://jao.io/" rcirc-buffer-maximum-lines 1000 rcirc-fill-column 82 rcirc-fill-prefix " " rcirc-time-format "%H:%M " rcirc-kill-channel-buffers t rcirc-response-formats '(("PRIVMSG" . "(%N) %m") ("NOTICE" . "-%N- %m") ("ACTION" . "(... %N %m)") ("COMMAND" . "%m") ("ERROR" . "%fw!!! %m") (t . "%fp*** %fs%n %r %m")) rcirc-prompt ": " rcirc-nick-completion-format "%s, " rcirc-reconnect-delay 120 rcirc-omit-responses '("JOIN" "PART" "QUIT" "NICK" "AWAY" "MODE" "KEEPALIVE")) :config (let ((fn (jao--get-user/password "libera")) (btl (jao--get-user/password "bitlbee"))) (setq rcirc-authinfo `(("libera" nickserv ,(nth 0 fn) ,(nth 1 fn)) ("localhost" bitlbee ,(nth 0 btl) ,(nth 1 btl))))) (jao-shorten-modes 'rcirc-mode) (define-minor-mode ncm-mode "" nil (:eval (format " [%S]" (length (rcirc-channel-nicks (rcirc-buffer-process) rcirc-target))))) (defun jao-rcirc-track () (dolist (b rcirc-activity) (tracking-add-buffer b)) (jao-minibuffer-refresh)) (add-hook 'rcirc-update-activity-string-hook #'jao-rcirc-track) (add-hook 'rcirc-mode-hook #'ncm-mode) (add-hook 'rcirc-mode-hook #'rcirc-omit-mode) :diminish ((rcirc-omit-mode . ""))) #+end_src * ace-window #+begin_src emacs-lisp (defun jao-ace-switch-buffer-other-window () (interactive) (aw-select "Other window" (if (eq jao-completion-engine 'consult) (lambda (w) (aw-switch-to-window w) (call-interactively 'consult-buffer)) #'aw-switch-buffer-in-window))) (defun jao-ace-find-file-other-window () (interactive) (aw-select "Other window" (lambda (w) (let ((df default-directory)) (aw-switch-to-window w) (let ((default-directory df)) (call-interactively 'find-file)))))) (global-set-key (kbd "C-x 4 f") #'jao-ace-find-file-other-window) (global-set-key (kbd "C-x 4 b") #'jao-ace-switch-buffer-other-window) #+end_src * switch window An alternative for this one is ace-window, but it has the problem of not displaying its overlay over org buffers (sometimes) and introducing a dependency (avy). #+begin_src emacs-lisp (use-package switch-window :ensure t :custom ((switch-window-minibuffer-shortcut ?z) (switch-window-background t) (switch-window-shortcut-style 'qwerty) (switch-window-shortcut-appearance 'text) (switch-window-timeout 7) (switch-window-threshold 2)) :init (defalias 'jao-other-window 'switch-window) :config (defun jao-switch-window--then (prompt cmd) (let ((f `(lambda () (let ((default-directory ,default-directory)) (call-interactively ',cmd))))) (switch-window--then prompt f f))) (defun jao-switch-window-then-dired () (interactive) (jao-switch-window--then "Find directory" 'dired)) (defun jao-switch-window-then-find-file () (interactive) (jao-switch-window--then "Find file" 'find-file)) (defun jao-switch-window-then-consult-buffer () (interactive) (jao-switch-window--then "Switch to buffer" 'consult-buffer)) :bind (("M-o" . switch-window) ("M-O" . switch-window-then-swap-buffer) ("s-o" . switch-window) ("s-O" . switch-window-then-swap-buffer) ("C-x 4 d" . jao-switch-window-then-dired) ("C-x 4 f" . jao-switch-window-then-find-file) ("C-x 4 b" . jao-switch-window-then-consult-buffer))) #+end_src * vterm *** vterm-toggle #+begin_src emacs-lisp :tangle no (use-package vterm-toggle :ensure t :config (defun jao-vterm--toggle (cd) (interactive "P") (if cd (vterm-toggle-cd) (vterm-toggle))) :bind (("C-" . jao-vterm--toggle))) #+end_src *** Vterm repls #+begin_src emacs-lisp (use-package jao-vterm-repl) (jao-define-attached-buffer "^\\* vrepl - .+ \\*.*") #+end_src * eshell here #+begin_src emacs-lisp (use-package eshell-toggle :ensure t :demand t :custom ((eshell-toggle-use-git-root t))) (defun jao-eshell-toggle (current) (interactive "P") (when (eq eshell-toggle--toggle-buffer-p t) (eshell-save-some-history) (eshell-autojump-save)) (let ((eshell-toggle-use-git-root (not current))) (eshell-toggle))) (global-set-key (kbd "") #'jao-eshell-toggle) #+end_src * scrolling #+begin_src emacs-lisp (use-package iscroll :ensure t :diminish) (with-eval-after-load "gnus-art" (add-hook 'gnus-article-mode-hook #'iscroll-mode)) (with-eval-after-load "eww" (add-hook 'eww-mode-hook #'iscroll-mode)) (with-eval-after-load "notmuch-show" (add-hook 'notmuch-show-mode #'iscroll-mode)) #+end_src * ednc #+begin_src emacs-lisp (use-package ednc :ensure t :diminish) (use-package jao-ednc :after ednc :commands (jao-ednc-setup) :config (jao-ednc-ignore-app "Spotify") (jao-ednc-ignore-app "NetworkManager") (defhydra jao-hydra-ednc (:color blue) "Notifications" ("s" jao-ednc-show "show last") ("d" jao-ednc-dismiss "dismiss last") ("D" jao-ednc-dismiss-all "dismiss all") ("i" jao-ednc-invoke-last-action "invoke last action") ("n" jao-ednc-pop "show all"))) #+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 * git helpers #+begin_src emacs-lisp (use-package github-review :ensure t :config (defun jao-gnus-github-review () (interactive) (gnus-summary-select-article-buffer) (goto-char (point-min)) (when (re-search-forward "https://github\.com/.*/pull/.*" nil t) (let ((url (match-string-no-properties 0))) (when (yes-or-no-p (format "Start review for %s" url)) (github-review-start url))))) (eval-after-load "gnus-art" '(progn (define-key gnus-summary-mode-map "\C-cG" 'jao-gnus-github-review) (define-key gnus-article-mode-map "\C-cG" 'jao-gnus-github-review))) (jao-transient-major-mode github-review ["Review" ("a" "Approve" github-review-approve) ("r" "Reject" github-review-reject) ("c" "Comment" github-review-reject)] ["Quit" ("Q" "Bury buffer" bury-buffer) ("k" "Kill buffer" kill-buffer)])) #+end_src * cape #+begin_src emacs-lisp (use-package cape :ensure t ;; Bind dedicated completion commands :bind (("C-c p p" . completion-at-point) ;; capf ("C-c p t" . complete-tag) ;; etags ("C-c p d" . cape-dabbrev) ;; or dabbrev-completion ("M-/" . cape-dabbrev) ("C-c p f" . cape-file) ("C-c p k" . cape-keyword) ("C-c p s" . cape-symbol) ("C-c p a" . cape-abbrev) ("C-c p i" . cape-ispell) ("C-c p l" . cape-line) ("C-c p w" . cape-dict)) :init ;; Add `completion-at-point-functions', used by `completion-at-point'. (add-to-list 'completion-at-point-functions #'cape-file) ;; (add-to-list 'completion-at-point-functions #'cape-dabbrev) ;; (add-to-list 'completion-at-point-functions #'cape-keyword) ;;(add-to-list 'completion-at-point-functions #'cape-abbrev) ;;(add-to-list 'completion-at-point-functions #'cape-ispell) ;;(add-to-list 'completion-at-point-functions #'cape-dict) ;;(add-to-list 'completion-at-point-functions #'cape-symbol) ;;(add-to-list 'completion-at-point-functions #'cape-line) ) #+end_src * vertico #+begin_src emacs-lisp (use-package vertico :ensure t :init (setq vertico-count 10 vertico-cycle t vertico-resize t org-refile-use-outline-path t resize-mini-windows nil) (vertico-mode) :bind (:map vertico-map (("RET" . vertico-directory-enter) ("M-" . vertico-directory-delete-word) ("" . vertico-directory-delete-char)))) (use-package vertico-directory :after vertico) (use-package vertico-reverse :after vertico :init (vertico-reverse-mode)) (use-package vertico-repeat :after vertico :config (add-hook 'minibuffer-setup-hook #'vertico-repeat-save) :bind (("M-R" . vertico-repeat))) ;; (use-package vertico-buffer ;; :after vertico ;; :init ;; (setq vertico-buffer-display-action ;; '(display-buffer-at-bottom (window-height . ,(+ 3 vertico-count)))) ;; (vertico-buffer-mode -1)) #+end_src * window config persistence #+begin_src emacs-lisp (use-package bookmark-view :ensure t :bind (("C-c v" . bookmark-view) ("C-c B" . bookmark-set))) #+end_src * notmuch #+begin_src emacs-lisp (defun jao-notmuch--show-hidden-html () (when (save-excursion (goto-char (point-min)) (re-search-forward "^\\[ text/html (hidden) \\]" nil t)) (jao-notmuch--toggle-mime))) (defun jao-notmuch-show-prefer-html () (add-hook 'notmuch-show-hook #'jao-notmuch--show-hidden-html)) #+end_src