;;; -*- lexical-binding: nil -*- ;; package manager (require `package) (with-eval-after-load `package (add-to-list `package-archives `("melpa" . "https://melpa.org/packages/")) ;; (add-to-list `package-archives `("nongnu" . "https://elpa.nongnu.org/nongnu/")) ) (defun package-install-all () "Install all of my packages." (interactive) (mapc #'package-install `(ledger-mode transpose-frame dictionary paredit expand-region pinentry rainbow-delimiters clhs emms ebdb markdown-mode magit captain exwm go-translate plz jabber languagetool elpher pomodoro mentor olivetti sicp crdt varuga forth-mode nov osm debbugs))) (defun make-first-emacs-init () "Build ~/.emacs.d/ to accept this init.el ." (interactive) (shell-command "mkdir -p ~/.emacs.d/my-libs ~/.emacs.d/gnus/rss ~/log ~/torrents ~/Downloads ~/.certs/mail") (shell-command "touch ~/.emacs.d/my-libs/my-lisp.el ~/.emacs.d/my-libs/my-secret.el ~/.emacs.d/my-libs/my-select-methods.el ~/.emacs.d/gnus/rss/nnrss.el ~/.emacs.d/my-libs/my-common-system.el ~/.emacs.d/my-libs/my-erc-coins-system.el ~/.emacs.d/my-libs/my-weri.el ~/.emacs.d/my-libs/my-go-translate.el ~/.emacs.d/my-libs/profanity.el ~/.emacs.d/my-libs/my-exwm.el ~/.emacs.d/my-libs/my-contribs.el")) ;; Inline function for expanding file and directory names inside ;; `user-emacs-directory'. For example: (+emacs.d "gnus/") (defsubst +emacs.d (path) "Expand PATH relative to `user-emacs-directory'." (expand-file-name (convert-standard-filename path) user-emacs-directory)) ;; load-path (add-to-list `load-path (+emacs.d "my-libs")) (add-to-list `load-path "/usr/share/emacs/site-lisp" `t) ;; My auxiliary functions ;;; Macros (defmacro dointerval (spec &rest body) "A dotimes starting at MIN." (declare (indent 1) (debug dolist)) (let ((var (nth 0 spec)) (start (nth 1 spec)) (end (nth 2 spec)) (counter (make-symbol "counter"))) `(let ((,counter ,start)) (while (<= ,counter ,end) (let ((,var ,counter)) ,@body) (set ',counter (1+ ,counter)))))) ;;; ELisp Functions (defun american-number-string-to-number (string) (string-to-number (string-replace "," "" string))) (defun random-interval (min max) "Get a random number between [MIN; MAX[." (+ min (random (- max min)))) (defun current-line-empty-p () "Check if current line is an empty line." (save-excursion (beginning-of-line) (looking-at-p "^[[:blank:]]*$"))) ;; my pending contributions (load "my-contribs") ;; load my elisp standard stuff (load "my-lisp") ;; emacs-only related variables ;;; necessary mainly because of M-x man (setenv "LANG" "en_GB.utf8") ;;; emacs related functions (defun emacs-eval-init-file () (interactive) (let ((buf-name "init.el")) (unless (get-buffer buf-name) (find-file (+emacs.d "init.el")) (previous-buffer)) (set-buffer buf-name) (eval-buffer))) (keymap-global-set "C-c g e" `emacs-eval-init-file) (defun search-backward-non-portuguese-char () (interactive) (push-mark) (re-search-backward "[^[:ascii:]áàéíóúâêôãõ窺ÁÀÉÍÓÚÂÊÔÃÕÇ]" nil `t)) (defun my-char-name () (interactive) (when (search-backward-non-portuguese-char) (let* ((char (char-after (point))) (unicode-name (or (char-to-name char) "char is not unicode"))) (message "char name: %s" unicode-name)))) (keymap-global-set "C-c g n" `my-char-name) (defun my-forward-sentence (&optional arg) (interactive "^p") (or arg (set `arg 1)) (let ((sentence-end-double-space nil)) (forward-sentence arg))) (defun my-backward-sentence (&optional arg) (interactive "^p") (or arg (set `arg 1)) (let ((sentence-end-double-space nil)) (backward-sentence arg))) (keymap-global-set "M-e" `my-forward-sentence) (keymap-global-set "M-a" `my-backward-sentence) (defun my-move-beginning-of-line (arg) (interactive "^p") (or arg (set `arg 1)) (cond ((eql (point) (save-excursion (re-search-backward "^\\([[:blank:]]+\\)" nil `t) (match-end 1))) (move-beginning-of-line arg)) (`t (back-to-indentation)))) (keymap-global-set "C-a" `my-move-beginning-of-line) (defun my-split-window-below () (interactive) (split-window-below) (set-window-buffer (next-window) (other-buffer)) (other-window 1)) (keymap-global-set "C-x 2" `my-split-window-below) (defun my-split-window-right () (interactive) (split-window-right) (set-window-buffer (next-window) (other-buffer)) (other-window 1)) (keymap-global-set "C-x 3" `my-split-window-right) (defun list-buffers-all (&optional files-only) "Display a list of names of existing buffers. The list is displayed in a buffer named `*Buffer List*'. Non-null optional arg FILES-ONLY means mention only file buffers. For more information, see the function `buffer-menu'." (interactive "P") (display-buffer (list-buffers-noselect files-only (buffer-list)))) ;; (keymap-global-set "C-x C-b" `list-all-buffers) (defun list-all-functions () "Lisp all current functions" (interactive) (apropos-command "." nil) (other-window 1) (read-only-mode -1) (goto-char (point-min)) (kill-line 2) (flush-lines "^ " nil nil `t) (re-search-forward "^\\([[:alnum:]/\\+\\*\\?!@#\\$%&_=-]+\\).*$") (replace-match "\\1") ;; (replace-match "\\1") ;; (replace-regexp ;; "^\\([[:alnum:]/\\+\\*\\?!@#\\$%&_=-]+\\).*$" "\\1" nil ;; (use-region-beginning) (use-region-end) nil (use-region-noncontiguous-p)) (save-excursion (let ((sort-fold-case `t)) (sort-lines nil (point-min) (point-max)))) (read-only-mode 1)) (keymap-global-set "ESC M-." `xref-find-apropos) (keymap-global-set "C-h C-a" `apropos-function) (keymap-global-set "C-h M-a" `apropos-variable) (keymap-global-set "C-h M-i" `info-apropos) ;;;; emacs eww functions (eval-when-compile (require `eww)) (defun get-tab-name-current () "Get current tab name" (alist-get `name (tab-bar--current-tab))) ;;; my other functions (defun insert-command (cmd) "Insert output of CMD to current buffer." (interactive (list (read-string "Shell command (today): " nil nil "today"))) (insert (string-trim-right (shell-command-to-string cmd)))) (defun play-alarm (file) "Play a sound alarm FILE." (shell-command (concat "ffplay -v 0 -nodisp -volume 100 -autoexit " (expand-file-name file) " &>/dev/null"))) (defun quack () "Hear a duck's quack." (interactive) (play-alarm "~/.local/share/sound/duck-quack.mp3") (message "quack...")) (defun gnu () "Hear the gnu sound." (interactive) (play-alarm "~/.local/share/sound/im-a-gnu.ogg") (message "spelled G-N-U")) (defun coin () "Hear a coin drop." (interactive) (play-alarm "~/.local/share/sound/coin.mp3")) (defun plink () "Hear a retro game sound." (interactive) (play-alarm "~/.local/share/sound/game-retro-beep.mp3")) (defun bip () "Hear a cool beep sound." (interactive) (play-alarm "~/.local/share/sound/error-deepin.mp3")) (defun birds () "Hear singing birds sound." (interactive) (play-alarm "~/.local/share/sound/little-birds-in-tree.mp3")) (defun heart () "Hear a heart machine sound." (interactive) (play-alarm "~/.local/share/sound/beep-heart-machine.mp3")) (defun 3-quack-alarm () (let ((pre-volume (emms-volume-amixer-get))) (shell-command (concat "amixer -c " (number-to-string emms-volume-amixer-card) " sset \"" emms-volume-amixer-control "\" 100% " "&> /dev/null")) (dotimes (i 3) (quack) (sit-for 1)) (shell-command (concat "amixer -c " (number-to-string emms-volume-amixer-card) " sset \"" emms-volume-amixer-control "\" " (number-to-string pre-volume) "% " "&> /dev/null"))) (message "Quack alarm done.")) (defun gnu-song () "Play the gnu song." (interactive) (emms-play-file (expand-file-name "~/me/files/audio/free-software/flanders-and-swann--the-gnu-song.ogg")) (message "Here is another animal song...")) (defun rice-minutes (secs) "Rice alarm." (interactive "nMinutes for the rice cooking: ") (run-with-timer (* 60 secs) 0 `3-quack-alarm) (message "Rice alarm set.")) (defun years-old (year) (interactive "nBirth year: ") (message "%d" (- (nth 5 (decode-time)) year))) (defun password-prompt () "Open a prompt, in the minibuffer, for passwords. Good when using M-x shell." (interactive) (comint-send-invisible) (clear-this-command-keys)) (keymap-global-set "C-c g w" `password-prompt) (with-eval-after-load `eww (defun lesspass (site username counter length symbol-type) "Use lpcli on EWW." (interactive (list (read-string "Site: " (progn (string-match "https?://\\(.*\\)/+?" (eww-current-url)) (match-string 1 (plist-get eww-data :url)))) (read-string "Username: " (getenv "LESSPASS_USER")) (number-to-string (read-number "Counter: " 1)) (number-to-string (read-number "Length: " 16)) (read-string "Symbol's type: " "ulds"))) (insert (shell-command-to-string (concat "printf " (read-passwd "Password: ") " | lpcli " site " ${LESSPASS_USER} -p" symbol-type "c" counter "n" length " | grep -v -E 'Options:|Enter Password' | tr -dc '[:print:]'")))) (defalias `lp `lesspass)) (defun my-save-buffers-kill-emacs () "Save buffers and kill Emacs daemon." (interactive) (when (y-or-n-p "Do you want to kill Emacs client and Emacs daemon? ") (save-buffers-kill-emacs))) (keymap-global-set "C-x C-c" `my-save-buffers-kill-emacs) (keymap-global-set "C-x M-c" `save-buffers-kill-terminal) (defun my-package-upgrade-all () "Refresh package list and upgrade all packages." (interactive) (package-upgrade-all nil)) (keymap-global-set "C-c g u" `my-package-upgrade-all) ;; which-key (which-key-mode 1) ;; help with M-x ;; (icomplete-mode) ;; grep (set `grep-command "grep --color=auto -nHI --null -i -e ") (set `grep-find-command `("find . -type f -exec grep --color=auto -nHI --null -i -e \\{\\} +" . 54)) ;; compiling (set `compile-command "make -j $(nproc --all) ") (set `compilation-scroll-output `t) ;; escape sequences ;;; compile with colors (no raw escape sequences) (require `ansi-color) (add-hook `compilation-filter-hook `ansi-color-compilation-filter) ;;; fix raw escape sequences in shell (add-hook `shell-mode-hook `ansi-color-for-comint-mode-on) ;; emacs global keybindings (keymap-global-set "C-f" `forward-word) (keymap-global-set "C-b" `backward-word) (keymap-global-set "M-f" `forward-char) (keymap-global-set "M-b" `backward-char) (keymap-global-set "C-c b" `beginning-of-buffer) (keymap-global-set "C-c e" `end-of-buffer) (keymap-global-set "C-w" `backward-kill-word) (keymap-global-set "C-c k" `kill-region) (keymap-global-set "C-_" `undo-only) (keymap-global-set "C-c ;" `comment-region) (keymap-global-set "M-%" `query-replace-regexp) (keymap-global-set "C-M-%" `query-replace) (keymap-global-set "C-c %" `shrink-window) ;; emacs default mode's hook (setq-default major-mode `text-mode) ;; deleting trailing whitespace (defun my-delete-trailing-whitespace () (interactive) (cond ((or (null buffer-file-name) (string-suffix-p ".md" buffer-file-name) (string-suffix-p ".markdown" buffer-file-name) ) nil) (`t (delete-trailing-whitespace)))) (add-hook `before-save-hook `my-delete-trailing-whitespace) ;; some general emacs variable options (set `make-backup-files nil) ;;(set `gc-cons-treshold 20000000) (set `sentence-end-double-space `t) (set `fill-column 72) ;; (set `message-fill-column 75) ;; my set fill-column (defun set-fill-column () "Set 'fill-column' in local buffer." (interactive) (setq-local fill-column 82)) (add-hook `Info-mode-hook `set-fill-column) (add-hook `elpher-mode-hook `set-fill-column) ;; dired with integration to gnus ;;; my dired functions and keybindings (defun my-gnus-dired-print (&optional file-name print-to) "In Dired, print FILE-NAME according to the mailcap file. If there is no print command, print in a PostScript image. If the optional argument PRINT-TO is nil, send the image to the printer. If PRINT-TO is a string, save the PostScript image in a file with that name. If PRINT-TO is a number, prompt the user for the name of the file to save in." (interactive (list (file-name-sans-versions (dired-get-filename) t) (ps-print-preprint '(4))) dired-mode) (gnus-dired-print file-name print-to)) (with-eval-after-load `gnus-dired (keymap-set gnus-dired-mode-map "C-c RET C-p" `my-gnus-dired-print)) ;; (mode for, for example, attaching multiple files) (add-hook `dired-mode-hook `turn-on-gnus-dired-mode) ;; LISP ;;; lisp show matching paren when cursor is after closing paren (show-paren-mode) ;;; lisp electric pairing (set `electric-pair-inhibit-predicate `electric-pair-conservative-inhibit) (electric-pair-mode) ;;; lisp color parenthesis automatic (package rainbow-delimiters) (add-hook `lisp-mode-hook `rainbow-delimiters-mode) (add-hook `eldoc-mode-hook `rainbow-delimiters-mode) ;;; lisp with paredit (with-eval-after-load `paredit ;; (keymap-set paredit-mode-map "C-c M-q" `slime-close-all-parens-in-sexp) (keymap-set paredit-mode-map "ESC DEL" `paredit-kill-region) (keymap-set paredit-mode-map "C-c M-<" `paredit-forward-barf-sexp) (keymap-set paredit-mode-map "C-c M->" `paredit-forward-slurp-sexp) (keymap-set paredit-mode-map "C-c M-s" `paredit-splice-sexp-killing-backward) (keymap-set paredit-mode-map "C-j" `eval-print-last-sexp)) (add-hook `lisp-mode-hook `enable-paredit-mode) (add-hook `emacs-lisp-mode-hook `enable-paredit-mode) ;; Forth (set `forth-executable "4tsh") (defun run-ans-forth () "Start an interactive ANS Forth session." (interactive) (let ((forth-executable "gforth")) (run-forth))) ;; Lali (add-to-list `auto-mode-alist `("\\.lali\\'" . lisp-mode)) ;;; Common Lisp (set `inferior-lisp-program "sbcl") ;;; (load (expand-file-name "~/quicklisp/slime-helper.el")) ;;; (require `slime) ;;; (slime-setup) (set `clhs-root "file:///usr/share/doc/clhs/HyperSpec/") (with-eval-after-load `lisp-mode (keymap-set lisp-mode-map "C-h C-s" `clhs-doc)) ;; ;;; Kilo Lisp ;; (defun run-klisp () ;; "Run LISP Club Language REPL." ;; (interactive) ;; (cd "~/me/programming/desktop/lisp/interpreter/klisp/klisp.new/") ;; (if (not (comint-check-proc "*inferior-kilolisp*")) ;; (let ((cmdlist (split-string-shell-command "kl")) ;; (inferior-lisp-buffer "*inferior-kilolisp*")) ;; (set-buffer (apply (function make-comint) ;; "inferior-kilolisp" (car cmdlist) nil (cdr cmdlist))))) ;; (pop-to-buffer "*inferior-kilolisp*" display-comint-buffer-action)) ;;; Scheme (set `scheme-program-name "/usr/bin/guile") ;; (set `scheme-program-name "/usr/bin/mit-scheme") ;; (set `scheme-program-name "gsi -:t") ;; gambit ;; Elpher (set `elpher-start-page-url "about:bookmarks") (defun my-elpher () "New Elpher session." (interactive) (elpher t)) (keymap-global-set "C-c w e" `my-elpher) ;; EWW (set `browse-url-browser-function `eww-browse-url) (set `eww-download-directory (expand-file-name "~/Downloads")) (set `shr-discard-aria-hidden `t) (set `shr-max-width 179) ;; show eww using all of my screen width (set `webjump-sites `(("GNU Project FTP Archive" . [mirrors "https://ftp.gnu.org/pub/gnu/" "https://ftpmirror.gnu.org"]) ("GNU Project Website" . "www.gnu.org") ("Emacs Website" . "www.gnu.org/software/emacs/emacs.html") ("Savannah Emacs page" . "savannah.gnu.org/projects/emacs") ("Emacs Lisp List" . "www.damtp.cam.ac.uk/user/eglen/emacs/ell.html") ("Savannah" . [simple-query "git.savannah.gnu.org/cgit" "https://git.savannah.gnu.org/cgit/?q=" #1=""]) ("Emacs Wiki" . [simple-query "www.emacswiki.org" "https://www.emacswiki.org/cgi-bin/wiki/" #1=""]) ("DuckDuckGo" . [simple-query "duckduckgo.com" "https://duckduckgo.com/?q=" #1#]) ("SearXNG" . [simple-query "searx.direitosdigitais.pt" "https://searx.direitosdigitais.pt/search?q=" #1#]) ("Google Groups" . [simple-query "groups.google.com" "https://groups.google.com/groups?q=" #1#]) ("Yahoo" . [simple-query "www.yahoo.com" "https://search.yahoo.com/search?p=" #1#]) ("Yahoo: Reference" . "www.yahoo.com/Reference/") ("Qwant Lite" . [simple-query "lite.qwant.com" "https://lite.qwant.com/?q=" #1#]) ("Wayback Classic" . [simple-query "wayback-classic.net" "https://wayback-classic.net/cgi-bin/search.cgi?utf8=%E2%9C%93&q=" #1#]) ("Mojeek" . [simple-query "www.mojeek.com" "https://www.mojeek.com/search?q=" #1#]) ("Wiby" . [simple-query "wiby.me" "https://wiby.me/?q=" #1#]) ("Marginalia" . [simple-query "old-search.marginalia.nu" "https://old-search.marginalia.nu/search?recent=default&profile=corpo&searchTitle=default&adtech=default&js=default&query=" #1#]) ("Frogfind" . [simple-query "frogfind.com" "http://frogfind.com/?q=" #1#]) ("Google" . [simple-query "www.google.com" "http://www.google.com/search?q=" #1#]) ("Wikipedia" . [simple-query "wikipedia.org" "https://en.wikipedia.org/wiki/Special:Search?go=Go&search=" #1#]) ("Invidious" . [simple-query "inv.nadeko.net" "https://inv.nadeko.net/search?q=" #1#]) ;; ("National Weather Service" . webjump-to-iwin) ("Usenet FAQs" . "www.faqs.org/faqs/") ("RTFM Usenet FAQs by Group" . "ftp://rtfm.mit.edu/pub/usenet-by-group/") ("RTFM Usenet FAQs by Hierarchy" . "ftp://rtfm.mit.edu/pub/usenet-by-hierarchy/") ("X Consortium Archive" . "ftp.x.org") ("Association for Computing Machinery" . "www.acm.org") ("Computer Professionals for Social Responsibility" . "www.cpsr.org") ("Electronic Frontier Foundation" . "www.eff.org") ("IEEE Computer Society" . "www.computer.org") ("Risks Digest" . webjump-to-risks) ("Supplemental Web site list for webjump" . "www.neilvandyke.org/webjump/") ("!Bangs" . "https://duckduckgo.com/bang_lite.html") ("GnuPG Blog" . "https://gnupg.org/blog/") ("tilde.club Wiki" . "http://tilde.club/wiki/") ("keyboardan Gopher" . "gopher://tilde.club/1/~keyboardan/") ("keyboardan Phlog" . "gopher://tilde.club/1/~keyboardan/phlog/") ("keyboardan Web" . "http://tilde.club/~keyboardan/") ("keyboardan Files" . "http://tilde.club/~keyboardan/files/") ("keyboardan Blog" . "http://tilde.club/~keyboardan/blog/") ("keyboardan Gemini" . "gemini://tilde.club/~keyboardan/") ("keyboardan Gemlog" . "gemini://tilde.club/~keyboardan/gemlog/") ("Phlogroll" . "gopher://box.matto.nl/1/phlogroll/") ("Bongusta" . "gopher://i-logout.cz/1/bongusta/") ("Random Gopher Sites" . "gopher://gopher.viste.fr/1/ogup/rnd") ("Priberam" . [simple-query "dicionario.priberam.org" "https://dicionario.priberam.org/" #1#]) ("Chambers" . [simple-query "chambers.co.uk/search/" "https://chambers.co.uk/search/?title=21st&query=" #1#]) ("Xiph" . [simple-query "dir.xiph.org" "http://dir.xiph.org/search?q=" #1#]) ("Archwiki" . [simple-query "wiki.archlinux.org" "https://wiki.archlinux.org/index.php?search=" #1#]) ("Man" . [simple-query "man.archlinux.org" "https://man.archlinux.org/search?go=Go&q=" #1#]) ("Parabolawiki" . [simple-query "wiki.parabola.nu" "https://wiki.parabola.nu/index.php?search=" #1#]) ("AUR" . [simple-query "aur.archlinux.org" "https://aur.archlinux.org/packages?O=0&K=" #1#]) ("Archlinux Packages" . [simple-query "archlinux.org/packages/" "https://archlinux.org/packages/?q=" #1#]) ("Parabola Packages" . [simple-query "www.parabola.nu/packages/" "https://www.parabola.nu/packages/?q=" #1#]) ("Artix Packages" . [simple-query "gitea.artixlinux.org" "https://gitea.artixlinux.org/packages?language=&sort=recentupdate&q=" #1#]) ("PKGBUILD Arch" . [simple-query "archlinux.org/packages/" "https://gitlab.archlinux.org/archlinux/packaging/packages/" #1="/-/raw/main/PKGBUILD"]) ("PKGBUILD Artix" . [simple-query "archlinux.org/packages/" "https://gitea.artixlinux.org/packages/" #1="/raw/branch/master/PKGBUILD"]) ("PKGBUILD AUR" . [simple-query "aur.archlinux.org" "https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h=" #1=""]) ("RFC" . [simple-query "https://datatracker.ietf.org" "https://datatracker.ietf.org/doc/html/rfc" #1=""]))) (defun eww-offline (file-path) "View offline webpages." (interactive (list (expand-file-name (read-file-name "Offline Webpage: " (concat eww-offline-webpages-directory "/"))))) (eww (concat "file://" file-path))) (defun eww-urlopen () "Open last /tmp/url.txt link." (interactive) (eww (string-trim-right (shell-command-to-string "tail -n 1 /tmp/url.txt")))) (defun read-urlopen (text) "Append TEXT to /tmp/url.txt file." (interactive (list (read-string "Text: "))) (shell-command (concat "echo '" text "' >> /tmp/url.txt")) (message "%s" text)) (defun insert-urlopen () "Insert last /tmp/url.txt link to the current buffer." (interactive) (insert (string-trim-right (shell-command-to-string "tail -n 1 /tmp/url.txt")))) (defun my-eww (url &optional new-buffer buffer) "Fetch URL and render the page. If the input doesn't look like an URL or a domain name, the word(s) will be searched for via `eww-search-prefix'. If NEW-BUFFER is non-nil (interactively, the prefix arg), use a new buffer instead of reusing the default EWW buffer. If BUFFER, the data to be rendered is in that buffer. In that case, this function doesn't actually fetch URL. BUFFER will be killed after rendering. For more information, see Info node `(eww) Top'." (interactive (let ((uris (eww-suggested-uris)) (minibuffer-local-completion-map eww-minibuffer-url-keymap)) (list (completing-read (format-prompt "Enter URL or keywords" (and uris (car uris))) (seq-uniq (append eww-prompt-history uris)) nil nil nil `eww-prompt-history uris) current-prefix-arg))) (setq url (eww--dwim-expand-url url)) (eww-refresh-useragent) (eww url new-buffer buffer)) (defun my-webjump () "Jumps to a Web site from a programmable hotlist. See the documentation for the `webjump-sites' variable for how to customize the hotlist. Please submit bug reports and other feedback to the author, Neil W. Van Dyke ." (interactive) (eww-refresh-useragent) (webjump)) (keymap-global-set "C-c w w" `my-eww) (keymap-global-set "C-c w q" `my-webjump) (keymap-global-set "C-c w o" `eww-offline) (keymap-global-set "C-c w u" `eww-urlopen) ;; unicode ;; (set-selection-coding-system `utf-8) ;; ;;; (set `x-select-request-type `(UTF8_STRING COMPOUND_TEXT TEXT STRING)) ;; (set-language-environment "UTF-8") ;; prefer utf-8 for language settings ;; (prefer-coding-system `utf-8) ;; (set-default-coding-systems `utf-8) ;; (set `sendmail-coding-system `utf-8) ;; ispell (keymap-global-set "C-c s" nil) ;; create keymap prefix (keymap-global-set "C-c s i" `ispell-message) ;; languagetool (require `languagetool) (set `languagetool-java-arguments `("-Dfile.encoding=UTF-8" "-cp" "/usr/share/languagetool:/usr/share/java/languagetool/*")) (set `languagetool-console-command "org.languagetool.commandline.Main") (set `languagetool-console-arguments `("--languagemodel" "~/.local/share/languagetool/ngram/")) (set `languagetool-server-command "org.languagetool.server.HTTPServer") (defun languagetool () "Interactively check a region or buffer for spelling errors using languagetool" (interactive) (if (region-active-p) (languagetool-console-check (region-beginning) (region-end)) (languagetool-console-check (point-min) (point-max))) (languagetool-correct-buffer)) (keymap-global-set "C-c s l" `languagetool) (keymap-global-set "C-c s q" `languagetool-clear-suggestions) ;; switch command mode (require `ido) (ido-mode `t) ;;; use filename at point, if it looks like an filename (set `ido-use-filename-at-point `guess) ;;; use all windows on all existing frames (set `ido-all-frames `t) ;;; ido and tramp ;; (customize-set-variable `tramp-default-method "ssh") (set `ido-work-directory-list-ignore-regexps `("/-:" "/ssh:" "/ftp:" "/rsync:")) ;; winner-mode (set `winner-dont-bind-my-keys `t) (winner-mode 1) (keymap-global-set "C-c w " `winner-undo) (keymap-global-set "C-c w " `winner-redo) ;; windmove (keymap-global-set "C-c w p" `windmove-up) (keymap-global-set "C-c w b" `windmove-left) (keymap-global-set "C-c w n" `windmove-down) (keymap-global-set "C-c w f" `windmove-right) ;; C language ;;; identation for C ;; (setq-default indent-tabs-mode nil) (setq-default tab-width 3) (set `c-basic-offset 2) ;;; gdb gud (set `gdb-many-windows `t) ;; info (set `Info-hide-note-references `hide) ;; org mode (set `org-export-with-toc nil) ;; abbrev (set `abbrev-file-name (+emacs.d "abbrev_defs")) (set `save-abbrevs `silently) (add-hook `erc-mode-hook `abbrev-mode) (add-hook `jabber-chat-mode-hook `abbrev-mode) (defun abbrev-save () (interactive) (write-abbrev-file (+emacs.d "abbrev_defs")) (message "Abbreviations saved.")) (keymap-global-set "C-x a s" `abbrev-save) (keymap-global-set "C-x a DEL" `unexpand-abbrev) ;; ledger (set `ledger-default-commodity `EUR) ;; gnus ;;; load secret data (load "my-secret") ;;; gnus my levels (set `gnus-level-default-subscribed 4) (defun gnus-begin-core () "Read core news." (interactive) (gnus-no-server 1)) (defun gnus-begin-mail () "Read mail news." (interactive) (gnus-no-server 2)) (defun gnus-begin-netnews () "Read netnews news." (interactive) (gnus-no-server 3)) (defun gnus-begin-feed () "Read feed news." (interactive) (gnus-no-server 4)) (defun my-gnus-group-restart (prefix) "My Gnus restart." (interactive "p") (gnus-save-newsrc-file) (gnus-clear-system) (cond ((eql 1 prefix) (gnus-begin-core)) ((eql 4 prefix) (gnus-begin-mail)) ((eql 16 prefix) (gnus-begin-netnews)) (`t (gnus-begin-feed)))) (with-eval-after-load `gnus-group (keymap-set gnus-group-mode-map "R" `my-gnus-group-restart) (keymap-set gnus-group-mode-map "C-c c" `ebdb)) ;;; general message config (set `message-kill-buffer-on-exit `t) ;; C-c C-c kills the buffer (set `message-signature-separator "^-- *$") ;; loose signature separator ;;; use bottom-posting by default (NEEDS FIX: `below puts the point on the signature) (set `message-cite-reply-position `below) ;;; wide-reply prune addresses (set `message-prine-recipient-rules `(("^\\([^@]+\\)@\\(.*\\)" "\\1@.*[.]\\2"))) ;;; open gnus in topics mode (add-hook `gnus-group-mode-hook `gnus-topic-mode) ;;; lines with time (set `gnus-summary-line-format "%U%R%z%I %4L %(%[%-25,25D %-23,23f%]%) %s ") ;;; disable threads by default (set `gnus-show-threads nil) ;;; order threads by most recent date (set `gnus-thread-sort-functions `(gnus-thread-sort-by-number gnus-thread-sort-by-subject gnus-thread-sort-by-date)) ;;; order linear view by most recent date (set `gnus-article-sort-functions `(gnus-article-sort-by-number gnus-article-sort-by-subject gnus-article-sort-by-date)) ;;; show certain message headers (set `gnus-visible-headers "^From:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^Followup-To:\\|^Reply-To:\\|^Organization:\\|^Summary:\\|^Keywords:\\|^Distribution:\\|^To:\\|^[BGF]?C[Cc]:\\|^Posted-To:\\|^Mail-Copies-To:\\|^Mail-Followup-To:\\|^Apparently-To:\\|^Gnus-Warning:\\|^Resent-From:\\|^Archived-At:\\|^User-Agent:\\|^List-Unsubscribe:\\|^X.*-Spam.*:\\|^X-.*Complain.*:\\|^X-.*Abuse.*:\\|^OpenPGP:\\|^X.*-Key.*:\\|^X.*-PGP.*:\\|^Autocrypt:\\|^X-Payment:\\|^X-Hashcash:\\|^X-Mailer:") ;;; remove this headers before sending mails (set `message-ignored-mail-headers "^[GF]cc:\\|^Resent-Fcc:\\|^Xref:\\|^X-Draft-From:\\|^X-Gnus-Agent-Meta-Information:\\|^X-GDPR:") ;;; remove this headers before sending news (set `message-ignored-news-headers "^NNTP-Posting-Host:\\|^Xref:\\|^[BGF]cc:\\|^Resent-Fcc:\\|^X-Draft-From:\\|^X-Gnus-Agent-Meta-Information:\\|^X-Message-SMTP-Method:\\|^X-Gnus-Delayed:\\|^X-GDPR:") ;;; hide summary lines of articles that have scores lower than this (set `gnus-summary-expunge-below -9) ;;; save article in a file (set `gnus-default-article-saver `gnus-summary-save-in-file) ;; mark sent messages as read (set `gnus-gcc-mark-as-read `t) ;; confirm when sending (set `message-confirm-send `t) ;; forward message as mime (set `message-forward-as-mime `t) ;; unbind C-c C-s (with-eval-after-load `message (keymap-set message-mode-map "C-c C-s" nil)) (load "my-select-methods.el") ;;; delete bogus .newsrc groups at gnus startup ;; (set `gnus-check-bogus-newsgroups nil) ;;; don't check for new groups ;; (set `gnus-check-new-newsgroups nil) ;;; subscribe for new groups interactively (set `gnus-subscribe-newsgroup-method `gnus-subscribe-interactively) ;;; subscription method for newsgroups with "option -n" in .newsrc ;; (set `gnus-subscribe-options-newsgroup-method `gnus-subscribe-interactively) ;;; ignore subscribing to this groups (set `gnus-options-not-subscribe ".*\\(gmane\\|gwene\\)\\..*") ;;; mailing list (set `message-subscribed-address-file (expand-file-name "~/.mail.d/mailinglists-all")) ;; (set `message-subscribed-address-functions ;; `(gnus-find-subscribed-addresses)) ;; (set `gnus-group-name-charset-group-alist `((".*" . utf-8))) ;;; default headers adding (defun message-add-default-headers () (let ((res "")) (unless (mail-fetch-field "gcc") (set `res (concat res "Gcc: "))) res)) ;; (set `message-default-headers `message-add-default-headers) ;;; spam ;;;; hashcash (require `hashcash) (set `message-generate-hashcash `t) (set `hashcash-double-spend-database (expand-file-name (concat (getenv "XDG_DATA_HOME") "/hashcash/hashcash.sdb"))) ;; (set `hashcash-default-payment 30) (set `hashcash-default-payment 27) (defun message-toggle-hashcash () "Toggle hashcash. Return `message-generate-hashcash' value." (interactive) (set `message-generate-hashcash (not message-generate-hashcash)) (message "%s" message-generate-hashcash)) (defun hashcash-insert-payment-all-async () "Insert 'X-Hashcash:' for all recipients." (interactive) (message "Generating hashcash...") ;; Wait for calculations already started to finish... (hashcash-wait-async) ;; ...and do calculations not already done. mail-add-payment-async ;; will leave existing X-Hashcash headers alone. (mail-add-payment-async) (message "Will be inserting hashcash for all... Proceed.")) (defun my-message-goto-body (&optional interactive) "Put Hashcash and move point to the beginning of the message body." (interactive "p" message-mode) (hashcash-insert-payment-all-async) (message-goto-body)) (with-eval-after-load `message (keymap-set message-mode-map "C-c h" `hashcash-insert-payment-all-async) (keymap-set message-mode-map "C-c C-b" `my-message-goto-body)) ;;;; show all headers of articles in spam newsgroup (defun gnus-spam-article-show-all-headers () (interactive) (when (equal gnus-newsgroup-name "spam") (gnus-summary-show-all-headers))) (set `gnus-select-article-hook `(gnus-spam-article-show-all-headers)) ;;; signature to message (set `message-signature nil) (set `message-signature-file nil) (set `message-signature-directory (expand-file-name "~/.mail.d/signatures")) (with-eval-after-load `message (defun message-kill-signature () "Kill the message signature from current buffer." (interactive) (save-excursion (goto-char (point-max)) (when (re-search-backward message-signature-separator nil `t) (kill-region (1- (point)) (point-max))))) (defun my-message-insert-signature (&optional file) "Insert a signature, according to a signature FILE, to the current message." (interactive) (let ((message-signature-file (or file (read-file-name "Signature file: " (concat message-signature-directory "/"))))) (message-kill-signature) (save-excursion (message-insert-signature 0)))) (keymap-set message-mode-map "C-c C-w" `my-message-insert-signature)) ;;; mailcap (eval-after-load `mailcap (mailcap-parse-mailcaps)) ;;; gnus search (set `gnus-search-default-engines `((nnimap . gnus-search-imap) (nnmaildir . gnus-search-find-grep) (nnselect . gnus-search-nnselect) ;;(nnselect . gnus-search-nnselect) ;; (nnselect . gnus-search-find-grep) )) ;;;; functions (defun message-set-header (search-tag insert-line) "Set message SEARCH-TAG header line as this INSERT-LINE." (save-excursion (save-restriction (message-narrow-to-headers-or-head) (if (re-search-forward (concat "^" search-tag ":.*$") nil `t) (replace-match insert-line) (message-add-header insert-line))))) (defun gnus-style-entry-gcc (group style-entry) "Process STYLE-ENTRY given GROUP and to return its \\=gcc entry. Otherwise, nil." (let ((pred (car style-entry)) (gcc (cadr (assq `gcc style-entry)))) (cond ((stringp pred) (cond ((null group) nil) ((string-match pred group) gcc) ((equal pred group) gcc) (`t nil))) ((and (functionp pred) (apply pred ())) gcc) ((eq pred `t) gcc)))) (defun gnus-get-default-gcc (styles) "Get the gcc entry from STYLES corresponding to `gnus-newsgroup-name'." (let ((res (gnus-style-entry-gcc gnus-newsgroup-name (car styles)))) (cond ((null styles) nil) (res (eval res)) (`t (gnus-get-default-gcc (cdr styles)))))) (defun message-set-all-of-my-headers (my-address &optional cipher-it) "Set all of my message header's fields." (let* ((name (cadr (my-email-info my-address))) (personalized-gcc (cond ((string-empty-p (caddr (my-email-info my-address))) nil) (`t (caddr (my-email-info my-address))))) (gcc (cond ((gcc-tantra-p) (progn (message "A") (gnus-get-default-gcc (reverse gnus-posting-styles)))) ((equal my-address user-mail-address) (progn (message "B") (or (gnus-get-default-gcc (reverse gnus-posting-styles)) personalized-gcc))) (`t (progn (message "C") personalized-gcc))))) ;; set From header (message-set-header "From" (concat "From: " name " <" my-address ">")) ;; set proper Gcc header ;; README: tried and faulty ;; (when (message-fetch-field "Gcc") ;; (message-set-header "Gcc" (concat "Gcc: " gcc))) ;; README: tried and working, needs more time with testing it ;; faulty! -> gcc, now, can be nil ;; (message-set-header "Gcc" (concat "Gcc: " gcc)) (if gcc (message-set-header "Gcc" (concat "Gcc: " gcc)) (message-position-on-field "Gcc" "From")) ;; set/unset OpenPGP header (message-set-openpgp-header my-address) ;; set/unset GDPR header (message-set-gdpr-header my-address))) (defun message-set-my-mml-and-headers (&optional my-address) "Set message headers and default mml cryptography." (let* ((address (or my-address (message-get-from-address))) (may-sign (pgp-has-key-p address)) (dest-has-key (pgp-has-key-p (message-get-to-address)))) (cond ((and (not (gcc-public-p)) dest-has-key may-sign) (mml-secure-message-encrypt-pgpmime)) (may-sign (mml-secure-message-sign)) (`t (mml-unsecure-message))) (message-set-all-of-my-headers address))) (add-hook `message-setup-hook `message-set-my-mml-and-headers) ;;; needs the below hook to properly place the mml secure tag in gnus (add-hook `gnus-message-setup-hook `message-set-my-mml-and-headers) (defun message-get-from-address () "Get current From email address from the email compose buffer." (let ((from (mail-fetch-field "from"))) (string-match "\\([A-z0-9_.+-]+@[A-z0-9_.+-]+\\)" from) (match-string 1 from))) (defun message-get-to-address () "Get current To email address from the email compose buffer." (let ((to (mail-fetch-field "to"))) (cond (to (progn (string-match "\\([A-z0-9_.+-]+@[A-z0-9_.+-]+\\)" to) (match-string 1 to))) (t nil)))) (defun message-loop-email (&optional email-config-list nth-pos) "Email loop and set through all of the EMAIL-CONFIG-LIST items." (interactive) (or email-config-list (set `email-config-list (mapcar `car my-email-addresses))) (or nth-pos (set `nth-pos 0)) (let ((current-address (message-get-from-address)) (next-address (nth (1+ nth-pos) email-config-list))) (cond ((length= (cdr email-config-list) nth-pos) (message-set-my-mml-and-headers (car email-config-list))) ((equal current-address (nth nth-pos email-config-list)) (message-set-my-mml-and-headers next-address)) (`t (message-loop-email email-config-list (1+ nth-pos)))))) (with-eval-after-load `message (keymap-set message-mode-map "" `message-loop-email) (keymap-set message-mode-map "" (lambda () (interactive) (message-loop-email (mapcar `car my-mobile-email-addresses))))) (defun message-to-public-p (my-address) "Says if I am sending an email message to the public (mailinglist or netnews)." (cond ((message-news-p) `t) ((member my-address my-public-addresses) `t) (`t nil))) (defun sending-email () (let ((from-address (message-get-from-address))) (cond ((equal from-address user-mail-address-tilde) (smtp-tilde-club)) ((member from-address (mapcar #'car my-mobile-email-addresses)) (smtp-native)) (`t (smtp-msmtp))))) (add-hook `message-send-hook `sending-email) ;;; mml-attach-file goes to the end of the message (set `mml-attach-file-at-the-end `t) ;;; gnus pgp (set `mml-secure-openpgp-signers nil) ;; we want to be able to read the emails we wrote. (set `mml-secure-openpgp-encrypt-to-self `t) ;; mml choose correct key for signing/ciphering (set `mml-secure-openpgp-sign-with-sender `t) ;; always verify signatures (set `mm-verify-option `always) (set `gnus-message-replysign `t) (set `gnus-message-replyencrypt `t) (set `gnus-message-replysignencrypted `t) (keymap-global-set "C-c ESC k" `epa-list-keys) ;;; buttonize ;; show result of pgp verification and other buttonizes (set `gnus-buttonized-mime-types `("multipart/signed" "multipart/encrypted" "application/pgp-keys" "image/.*" "video/.*")) ;; mime parts with less priority ;; (set `mm-discouraged-alternatives `("text/html" ;; "text/richtext")) ;; all mime parts get buttons (set `gnus-inhibit-mime-unbuttonizing `t) ;;; enable epa-mail-mode (add-hook `message-setup-hook `epa-mail-mode) (defun pgp-keyid (email-address) "Get PGP keyid (short format without \"0x\") of EMAIL-ADDRESS. Return NIL if there is no keyid for EMAIL-ADDRESS." (let ((keyid (string-trim-right (shell-command-to-string (concat "keyid-to-cipher \\<" email-address "\\>"))))) (cond ((or (null email-address) (string-empty-p keyid)) nil) (`t keyid)))) (defun pgp-has-key-p (my-address) "Say if message can be signed, according to MY-ADDRESS." (cond ;; ((message-to-public-p my-address) nil) ((pgp-keyid my-address) `t) (`t nil))) (defun mml-secure-tag-p () "Say whether the <#secure tag is present anywhere in the buffer." (save-excursion (goto-char (point-min)) (message-goto-body) (re-search-forward "<#secure .*>$" nil `t))) ;;; openpgp header (defun message-set-openpgp-header (my-address) "Set the openpgp message header." (mail-fetch-field "openpgp" nil nil nil `t) ;;; remove OpenPGP header (let* ((pgp-keyid (pgp-keyid my-address)) (pgp-keyurl (cond ((equal my-address user-mail-address-tilde) my-wkd-tilde-url) (`t (string-trim-right (shell-command-to-string (concat "gpg-wks-client --print-wkd-url " my-address)))))) (message-openpgp-header (list (concat "0x" pgp-keyid) pgp-keyurl "signencrypt"))) (when (pgp-has-key-p my-address) (save-excursion (message-add-openpgp-header))))) (defun my-mml-unsecure-message () "Remove MML tag from message." (interactive) (mml-unsecure-message) (message-set-all-of-my-headers (message-get-from-address)) (save-excursion (message-remove-header "OpenPGP"))) ;;; attempt to sign all non-news mails I'll be sending. (defun my-mml-secure-message-sign (&optional prefix) "Add MML signing tag to message." (interactive "p") (cond ((eql prefix 1) (mml-secure-message-sign-pgpmime)) (`t (mml-secure-message-sign-pgp))) (message-set-all-of-my-headers (message-get-from-address))) ;;; gnus pgp keybindings (defun my-mml-secure-message-sign-encrypt (&optional prefix) "Add MML sign and ciphering tag to message." (interactive "p") (cond ((eql prefix 1) (mml-secure-message-encrypt-pgpmime)) (`t (mml-secure-message-encrypt-pgp))) (message-set-all-of-my-headers (message-get-from-address))) (with-eval-after-load `message (keymap-set mml-mode-map "C-c RET C-n" `my-mml-unsecure-message) (keymap-set mml-mode-map "C-c RET C-s" `my-mml-secure-message-sign) (keymap-set mml-mode-map "C-c RET C-e" `my-mml-secure-message-sign-encrypt)) ;;; GDPR notice (with-eval-after-load `message (defun message-insert-or-toggle-gdpr-header (&optional values) "Insert a \"X-GDPR: pt\" header, or cycle through this header values." (interactive nil message-mode) (or values (set `values `("pt" "en" _))) (save-excursion (let ((cur (message-fetch-field "X-GDPR"))) (cond ((null cur) ;;; if it is the first try (message-add-header (concat "X-GDPR: " (car values)))) ((equal `_ (cadr values)) (message-remove-header "X-GDPR")) ((equal (car values) cur) (progn (message-remove-header "X-GDPR") (message-add-header (concat "X-GDPR: " (cadr values))))) (`t (message-insert-or-toggle-gdpr-header (cdr values))))))) (keymap-set message-mode-map "C-c C-f C-g" `message-insert-or-toggle-gdpr-header)) (defun message-set-gdpr-header (my-address) "Initial set of GDPR header. Set the specific situations when GDPR notice is disabled or enabled." (save-excursion (save-restriction (message-remove-header "X-GDPR") (let ((lang (message-fetch-field "Content-Language"))) (cond ((or (message-to-public-p my-address) (mml-secure-is-encrypted-p)) ()) (lang (message-add-header (concat "X-GDPR: " lang))) (`t (message-add-header "X-GDPR: pt"))))))) (defun message-insert-gdpr-notice () "Insert GDPR notice." (let ((gdpr-field (message-fetch-field "X-GDPR"))) (when gdpr-field (save-excursion (goto-char (point-max)) (when (re-search-backward message-signature-separator nil `t) (forward-line -1) (move-end-of-line nil)) (unless (current-line-empty-p) (newline)) (newline) (newline) (insert-file-contents (expand-file-name (concat "~/.gdpr/" gdpr-field ".txt"))) (message-remove-header "X-GDPR"))))) ;;;; cannot be message-send-mail-hook . It is too late. (add-hook `message-send-hook `message-insert-gdpr-notice -90) ;;; language set-up (defun message-set-language (lang) "Set language specific headers and message signature, according to LANG." (message-set-header "Content-Language" (concat "Content-Language: " lang)) (unless (or (message-to-public-p user-mail-address) (mml-secure-is-encrypted-p)) (message-set-header "X-GDPR" (concat "X-GDPR: " lang))) (let ((hero (cond ((equal lang "pt") "pt-einstein") ((equal lang "en") "en-milne") (`t "en-milne")))) (my-message-insert-signature (concat message-signature-directory "/" hero ".txt")))) (with-eval-after-load `message (defun message-choose-language () "Choose a language for a Content-Language header." (interactive nil message-mode) (message-set-language (cadr (read-multiple-choice "Language" `((?p "pt" "Português") (?e "en" "English")))))) (keymap-set message-mode-map "C-c C-f C-l" `message-choose-language)) ;;; gnus activate yubikey on sending (defun yubikey-pin () (interactive) (shell-command "gpg-change-homedir personal") (call-process (expand-file-name "~/.local/bin/gpg-pass-ask") nil nil nil)) (defalias `y `yubikey-pin) ;;;; cannot be message-send-mail-hook (add-hook `message-send-hook `yubikey-pin) ;;; gnus mail other people certificate PEM certificates (set `smime-certificate-directory (expand-file-name "~/.certs/mail")) ;;; gnus rss (set `nnrss-directory (+emacs.d "gnus/rss")) (load-file (+emacs.d "gnus/rss/nnrss.el")) ;;; gnus in M-x mail (set `mail-user-agent `gnus-user-agent) ;;; read mail in Gnus (set `read-mail-command `gnus) ;; ;;; gnus atom feeds ;; (require `mm-url) ;; (defadvice mm-url-insert (after DE-convert-atom-to-rss () ) ;; "Converts atom to RSS by calling xsltproc." ;; (when (re-search-forward "xmlns=\"http://www.w3.org/.*/Atom\"" ;; nil `t) ;; (goto-char (point-min)) ;; (message "Converting Atom to RSS... ") ;; (call-process-region (point-min) (point-max) ;; "xsltproc" ;; `t `t nil ;; (expand-file-name "~/.emacs.d/gnus/atom2rss.xsl") ;; "-") ;; (goto-char (point-min)) ;; (message "Converting Atom to RSS... done"))) ;; ;; (ad-activate `mm-url-insert) ;; ;; (defun mm-url-insert--DE-convert-atom-to-rss () ;; "Converts atom to RSS by calling xsltproc." ;; (when (re-search-forward "xmlns=\"http://www.w3.org/.*/Atom\"" ;; nil `t) ;; (goto-char (point-min)) ;; (message "Converting Atom to RSS... ") ;; (call-process-region (point-min) (point-max) ;; "xsltproc" ;; `t `t nil ;; (expand-file-name "~/.emacs.d/gnus/atom2rss.xsl") "-") ;; (goto-char (point-min)) ;; (message "Converting Atom to RSS... done"))) ;; ;; (advice-add `mm-url-insert :after #'mm-url-insert--DE-convert-atom-to-rss) ;;; gnus shortcut (defun my-gnus (prefix) "My way of opening Gnus." (interactive "p") (tab-bar-new-tab-to 2) (tab-rename "message") (my-gnus-group-restart prefix)) (keymap-global-set "C-c g m" `my-gnus) ;; gpg pinentry (require `pinentry) ;;; setup the more secure loopback with pinentry (set `epg-pinentry-mode `loopback) (when (and (not (bound-and-true-p pinentry--server-process)) (equal (getenv "GPG_TTY") "/dev/tty1")) (pinentry-start)) (with-eval-after-load `pinentry (defun pinentry-restart () (interactive) (shell-command "gpg-reload") (pinentry-stop) (pinentry-start))) (defalias `pr `pinentry-restart) (keymap-global-set "C-c g g" `pinentry-restart) ;; footnotes (autoload `footnote-mode "footnote" nil `t) (set `footnote-section-tag "") (set `footnote-spaced-footnotes nil) (require `footnote) (add-hook `message-mode-hook `footnote-mode) (set `footnote-index-starting-number 0) (with-eval-after-load `footnote (defun footnote--insert-footnote (arg) "Insert a footnote numbered ARG, at (point)." (push-mark) (let ((ptr (footnote--insert-numbered-footnote arg 't))) (footnote--goto-char-point-max) (if (footnote--goto-first) (save-restriction (when footnote-narrow-to-footnotes-when-editing (footnote--narrow-to-footnotes)) (footnote-goto-footnote (1- arg)) ; evil, FIXME (less evil now) ;; (message "Inserting footnote %d" arg) (or (eq arg footnote-index-starting-number) (when (re-search-forward (if footnote-spaced-footnotes "\n\n" (concat "\n" (footnote--current-regexp))) nil 't) (beginning-of-line) 't) (footnote--goto-char-point-max) (footnote--goto-first))) (unless (looking-at "^$") (newline)) (when (eobp) (newline)) (unless (equal footnote-section-tag "") (insert footnote-section-tag "\n"))) (let ((text (footnote--insert-numbered-footnote arg nil))) (footnote--insert-markers arg text ptr)))) (defun footnote--make-hole () "Make room in the alist for a new footnote at point. Return the footnote number to use." (save-excursion (let (rc) (dolist (alist-elem footnote--markers-alist) (when (<= (point) (caddr alist-elem)) (unless rc (set 'rc (car alist-elem))) (save-excursion (message "Renumbering from %s to %s" (footnote--index-to-string (car alist-elem)) (footnote--index-to-string (1+ (car alist-elem)))) (footnote--renumber (1+ (car alist-elem)) alist-elem)))) (or rc (1+ (or (caar (last footnote--markers-alist)) (1- footnote-index-starting-number))))))) (defun footnote-renumber-footnotes () "Renumber footnotes, starting from `footnote-index-starting-number'." (interactive "*") (save-excursion (let ((i footnote-index-starting-number)) (dolist (alist-elem footnote--markers-alist) (footnote--renumber i alist-elem) (set 'i (1+ i))))))) ;; display buffers (set `display-buffer-alist '(("\\*graphical-web-browser.*" display-buffer-no-window))) ;; ebdb (require `ebdb-gnus) (require `ebdb-message) (set `ebdb-record-self "36b79c52-1bbf-432a-9c80-c84e056fbcd1") (keymap-global-set "C-c g p" `ebdb) ;; managesieve (autoload `sieve-mode "sieve-mode") (set `auto-mode-alist (cons `("\\.s\\(v\\|iv\\|ieve\\)\\'" . sieve-mode) auto-mode-alist)) ;; erc (set `erc-user-full-name user-full-name) (set `erc-session-client-certificate `t) (set `erc-track-enable-keybindings nil) (set `erc-track-exclude-server-buffer `t) (set `erc-hide-list `("PART" "QUIT")) ;; hide irc part and quit messages (join allowed) (set `erc-kill-buffer-on-part `t) ;;; erc modules (set `erc-modules `(log autoaway netsplit fill button match track completion readonly networks ring noncommands irccontrols move-to-prompt stamp menu list nicks)) ;;; prevent bot functions from displaying text of ignored nicks ;; (defun erc-bot-messages-ignore (string) ;; (when ;; (and ;; (or ;; (string-match ;; "^<[][:alnum:]`|^_{}[-]+> \\[Sed\\] <\\([][:alnum:]`|^_{}[-]+\\)> .*" ;; string) ;; (string-match ;; "^<[][:alnum:]`|^_{}[-]+> \\[Karma\\] .+ now has [0-9]+ karma ([0-9]+ from \\([][:alnum:]`|^_{}[-]+\\))" ;; string) ;; (string-match ;; "^<[][:alnum:]`|^_{}[-]+> \\([][:alnum:]`|^_{}[-]+\\): <[][:alnum:]`|^_{}[-]+> .*" ;; string)) ;; (member (match-string 1 string) erc-ignore-list)) ;; (set `erc-insert-this nil))) ;; (add-hook `erc-insert-pre-hook `erc-bot-messages-ignore) ;;; erc auto-away (set `erc-auto-set-away `t) (set `erc-autoaway-use-emacs-idle `t) (set `erc-auto-discard-away `t) (set `erc-autoaway-idle-seconds 210) (set `erc-autoaway-message "...") ;;; erc logging (set `erc-log-channels-directory (expand-file-name "~/log")) ;;; erc custom function ;;;; voice and devoice nick(s) (defun erc-cmd-VOICE (&rest people) "Add the voice mode to users(s) given in PEOPLE." (when (> (length people) 0) (erc-server-send (concat "MODE " (erc-default-target) " +" (make-string (length people) ?v) " " (mapconcat #'identity people " "))) `t)) (defun erc-cmd-DEVOICE (&rest people) "Remove the voice setting from user(s) given in PEOPLE." (when (> (length people) 0) (erc-server-send (concat "MODE " (erc-default-target) " -" (make-string (length people) ?v) " " (mapconcat #'identity people " "))) `t)) ;;;; faith spreading (defun erc-cmd-FAITH (&rest ignore) "Post faith in the current channel." (interactive) (require 'faith) (erc-send-message (mapconcat 'identity (split-string (faith-quote) "\n") " "))) ;;;; query nick (defun erc-query-channel-nick (nick) "Query a nick of the current channel." (interactive (list (completing-read "Nick: " erc-channel-users))) (erc-cmd-QUERY nick)) (with-eval-after-load `erc (keymap-set erc-mode-map "C-c q" `erc-query-channel-nick)) ;;;; always send a final point at the end (defun erc-insert-final-point (input-struct) (let* ((input-string (cl-struct-slot-value `erc-input `string input-struct)) (last-char (string-to-char (substring input-string -1))) (first-char (string-to-char (substring input-string 0 1)))) (cond ((or (eq last-char ?.) (eq last-char ?!) (eq last-char ??) (eq last-char ?,) (eq last-char ?\;) (eq last-char ?:) (eq first-char ?,) (eq first-char ?/) (string-match "^s/" input-string)) `t) ((string-match " $" input-string) (setf (cl-struct-slot-value `erc-input `string input-struct) (substring input-string 0 -2))) ((or ;; smiley (string-match "[:;%8>xX]\\{1\\}[`',]?-?[)(/\\ZzXxDPpSsbO]\\{1,4\\}$" input-string) ;; URLs (string-match "\\(?:http\\|ftp\\|file\\|gopher\\|gemini\\)s?://.+?[^ )]+$" input-string) ;; other (eq last-char ?^)) (setf (cl-struct-slot-value `erc-input `string input-struct) (concat input-string " ."))) (`t (setf (cl-struct-slot-value `erc-input `string input-struct) (concat input-string ".")))))) (add-hook `erc-pre-send-functions `erc-insert-final-point) ;;;; fix the double correction issue (defun my-erc-send-current-line () "Parse current line and send it to IRC." (interactive) (let ((now (current-time))) (if (or (not erc-accidental-paste-threshold-seconds) (time-less-p erc-accidental-paste-threshold-seconds (time-subtract now erc-last-input-time))) (save-restriction ;; If there's an abbrev at the end of the line, expand it. ;; (when (and abbrev-mode ;; (eolp)) ;; (expand-abbrev)) (widen) (let* ((str (erc-user-input)) (state (erc--make-input-split str))) (run-hook-with-args 'erc--input-review-functions state) (when-let (((not (erc--input-split-abortp state))) (inhibit-read-only t) (erc--current-line-input-split state) (old-buf (current-buffer))) (progn ; unprogn this during next major surgery (erc-set-active-buffer (current-buffer)) ;; Kill the input and the prompt (delete-region erc-input-marker (erc-end-of-input-line)) (unwind-protect (erc--send-input-lines (erc--run-send-hooks state)) ;; Fix the buffer if the command didn't kill it (when (buffer-live-p old-buf) (with-current-buffer old-buf (save-restriction (widen) (let ((buffer-modified (buffer-modified-p))) (set-buffer-modified-p buffer-modified)))))) ;; Only when last hook has been run... (run-hook-with-args 'erc-send-completed-hook str))) (set 'erc-last-input-time now))) (switch-to-buffer "*ERC Accidental Paste Overflow*") (lwarn 'erc :warning "You seem to have accidentally pasted some text!")))) (with-eval-after-load `erc (keymap-set erc-mode-map "RET" `my-erc-send-current-line)) ;;; other erc functions (load "my-common-system") ;; (load "my-quack-system") (load "my-erc-coins-system") (load "my-weri") (defun erc-rejoin-channel () "Rejoin current IRC channel." (interactive) (erc-join-channel (erc-channel-name (buffer-name)) nil)) (with-eval-after-load `erc (keymap-set erc-mode-map "C-c j" `erc-rejoin-channel)) ;; jabber (require `jabber) ;;; disable roster keybindings menu (set `jabber-roster-show-bindings nil) ;;; make fsm output debug buffer disappear (set `fsm-debug nil) ;; (add-to-list `load-path (expand-file-name "~/me/programming/desktop/emacs-jabber/lisp/")) ;; (add-to-list `load-path (expand-file-name "~/me/programming/desktop/emacs-jabber/")) ;; (load (expand-file-name "~/me/programming/desktop/emacs-jabber/jabber-autoloads")) ;;; upload files (M-x jabber-httpupload-send-file) (require `jabber-httpupload) (keymap-global-set "C-x C-j C-m" `jabber-roster-switch-muc) (with-eval-after-load `jabber-muc (keymap-set jabber-chat-mode-map "C-c C-n" `jabber-muc-names) (keymap-set jabber-chat-mode-map "C-c C-t" `jabber-muc-set-topic) (keymap-set jabber-chat-mode-map "C-c C-p" `jabber-muc-leave) (keymap-set jabber-chat-mode-map "C-c q" `jabber-muc-private)) (with-eval-after-load `jabber-httpupload (keymap-set jabber-chat-mode-map "C-c a" `jabber-httpupload-send-file)) ;; (unless (package-installed-p `jabber) ;; (require `package-vc) ;; (add-to-list `package-vc-selected-packages ;; `(jabber ;; :url "https://codeberg.org/emacs-jabber/emacs-jabber" ;; :branch "production" ;; :lisp-dir "lisp" ;; :doc "README.org")) ;; ;; Change the path below to the location of your local jabber.el repository. ;; (package-vc-install-from-checkout (expand-file-name "~/me/programming/desktop/emacs-jabber/") "jabber")) ;; emms (require `emms-info-exiftool) ;; metadata (emms-all) (set `emms-player-list `(emms-player-vlc emms-player-alsaplayer)) ;; need pacman -S perl-image-exiftool below (set `emms-info-functions `(emms-info-exiftool emms-info-metaflac emms-info-native)) (set `emms-source-file-default-directory (expand-file-name "~/me/files/audio/music")) ;;; disable in modeline (emms-mode-line-mode -1) ;;; amixer (set `emms-volume-change-function `emms-volume-amixer-change) (set `emms-volume-change-amount 1) (set `emms-volume-amixer-card 3) (set `emms-volume-amixer-control "PCM Soft") ;;; pulseaudio volume changer ;; (set `emms-volume-change-function `emms-volume-pulse-change) (defun pulseaudio-sinks () (let ((output (shell-command-to-string "pactl list short sinks")) (last-match-index 0) (result nil)) (while (set `last-match-index (and (string-match "^\\([0-9]+\\)" output last-match-index) (1+ (string-match "^\\([0-9]+\\)" output last-match-index)))) (push (string-to-number (match-string 1 output)) result)) (reverse result))) ;;; my offline music playing (defun my-play-music (dir message) "Play my music." (interactive) (emms-play-m3u-playlist (expand-file-name dir)) (emms-playlist-sort-by-random) (emms-playlist-sort-by-random) (emms-random) (emms-playlist-sort-by-random) (tab-switch "music") (switch-to-buffer " *EMMS Playlist*") (message message)) (defun my-emms-show (&optional insertp) "Describe the current EMMS track in the minibuffer. If INSERTP is non-nil, insert the description into the current buffer instead. This function uses `emms-show-format' to format the current track." (interactive "P") (let ((string (if emms-player-playing-p (format "Currently playing: ~/%s" (string-join (cdddr (split-string (emms-track-description (emms-playlist-current-selected-track)) "/")) "/")) "Nothing playing right now"))) (if insertp (insert string) (message "%s" string)))) (defun emms-insert-show () "Insert playing music into buffer." (interactive) (insert (my-emms-show))) (defun emms-restart () "Restart playing." (interactive) (emms-stop) (set-buffer " *EMMS Playlist*") (emms-playlist-mode-play-current-track)) ;;;; twitch playing (defun twitch-list-channel-urls (channel &optional number) "List last video URLs of twitch CHANNEL." (interactive (list (read-string "Channel name: ") (read-number "Maximum number of last URLs: " 5))) (async-shell-command (concat "yt-dlp " (when number (concat "--max-downloads " (number-to-string number) " ")) "-s https://www.twitch.tv/" channel "/videos?filter=default | " "grep \"https://www.twitch.tv/videos/\" | " "awk '{print $4}'") "*twitch-channel-urls*")) (defun twitch-play (channel) (interactive "MTwitch channel: ") (async-shell-command (concat "yt-dlp -f audio_only -o - https://www.twitch.tv/" channel " | cvlc - >/dev/null") "*twitch-play*")) ;;; volume mode timeout (set `emms-volume-mode-timeout 5) ;;; emms keybindings (keymap-global-set "C-c p +" `emms-volume-mode-plus) (keymap-global-set "C-c p -" `emms-volume-mode-minus) (keymap-global-set "C-c p " `fresh) (keymap-global-set "C-c p " `emms-stop) (keymap-global-set "C-c p " `emms-next) (keymap-global-set "C-c p " `emms-previous) (keymap-global-set "C-c p SPC" `emms-pause) (keymap-global-set "C-c p RET" `emms-restart) (keymap-global-set "C-c p r" `emms-random) (keymap-global-set "C-c p t" `emms-toggle-random-playlist) (keymap-global-set "C-c p ." `my-emms-show) (keymap-global-set "C-c p i" `emms-insert-show) ;;; set audio output ;;;; set pulseaudio's output (defun speakers-set-pulse (number) "Set audio speakers with a sink NUMBER." (interactive "NSink number: ") (shell-command (concat "pactl set-default-sink " (number-to-string number))) (set `emms-volume-pulse-sink number)) (defun mic-mute-pulse () "Mute default mic." (interactive) (shell-command (concat "pactl set-source-mute " (string-trim-right (shell-command-to-string "pactl get-default-source")) " 1")) (message "Mic muted.")) (defun mic-unmute-pulse () "Unmute default mic." (interactive) (shell-command (concat "pactl set-source-mute " (string-trim-right (shell-command-to-string "pactl get-default-source")) " 0")) (message "Mic unmuted.")) ;;;; set amixer's output (defun speakers-toggle-alsa () "Toggle ALSA output card." (interactive) (cond ((file-exists-p "~/.asoundrc-headphones.lock") (progn (shell-command "rm ~/.asoundrc") (shell-command "rm ~/.asoundrc-headphones.lock") (shell-command "ln ~/.asoundrc-speaker ~/.asoundrc") (set `emms-volume-amixer-card 3) (set `emms-volume-amixer-control "PCM Soft") (message "Sound in speakers."))) (`t (progn (shell-command "rm ~/.asoundrc") (shell-command "touch ~/.asoundrc-headphones.lock") (shell-command "ln ~/.asoundrc-headphones ~/.asoundrc") (set `emms-volume-amixer-card 1) (set `emms-volume-amixer-control "Master") (message "Sound in headphones."))))) (defun speakers-mute-alsa () "Mute default mic." (interactive) (shell-command (concat "amixer -c " (number-to-string emms-volume-amixer-card) " set \"Speaker\" mute")) (message "Speakers muted.")) (defun speakers-unmute-alsa () "Unmute default mic." (interactive) (shell-command (concat "amixer -c " (number-to-string emms-volume-amixer-card) " set \"Speaker\" unmute")) (message "Speakers unmuted.")) ;;;; set preferred audio keybindings (keymap-global-set "C-c p s" `speakers-toggle-alsa) (keymap-global-set "C-c p m" `speakers-mute-alsa) (keymap-global-set "C-c p u" `speakers-unmute-alsa) ;; time european (set `calendar-time-display-form `(24-hours ":" minutes (when time-zone " (") time-zone (when time-zone ")"))) (set `display-time-24hr-format `t) ;; calendar daylight timezones (require 'cal-dst) ;; time world (set `zoneinfo-style-world-list '(("America/Los_Angeles" "Los Angeles") ("America/Vancouver" "Vancouver") ("America/Mexico_City" "Mexico City") ("America/Denver" "Denver") ("America/Chicago" "Chicago") ("America/New_York" "New York") ("America/Toronto" "Toronto") ("America/Montreal" "Montreal") ("America/Sao_Paulo" "São Paulo") ("UTC" "UTC") ("Europe/Dublin" "Dublin") ("Europe/Lisbon" "Lisbon") ("Europe/London" "London") ("Europe/Madrid" "Madrid") ("Europe/Paris" "Paris") ("Europe/Brussels" "Brussels") ("Europe/Amsterdam" "Amsterdam") ("Europe/Oslo" "Oslo") ("Europe/Berlin" "Berlin") ("Europe/Athens" "Athens") ("Asia/Nicosia" "Lefkosia") ("Asia/Istanbul" "Istanbul") ("Asia/Baghdad" "Baghdad") ("Asia/Riyadh" "Riyadh") ("Asia/Tehran" "Tehran") ("Asia/Tbilisi" "Tbilisi") ("Asia/Tashkent" "Tashkent") ("Asia/Karachi" "Karachi") ("Asia/Kolkata" "Kolkata") ("Asia/Dhaka" "Dhaka") ("Asia/Bangkok" "Bangkok") ("Asia/Ho_Chi_Minh" "Ho Chi Minh") ("Asia/Singapore" "Singapore") ("Asia/Macau" "Macau") ("Asia/Shanghai" "Shanghai") ("Asia/Seoul" "Seoul") ("Asia/Tokyo" "Tokyo") ("Australia/Brisbane" "Brisbane") ("Australia/Sydney" "Sydney") ("Pacific/Auckland" "Auckland"))) ;; display time (display-time-mode) ;; calendar (defun my-calendar-exit () (interactive) (calendar-exit `t)) (keymap-set calendar-mode-map "q" `my-calendar-exit) ;;; holidays ;;;; job holidays ;;;###autoload (defcustom holiday-job-holidays nil "Job holidays." :type 'sexp) ;;;###autoload (put 'holiday-job-holidays 'risky-local-variable t) ;;;; my holidays function for accommodating 'holiday-job-holidays (advice-add `holiday-available-holiday-lists :override (lambda () "Return a list of all holiday lists. This is used by `list-holidays', and you can customize the return value by using `add-function'." (delq nil (list (cons "All" calendar-holidays) (cons "Equinoxes/Solstices" (list (list 'solar-equinoxes-solstices))) (if holiday-general-holidays (cons "General" holiday-general-holidays)) (if holiday-local-holidays (cons "Local" holiday-local-holidays)) (if holiday-job-holidays (cons "Job" holiday-job-holidays)) (if holiday-other-holidays (cons "Other" holiday-other-holidays)) (if holiday-christian-holidays (cons "Christian" holiday-christian-holidays)) (if holiday-hebrew-holidays (cons "Hebrew" holiday-hebrew-holidays)) (if holiday-islamic-holidays (cons "Islamic" holiday-islamic-holidays)) (if holiday-bahai-holidays (cons "Bahá’í" holiday-bahai-holidays)) (if holiday-oriental-holidays (cons "Oriental" holiday-oriental-holidays)) (if holiday-solar-holidays (cons "Solar" holiday-solar-holidays)) (cons "Ask" nil))))) (set `calendar-mark-holidays-flag `t) ;; enable holidays in calendar (set `calendar-date-style `european) ;; diary (set `calendar-mark-diary-entries-flag `t) ;; enable diary in calendar (set `diary-comment-start ";") ;; set comments for diary files ;;; enable include facility in diary files (add-hook `diary-list-entries-hook `diary-include-other-diary-files) (add-hook `diary-mark-entries-hook `diary-mark-included-diary-files) ;;; cal function (defun cal () (interactive) (calendar) (kill-buffer "diary")) (keymap-global-set "C-c g c" `cal) (defun today () (interactive) (shell-command "date")) (keymap-global-set "C-c g t" `today) (defun moon () (interactive) ;; (lunar-phases) (calendar) (calendar-lunar-phases) ) (defun sun () (interactive) ;; (sunrise-sunset) (calendar) (calendar-sunrise-sunset-month) ) ;; remember (set `remember-notes-initial-major-mode `text-mode) (keymap-global-set "C-c g r" `remember) (keymap-global-set "C-c g R" `remember-notes) ;; po ;; (require `po-mode) ;;; autofill untranslated with msgid (set `po-auto-edit-with-msgid `t) ;;; po file preprocessing (defun po-update-this-file () (interactive) (shell-command "po-update") nil) ;; (add-hook `po-mode-hook `po-update-this-file) (with-eval-after-load `po-mode (defun po-replace-project-id-version () "Update the Project-Id-Version in the PO file header." (save-excursion (goto-char (point-min)) (when (re-search-forward "^\"Project-Id-Version:.*" nil `t) (let* ((buffer-read-only po-read-only)) (replace-match (concat "\"Project-Id-Version: " (shell-command-to-string "version") "\\n\"") `t `t)))) ;; Return nil to indicate that the buffer has not yet been saved. nil) ;; (add-hook `po-mode-hook `po-replace-project-id-version) ) ;;; substitution (defun subst (x y z) "Result of substituting the S-expression X for all occurences of the atomic symbol Y in the S-expression Z." (cond ((atom z) (cond ((equal z y) x) (t z))) (t (cons (subst x y (car z)) (subst x y (cdr z)))))) (defun subst-string (data-var) (mapc (lambda (list-pair) (goto-char (point-min)) (replace-string (car list-pair) (cdr list-pair))) data-var) (goto-char (point-max))) (defun subst-bing () (interactive) (subst-string subst-data-bing)) (set `subst-data-bing `(("senha" . "frase-secreta") ("frase secreta" . "frase-secreta") ("frases secretas" . "frases-secretas") ("SSH" . "ssh") ("o cache" . "a cache") ("um cache" . "uma cache") ("não alfa" . "não alfabéticos") ("mouse" . "rato") ("soquete" . "socket") ("agente GPG" . "gpg-agent") ("agente gpg" . "gpg-agent") ("escutando" . "ouvindo") ("o diretório" . "a pasta") ("diretório" . "pasta") ("diretoria" . "pasta") ("manipulador" . "handler") ("arquivo" . "ficheiro") ("do usuário" . "de utilizador") ("usuário" . "utilizador") ("placas" . "cartões") ("placa" . "cartão") ("cadeia de caracteres" . "string") ("criptografia" . "cifragem") ("cifragem" . "cifração") ("encripta" . "cifra") ("desencripta" . "decifra") ("administrador" . "Admin") ("modo de lote" . "modo batch") ("excluí" . "apaga") ("exclui" . "apaga") ("somente" . "só") ("(s/n)" . "(s/N)") ("e-mail" . "email") ("e armadura" . "a blindagem") ("armadura" . "blindagem") ("compactaç" . "compress") ("propriedade" . "ownership") ("listagens de assinatura" . "listagens de assinaturas") ("autoassina" . "auto-assina") ("tecla" . "chave") ("conjunto de chaves" . "porta-chaves") ("chaveiro" . "porta-chaves") ("agente" . "agent") ("mescla" . "fundi") ("detect" . "detet") ("insir" . "introduz") ("digite" . "introduza") ("cartão inteligente" . "smartcard") ("Você realmente quer" . "De certeza que você deseja") ("Você realmente" . "De certeza que você") ("você realmente quer" . "de certeza que você deseja") ("você realmente" . "de certeza que você") ("um banco de dados" . "uma base de dados") ("o banco de dados" . "a base de dados") ("Realmente" . "De certeza que deseja") ("primária" . "principal") ("primário" . "principal") ("o ID" . "a ID") ("um ID" . "uma ID") ("um documento de identificação com foto" . "uma ID fotográfica") ("o documento de identificação com foto" . "a ID fotográfica") ("portanto" . "por isso") ("resumo" . "digest") ("descriptograf" . "decifr") ("preterid" . "depreciad") ("acessar" . "aceder") ("essa" . "esta") ("esse" . "este") ("Observação:" . "Nota:") ("cadeia" . "corrente") ("assunto" . "entidade") ("gravar" . "escrever") ("registr" . "regist") ("carimbo de data/hora" . "timestamp") ("expressão S" . "S-expression") ("banco" . "base") ("sinalizador" . "flag") ("solicitação" . "pedido") ("ruim" . "inválido") ("incorret" . "inválid") ("incorrect" . "inválid") ("geral" . "genérico") ("decodificação" . "descodificação"))) (defun po-mark-whole-subedit-buffer () (interactive) (goto-char (point-min)) (push-mark (1- (point-max)) nil `t)) ;;; po send email (set `po-default-commit-message "po: Update Portuguese Translation.") (defun po-git-commit (msg) "My function to git commit before sending a patch." (shell-command "rm 0001-*.patch") (shell-command (concat "git add " (file-name-nondirectory buffer-file-name))) (shell-command (concat "git commit " (when (yes-or-no-p "Amend commit? ") "--amend ") (when (yes-or-no-p "Signoff commit? ") "-s ") "-m \"" msg "\"")) ;; (shell-command "git format-patch -k HEAD~1") (shell-command "git format-patch -1")) (defun po-send-address () (let ((gnupg "GnuPG , Werner Koch ")) (cond ((or (string-search "/gnupg/1-libgpg-error/" default-directory)) (string-search "/gnupg/7-gnupg/" default-directory) gnupg) (`t (po-guess-team-address))))) (defun my-po-send-mail () "My function to start composing a letter, and send git PO patch file." (interactive) (shell-command (concat "po-prod " (file-name-nondirectory buffer-file-name))) (let ((string-msg (read-string "Commit message: " po-default-commit-message)) (user-mail-address user-mail-address-translator)) (po-git-commit string-msg) (compose-mail-other-window (po-send-address) string-msg nil) (message-set-openpgp-header user-mail-address)) (message-goto-body) (newline) (newline) (mml-attach-file (shell-command-to-string "printf ${PWD}/0001-*.patch") "text/x-patch" (concat (shell-command-to-string "printf $(version | awk 'NF{NF-=1};1')") " patch.")) (message-goto-body) (open-line 2) (my-mml-secure-message-sign) (message "You may start writing the email...")) ;; (with-eval-after-load `po-mode ;; (keymap-set po-subedit-mode-map "C-c h" `po-mark-whole-subedit-buffer) ;; (keymap-set po-subedit-mode-map "" `subst-bing) ;; (keymap-set po-subedit-mode-map "C-c s" nil) ;; (keymap-set po-subedit-mode-map "C-c s i" `ispell-message) ;; (keymap-set po-mode-map "M" `my-po-send-mail)) ;; (with-eval-after-load `po-mode ;; (defvar po-subedit-mode-map ;; ;; Use (make-keymap) because (make-sparse-keymap) does not work on Demacs. ;; (let ((po-subedit-mode-map (make-keymap))) ;; (define-key po-subedit-mode-map "\C-c\C-a" `po-subedit-cycle-auxiliary) ;; (define-key po-subedit-mode-map "\C-c\C-c" `po-subedit-exit) ;; (define-key po-subedit-mode-map "\C-c\C-e" `po-subedit-ediff) ;; (define-key po-subedit-mode-map "\C-c\C-k" `po-subedit-abort) ;; (define-key po-subedit-mode-map "\C-ch" `po-mark-whole-subedit-buffer) ;; (define-key po-subedit-mode-map "" `subst-bing) ;; (define-key po-subedit-mode-map "\C-cs" nil) ;; (define-key po-subedit-mode-map "\C-csi" `ispell-message) ;; po-subedit-mode-map) ;; "Keymap while editing a PO mode entry (or the full PO file).") ;; (keymap-set po-mode-map "M" `my-po-send-mail)) ;; po-mode package instructions (autoload 'po-mode "po-mode" "Major mode for translators to edit PO files" t) (setq auto-mode-alist (cons '("\\.po\\'\\|\\.po\\." . po-mode) auto-mode-alist)) (autoload 'po-find-file-coding-system "po-compat") (modify-coding-system-alist 'file "\\.po\\'\\|\\.po\\." 'po-find-file-coding-system) ;; go-translate (load "my-go-translate") ;; emerge (set `emerge-combine-versions-template "%a%b") ;; bookmarks (set `bookmark-save-flag 1) ;; expand-region (keymap-global-set "C-c DEL" `er/contract-region) (keymap-global-set "C-c C-SPC" `er/expand-region) ;; dictd (keymap-global-set "C-c d" `dictionary-search) ;; captain (with-eval-after-load `captain (defun captain--default-predicate () "The default predicate for determining whether the captain should work." `t)) ;; (defun auto-capitalization-total () ;; (defvar captain-predicate (lambda () `t))) ;; (add-hook `erc-mode-hook `auto-capitalization-total) ;; (add-hook `jabber-chat-mode-hook `auto-capitalization-total) ;; (add-hook `message-mode-hook `auto-capitalization-total) (add-hook `erc-mode-hook `captain-mode) (add-hook `jabber-chat-mode-hook `captain-mode) (add-hook `message-mode-hook `captain-mode) (defun fancy-mode () "Set all the fancy modes on a buffer." (interactive) (auto-fill-mode) (abbrev-mode) (captain-mode) (defvar captain-predicate (lambda () `t))) ;; battery (defun battery () "Get the percentage of battery charge." (interactive) (message "%d" (/ (* (string-to-number (shell-command-to-string "cat /sys/class/power_supply/BAT1/charge_now")) 100) (string-to-number (shell-command-to-string "cat /sys/class/power_supply/BAT1/charge_full"))))) ;; profanity (load "profanity") (defun xmpp () "Open XMPP client." (interactive) (profanity "personal")) (defun my-xmpp () "My way of opening XMPP." (interactive) (tab-bar-new-tab-to 3) (tab-rename "xmpp") ;; (run-with-timer 5 0 `xmpp) (xmpp)) (keymap-global-set "C-c g x" `my-xmpp) ;; pomodoro (require `pomodoro) (set `pomodoro-play-sounds nil) (set `pomodoro-sound-player "cvlc") (set `pomodoro-break-start-sound "") (set `pomodoro-work-start-sound "") ;; mentor (set `mentor-rtorrent-download-directory (expand-file-name "~/torrents")) ;; olivetti (add-hook `Info-mode-hook `olivetti-mode) (add-hook `elpher-mode-hook `olivetti-mode) ;; nov (add-to-list `auto-mode-alist `("\\.epub\\'" . nov-mode)) (setq nov-unzip-program (executable-find "bsdtar") nov-unzip-args `("-xC" directory "-f" filename)) (setq nov-text-width 70) ;; other keybindings (keymap-global-set "C-x t t" `tab-bar-mode) (keymap-global-set "C-x 7" `flop-frame) (keymap-global-set "C-x 8" `flip-frame) (keymap-global-set "C-x 9" `transpose-frame) (keymap-global-set "C-c w c" `olivetti-mode) (keymap-global-set "C-c g s" `scratch-buffer) (keymap-global-set "C-c g l" `auth-source-forget-all-cached) (keymap-global-set "C-c g a" (lambda () (interactive) (ansi-term "/bin/bash"))) ;; other aliases (defalias `u `uncomment-region) (defalias `sh `shell) (defalias `short-doc `shortdoc) (defalias `print-buffer-to-file `ps-print-buffer) (defalias `print-buffer-to-file-from-x `ps-print-buffer-with-faces) ;; always enable some disable commands ;; this below have been configured with the M-x enable-command (put `list-timers `disabled nil) ;; disable the too much stuff for graphical enviroment (tool-bar-mode -1) (menu-bar-no-scroll-bar) (menu-bar-mode -1) (tab-bar-mode (if (getenv "DISPLAY") -1 nil)) (and (fboundp `fringe-mode) (fringe-mode `(0 . 0))) (unless (or (getenv "DISPLAY") (get-buffer "*Group*") (get-buffer "*-jabber-roster-*") (get-buffer "*profanity personal*")) (tab-rename "music")) ;; EXWM (load "my-exwm") ;; final message (message "GNU Emacs configuration loaded.") ;;; end of emacs configuration (custom-set-variables ;; custom-set-variables was added by Custom. ;; If you edit it by hand, you could mess it up, so be careful. ;; Your init file should contain only one such instance. ;; If there is more than one, they won't work right. '(erc-nicks-bg-color "black") '(package-selected-packages '(0x0 captain clhs crdt debbugs dictionary ebdb elpher emms expand-region exwm forth-mode fsm go-translate jabber languagetool ledger-mode logos magit markdown-mode mediawiki mentor nov olivetti osm paredit pinentry plz po-mode pomodoro rainbow-delimiters sicp srv transpose-frame varuga)) '(send-mail-function 'sendmail-send-it)) (custom-set-faces ;; custom-set-faces was added by Custom. ;; If you edit it by hand, you could mess it up, so be careful. ;; Your init file should contain only one such instance. ;; If there is more than one, they won't work right. '(erc-fool-face ((t (:strike-through t :slant italic)))) '(magit-blame-dimmed ((t (:inherit magit-dimmed)))) '(magit-diff-added ((t (:extend t :background "#335533" :foreground "black")))) '(magit-diff-added-highlight ((t (:extend t :background "#336633" :foreground "black")))) '(magit-diff-base ((t (:extend t :background "#555522" :foreground "black")))) '(magit-diff-base-highlight ((t (:extend t :background "#666622" :foreground "black")))) '(magit-diff-removed ((t (:extend t :background "#553333" :foreground "black")))) '(magit-diff-removed-highlight ((t (:extend t :background "#663333" :foreground "black")))) '(magit-dimmed ((t (:slant italic)))) '(magit-hash ((t (:slant italic)))) '(magit-reflog-checkout ((t (:background "white" :foreground "blue")))))