Skip to content

Instantly share code, notes, and snippets.

@dsalychev
Created August 31, 2022 09:28
Show Gist options
  • Save dsalychev/6dde825c7a2a3952d5d00a4dafcf1e66 to your computer and use it in GitHub Desktop.
Save dsalychev/6dde825c7a2a3952d5d00a4dafcf1e66 to your computer and use it in GitHub Desktop.
;; ----------------- 1. Startup and Runtime Performance ------------------------
;; NOTE: https://config.daviwil.com/emacs
;; Make startup faster by reducing the frequency of garbage collection and then
;; use a hook to measure Emacs startup time.
;; The default is 800 kilobytes. Measured in bytes.
(setq gc-cons-threshold (* 50 1000 1000))
;; Profile emacs startup
(add-hook 'emacs-startup-hook
(lambda ()
(message "Emacs loaded in %s with %d garbage collections."
(format "%.2f seconds"
(float-time
(time-subtract after-init-time before-init-time)))
gcs-done)))
;; Dial the GC threshold back down so that garbage collection happens more
;; frequently but in less time.
;; Make gc pauses faster by decreasing the threshold.
(setq gc-cons-threshold (* 2 1000 1000))
;; ----------------- 2. Package Management -------------------------------------
;; Initialize package repositories
(require 'package)
(setq package-archives '(("melpa" . "https://melpa.org/packages/")
("melpa-stable" . "https://stable.melpa.org/packages/")
("org" . "https://orgmode.org/elpa/")
("elpa" . "https://elpa.gnu.org/packages/")))
(package-initialize)
;; Initialize use-package
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package))
(eval-when-compile
(require 'use-package))
;; Setting use-package-always-ensure to "true" saves us the trouble of having
;; to specify :ensure t in any future packages we’d like to declare and install.
;;
;; The :ensure macro basically makes sure that the packages are correctly
;; installed at every startup, and automatically installs the missing ones
;; for you. This is extremely useful when you frequently move between different
;; machines and need to port your entire Emacs config over to a new setup.
(eval-and-compile
(setq use-package-always-ensure t
use-package-expand-minimally t))
;; Uncomment this to get a reading on packages that get loaded at startup
;;(setq use-package-verbose t)
;; ----------------- 3. Keep .emacs.d clean ------------------------------------
;; Change the user-emacs-directory to keep unwanted things out of ~/.emacs.d
(setq user-emacs-directory (expand-file-name "~/.cache/emacs/")
url-history-file (expand-file-name "url/history" user-emacs-directory))
;; Use no-littering to automatically set common paths to the new user-emacs-directory
(use-package no-littering)
;; Keep customization settings in a temporary file (thanks Ambrevar!)
;; (setq custom-file
;; (if (boundp 'server-socket-dir)
;; (expand-file-name "custom.el" server-socket-dir)
;; (expand-file-name (format "emacs-custom-%s.el" (user-uid)) temporary-file-directory)))
;; (load custom-file t)
;; ----------------- 4. Update Load Path ---------------------------------------
;; Add my library path to load-path
(push "~/.emacs.d/elisp" load-path)
;; FreeBSD-specific path
(push "/usr/local/share/emacs/site-lisp" load-path)
;; ----------------- 5. Default Coding System ----------------------------------
(set-default-coding-systems 'utf-8)
;; ----------------- 6. Server Mode --------------------------------------------
;; Start the Emacs server from this instance so that all emacsclient calls are
; routed here.
(server-start)
;; ----------------- 7. Packages Configuration ---------------------------------
(use-package highlight-parentheses)
(use-package dracula-theme)
(use-package magit
:defer 10)
(use-package unicode-fonts)
(use-package persistent-soft ; To cache the fonts and reduce load time
:after unicode-fonts
:config
(unicode-fonts-setup))
;; Say I want to turn on the visualization of matching parentheses. That is,
;; when my cursor stops at a parenthesis/bracket/brace, the matching instance on
;; the other end is highlighted.
;;
;; This requires tweaking the “paren” package, which is a built-in package in
;; Emacs already. To prevent use-package from looking for the paren package in
;; the internet archives, we turn off the :ensure flag. Then, in
;; the :config section, we specify the desired show-paren-mode.
(use-package paren
:ensure nil ;; built-in package, don't search in the repos
:config
(show-paren-mode +1))
;; OpenBSD KNF style for C/C++: https://github.com/hogand/openbsd-knf-emacs
(use-package openbsd-knf-style
:ensure nil ;; no package in the public repos yet :(
:config
(c-add-style "OpenBSD" openbsd-knf-style)
(setq c-default-style '((c-mode . "OpenBSD")))
;; In the modeline, show which function you're currently in.
(add-hook 'c-mode-common-hook
(lambda ()
(when (derived-mode-p 'c-mode 'c++-mode 'java-mode)
(which-func-mode 1)))))
;; Jornaling with org-journal: https://github.com/bastibe/org-journal
(use-package org-journal
:defer 20 ; postpone loading by 20s
:init
(setq org-journal-dir "~/Journal/"))
;; Configure whitespace package.
(use-package whitespace
:ensure nil ;; built-in package, don't search in the repos
:config
(setq-default show-trailing-whitespace t))
;; Single Dired buffer: https://github.com/crocket/dired-single
(use-package dired-single
:config
(defun my-dired-init ()
"Bunch of stuff to run for dired, either immediately or when it's
loaded."
;; <add other stuff here>
(define-key dired-mode-map [remap dired-find-file]
'dired-single-buffer)
(define-key dired-mode-map [remap dired-mouse-find-file-other-window]
'dired-single-buffer-mouse)
(define-key dired-mode-map [remap dired-up-directory]
'dired-single-up-directory))
;; if dired's already loaded, then the keymap will be bound
(if (boundp 'dired-mode-map)
;; we're good to go; just add our bindings
(my-dired-init)
;; it's not loaded yet, so add our bindings to the load-hook
(add-hook 'dired-load-hook 'my-dired-init)))
;; Emacs Neotree config: https://github.com/jaypei/emacs-neotree
(use-package neotree
:config
(global-set-key [f8] 'neotree-toggle)
(setq neo-theme (if (display-graphic-p) 'icons 'arrow)))
(use-package helm
:init
(setq helm-command-prefix-key "C-c h")
(setq helm-semantic-fuzzy-match t
helm-imenu-fuzzy-match t)
:config
(require 'helm-config)
(helm-mode 1))
;; GNU GLOBAL helm interface: https://github.com/emacsorphanage/helm-gtags
(use-package helm-gtags
:after helm
:init
(setq helm-gtags-ignore-case t
helm-gtags-auto-update t
helm-gtags-use-input-at-cursor t
helm-gtags-pulse-at-cursor t
helm-gtags-prefix-key "\C-cg"
helm-gtags-suggested-key-mapping t)
(add-hook 'dired-mode-hook 'helm-gtags-mode)
(add-hook 'eshell-mode-hook 'helm-gtags-mode)
(add-hook 'c-mode-hook 'helm-gtags-mode)
(add-hook 'c++-mode-hook 'helm-gtags-mode)
(add-hook 'asm-mode-hook 'helm-gtags-mode)
:config
(define-key helm-gtags-mode-map (kbd "C-c g a") 'helm-gtags-tags-in-this-function)
(define-key helm-gtags-mode-map (kbd "C-j") 'helm-gtags-select)
(define-key helm-gtags-mode-map (kbd "M-.") 'helm-gtags-dwim)
(define-key helm-gtags-mode-map (kbd "M-,") 'helm-gtags-pop-stack)
(define-key helm-gtags-mode-map (kbd "C-c <") 'helm-gtags-previous-history)
(define-key helm-gtags-mode-map (kbd "C-c >") 'helm-gtags-next-history))
;; all-the-icons config: https://github.com/domtronn/all-the-icons.el
(use-package all-the-icons)
;; fill-column-indicator: https://www.emacswiki.org/emacs/FillColumnIndicator
(use-package fill-column-indicator
:config
(setq fci-rule-column 80)
(setq fci-rule-color "#373844")
(define-globalized-minor-mode global-fci-mode fci-mode
(lambda ()
(if (and
(not (string-match "^\*.*\*$" (buffer-name)))
(not (eq major-mode 'dired-mode))
(not (eq major-mode 'neotree-mode))
(not (eq major-mode 'magit-mode)))
(fci-mode 1))))
(global-fci-mode 1))
;; ibuffer-vc: https://github.com/purcell/ibuffer-vc
(use-package ibuffer-vc
:config
(global-set-key (kbd "C-x C-b") 'ibuffer)
(add-hook 'ibuffer-hook
(lambda ()
(ibuffer-vc-set-filter-groups-by-vc-root)
(unless (eq ibuffer-sorting-mode 'alphabetic)
(ibuffer-do-sort-by-alphabetic)))))
;; centaur-tabs: https://github.com/ema2159/centaur-tabs
(use-package centaur-tabs
:config
(centaur-tabs-mode t)
(centaur-tabs-headline-match)
(global-set-key (kbd "C-<prior>") 'centaur-tabs-backward)
(global-set-key (kbd "C-<next>") 'centaur-tabs-forward)
(setq centaur-tabs-style "bar")
(setq centaur-tabs-height 28)
(setq centaur-tabs-set-icons t)
(setq centaur-tabs-gray-out-icons 'buffer)
(setq centaur-tabs-set-modified-marker t)
(put 'upcase-region 'disabled nil)
(put 'downcase-region 'disabled nil))
(use-package mu4e
:ensure nil ; installed using FreeBSD's pkg
:defer 5 ; postpone loading by 5s
:init
(setq mu4e-view-show-images nil)
:config
;; Load org-mode integration
(require 'org-mu4e)
;; Refresh mail using isync every 10 minutes
(setq mu4e-update-interval (* 10 60))
(setq mu4e-index-update-in-background t)
(setq mu4e-get-mail-command "mbsync -a -c ~/.emacs.d/mbsyncrc")
(setq mu4e-maildir "~/Mail")
;; prefer plain text during rendering
(setq mu4e-view-prefer-html nil)
;; w3m should be installed beforehand
(setq mu4e-html2text-command "w3m -dump -T text/html -o display_link_number=true")
(setq mu4e-view-html-plaintext-ratio-heuristic most-positive-fixnum)
;; Do NOT render HTML colors
(setq shr-use-colors nil)
;; ;; Use Ivy for mu4e completions (maildir folders, etc)
;; (setq mu4e-completing-read-function #'ivy-completing-read)
;; Make sure that moving a message (like to Trash) causes the
;; message to get a new file name. This helps to avoid the
;; dreaded "UID is N beyond highest assigned" error.
;; See this link for more info: https://stackoverflow.com/a/43461973
(setq mu4e-change-filenames-when-moving t)
;; Set up contexts for email accounts
(setq mu4e-contexts
`(,(make-mu4e-context
:name "mcusim.org"
:match-func (lambda (msg) (when msg
(string-prefix-p "/MCUSim" (mu4e-message-field msg :maildir))))
:vars '(
(user-full-name . "Dmitry Salychev")
(user-mail-address . "dsl@mcusim.org")
(mu4e-sent-folder . "/MCUSim/Sent")
(mu4e-trash-folder . "/MCUSim/Trash")
(mu4e-drafts-folder . "/MCUSim/Drafts")
(mu4e-refile-folder . "/MCUSim/Archive")
(mu4e-sent-messages-behavior . sent)
))
))
(setq mu4e-context-policy 'pick-first)
;; ;; Prevent mu4e from permanently deleting trashed items
;; ;; This snippet was taken from the following article:
;; ;; http://cachestocaches.com/2017/3/complete-guide-email-emacs-using-mu-and-/
;; (defun remove-nth-element (nth list)
;; (if (zerop nth) (cdr list)
;; (let ((last (nthcdr (1- nth) list)))
;; (setcdr last (cddr last))
;; list)))
;; (setq mu4e-marks (remove-nth-element 5 mu4e-marks))
;; (add-to-list 'mu4e-marks
;; '(trash
;; :char ("d" . "▼")
;; :prompt "dtrash"
;; :dyn-target (lambda (target msg) (mu4e-get-trash-folder msg))
;; :action (lambda (docid msg target)
;; (mu4e~proc-move docid
;; (mu4e~mark-check-target target) "-N"))))
;; Display options
(setq mu4e-view-show-images nil)
(setq mu4e-view-show-addresses 't)
;; Do not show attached images as inlined ones
;; (setq gnus-inhibit-images t)
;; Composing mail
(setq mu4e-compose-dont-reply-to-self t)
;; ;; Use mu4e for sending e-mail
;; (setq mail-user-agent 'mu4e-user-agent
;; message-send-mail-function 'smtpmail-send-it
;; smtpmail-smtp-server "smtp.fastmail.com"
;; smtpmail-smtp-service 465
;; smtpmail-stream-type 'ssl)
;; ;; Signing messages (use mml-secure-sign-pgpmime)
;; (setq mml-secure-openpgp-signers '("53C41E6E41AAFE55335ACA5E446A2ED4D940BF14"))
;; ;; (See the documentation for `mu4e-sent-messages-behavior' if you have
;; ;; additional non-Gmail addresses and want assign them different
;; ;; behavior.)
;; setup some handy shortcuts
;; you can quickly switch to your Inbox -- press ``ji''
;; then, when you want archive some messages, move them to
;; the 'All Mail' folder by pressing ``ma''.
;; (setq mu4e-maildir-shortcuts
;; '(("/MCUSim/INBOX" . ?1)
;; ("/MCUSim/Sent" . ?2)
;; ("/MCUSim/Drafts" . ?3)
;; ("/MCUSim/Archive" . ?4)
;; ("/MCUSim/Trash" . ?5)))
(setq mu4e-bookmarks
;; General directories
`(,(make-mu4e-bookmark
:name "Inbox"
:query "maildir:/MCUSim/INBOX"
:key ?1)
,(make-mu4e-bookmark
:name "Sent"
:query "maildir:/MCUSim/Sent"
:key ?2)
,(make-mu4e-bookmark
:name "Drafts"
:query "maildir:/MCUSim/Drafts"
:key ?3)
,(make-mu4e-bookmark
:name "Archive"
:query "maildir:/MCUSim/Archive"
:key ?4)
,(make-mu4e-bookmark
:name "Trash"
:query "maildir:/MCUSim/Trash"
:key ?5)
,(make-mu4e-bookmark
:name "Junk"
:query "maildir:/MCUSim/Junk"
:key ?6)
;; FreeBSD mailing lists
,(make-mu4e-bookmark
:name "FreeBSD - src-committers (!)"
:query "maildir:/MCUSim/FreeBSD/!src-committers"
:key ?q)
,(make-mu4e-bookmark
:name "FreeBSD - developers (!)"
:query "maildir:/MCUSim/FreeBSD/!developers"
:key ?w)
,(make-mu4e-bookmark
:name "FreeBSD - current"
:query "maildir:/MCUSim/FreeBSD/current"
:key ?e)
,(make-mu4e-bookmark
:name "FreeBSD - phabric-noreply"
:query "maildir:/MCUSim/FreeBSD/phabric-noreply"
:key ?r)
,(make-mu4e-bookmark
:name "FreeBSD - hackers"
:query "maildir:/MCUSim/FreeBSD/hackers"
:key ?t)
,(make-mu4e-bookmark
:name "FreeBSD - drivers"
:query "maildir:/MCUSim/FreeBSD/drivers"
:key ?y)
,(make-mu4e-bookmark
:name "FreeBSD - embedded"
:query "maildir:/MCUSim/FreeBSD/embedded"
:key ?u)
,(make-mu4e-bookmark
:name "FreeBSD - arm"
:query "maildir:/MCUSim/FreeBSD/arm"
:key ?i)
,(make-mu4e-bookmark
:name "FreeBSD - advocacy"
:query "maildir:/MCUSim/FreeBSD/advocacy"
:key ?o)
,(make-mu4e-bookmark
:name "FreeBSD - announce"
:query "maildir:/MCUSim/FreeBSD/announce"
:key ?p)
,(make-mu4e-bookmark
:name "FreeBSD - advisories"
:query "maildir:/MCUSim/FreeBSD/advisories"
:key ?a)
,(make-mu4e-bookmark
:name "FreeBSD - errata"
:query "maildir:/MCUSim/FreeBSD/errata"
:key ?s)
,(make-mu4e-bookmark
:name "FreeBSD - net"
:query "maildir:/MCUSim/FreeBSD/net"
:key ?d)
,(make-mu4e-bookmark
:name "FreeBSD - head"
:query "maildir:/MCUSim/FreeBSD/head"
:key ?f)
,(make-mu4e-bookmark
:name "FreeBSD - ports"
:query "maildir:/MCUSim/FreeBSD/ports"
:key ?g)
,(make-mu4e-bookmark
:name "FreeBSD - src-all"
:query "maildir:/MCUSim/FreeBSD/src-all"
:key ?h)
,(make-mu4e-bookmark
:name "FreeBSD - freebsd-virtualization"
:query "maildir:/MCUSim/FreeBSD/freebsd-virtualization"
:key ?j)
,(make-mu4e-bookmark
:name "FreeBSD - dev-commits-src-branches"
:query "maildir:/MCUSim/FreeBSD/dev-commits-src-branches"
:key ?k)
,(make-mu4e-bookmark
:name "FreeBSD - dev-commits-src-all"
:query "maildir:/MCUSim/FreeBSD/dev-commits-src-all"
:key ?l)
,(make-mu4e-bookmark
:name "FreeBSD - dev-commits-src-main"
:query "maildir:/MCUSim/FreeBSD/dev-commits-src-main"
:key ?z)
,(make-mu4e-bookmark
:name "FreeBSD - dev-commits-ports-main"
:query "maildir:/MCUSim/FreeBSD/dev-commits-ports-main"
:key ?x)
;; Others
,(make-mu4e-bookmark
:name "BSDWeekly - newsletter"
:query "maildir:/MCUSim/BSDWeekly/newsletter"
:key ?c)
,(make-mu4e-bookmark
:name "EuroBSDCon - chat"
:query "maildir:/MCUSim/EuroBSDCon/chat"
:key ?v)
,(make-mu4e-bookmark
:name "MCUSim"
:query "maildir:/MCUSim/MCUSim"
:key ?b)
,(make-mu4e-bookmark
:name "MCUSim - dev"
:query "maildir:/MCUSim/MCUSim/dev"
:key ?n)
,(make-mu4e-bookmark
:name "NomadBSD"
:query "maildir:/MCUSim/NomadBSD"
:key ?m)
,(make-mu4e-bookmark
:name "US-CERT"
:query "maildir:/MCUSim/US-CERT"
:key ?7)
,(make-mu4e-bookmark
:name "GOG"
:query "maildir:/MCUSim/GOG"
:key ?8)
,(make-mu4e-bookmark
:name "Hackaday"
:query "maildir:/MCUSim/Hackaday"
:key ?9)
,(make-mu4e-bookmark
:name "Tindie"
:query "maildir:/MCUSim/Tindie"
:key ?0)
,(make-mu4e-bookmark
:name "Italki"
:query "maildir:/MCUSim/Italki"
:key ?-)
))
;; don't keep message buffers around
(setq message-kill-buffer-on-exit t)
;; (setq dw/mu4e-inbox-query
;; "(maildir:/Personal/Inbox OR maildir:/Fastmail/INBOX) AND flag:unread")
;; (defun dw/go-to-inbox ()
;; (interactive)
;; (mu4e-headers-search dw/mu4e-inbox-query))
;; (dw/leader-key-def
;; "m" '(:ignore t :which-key "mail")
;; "mm" 'mu4e
;; "mc" 'mu4e-compose-new
;; "mi" 'dw/go-to-inbox
;; "ms" 'mu4e-update-mail-and-index)
;; Use fancy characters for threads
(setq mu4e-use-fancy-chars nil)
(setq mu4e-headers-thread-child-prefix '("├> " . "├▶ "))
(setq mu4e-headers-thread-last-child-prefix '("└> " . "└▶ "))
(setq mu4e-headers-thread-connection-prefix '("│ " . "│ "))
(setq mu4e-headers-thread-orphan-prefix '("┬> " . "┬▶ "))
(setq mu4e-headers-thread-single-orphan-prefix '("─> " . "─▶ "))
;; Start mu4e in the background so that it syncs mail periodically
(mu4e t))
(use-package mu4e-alert
:after mu4e
:config
;; Show unread emails from MCUSim inbox.
(setq mu4e-alert-interesting-mail-query "maildir:/MCUSim/INBOX")
;; Show notifications for mails already notified.
(setq mu4e-alert-notify-repeated-mails nil)
(mu4e-alert-enable-notifications))
;; ----------------- 8. General Configuration ----------------------------------
;; Frame opacity
;; (set-frame-parameter (selected-frame) 'alpha '(90 . 50))
;; (add-to-list 'default-frame-alist '(alpha . (90 . 50)))
;; Show line numbers the easy way.
;; See https://www.emacswiki.org/emacs/LineNumbers#toc1 for details.
;; (when (version<= "26.0.50" emacs-version)
;; (global-display-line-numbers-mode))
;; Show line numbers in the programming modes only.
(add-hook 'prog-mode-hook 'display-line-numbers-mode)
;; General tweaks.
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
(set-face-attribute 'default nil :height 105)
(semantic-mode 1)
(set-default 'semantic-case-fold t)
(desktop-save-mode 0)
;; ----------------- 9. Custom Configuration (auto-generated) -----------------
(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.
'(custom-enabled-themes '(dracula))
'(neo-theme 'icons)
'(neo-window-width 70)
'(package-selected-packages
'(use-package unicode-fonts org-journal no-littering neotree mu4e-alert magit ibuffer-vc highlight-parentheses helm-gtags fill-column-indicator dracula-theme dired-single centaur-tabs all-the-icons)))
(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.
'(default ((t (:height 105 :family "Hack"))))
'(tab-line-tab ((t (:background "#282a36" :foreground "#ff79c6" :box (:line-width 3 :color "#282a36"))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment