mirror of
https://github.com/pestctrl/emacs-config.git
synced 2026-02-16 16:24:18 +00:00
30 KiB
30 KiB
- Various tools
- pdf-tools use isearch
- freezing time
- Programming stuff
- colorful compilation buffer
- Various common files
- New
- transpose-frame
- e2wm
- Youtube-dl
- set-default-directory
- World time include Taiwan
- auto-save files in same directory
- Scroll interval
- Setup convenient headers
- Profiler Keymap
- Open dev workspace
- Helpful view-mode
- man select window
- find-file-view
- rmsbolt
- ivy-posframe
- Elfeed
- pavucontrol switch speakers headphones
Various tools
ledger
(use-package ledger-mode
:mode "\\.dat\\'"
:config
(defconst new-report-str (concat "%(binary) -f %(ledger-file) --cleared-format "
"'%(justify(scrub(get_at(display_total, 0)), 16, 16 + int(prepend_width), true, color))"
" %(justify(scrub(get_at(display_total, 1)), 18, 36 + int(prepend_width), true, color))"
" %(justify(scrub(get_at(display_total, 0) - get_at(display_total, 1)), 18, 36 + int(prepend_width), true, color))"
" %(latest_cleared ? format_date(latest_cleared) : \" \")"
" %(!options.flat ? depth_spacer : \"\")%-(ansify_if(partial_account(options.flat), blue if color))\\n"
"%/%$1 %$2 %$3 %$4\\n"
"%/%(prepend_width ? \" \" * int(prepend_width) : \"\")---------------- ---------------- ---------------- ---------\\n'"
" cleared"))
(setq ledger-reports
`(("account" "%(binary) -f %(ledger-file) reg %(account)")
("bal" "%(binary) -f %(ledger-file) bal")
("reg" "%(binary) -f %(ledger-file) reg")
("equity" "%(binary) -f %(ledger-file) bal ^Exp ^RE ^Rev")
("cleared" ,new-report-str)
("last-superfluous" "%(binary) -f %(ledger-file) bal --limit='account =~ /^Exp:(Food|Luxury|NewTech|People)/ && date >= [last month]'")
("superfluous" "%(binary) -f %(ledger-file) reg --limit='account =~ /^Exp:(Food|Luxury|NewTech|People)/'")
("recurring" "%(binary) -f %(ledger-file) reg --limit='has_tag(\"RECURRING\")'")
("expmonth" "%(binary) -f %(ledger-file) -M reg Expenses")
("owedmom" "%(binary) -f %(ledger-file) reg Liabilities")
("progress" "%(binary) -f %(ledger-file) reg Assets Equity Liabilities")
("payee" "%(binary) -f %(ledger-file) reg @%(payee)")))
(setq dynamic-reports
'(("budgetcal" "%(binary) -f ~/MEGA/org/entries/food.ledger --daily --add-budget reg Expenses")))
(defun ledger-dynamic-report ()
(interactive)
(let* ((ledger-reports dynamic-reports)
(report-name (ledger-report-read-name)))
(ledger-report report-name nil)))
(setq ledger-reconcile-buffer-line-format
"%(date)s %-4(code)s %-30(payee)s %-30(account)s %15(amount)s\n")
(defun ledger-account-check-dont-include-regexp (orig account)
(when (= (aref account 0)
?^)
(setq account
(substring account 1))))
(defun ledger-report-show-monthly-average ()
(interactive)
(let ((average-string "-A -M -n"))
(unless (string-match-p average-string ledger-report-cmd)
(setq ledger-report-cmd
(concat ledger-report-cmd " " average-string))
(ledger-report-redo))))
(setq ledger-amount-regexp
(concat "\\( \\|\t\\| \t\\)[ \t]*-?"
"\\(?:" "?-" ledger-commodity-regexp " *\\)?"
;; We either match just a number after the commodity with no
;; decimal or thousand separators or a number with thousand
;; separators. If we have a decimal part starting with `,'
;; or `.', because the match is non-greedy, it must leave at
;; least one of those symbols for the following capture
;; group, which then finishes the decimal part.
"\\(-?\\(?:[0-9]+\\|[0-9,.]+?\\)\\)"
"\\([,.][0-9)]+\\)?"
"\\(?: *" ledger-commodity-regexp "\\)?"
"\\([ \t]*[@={]@?[^\n;]+?\\)?"
"\\([ \t]+;.+?\\|[ \t]*\\)?$"))
(define-key ledger-report-mode-map (kbd "M") #'ledger-report-show-monthly-average))
Credit Card Statement Macro
(fset 'credit_card_statement
[?\M-x ?o ?r ?g ?- ?m ?o ?d ?e return ?\M-x ?q backspace ?r ?e ?p ?l ?a ?c ?e ?- ?r ?e ?g ?e ?x ?p return ?^ ?\C-q tab return ? ? ? ? return ?\M-< ?\C- ?\C-f ?\C-f ?\C-f ?\C-f ?\C-c ?m ?a ?\C-w ?- ? ?\[ ? ?\] ? ?\C-e ?\C-k ?\C-c ?m ? ?\C-q tab ?\C-q tab ?\C-e ?\C-j ?y ?\C-a ?_ ?_ ?_ ?_ backspace backspace backspace backspace ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?= ?\C-p ?\C-p ?\C-k ?\C-c ?m ? ?\C-q tab ?\C-q tab ?\C-d ?\C-d return ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n ?\C-n])
encryption
(require 'epa-file)
(epa-file-enable)
(setq epa-pinentry-mode 'loopback)
(setq epa-file-cache-passphrase-for-symmetric-encryption t)
(setenv "GPG_AGENT_INFO" nil)
(setq epg-gpg-program "gpg2")
(setq auth-source-debug t)
(setq auth-sources '((:source "~/.emacs.d/secrets/.authinfo.gpg")))
(setq user-mail-address "bensonchu457@gmail.com"
user-full-name "Benson Chu")
(setq smtpmail-smtp-server "smtp.gmail.com"
smtpmail-smtp-service 587
send-mail-function 'smtpmail-send-it
message-send-mail-function 'smtpmail-send-it)
(mailcap-add "text/html" "/usr/bin/xdg-open %s ")
(setq mail-specify-envelope-from t
message-sendmail-envelope-from 'header
mail-envelope-from 'header)
(use-package notmuch
:commands notmuch
:bind (:map notmuch-message-mode-map
("C-c C-c" . #'my/choose-email-address-and-send)
:map notmuch-search-mode-map
("z" . #'notmuch-search-tree-current-thread)
("<mouse-1>" . nil)
:map notmuch-tree-mode-map
("<tab>" . #'notmuch-tree-explore-here)
("<down>" . #'notmuch-tree-next-message)
("<up>" . #'notmuch-tree-prev-message)
("d" . #'my/notmuch-delete-mail)
("U" . #'notmuch-tree-unfold-all)
("u" . #'notmuch-tree-up-thread)
("N" . #'notmuch-tree-next-sibling)
("P" . #'notmuch-tree-prev-sibling)
("t" . #'notmuch-tree-toggle-folding-thread)
("F" . #'notmuch-tree-focus)
("S-SPC" . #'notmuch-tree-scroll-message-window-back))
:config
(require 'notmuch-nav)
(require 'notmuch-tree-hide)
(require 'notmuch-tree)
(require 'notmuch-fold)
(custom-set-faces
'(notmuch-tree-match-tree-face ((t (:family "DejaVu Sans Mono"))) t)
'(notmuch-tree-no-match-tree-face ((t (:family "DejaVu Sans Mono"))) t))
(set-face-attribute 'notmuch-search-unread-face nil :foreground "white")
(set-face-attribute 'notmuch-message-summary-face nil :background "steel blue" :foreground "snow")
(add-to-list 'notmuch-search-line-faces
'("deleted" . font-lock-comment-face))
(defun notmuch-search-tree-current-thread (arg)
(interactive "P")
(setq notmuch-tree-show-filter-function (unless arg #'notmuch-tree-hide-dead-trees))
(let* ((thread-id (notmuch-search-find-thread-id))
(input (notmuch-read-query (concat "Notmuch tree: " thread-id " and "))))
(notmuch-tree thread-id (unless (zerop (length input)) input))))
(defun notmuch-tree-focus (arg)
(interactive "P")
(setq notmuch-tree-show-filter-function (if (not arg) #'notmuch-tree-hide-dead-trees #'notmuch-tree-show-trail-and-alive-children))
(notmuch-tree notmuch-tree-basic-query (notmuch-tree-get-message-id)))
(setq notmuch-search-oldest-first nil
notmuch-saved-searches
'((:name "inbox" :query "tag:inbox" :key "i")
(:name "inbox today" :query "date:2020-07-25.. and tag:inbox" :key "t")
(:name "work" :query "tag:work" :key "w")
(:name "mailing lists" :query "tag:mlist" :key "m")
(:name "emacs-devel" :query "tag:emacs-devel and date:30d.." :key "e")
(:name "emacs bugs" :query "tag:bug-gnu-emacs and date:30d.." :key "E")
(:name "emacs help" :query "tag:help-gnu-emacs and date:30d.." :key "h")
(:name "org-mode" :query "tag:org-mode" :key "o")
(:name "recruiting" :query "tag:recruiting" :key "r")
(:name "unread" :query "tag:unread" :key "u")
(:name "flagged" :query "tag:flagged" :key "f")
(:name "cs" :query "tag:cs" :key "c")
(:name "receipts" :query "tag:receipts" :key "R")
;; (:name "sent" :query "tag:sent" :key "s")
;; (:name "drafts" :query "tag:draft" :key "d")
(:name "all mail" :query "*" :key "a")))
(defun my/choose-email-address-and-send ()
(interactive)
(let ((resp (completing-read "Which email? " '("bchu3@cougarnet.uh.edu" "bensonchu457@gmail.com") nil t "^")))
(setq smtpmail-smtp-server
(if (string= resp "bensonchu457@gmail.com")
"smtp.gmail.com"
"smtp.office365.com"))
(notmuch-mua-send-and-exit)))
(add-to-list 'notmuch-tagging-keys
'("R" ("-inbox" "+recruiting") "Recruiting"))
(setf (cdr (assoc "d" notmuch-tagging-keys))
'(("+deleted") "Delete"))
(advice-add #'notmuch-tag-jump :after #'(lambda (&rest args) (next-line))))
(use-package exwm
:config
(defvar offlineimap-timer nil)
(defvar offlineimap-process nil)
(defun run-offlineimap ()
(interactive)
(if (and (processp offlineimap-process)
(process-live-p offlineimap-process))
(message "offlineimap already running...")
(message "offlineimap starting...")
(when (and (timerp offlineimap-timer)
(not (timer--triggered offlineimap-timer)))
(cancel-timer offlineimap-timer))
(set-process-sentinel
(setq offlineimap-process
(start-process-shell-command "offlineimap" "*offlineimap-output*" "offlineimap"))
#'(lambda (process event)
(when (string-match-p "exited abnormally with code 1" event)
(with-current-buffer (process-buffer offlineimap-process)
(when (string-match-p "get_password_emacs"(buffer-string))
(erase-buffer)
(message "Oops, didn't grab a password. ")
(setq offlineimap-timer (run-with-timer 300 nil #'run-offlineimap)))))
(when (string-match-p "^finished" event)
(message "Offlineimap finished")
(setq offlineimap-timer (run-with-timer 300 nil #'run-offlineimap)))))))
(defun stop-offlineimap ()
(interactive)
(when (timerp offlineimap-timer)
(cancel-timer offlineimap-timer))
(when (processp offlineimap-process)
(set-process-sentinel offlineimap-process
nil)))
(add-to-list 'exwm-init-hook
#'run-offlineimap
t))
erc
(use-package erc)
(use-package erc-hl-nicks)
(use-package erc-colorize)
(require 'netrc)
(erc-hl-nicks-mode)
(erc-colorize-mode)
(setq erc-user-full-name "Benson Chu")
(setq erc-kill-buffer-on-part t)
(setq erc-autojoin-channels-alist
'(("freenode.net" "#emacs" "#org-mode"
;; "##linux" "#compilers" "#pltclub"
;; "##cs" "##computerscience" "##programming" "#lisp" "##lisp"
;; "#sbcl" "#ecl"
)))
(defun get-authinfo (host port)
(let* ((netrc (netrc-parse (expand-file-name "~/.emacs.d/secrets/.authinfo.gpg")))
(hostentry (netrc-machine netrc host port)))
(when hostentry (netrc-get hostentry "password"))))
(defun freenode-connect (nick password)
(erc :server "irc.freenode.net" :port 6667
:password password :nick nick))
(defun irc-connect ()
(interactive)
(when (y-or-n-p "Connect to IRC? ")
(freenode-connect "pest-ctrl" (get-authinfo "irc.freenode.net" "6667"))))
pdf-tools use isearch
(when (not (eq system-type 'windows-nt))
(use-package pdf-tools)
(pdf-tools-install)
(define-key pdf-view-mode-map (kbd "C-s") 'isearch-forward)
(define-key pdf-view-mode-map (kbd "d") (lambda () (interactive) (pdf-view-next-line-or-next-page 8)))
(define-key pdf-view-mode-map (kbd "u") (lambda () (interactive) (pdf-view-previous-line-or-previous-page 8))))
freezing time
(defvar my/frozen-time nil)
(defvar my/format-time-string-function nil)
(defun my/org-today ()
(time-to-days my/frozen-time))
(defun my/current-time ()
my/frozen-time)
(defun my/format-time-string (original format-string &optional time zone)
(apply original
format-string
(if time
time
my/frozen-time)
zone))
(defun my/decode-time (original &optional time zone)
(apply original
(if time
time
my/frozen-time)
zone))
;; Change and freeze time
(defun za-warudo ()
"Freeze `current-time' at the current active or inactive timestamp. If point
is not on a timestamp, the function prompts for one. If time is not specified,
either by the timstamp under point or prompt, the time defaults to the
current HH:MM of today at the selected date."
(interactive)
(let* ((org-read-date-prefer-future nil)
(time (org-read-date t 'totime nil "Input freeze time: ")))
(setq my/frozen-time (append time '(0 0)))
(advice-add #'current-time :override #'my/current-time)
(advice-add #'format-time-string :around #'my/format-time-string)
(advice-add #'decode-time :around #'my/decode-time)
(advice-add #'org-today :override #'my/org-today)
(set-face-background 'fringe "firebrick2")
(message "Toki yo tomare")))
(define-key *root-map* (kbd "C-z") 'za-warudo)
;; Release changed / frozen time
(defun un-za-warudo ()
"Release the time frozen by `freeze-time'."
(interactive)
(advice-remove #'current-time #'my/current-time)
(advice-remove #'format-time-string #'my/format-time-string)
(advice-remove #'decode-time #'my/decode-time)
(advice-remove #'org-today #'my/org-today)
(setq my/frozen-time nil)
(set-face-background 'fringe nil)
(message "Soshite, toki wa ugoki dasu"))
(define-key *root-map* (kbd "C-r") 'un-za-warudo)
Programming stuff
lsp
(use-package lsp-mode
:commands lsp)
(use-package lsp-ui
:after lsp-mode
:bind (:map lsp-mode-map
("M-." . #'lsp-ui-peek-find-definitions)
("M-?" . #'lsp-ui-peek-find-references)
("M-p" . #'lsp-ui-peek-jump-forward))
:hook (lsp-mode . lsp-ui-mode)
:config
(setq lsp-ui-flycheck-enable t)
(setq lsp-ui-flycheck-live-reporting t))
(use-package dap-mode
:hook ((java-mode . dap-mode)
(java-mode . dap-ui-mode))
:bind (:map dap-mode-map
("C-c h" . #'dap-hydra)
("C-c b" . #'dap-breakpoint-toggle)
("C-c d r" . #'dap-java-debug)
("C-c d m" . #'dap-java-debug-test-class)
("C-c r t" . #'mvn-test)))
c++
(use-package ccls
:hook
((c-mode c++-mode objc-mode) .
(lambda () (let ((project-root (projectile-project-p)))
(when (and project-root
(file-readable-p (concat project-root "/compile_commands.json")))
(require 'ccls) (lsp)))))
:config
(setq ccls-sem-highlight-method 'font-lock-mode)
(when-let (l (getenv "https_proxy"))
(when (and (string-match-p "ti\.com" l)
(not (memq window-system '(mac ns))))
(setq ccls-executable "/db/sds/packages2/ccls/ccls"))))
Projectile
(use-package projectile
:defer 5
:bind-keymap ("C-c C-." . projectile-command-map)
:init (progn
(setq projectile-enable-caching nil)
(setq projectile-git-submodule-command nil)
(setq projectile-completion-system 'ivy)
;; (setq counsel-projectile-switch-project-action 'projectile-vc)
(setq projectile-switch-project-action 'projectile-dired)
(setq projectile-require-project-root t))
:config
(projectile-mode)
;; Provide my own projectile-compile-project which uses
;; cca/projectile-compilation-dir instead of projectile-compilation-dir.
(defvar cca/projectile-compilation-hash (make-hash-table :test 'equal)
"Has of project roots to compilation directories")
(defun cca/projectile-get-compilation-dir (key_dir)
"Get the compilation directory associated with the specified root directory"
(gethash key_dir cca/projectile-compilation-hash))
(defun cca/projectile-set-compilation-dir (key_dir value)
"Set the compilation directory for the specified root directory"
(puthash key_dir value cca/projectile-compilation-hash))
(defun cca/projectile-compilation-dir()
"Prompts the user for a directory relative to the project root
and returns the absolute path. It also stores the relative path
from the current project root into projectile-compilation-dir."
(let* ((root (projectile-project-root))
(base-compilation-dir (or (cca/projectile-get-compilation-dir root) root))
(full-compilation-dir (expand-file-name
(read-directory-name "Build directory: " base-compilation-dir))))
(setq projectile-project-compilation-dir (file-relative-name full-compilation-dir root))
(cca/projectile-set-compilation-dir root full-compilation-dir)))
(defun projectile-compile-project (arg)
"Run project compilation command.
Normally you'll be prompted for a compilation command, unless
variable `compilation-read-command'. You can force the prompt
with a prefix ARG."
(interactive "P")
(let ((command (projectile-compilation-command (cca/projectile-compilation-dir))))
(projectile--run-project-cmd command projectile-compilation-cmd-map
:show-prompt arg
:prompt-prefix "Compile command: "
:save-buffers t))))
Slime mode
(use-package slime
:commands slime slime-switch-lisps
:hook ((inferior-lisp-mode . inferior-slime-mode))
:config
(setq inferior-lisp-program "/usr/bin/sbcl")
(defun slime-switch-lisps (lisp)
(interactive (list (completing-read "Which lisp? "
'("sbcl" "ecl" "cmucl" "clozure-cl"))))
(setq inferior-lisp-program lisp))
(let ((clhs-file "~/quicklisp/clhs-use-local.el"))
(if (file-exists-p clhs-file)
(load-file clhs-file)
(warn "clhs not installed. Please install"))))
(use-package slime-company
:after slime company
:config
(slime-setup '(slime-fancy slime-asdf slime-company)))
rust
(use-package cargo)
(use-package rust-mode)
(use-package rustic)
golang
(use-package go-mode
:hook (go-mode . (lambda ()
(add-hook 'before-save-hook 'gofmt-before-save nil t)
(setq indent-tabs-mode nil)))
:config
;; This is for lsp to work
(add-to-list 'exec-path "~/go/bin/"))
python
(use-package elpy)
(elpy-enable)
(use-package ein)
(add-to-list 'exec-path
"/home/benson/anaconda3/bin/" t)
web stuff
(use-package web-mode
:commands web-mode
:init
(add-to-list 'auto-mode-alist '("\\.phtml\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.tpl\\.php\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.[agj]sp\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.as[cp]x\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.erb\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.mustache\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.djhtml\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.cshtml\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode))
:config
(setq web-mode-auto-close-style 2))
(use-package js2-mode
:commands js2-mode
:init
(add-to-list 'auto-mode-alist '("\\.js$" . js2-mode)))
colorful compilation buffer
(require 'ansi-color)
(defun colorize-compilation-buffer ()
(let ((buffer-read-only nil))
(ansi-color-apply-on-region (point-min) (point-max))))
(add-hook 'compilation-filter-hook 'colorize-compilation-buffer)
Various common files
(use-package csv-mode
:commands csv-mode
:init
(add-to-list 'auto-mode-alist
'("\\.csv$" . csv-mode)))
(use-package yaml-mode
:commands yaml-mode
:init
(add-to-list 'auto-mode-alist
'("\\.yaml$" . yaml-mode)
'("\\.yml$" . yaml-mode)))
New
transpose-frame
(use-package transpose-frame)
e2wm
(use-package e2wm
:bind (("M-+" . e2wm:start-management)))
Youtube-dl
(add-to-list 'load-path "~/.emacs.d/submodule/youtube-dl-emacs/")
(require 'youtube-dl)
(defun youtube-dl-song (url)
(interactive
(list (read-from-minibuffer
"URL: " (or (thing-at-point 'url)
(when interprogram-paste-function
(funcall interprogram-paste-function))))))
(async-shell-command (format "youtube-dl -x -f \"bestaudio[ext=m4a]\" \"%s\"; tageditor -s album=\"youtube-dl\" -f *.m4a" url)))
set-default-directory
(defun set-default-directory (dir)
(interactive "f")
(setq default-directory dir))
World time include Taiwan
(setq display-time-world-list
'(("America/Chicago" "Houston")
("Asia/Taipei" "Taiwan")))
auto-save files in same directory
(setq backup-directory-alist `(("." . "~/.emacs.d/backups/")))
(setq make-backup-files t ; backup of a file the first time it is saved.
backup-by-copying t ; don't clobber symlinks
version-control t ; version numbers for backup files
kept-old-versions 6 ; oldest versions to keep when a new numbered backup is made (default: 2)
kept-new-versions 9 ; newest versions to keep when a new numbered backup is made (default: 2)
auto-save-default t ; auto-save every buffer that visits a file
auto-save-timeout 20 ; number of seconds idle time before auto-save (default: 30)
auto-save-interval 200 ; number of keystrokes between auto-saves (default: 300)
)
Scroll interval
(setq scroll-margin 1
hscroll-margin 2
hscroll-step 1
scroll-conservatively 101
scroll-preserve-screen-position t
mouse-wheel-scroll-amount '(3)
mouse-wheel-progressive-speed nil)
Setup convenient headers
(setq auto-insert-alist
'(((emacs-lisp-mode . "Emacs lisp mode") nil
";;; " (file-name-nondirectory buffer-file-name) " --- " _ " -*- lexical-binding: t -*-\n\n"
";; Copyright (C) " (format-time-string "%Y") " Benson Chu\n\n"
";; Author: Benson Chu <bensonchu457@gmail.com>\n"
";; Created: " (format-time-string "[%Y-%m-%d %H:%M]") "\n\n"
";; This file is not part of GNU Emacs\n\n"
";; This program is free software: you can redistribute it and/or modify\n"
";; it under the terms of the GNU General Public License as published by\n"
";; the Free Software Foundation, either version 3 of the License, or\n"
";; (at your option) any later version.\n\n"
";; This program is distributed in the hope that it will be useful,\n"
";; but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
";; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
";; GNU General Public License for more details.\n\n"
";; You should have received a copy of the GNU General Public License\n"
";; along with this program. If not, see <https://www.gnu.org/licenses/>.\n\n"
";;; Commentary:\n\n"
";;; Code:\n\n"
"(provide '" (file-name-sans-extension (file-name-nondirectory buffer-file-name)) ")\n"
";;; " (file-name-nondirectory buffer-file-name) " ends here\n")
((lisp-mode . "Common Lisp") nil
"(defpackage :" (file-name-sans-extension (file-name-nondirectory buffer-file-name)) "\n"
" (:use :cl :alexandria)\n"
" (:export))\n\n"
"(in-package :" (file-name-sans-extension (file-name-nondirectory buffer-file-name)) ")")))
(auto-insert-mode)
Profiler Keymap
(define-prefix-command '*profiler-map*)
(define-key *profiler-map* (kbd "s") #'profiler-start)
(define-key *profiler-map* (kbd "r") #'profiler-report)
(define-key *profiler-map* (kbd "S") #'profiler-stop)
(define-key *root-map* (kbd "p") '*profiler-map*)
Open dev workspace
(defun open-dev-workspace ()
(interactive)
(dired "~/big_files/workspace"))
Helpful view-mode
(defun helpful--navigate-view-mode (orig button)
(let ((w (window-parameter (selected-window) 'quit-restore)))
(funcall orig button)
(view-mode)
(setq-local view-exit-action
`(lambda (&rest args)
(set-window-parameter (selected-window) 'quit-restore ',w)))))
(advice-add #'helpful--navigate
:around
#'helpful--navigate-view-mode)
man select window
(setq Man-notify-method 'aggressive)
find-file-view
(defun view-file ()
(interactive)
(call-interactively #'ido-find-file)
(view-mode))
(global-set-key (kbd "C-c C-v") #'view-file)
rmsbolt
(use-package rmsbolt)
ivy-posframe
(when (eq 'hash-table (type-of face-new-frame-defaults))
(use-package ivy-posframe)
;; (setq ivy-posframe-parameters '((parent-frame t)))
;; Different command can use different display function.
(setq ivy-posframe-display-functions-alist
'((swiper . ivy-posframe-display-at-frame-center)
(complete-symbol . ivy-posframe-display-at-point)
(iwc-switch-to-wc . nil)
(t . ivy-posframe-display-at-window-top-center)))
;; (ivy-posframe-mode 1)
(defun disable-ivy-posframe-on-exwm-windows (orig &rest args)
(if (not (eq major-mode 'exwm-mode))
(apply orig args)
(letf (((symbol-function 'display-graphic-p) (lambda (&optional display) nil)))
(apply orig args))))
;; (def-face-copier my/posframe-faces (sym)
;; (let ((name (symbol-name sym)))
;; (string-match-p "^ivy-.*"
;; name)))
(advice-add #'ivy-posframe--read
:around
#'disable-ivy-posframe-on-exwm-windows)
(defun ivy-posframe-display-at-window-top-center (str)
(ivy-posframe--display str #'posframe-poshandler-window-top-center))
(defun posframe-poshandler-window-top-center (info)
"Posframe's position handler.
Get a position which let posframe stay onto current window's
center. The structure of INFO can be found in docstring
of `posframe-show'."
(let* ((frame-width (plist-get info :parent-frame-width))
(window-left (plist-get info :parent-window-left))
(window-top (plist-get info :parent-window-top))
(window-width (plist-get info :parent-window-width))
(posframe-width (plist-get info :posframe-width)))
(cons (min (- frame-width posframe-width)
(+ window-left (max 0
(/ (- window-width posframe-width) 2))))
(+ window-top 50))))
(use-package ivy-rich)
(ivy-rich-mode 1)
;;(setq ivy-posframe-min-height 0)
;; (setq ivy-posframe-height 24)
;; (setq ivy-height-alist
;; '((t . 24)))
;; (setq ivy-posframe-height-alist
;; '((counsel-M-x . 8)
;; (t . 24)))
;; '((swiper . 24)))
)
Elfeed
(require 'elfeed)
(setq elfeed-use-curl t)
(elfeed-set-timeout 36000)
(setq elfeed-curl-extra-arguments '("--insecure"))
;; enable elfeed-protocol
(elfeed-protocol-enable)
pavucontrol switch speakers headphones
(defvar laptop-sink-index 0)
;; (let* ((result (shell-command-to-string "pacmd list-modules"))
;; (split (cdr (split-string result "index: "))))
;; split)
(let* ((result (shell-command-to-string "pactl list short sinks")))
(when (string-match "\\([0-9]\\).*analog-stereo" result)
(setq laptop-sink-index
(string-to-number
(match-string 1 result)))))
(defun current-speakers ()
(let ((string (shell-command-to-string "pactl list sinks | grep 'Active Port: '")))
(if (string-match-p "headphones" string)
'headphones
'speakers)))
(defun toggle-audio-output ()
(interactive)
(if (eq (current-speakers)
'headphones)
(shell-command (format "pactl set-sink-port %d analog-output-speaker"
laptop-sink-index))
(shell-command (format "pactl set-sink-port %d analog-output-headphones"
laptop-sink-index))))
(exwm-global-set-key (kbd "s-s") #'toggle-audio-output)