- Introduction to the Config
- Global Options
- Fonts
- Core
- Org Mode
- Office Tools
- Development Tools
- LSP
- RSS
- Spell Checking
- Global Keybindings
- Local Overwrite
- Additional Notes
Place your private configuration here! Remember, you do not need to run ‘doom sync’ after modifying this file!
;;; $DOOMDIR/config.el -*- lexical-binding: t; -*-
Personal Info Some functionality uses this to identify you, e.g. GPG configuration, email clients, file templates and snippets.
(when (file-exists-p (expand-file-name "personal.el" doom-private-dir))
(load! (expand-file-name "personal.el" doom-private-dir))
)
(setq
doom-theme 'doom-gruvbox
display-line-numbers-type 'relative
scroll-margin 2
window-divider-default-right-width 6 ;; set width of window dividers
split-height-threshold nil ;; HACK diable to allow peep-dired to work (prefered 0)
confirm-kill-emacs nil)
(xterm-mouse-mode 1)
Doom exposes five (optional) variables for controlling fonts in Doom. Here are the three important ones:
- ‘doom-font’ – standard monospace font that is used for most things in Emacs.
- ‘doom-variable-pitch-font’ – variable font which is useful in some Emacs plugins.
- ‘doom-big-font’ – used in doom-big-font-mode; useful for presentations.
- ‘font-lock-comment-face’ – for comments.
- ‘font-lock-keyword-face’ – for keywords with special significance like ‘setq’ in elisp.
- ‘global-prettify-symbols-mode’ – change certain keywords to symbols, such as lambda!
They all accept either a font-spec, font string (“Input Mono-12”), or xlfd font string. You generally only need these two:
(setq
doom-font (font-spec :family "Hack Nerd Font" :size 16)
doom-variable-pitch-font (font-spec :family "Hack Nerd Font")
global-prettify-symbols-mode t)
(if (featurep :system 'macos) (setq
doom-symbol-font (font-spec :family "STIX Two Math")))
(custom-set-faces!
'(font-lock-comment-face :slant italic)
'(font-lock-keyword-face :slant italic))
(use-package! doom-themes
:config
(setq
doom-themes-enable-bold t
doom-themes-enable-italic t))
(use-package! emojify
:defer t
:hook (after-init . global-emojify-mode))
(doom-big-font-mode)
(setq
fancy-splash-image (expand-file-name "doom-logo.png" doom-user-dir)
+doom-dashboard-menu-sections '(
("Reload last session" :icon
(nerd-icons-octicon "nf-oct-history" :face 'doom-dashboard-menu-title)
:when
(cond
((modulep! :ui workspaces)
(file-exists-p
(expand-file-name persp-auto-save-fname persp-save-dir)))
((require 'desktop nil t)
(file-exists-p
(desktop-full-file-name))))
:action doom/quickload-session)
("Recently opened files" :icon
(nerd-icons-faicon "nf-fa-file_text" :face 'doom-dashboard-menu-title)
:action recentf-open-files)
("Open org-agenda" :icon
(nerd-icons-octicon "nf-oct-calendar" :face 'doom-dashboard-menu-title)
:when
(fboundp 'org-agenda)
:action org-agenda)
("Open project" :icon
(nerd-icons-octicon "nf-oct-briefcase" :face 'doom-dashboard-menu-title)
:action projectile-switch-project)
("Jump to bookmark" :icon
(nerd-icons-octicon "nf-oct-bookmark" :face 'doom-dashboard-menu-title)
:action bookmark-jump)
("Open private configuration" :icon
(nerd-icons-octicon "nf-oct-tools" :face 'doom-dashboard-menu-title)
:when
(file-directory-p doom-user-dir)
:action doom/open-private-config)
("Open documentation" :icon
(nerd-icons-octicon "nf-oct-book" :face 'doom-dashboard-menu-title)
:action doom/help)))
(use-package! doom-modeline
:config
(remove-hook 'doom-modeline-mode-hook #'size-indication-mode) ; filesize in modeline
(setq
doom-modeline-height 32
doom-modeline-column-zero-based nil
doom-modeline-indent-info t
doom-modeline-major-mode-icon t))
(use-package! dired
:commands (dired dired-jump)
:config
(map! :map dired-mode-map
:desc "Go to parent directory" :n "h" #'dired-up-directory
:desc "Go to directory / Open file" :n "l" #'dired-find-file
:desc "Create symlink" :n "S" #'dired-do-symlink
:desc "Create new file" :n "-" #'dired-create-empty-file))
Toggle hidden files in Dired
(use-package! dired-hide-dotfiles
:after dired
:hook (dired-mode . dired-hide-dotfiles-mode)
:config
(map! :map dired-mode-map
:desc "Hide dot files" :n "zo" (lambda () (interactive) (dired-hide-dotfiles-mode 0))
:desc "Show dot files" :n "zm" (lambda () (interactive) (dired-hide-dotfiles-mode 1))
:desc "Toggle dot files" :n "za" #'dired-hide-dotfiles-mode
:desc "Toggle dot files" :n "z." #'dired-hide-dotfiles-mode))
Peep
(use-package! peep-dired
:after dired
:config
(add-hook 'peep-dired-hook 'evil-normalize-keymaps)
(map! :map dired-mode-map
:desc "Preview a file" :n "p" #'peep-dired
:map peep-dired-mode-map
:desc "Preview next file" :n "k" #'peep-dired-prev-file
:desc "Preview prev file" :n "j" #'peep-dired-next-file
:desc "Scroll preview pane up" :n "C-k" #'peep-dired-scroll-page-up
:desc "Scroll preview pane down" :n "C-j" #'peep-dired-scroll-page-down)
(setq
peep-dired-cleanup-eagerly nil
peep-dired-cleanup-on-disable t))
(use-package! evil
:config
(map! :map evil-insert-state-map
:i "<C-h>" #'evil-delete-backward-char-and-join)
(setq evil-cross-lines t))
(use-package! which-key
:init
(setq which-key-idle-delay 0.4))
(use-package! xdg)
(use-package! smartparens-mode
:ensure smartparens
;; :defer t
:hook (js-mode . smartparens-strict-mode)
:config
(require 'smartparens-config))
(use-package! org
:commands org-capture-goto-target
:init
(setq
org-directory (if (featurep :system 'macos) "~/Documents/notes/"
(expand-file-name "notes/" (xdg-user-dir "DOCUMENTS")))
org-agenda-files (list org-directory)
org-default-notes-file (expand-file-name "notes.org" org-directory)
+org-capture-journal-file (expand-file-name "writing/journal.org" org-directory)
org-archive-location (expand-file-name "archive.org::datetree/" org-directory) ;; can also use "archive.org::datetrea/* %s"
org-id-locations-file (expand-file-name ".orgids" org-directory))
:hook (org-mode . (lambda ()
(make-local-variable 'display-line-numbers)
(visual-line-mode -1)
(setq display-line-numbers 'visual)))
:config
(map! :mode org-mode
:localleader
:n "B" #'org-babel-tangle)
(map! :map org-mode-map
:desc "Move line(s) up" :nv "<M-up>" #'drag-stuff-up
:desc "Move line(s) down" :nv "<M-down>" #'drag-stuff-down
:desc "Move line(s) left" :nv "<M-left>" #'drag-stuff-left
:desc "Move line(s) right" :nv "<M-right>" #'drag-stuff-right
:desc "Go to prev visual line" :n "<up>" #'evil-previous-visual-line
:desc "Go to next visual line" :n "<down>" #'evil-next-visual-line)
;; (map! :map org-mode-map
;; :n "<M-h>" #'org-table-previous-field
;; :n "<M-j>" #'org-table-next-row
;; :n "<M-k>" #'org-table-previous-row
;; :n "<M-l>" #'org-table-next-field)
;; ----- org-capture -----------------------------------------------------
;; (pushnew! org-capture-templates
;; ;; '("j" "Journal" entry (file+olp+datetree +org-capture-journal-file) "* %U %?\n%i\n%a" :prepend t)
;; '("w" "Work todo" entry (file+headline "work.org" "Inbox") "* TODO %?\n%i\n%a" :prepend t)
;; '("h" "Housing todo" entry (file+headline "housing.org" "Inbox") "* TODO %?\n%i\n%a" :prepend t))
;; ----- headings --------------------------------------------------------
(setq org-ellipsis " ▼ "
org-log-into-drawer t
org-log-done 'time
org-hide-emphasis-markers t)
;; ----- fonts -----------------------------------------------------------
;; font sizes for each header level in Org mode.
(custom-set-faces
'(org-level-1 ((t (:inherit outline-1 :height 1.2))))
'(org-level-2 ((t (:inherit outline-2 :height 1.1))))
'(org-level-3 ((t (:inherit outline-3 :height 1.0))))
'(org-level-4 ((t (:inherit outline-4 :height 1.0))))
'(org-level-5 ((t (:inherit outline-5 :height 1.0)))))
;; ----- org-special -----------------------------------------------------
(setq org-src-window-setup 'other-frame)
(set-popup-rule! "^\\*Org Src" :ignore t)
;; ----- org-refile ------------------------------------------------------
(setq org-refile-targets '((org-agenda-files :maxlevel . 1)))
(advice-add 'org-refile :after 'org-save-all-org-buffers)
;; ----- org-archive -----------------------------------------------------
(setq org-archive-subtree-add-inherited-tags t)
;; ----- org-publish -----------------------------------------------------
(setq org-publish-project-alist
'(("github.io"
:base-directory "~/projects/git/artemsmaznov.github.io/org"
:base-extension "org"
:publishing-directory "~/projects/git/artemsmaznov.github.io"
:recursive t
:publishing-function org-html-publish-to-html
:headline-levels 4
:auto-preamble t
:exclude "header.org")))
;; ----- Search Engines --------------------------------------------------
;; e.g. [[arch-wiki:emacs][Emacs Page]]
(setq org-link-abbrev-alist
'(("arch-wiki" . "https://wiki.archlinux.org/title/")
("pacman" . "https://archlinux.org/packages/?name=")
("aur" . "https://aur.archlinux.org/packages/")
("github" . "https://github.com/")
("google" . "http://www.google.com/search?q=")
("brave" . "https://search.brave.com/search?q=")
("wiki" . "https://en.wikipedia.org/wiki/")
))
;; ----- org-clock -------------------------------------------------------
(map! :mode org-mode
:localleader
:prefix "c"
:n "p" #'org-clock-display)
(setq org-clock-persist 'history
org-clock-idle-time nil)
(org-clock-persistence-insinuate)
;; ----- Org templates ---------------------------------------------------
(require 'org-tempo)
;; extra languages for src blocks
(pushnew! org-structure-template-alist
'("el" . "src emacs-lisp")
'("js" . "src javascript")
'("lu" . "src lua")
'("py" . "src python")
'("sh" . "src shell")
'("ya" . "src yaml"))
;; extra org structure templates
(pushnew! org-src-lang-modes
'("conf-unix" . conf-unix)
'("toml" . conf-toml)))
(use-package! org-journal
:after org
:init
(setq
org-journal-dir (expand-file-name "writing/" org-directory))
:config
(setq
org-journal-hide-entries-p nil
org-journal-search-results-order-by :desc
org-journal-enable-encryption nil
org-journal-encrypt-journal nil))
(use-package! org-roam
:after org
:config
(setq org-roam-directory org-directory))
(use-package! org-agenda
:after org
:defer t
:config
(map! :map org-agenda-mode-map
:m "D" #'org-agenda-day-view
:m "W" #'org-agenda-week-view
:m "M" #'org-agenda-month-view ;; doesn't work
:m "T" #'org-agenda-fortnight-view
:m "C-." #'org-agenda-goto-today
:m "C-h" #'org-agenda-earlier
:m "C-l" #'org-agenda-later)
(setq org-agenda-start-with-log-mode t
org-agenda-start-day nil
org-agenda-span 'week
org-agenda-start-on-weekday 1
org-deadline-warning-days 14))
(use-package! org-superstar
:after org
:defer t
:hook (org-mode . org-superstar-mode))
Put at the header of the Org
document to enable auto tangle on save for it
#+auto_tangle: t
(use-package! org-auto-tangle
:after org
:defer t
:hook (org-mode . org-auto-tangle-mode)
:config
(setq org-auto-tangle-babel-safelist
'("README.org"
"SHELLS.org"
"local.org")))
We need ox-man for “Org eXporting” to manpage format.
(after! org
(use-package ox-man))
(setq rmail-spool-directory "/var/spool/mail/artem")
Setting up ~/.authinfo.gpg
with credentials
machine smtp.gmail.com login [email protected] password eXaMpLePaSsWoRd port 465
- Arch Linux:
$ pacman -S isync
$ paru -S mu
A custom variable containing an email address string needs to be defined for each context
(defvar my/email/main "[email protected]" "My primary email address")
(use-package! mu4e
:defer t
:init
(setq
doom-modeline-mu4e t)
;; start mu4e in the background so it auto-syncs emails
(if (and
(executable-find "mu")
(not (get-process " *mu4e-server*")))
(mu4e t))
:config
(map! :map mu4e-view-mode-map
:n "m" #'mu4e-view-mark-for-something
:n "M" #'mu4e-view-mark-for-move
:n "t" #'mu4e-view-mark-subthread
:n "T" #'mu4e-view-mark-thread
:map mu4e-headers-mode-map
:n "m" #'mu4e-headers-mark-for-something
:n "M" #'mu4e-headers-mark-for-move
:n "t" #'mu4e-headers-mark-subthread
:n "T" #'mu4e-headers-mark-thread)
(setq
mu4e-update-interval (* 5 60) ;; auto-sync interval in seconds
mu4e-confirm-quit t
mu4e-get-mail-command "true"
mu4e-maildir-shortcuts
'(("/inbox" . ?i)
("/drafts" . ?d)
("/sent" . ?s)
("/archive" . ?a)
("/trash" . ?t))
+mu4e-header--maildir-colors
'(("/sent" . all-the-icons-dgreen)
("/drafts" . all-the-icons-yellow)
("/trash" . all-the-icons-red))
;; headers - view listing the emails
mu4e-split-view 'vertical
mu4e-headers-visible-columns 170
mu4e-headers-time-format "%l:%M:%S %p"
mu4e-headers-date-format "%e %b %Y"
mu4e-headers-long-date-format "%a, %e %B %Y, %l:%M:%S %p"
;; colum layout for mail list
mu4e-headers-fields
'((:account-stripe . 1)
(:flags . 7)
(:human-date . 12)
(:from-or-to . 25)
(:thread-subject . nil))
;; message
;; mu4e-view-date-format "%c"
;; mu4e-date-format-long "%c"
message-kill-buffer-on-exit t ;; don't keep message buffers
;; composing
mu4e-compose-format-flowed t ;; use html formatting for outgoing emails
mu4e-compose-dont-reply-to-self t
;; contexts
user-full-name "Artem Smaznov"
mu4e-context-policy 'pick-first
mu4e-compose-context-policy 'ask-if-none
;; mu4e-index-cleanup nil ;; don't need to run cleanup after indexing for gmail
;; mu4e-index-lazy-check t ;; because gmail uses labels as folders we can use lazy check since messages don't really "move"
mu4e-contexts
`(
,(make-mu4e-context
:name "spool"
;; :vars `((user-mail-address . ,my/email/artem))
)))
;; modeline
(setq
;; mu4e-alert-interesting-mail-query "flag:unread AND NOT flag:trashed AND NOT maildir:\"/[Gmail]/All Mail\""
mu4e-display-update-status-in-modeline t))
;; (use-package! mu4e
;; :defer t
;; :init
;; (setq
;; doom-modeline-mu4e t)
;; :config
;; (map! :map mu4e-view-mode-map
;; :n "m" #'mu4e-view-mark-for-something
;; :n "M" #'mu4e-view-mark-for-move
;; :n "t" #'mu4e-view-mark-subthread
;; :n "T" #'mu4e-view-mark-thread
;; :map mu4e-headers-mode-map
;; :n "m" #'mu4e-headers-mark-for-something
;; :n "M" #'mu4e-headers-mark-for-move
;; :n "t" #'mu4e-headers-mark-subthread
;; :n "T" #'mu4e-headers-mark-thread)
;; (setq
;; mu4e-get-mail-command (concat "mbsync -a -c " (xdg-config-home) "/isync/mbsyncrc" )
;; mu4e-update-interval (* 15 60) ;; auto-sync interval in seconds
;; mu4e-maildir-shortcuts
;; '(("/Inbox" . ?i)
;; ("/Work" . ?w)
;; ("/[Gmail]/Important" . ?I)
;; ("/[Gmail]/Sent Mail" . ?s)
;; ("/[Gmail]/Drafts" . ?d)
;; ("/[Gmail]/All Mail" . ?a)
;; ("/[Gmail]/Trash" . ?t))
;; +mu4e-header--maildir-colors
;; '(("/Inbox" . all-the-icons-yellow)
;; ("/Work" . all-the-icons-red)
;; ("[Gmail]" . all-the-icons-dgreen)))
;; ;; headers - view listing the emails
;; (setq
;; mu4e-split-view 'vertical
;; mu4e-headers-visible-columns 170
;; mu4e-headers-time-format "%l:%M:%S %p"
;; mu4e-headers-date-format "%e %b %Y"
;; mu4e-headers-long-date-format "%a, %e %B %Y, %l:%M:%S %p"
;; ;; colum layout for mail list
;; mu4e-headers-fields
;; '((:account-stripe . 1)
;; (:flags . 7)
;; (:human-date . 12)
;; (:from-or-to . 25)
;; (:thread-subject . nil)))
;; ;; message
;; (setq
;; ;; mu4e-view-date-format "%c"
;; ;; mu4e-date-format-long "%c"
;; message-kill-buffer-on-exit t) ;; don't keep message buffers
;; ;; composing
;; (setq
;; mu4e-compose-format-flowed t ;; use html formatting for outgoing emails
;; mu4e-compose-dont-reply-to-self t)
;; ;; contexts
;; (setq
;; user-full-name "Artem Smaznov"
;; mu4e-context-policy 'pick-first
;; mu4e-compose-context-policy 'ask-if-none
;; ;; mu4e-index-cleanup nil ;; don't need to run cleanup after indexing for gmail
;; ;; mu4e-index-lazy-check t ;; because gmail uses labels as folders we can use lazy check since messages don't really "move"
;; mu4e-contexts
;; `(
;; ;; ,(make-mu4e-context
;; ;; :name "Artem"
;; ;; :match-func (lambda (msg) (when msg (mu4e-message-contact-field-matches msg :to my/email/artem)))
;; ;; :vars `((smtpmail-smtp-server . "smtp.gmail.com")
;; ;; (smtpmail-smtp-service . 465)
;; ;; (smtpmail-stream-type . ssl)
;; ;; (user-mail-address . ,my/email/artem)
;; ;; (mu4e-drafts-folder . "/[Gmail]/Drafts")
;; ;; (mu4e-sent-folder . "/[Gmail]/Sent Mail")
;; ;; (mu4e-refile-folder . "/[Gmail]/All Mail")
;; ;; (mu4e-trash-folder . "/[Gmail]/Trash")))
;; ,(make-mu4e-context
;; :name "Main"
;; :match-func (lambda (msg) (when msg (mu4e-message-contact-field-matches msg :to my/email/main)))
;; ;; :match-func (lambda (msg) (when msg (string-prefix-p "/Main" (mu4e-message-field msg :maildir))))
;; :vars `((user-mail-address . ,my/email/main)
;; (mu4e-drafts-folder . "/[Gmail]/Drafts")
;; (mu4e-sent-folder . "/[Gmail]/Sent Mail")
;; (mu4e-refile-folder . "/[Gmail]/All Mail")
;; (mu4e-trash-folder . "/[Gmail]/Trash")))))
;; ;; start mu4e in the background so it auto-syncs emails
;; (mu4e t)
;; ;; modeline
;; (setq
;; mu4e-alert-interesting-mail-query "flag:unread AND NOT flag:trashed AND NOT maildir:\"/[Gmail]/All Mail\""
;; mu4e-display-update-status-in-modeline t))
Function used by mbsync
for authentication with the email server
(defun my/lookup-password (&rest keys)
(let ((result (apply #'auth-source-search keys)))
(if result
(funcall (plist-get (car result) :secret))
nil)))
(use-package! calfw
:defer t
:init
(map! :leader
:prefix "o"
:desc "Calendar" :e "c" #'cfw:open-org-calendar)
:config
(map! :map cfw:calendar-mode-map
:m "C-j" #'cfw:navi-next-month-command
:m "C-k" #'cfw:navi-previous-month-command
:m "C-." #'cfw:navi-goto-today-command
:m "0" #'cfw:navi-goto-week-begin-command
:m "gd" #'cfw:org-goto-date
:m "zd" #'cfw:change-view-day
:m "zw" #'cfw:change-view-week
:m "zm" #'cfw:change-view-month
:m "zt" #'cfw:change-view-two-weeks
:m "T" #'cfw:change-view-two-weeks) ;; not active due to evil-snipe and evil-find-char
(setq
calendar-week-start-day 1
calendar-date-style 'european))
(use-package! icalendar
:defer t
:config
(setq
org-icalendar-use-scheduled '(event-if-todo event-if-not-todo todo-start)
org-icalendar-use-deadline '(event-if-todo-not-done)))
(use-package! org-caldav
:after calfw
:init
(map! :leader
:prefix "n"
:desc "Sync with server" :e "C-s" #'org-caldav-sync)
:config
(setq
org-caldav-url (concat "https://" my/nextcloud/url "/remote.php/dav/calendars/" my/username)
org-caldav-delete-calendar-entries 'always
org-caldav-delete-org-entries 'ask
org-caldav-show-sync-results nil
org-caldav-save-directory (expand-file-name ".caldav/" org-directory)
org-caldav-backup-file (expand-file-name "backup.org" org-caldav-save-directory)
org-caldav-location-newline-replacement ","
org-caldav-exclude-tags '("nocal")
org-caldav-calendars `((:calendar-id "personal" :select-tags ("calgnr")
:inbox ,(expand-file-name "todo.org" org-directory)
:files (,(expand-file-name "todo.org" org-directory)
,(expand-file-name "archive.org" org-directory)))
(:calendar-id "housing" :select-tags ("calhsn")
:inbox ,(expand-file-name "todo.org" org-directory)
:files (,(expand-file-name "todo.org" org-directory)
,(expand-file-name "archive.org" org-directory)))
(:calendar-id "work" :select-tags ("calwrk")
:inbox ,(expand-file-name "todo.org" org-directory)
:files (,(expand-file-name "todo.org" org-directory)
,(expand-file-name "archive.org" org-directory))))))
(use-package! ledger-mode
:defer t
:config
(map! :map ledger-mode-map
:localleader
:e "c" #'ledger-mode-clean-buffer)
(setq ledger-default-date-format "%Y-%m-%d"))
(use-package! org-tree-slide
:after org
:defer t
:init
(map! :map org-mode-map
:leader
:prefix "t"
:desc "Presentation" :e "p" #'org-tree-slide-mode)
:hook ((org-tree-slide-play . my/presentation-start)
(org-tree-slide-stop . my/presentation-end))
:config
(map! :map org-tree-slide-mode-map
"C-h" #'org-tree-slide-move-previous-tree
"C-l" #'org-tree-slide-move-next-tree
"C-SPC" #'org-tree-slide-content)
(setq
org-tree-slide-activate-message "Presentation started!"
org-tree-slide-deactivate-message "Presentation finished!"
org-tree-slide-slide-in-effect t
org-tree-slide-header t
org-tree-slide-breadcrumbs " > "
org-image-actual-width nil))
(defun my/presentation-start ()
(writeroom-mode 1)
(display-line-numbers-mode 0)
(org-display-inline-images) ;; Can also use org-startup-with-inline-images
)
(defun my/presentation-end ()
(writeroom-mode 0)
(display-line-numbers-mode 1)
)
(use-package! magit
:defer t
:config
(setq
magit-repository-directories `((,(xdg-config-home) . 1)
("~/.local/bin" . 0)
("~/projects" . 5))
magit-revision-show-gravatars t ;; enable gravatars
;; magit-display-buffer-function 'magit-display-buffer-traditional ;; open magit in a side window
;; enable granular diff-highlights for all hunks
;; change to t if performance is bad
magit-diff-refine-hunk 'all
magit-repolist-column-flag-alist ' ((magit-untracked-files . "?")
(magit-unstaged-files . "!")
(magit-staged-files . "+"))
magit-repolist-columns ' (("" 10 magit-repolist-column-branch ((:right-align t)))
("B<U" 3 magit-repolist-column-unpulled-from-upstream ((:right-align t) (:sort <)))
("B>U" 3 magit-repolist-column-unpushed-to-upstream ((:right-align t) (:sort <)))
("F" 3 magit-repolist-column-flags nil)
("Name" 25 magit-repolist-column-ident nil)
("Version" 25 magit-repolist-column-version ((:sort magit-repolist-version<)))
("Path" 99 magit-repolist-column-path nil))
magit-submodule-list-columns ' (("Path" 40 magit-modulelist-column-path nil)
("Version" 25 magit-repolist-column-version
((:sort magit-repolist-version<)))
("Branch" 20 magit-repolist-column-branch nil)
("B<U" 3 magit-repolist-column-unpulled-from-upstream
((:right-align t)
(:sort <)))
("B>U" 3 magit-repolist-column-unpushed-to-upstream
((:right-align t)
(:sort <)))
("B<P" 3 magit-repolist-column-unpulled-from-pushremote
((:right-align t)
(:sort <)))
("B>P" 3 magit-repolist-column-unpushed-to-pushremote
((:right-align t)
(:sort <)))
("B" 3 magit-repolist-column-branches
((:right-align t)
(:sort <)))
("S" 3 magit-repolist-column-stashes
((:right-align t)
(:sort <))))))
(use-package! forge
:after magit
:defer t
:init
(if (featurep :system 'macos)
(setq doom-modeline-github nil)
(setq doom-modeline-github t))
:config
(setq
forge-pull-notifications nil
forge-repository-list-columns '(("Owner" 20 t nil owner nil)
("N" 1 t nil sparse-p nil)
("S" 1 t nil selective-p nil)
("Name" 50 t nil name nil)
("Worktree" 99 t nil worktree nil))))
(use-package! code-review
:after magit
:defer t
:config
(map! :map magit-mode-map
"R" #'code-review-forge-pr-at-point
:map forge-topic-mode-map
"R" #'code-review-forge-pr-at-point))
(use-package! magit-todos
:after magit
:defer t
:hook
(magit-mode . magit-todos-mode)
:config
(pushnew! magit-todos-exclude-globs
"Basemark*/"
"Brave*/"
"Code*/"
"Cypress/"
"GIMP/"
"KDE/"
"Nextcloud/"
"chromium/"
"coc/"
"discord/"
"glib*/"
"google*/"
"google-chrome/"
"kde*/"
"torbrowser*/"
"unity*/"
"vivaldi*/"
"{emacs,doom}/"))
(use-package! ansible
:defer t
:hook
(yaml-mode . (lambda ()
(if (s-contains? "ansible" (file-name-directory buffer-file-name) t)
(ansible 1)))))
(use-package! projectile
:defer t
:init
(setq projectile-switch-project-action #'projectile-dired)
(when (file-directory-p "~/projects")
(setq projectile-project-search-path '("~/projects")))
:config
(map! :leader
:prefix "p"
:desc "Run project" :e "A" #'projectile-run-project
:desc "Project substitute" :e "R" #'projectile-replace-regexp))
(use-package! lsp-treemacs
:defer t
:commands lsp-treemacs-errors-list)
(use-package! company
:defer t
:config
(map! :after lsp-mode
:map lsp-mode-map
:i "<tab>" #'company-indent-or-complete-common)
(setq
company-idle-delay 0.5
company-tooltip-idle-delay 2
company-minimum-prefix-length 1))
(use-package! lsp-ivy
:defer t
:commands lsp-ivy-workspace-symbol)
To enable a set of items to cycle through globally, add the following to your configuration
(use-package! rotate-text
:defer t
:config
(pushnew! rotate-text-words
'("yes" "no")
'("on" "off")
'("start" "end")))
(use-package! highlight-indent-guides
:defer t
:config
(setq highlight-indent-guides-method 'fill))
Highlight colors in file
(use-package! rainbow-mode
:defer t
:init
(map! :leader
:prefix "t"
:desc "Colors" :e "c" #'rainbow-mode))
(use-package! lsp-mode
:defer t
:commands (lsp lsp-deferred)
:hook
(rjsx-mode . lsp-deferred)
(python-mode . lsp-deferred)
(feature-mode . lsp-deferred)
(vimrc-mode . lsp-deferred)
(groovy-mode . lsp-deferred))
See this for LSP UI elements and their respective variables
(use-package! lsp-ui
:defer t
:commands lsp-ui-mode
:hook
(lsp-mode . lsp-ui-mode)
:config
(setq
;; 1. Symbol highlighting
lsp-enable-symbol-highlighting t
;; 2. `lsp-ui-doc` hover dialogs
lsp-ui-doc-enable t
lsp-ui-doc-delay 0.75
lsp-ui-doc-show-with-cursor t
lsp-ui-doc-show-with-mouse nil
lsp-ui-doc-position 'top
lsp-ui-doc-alignment 'window
lsp-ui-doc-header t
lsp-ui-doc-border "gray"
;; 3. Lenses
lsp-lens-enable t
;; 4. Headerline
lsp-headerline-breadcrumb-enable t
;; 5. Sideline code actions
lsp-ui-sideline-enable t
lsp-ui-sideline-show-code-actions t
;; 6. Sideline hover symbols
lsp-ui-sideline-show-hover nil
;; 7. Modeline code actions
lsp-modeline-code-actions-enable t
;; 8. Flycheck / flymake
;; lsp-diagnostics-provider :auto
;; 9. Sideline diagnostics
lsp-ui-sideline-show-diagnostics t
;; 10. Eldoc
lsp-eldoc-enable-hover t
;; 11. Modeline diagnostics statistics
lsp-modeline-diagnostics-enable t
;; 12. Signarure help
;; lsp-signature-auto-activate '(:on-trigger-char :on-server-request)
;; 13.
lsp-signature-render-documentation t
;; 14. Completion
;; lsp-completion-provider :capf
;; 15. Completion item detail
lsp-completion-show-detail t
;; 16. Completion item kind
lsp-completion-show-kind t))
;; (use-package! rjsx-mode
;; :ensure t
;; :mode
;; "\\.js\\'"
;; )
- macOS:
$ brew install pyright
- Arch Linux:
$ pacman -S pyright
(use-package! groovy-mode
:defer t
:mode
"/Jenkinsfile.*\\'"
"\\.pipe\\'"
"\\.PIPE\\'"
:hook
(groovy-mode . (lambda () (rainbow-delimiters-mode 1)))
:config
(setq groovy-indent-offset 2))
(use-package! yaml-mode
:defer t
:hook
(yaml-mode . (lambda ()
(spell-fu-mode -1))))
(use-package! jsonc-mode
:defer t
:mode
"\\.jsonc\\'"
)
(use-package! conf-mode
:defer t
:mode
"\\.automount\\'"
"\\.mount\\'"
"\\.path\\'"
"\\.service\\'"
"\\.slice\\'"
"\\.socket\\'"
"\\.target\\'"
"\\.timer\\'"
)
(use-package! crontab-mode
:defer t
;; :mode
;; "cron\\(.d\\)?"
)
(use-package! jinja2-mode
:defer t
:hook
(jinja2-mode . (lambda ()
(spell-fu-mode -1))))
(use-package! feature-mode
:defer t
:mode
"\\.feature\\'"
:config
(setq
feature-default-language "en"
;; feature-step-search-path "features/../**/*step*/*.js"
))
Enable syntax highlighting for .vim files
(use-package! vimrc-mode
:defer t
:mode
"\\.vim\\(rc\\)?\\'"
"\\.vifm\\'"
:config
(setq evil-shift-width 2))
(use-package! syslog-mode
:defer t
:mode
"\\.log"
"\\.[0-9]+\\'"
:hook
(syslog-mode . (lambda ()
(make-local-variable 'display-line-numbers-type)
(setq display-line-numbers-type t)
(display-line-numbers-mode 1))))
(use-package! elfeed
:defer t
:init
(map! :leader
:prefix "o"
:desc "RSS News" :e "n" #'elfeed)
:config
(map! :mode elfeed-search-mode
:desc "Remove Selected" :n "D" #'my/elfeed-search-remove-selected
:mode (elfeed-search-mode elfeed-show-mode)
:localleader
:desc "Show starred" :n "s" #'my/elfeed-show-starred
:desc "Toggle logs" :n "l" #'elfeed-goodies/toggle-logs
:desc "Update" :n "u" #'elfeed-update)
(elfeed-set-timeout 36000)
(setq
elfeed-log-level 'info
elfeed-goodies/log-window-position 'bottom
elfeed-goodies/wide-threshold 0.3
elfeed-goodies/show-mode-padding 1
elfeed-goodies/entry-pane-size 0.5
elfeed-goodies/feed-source-column-width 20
elfeed-use-curl t
elfeed-search-date-format '("%d-%m-%Y" 10 :left)
elfeed-search-filter "@1-month-ago +unread")
(defun my/elfeed-show-starred ()
"Show all starred feeds"
(interactive)
(elfeed-search-set-filter "+star"))
(defun my/elfeed-db-remove-entry (id)
"Removes elfeed entry for given ID"
(avl-tree-delete elfeed-db-index id)
(remhash id elfeed-db-entries))
(defun my/elfeed-search-remove-selected ()
"Remove selected entries from elfeed database"
(interactive)
(let* ((entries (elfeed-search-selected))
(count (length entries)))
(when (y-or-n-p (format "Delete %d entires?" count))
(cl-loop for entry in entries
do (my/elfeed-db-remove-entry (elfeed-entry-id entry)))))
(elfeed-search-update--force)))
(use-package! elfeed-org
:after elfeed
:config
(setq
rmh-elfeed-org-files (list (expand-file-name "rss.org" org-directory))
rmh-elfeed-org-tree-id "elfeed"
rmh-elfeed-org-ignore-tag "ignore"))
(use-package! elfeed-protocol
:after elfeed elfeed-org
:config
(defadvice elfeed (after configure-elfeed-protocol-feeds activate)
"Make elfeed-org autotags rules works with elfeed-protocol."
(setq
elfeed-protocol-feeds (list
(list (concat "owncloud+https://" my/username "@" my/nextcloud/url)
:use-authinfo t
:autotags elfeed-feeds)))
(elfeed-update))
(setq
elfeed-protocol-enabled-protocols '(owncloud)
elfeed-protocol-owncloud-fetch-category-as-tag nil
elfeed-protocol-owncloud-update-with-modified-time t
elfeed-protocol-owncloud-star-tag 'star)
(elfeed-protocol-enable))
- macOS:
$ brew install aspell
- Arch Linux:
$ pacman -S aspell aspell-en aspell-ru
(use-package! spell-fu
:defer t
:hook
(spell-fu-mode
. (lambda ()
;; extra languages
(spell-fu-dictionary-add (spell-fu-get-ispell-dictionary "ru"))
(spell-fu-dictionary-add (spell-fu-get-personal-dictionary
"ru"
(expand-file-name
"dict/ru.pws" (xdg-data-home))))
;; extra personal dictionaries
(spell-fu-dictionary-add (spell-fu-get-personal-dictionary
"people"
(expand-file-name
"dict/en.people.pws" (xdg-data-home))))
(spell-fu-dictionary-add (spell-fu-get-personal-dictionary
"places"
(expand-file-name
"dict/en.places.pws" (xdg-data-home))))
(spell-fu-dictionary-add (spell-fu-get-personal-dictionary
"brands"
(expand-file-name
"dict/en.brands.pws" (xdg-data-home))))
(spell-fu-dictionary-add (spell-fu-get-personal-dictionary
"finance"
(expand-file-name
"dict/en.finance.pws" (xdg-data-home))))
(spell-fu-dictionary-add (spell-fu-get-personal-dictionary
"dev"
(expand-file-name
"dict/en.dev.pws" (xdg-data-home))))
(spell-fu-dictionary-add (spell-fu-get-personal-dictionary
"work"
(expand-file-name
"dict/en.work.pws" (xdg-data-home))))))
:config
(setq
spell-fu-word-delimit-camel-case t
spell-fu-idle-delay 0.25
ispell-personal-dictionary (expand-file-name
"dict/en.pws" (xdg-data-home))))
(map! :leader
;; buffer/bookmark
:prefix "b"
:desc "List bookmarks" :e "L" #'list-bookmarks
:desc "Save current bookmarks to bookmark file" :e "w" #'bookmark-save
;; :desc "Clone indirect buffer other window" "c" #'clone-indirect-buffer-other-window
;; insert
:prefix "i"
:desc "Toilet pagga" :e "t" (cmd! (evil-ex "R!toilet -f pagga "))
;; <localleader>
:prefix "m"
:desc "Justify text" :e "j" #'set-justification
;; toggle
:prefix "t"
:desc "Toggle auto fill mode" :e "a" #'auto-fill-mode
:desc "Toggle scroll bars" :e "S" #'scroll-bar-mode
:desc "Fill column indicator" :e "|" #'global-display-fill-column-indicator-mode
;; workspace
:prefix "TAB"
:desc "Move workspace left" :e "<" #'+workspace/swap-left
:desc "Move workspace right" :e ">" #'+workspace/swap-right)
Load custom configuration overwrites from and external file
(when (file-exists-p (expand-file-name "local.el" doom-private-dir))
(load! (expand-file-name "local.el" doom-private-dir))
)
Whenever you reconfigure a package, make sure to wrap your config in an `after!’ block, otherwise Doom’s defaults may override your settings. E.g.
(after! PACKAGE (setq x y))
The exceptions to this rule:
- Setting file/directory variables (like `org-directory’)
- Setting variables which explicitly tell you to set them before their package is loaded (see ‘C-h v VARIABLE’ to look up their documentation).
- Setting doom variables (which start with ‘doom-’ or ‘+’).
Here are some additional functions/macros that will help you configure Doom.
- `load!’ for loading external *.el files relative to this one
- `use-package!’ for configuring packages
- `after!’ for running code after a package has loaded
- `add-load-path!’ for adding directories to the `load-path’, relative to
this file. Emacs searches the `load-path’ when you load packages with `require’ or `use-package’.
- `map!’ for binding new keys
To get information about any of these functions/macros, move the cursor over the highlighted symbol at press ‘K’ (non-evil users must press ‘C-c c k’). This will open documentation for it, including demos of how they are used. Alternatively, use `C-h o’ to look up a symbol (functions, variables, faces, etc).
You can also try ‘gd’ (or ‘C-c c d’) to jump to their definition and see how they are implemented.