Hermes: First (unsuccessful) attempt at nix-doom-emacs

The missing autload file issue is still there and unfortunately preventing the
installation. Reverting until fix is known.
This commit is contained in:
Payas Relekar 2022-06-08 15:57:34 +05:30
parent aabfc0058c
commit e6cc9ccb5b
7 changed files with 1760 additions and 24 deletions

View file

@ -20,6 +20,39 @@
"type": "github"
}
},
"doom-emacs": {
"flake": false,
"locked": {
"lastModified": 1651775574,
"narHash": "sha256-ux4bzsQJmSxscLrtLR5h2SbXGlt4mKS0B1ffzvO35Ng=",
"owner": "hlissner",
"repo": "doom-emacs",
"rev": "80cd7557e147ccd0abef05ff4eafb93fe9545ad4",
"type": "github"
},
"original": {
"owner": "hlissner",
"ref": "master",
"repo": "doom-emacs",
"type": "github"
}
},
"doom-snippets": {
"flake": false,
"locked": {
"lastModified": 1651709822,
"narHash": "sha256-/PJwt5EuTuUwTD8fmt9vYye3PyPVF0Mrco+Ext0KEJ4=",
"owner": "hlissner",
"repo": "doom-snippets",
"rev": "2596cead5e03896996b7268d057c1d734180547f",
"type": "github"
},
"original": {
"owner": "hlissner",
"repo": "doom-snippets",
"type": "github"
}
},
"emacs-overlay": {
"inputs": {
"flake-utils": "flake-utils",
@ -41,6 +74,102 @@
"type": "github"
}
},
"emacs-overlay_2": {
"flake": false,
"locked": {
"lastModified": 1651724664,
"narHash": "sha256-/Z0AkB2DAxMdOaFYBSkTPjHrMH2e3kReuLEtpLQZfk4=",
"owner": "nix-community",
"repo": "emacs-overlay",
"rev": "1deb4d66be3117dd0d9dbf31fd458035e0f3c4de",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "emacs-overlay",
"type": "github"
}
},
"emacs-so-long": {
"flake": false,
"locked": {
"lastModified": 1575031854,
"narHash": "sha256-xIa5zO0ZaToDrec1OFjBK6l39AbA4l/CE4LInVu2hi0=",
"owner": "hlissner",
"repo": "emacs-so-long",
"rev": "ed666b0716f60e8988c455804de24b55919e71ca",
"type": "github"
},
"original": {
"owner": "hlissner",
"repo": "emacs-so-long",
"type": "github"
}
},
"evil-markdown": {
"flake": false,
"locked": {
"lastModified": 1626852210,
"narHash": "sha256-HBBuZ1VWIn6kwK5CtGIvHM1+9eiNiKPH0GUsyvpUVN8=",
"owner": "Somelauw",
"repo": "evil-markdown",
"rev": "8e6cc68af83914b2fa9fd3a3b8472573dbcef477",
"type": "github"
},
"original": {
"owner": "Somelauw",
"repo": "evil-markdown",
"type": "github"
}
},
"evil-org-mode": {
"flake": false,
"locked": {
"lastModified": 1607203864,
"narHash": "sha256-JxwqVYDN6OIJEH15MVI6XOZAPtUWUhJQWHyzcrUvrFg=",
"owner": "hlissner",
"repo": "evil-org-mode",
"rev": "a9706da260c45b98601bcd72b1d2c0a24a017700",
"type": "github"
},
"original": {
"owner": "hlissner",
"repo": "evil-org-mode",
"type": "github"
}
},
"evil-quick-diff": {
"flake": false,
"locked": {
"lastModified": 1575189609,
"narHash": "sha256-oGzl1ayW9rIuq0haoiFS7RZsS8NFMdEA7K1BSozgnJU=",
"owner": "rgrinberg",
"repo": "evil-quick-diff",
"rev": "69c883720b30a892c63bc89f49d4f0e8b8028908",
"type": "github"
},
"original": {
"owner": "rgrinberg",
"repo": "evil-quick-diff",
"type": "github"
}
},
"explain-pause-mode": {
"flake": false,
"locked": {
"lastModified": 1595842060,
"narHash": "sha256-++znrjiDSx+cy4okFBBXUBkRFdtnE2x+trkmqjB3Njs=",
"owner": "lastquestion",
"repo": "explain-pause-mode",
"rev": "2356c8c3639cbeeb9751744dbe737267849b4b51",
"type": "github"
},
"original": {
"owner": "lastquestion",
"repo": "explain-pause-mode",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
@ -89,6 +218,21 @@
}
},
"flake-utils_2": {
"locked": {
"lastModified": 1649676176,
"narHash": "sha256-OWKJratjt2RW151VUlJPRALb7OU2S5s+f0vLj4o1bHM=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "a4b154ebbdc88c8498a5c7b01589addc9e9cb678",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_3": {
"locked": {
"lastModified": 1653893745,
"narHash": "sha256-0jntwV3Z8//YwuOjzhV2sgJJPt+HY6KhU7VZUL0fKZQ=",
@ -103,6 +247,23 @@
"type": "github"
}
},
"format-all": {
"flake": false,
"locked": {
"lastModified": 1581716637,
"narHash": "sha256-ul7LCe60W8TIvUmUtZtZRo8489TK9iTPDsLHmzxY57M=",
"owner": "lassik",
"repo": "emacs-format-all-the-code",
"rev": "47d862d40a088ca089c92cd393c6dca4628f87d3",
"type": "github"
},
"original": {
"owner": "lassik",
"repo": "emacs-format-all-the-code",
"rev": "47d862d40a088ca089c92cd393c6dca4628f87d3",
"type": "github"
}
},
"home-manager": {
"inputs": {
"flake-compat": "flake-compat",
@ -127,6 +288,61 @@
"type": "github"
}
},
"nix-doom-emacs": {
"inputs": {
"doom-emacs": "doom-emacs",
"doom-snippets": "doom-snippets",
"emacs-overlay": "emacs-overlay_2",
"emacs-so-long": "emacs-so-long",
"evil-markdown": "evil-markdown",
"evil-org-mode": "evil-org-mode",
"evil-quick-diff": "evil-quick-diff",
"explain-pause-mode": "explain-pause-mode",
"flake-utils": "flake-utils_2",
"format-all": "format-all",
"nix-straight": "nix-straight",
"nixpkgs": [
"nixpkgs-unstable"
],
"nose": "nose",
"ob-racket": "ob-racket",
"org": "org",
"org-contrib": "org-contrib",
"org-yt": "org-yt",
"php-extras": "php-extras",
"revealjs": "revealjs",
"rotate-text": "rotate-text"
},
"locked": {
"lastModified": 1652175409,
"narHash": "sha256-8EStP60lqDmVyeRJ9zdH64oAOHAPBlPa8oYqquVrw5Q=",
"owner": "nix-community",
"repo": "nix-doom-emacs",
"rev": "edbe868dd5f8bf447eaffd4cff85167d0771ce0f",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nix-doom-emacs",
"type": "github"
}
},
"nix-straight": {
"flake": false,
"locked": {
"lastModified": 1643475817,
"narHash": "sha256-NpExq5nbPbj/ppkBX3SnETEJuOne1MKJxen8vVHsDFg=",
"owner": "nix-community",
"repo": "nix-straight.el",
"rev": "08d75e5651cb52f8a07e03408ed19e04bee07505",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nix-straight.el",
"type": "github"
}
},
"nixos-hardware": {
"locked": {
"lastModified": 1654057797,
@ -146,7 +362,7 @@
"nixos-wsl": {
"inputs": {
"flake-compat": "flake-compat_2",
"flake-utils": "flake-utils_2",
"flake-utils": "flake-utils_3",
"nixpkgs": [
"nixpkgs-unstable"
]
@ -233,17 +449,146 @@
"type": "gitlab"
}
},
"nose": {
"flake": false,
"locked": {
"lastModified": 1400604510,
"narHash": "sha256-daEi8Kta1oGaDEmUUDDQMahTTPOpvNpDKk22rlr7cB0=",
"owner": "emacsattic",
"repo": "nose",
"rev": "f8528297519eba911696c4e68fa88892de9a7b72",
"type": "github"
},
"original": {
"owner": "emacsattic",
"repo": "nose",
"type": "github"
}
},
"ob-racket": {
"flake": false,
"locked": {
"lastModified": 1584656173,
"narHash": "sha256-rBUYDDCXb+3D4xTPQo9UocbTPZ32kWV1Uya/1DmZknU=",
"owner": "xchrishawk",
"repo": "ob-racket",
"rev": "83457ec9e1e96a29fd2086ed19432b9d75787673",
"type": "github"
},
"original": {
"owner": "xchrishawk",
"repo": "ob-racket",
"type": "github"
}
},
"org": {
"flake": false,
"locked": {
"lastModified": 1651675049,
"narHash": "sha256-lReN2q3o6CUDT8dDsj+LZ4ptzG9E2PwNv5JWWb5D5B4=",
"owner": "emacs-straight",
"repo": "org-mode",
"rev": "d2a459d2596a0cfb1389207b117533389fa59e0f",
"type": "github"
},
"original": {
"owner": "emacs-straight",
"repo": "org-mode",
"type": "github"
}
},
"org-contrib": {
"flake": false,
"locked": {
"lastModified": 1639727892,
"narHash": "sha256-+T6Y87aSAx7kMpigm8d1ODDQIyPBM6a+4qGolXjCEXs=",
"ref": "master",
"rev": "5766ff1088191e4df5fecd55007ba4271e609bcc",
"revCount": 2611,
"type": "git",
"url": "https://git.sr.ht/~bzg/org-contrib"
},
"original": {
"type": "git",
"url": "https://git.sr.ht/~bzg/org-contrib"
}
},
"org-yt": {
"flake": false,
"locked": {
"lastModified": 1527381913,
"narHash": "sha256-dzQ6B7ryzatHCTLyEnRSbWO0VUiX/FHYnpHTs74aVUs=",
"owner": "TobiasZawada",
"repo": "org-yt",
"rev": "40cc1ac76d741055cbefa13860d9f070a7ade001",
"type": "github"
},
"original": {
"owner": "TobiasZawada",
"repo": "org-yt",
"type": "github"
}
},
"php-extras": {
"flake": false,
"locked": {
"lastModified": 1573312690,
"narHash": "sha256-r4WyVbzvT0ra4Z6JywNBOw5RxOEYd6Qe2IpebHXkj1U=",
"owner": "arnested",
"repo": "php-extras",
"rev": "d410c5af663c30c01d461ac476d1cbfbacb49367",
"type": "github"
},
"original": {
"owner": "arnested",
"repo": "php-extras",
"type": "github"
}
},
"revealjs": {
"flake": false,
"locked": {
"lastModified": 1651495761,
"narHash": "sha256-B3L8h0CyYgZCen8aWyLiDXHZMugXAzFToLJNg8f2PWU=",
"owner": "hakimel",
"repo": "reveal.js",
"rev": "0ca389721c5c7eff5db6f67159cbb1cdd51a3d7f",
"type": "github"
},
"original": {
"owner": "hakimel",
"repo": "reveal.js",
"type": "github"
}
},
"root": {
"inputs": {
"agenix": "agenix",
"emacs-overlay": "emacs-overlay",
"home-manager": "home-manager",
"nix-doom-emacs": "nix-doom-emacs",
"nixos-hardware": "nixos-hardware",
"nixos-wsl": "nixos-wsl",
"nixpkgs": "nixpkgs",
"nixpkgs-unstable": "nixpkgs-unstable"
}
},
"rotate-text": {
"flake": false,
"locked": {
"lastModified": 1322962747,
"narHash": "sha256-SOeOgSlcEIsKhUiYDJv0p+mLUb420s9E2BmvZQvZ0wk=",
"owner": "debug-ito",
"repo": "rotate-text.el",
"rev": "48f193697db996855aee1ad2bc99b38c6646fe76",
"type": "github"
},
"original": {
"owner": "debug-ito",
"repo": "rotate-text.el",
"type": "github"
}
},
"utils": {
"locked": {
"lastModified": 1653893745,

View file

@ -19,6 +19,13 @@
url = "github:nix-community/emacs-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
nix-doom-emacs = {
url = "github:nix-community/nix-doom-emacs";
inputs = {
home-manager.follows = "home-manager";
nixpkgs.follows = "nixpkgs-unstable";
};
};
agenix = {
url = "github:ryantm/agenix";
inputs.nixpkgs.follows = "nixpkgs";
@ -32,6 +39,7 @@
, nixos-wsl
, home-manager
, emacs-overlay
, nix-doom-emacs
, agenix
, nixos-hardware
, ...
@ -72,7 +80,11 @@
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.users.payas = import ./hosts/hermes/home.nix;
home-manager.users.payas = nixpkgs.lib.mkMerge [
./hosts/hermes/home.nix
nix-doom-emacs.hmModule
];
}
];

View file

@ -0,0 +1,371 @@
;-*- lexical-binding: t; -*-
(setq display-line-numbers-type t
backup-by-copying t
auto-save-file-name-transforms '((".*" "~/.emacs.d/tmp/auto-save/" t))
backup-directory-alist '(("." . "~/.emacs.d/tmp/"))
delete-old-versions t
kept-new-versions 3
kept-old-versions 3
version-control t
create-lockfiles nil
confirm-kill-emacs nil
bidi-inhibit-bpa t
pixel-scroll-precision-interpolate-page t ; only works when pixel-scroll-precision-mode is active
show-trailing-whitespace t)
(setq-default bidi-paragraph-direction 'letf-to-right)
(add-to-list 'initial-frame-alist '(fullscreen . maximized))
(global-whitespace-mode 0)
(column-number-mode)
(pixel-scroll-precision-mode)
(setq modus-themes-paren-match '(bold intense underline)
modus-themes-mode-line '(borderless (padding 1) (height 0.95))
modus-themes-headings '((t . (rainbow overline)))
modus-themes-region '(bg-only accented)
modus-themes-completions '((matches . (intense italic regular text-also))
(t . (regular)))
modus-themes-syntax '(green-strings yellow-comments)
modus-themes-subtle-line-numbers t
modus-themes-markup '(background intense)
modus-themes-italic-constructs t
modus-themes-bold-constructs t
modus-themes-fringes 'subtle
modus-themes-box-buttons '(flat accented faint variable-pitch)
modus-themes-org-blocks 'gray-background)
(map! :leader (:desc "Switch Modus-theme"
:prefix "t"
:g "m" #'modus-themes-toggle))
(use-package! minions
:config
(setq minions-mode-line-lighter ";")
(minions-mode 1))
(map!
:map global-map
"C-<" #'bhankas-scroll-up-half-page
"C->" #'bhankas-scroll-down-half-page)
(setq doom-font (font-spec :family "Cascadia Code PL SemiLight" :size 28)
doom-variable-pitch-font (font-spec :family "Work Sans" :size 28)
doom-unicode-font (font-spec :family "JuliaMono")
doom-serif-font (font-spec :family "IBM Plex Mono" :weight 'light)
doom-theme 'modus-vivendi
which-key-idle-delay 0.1)
(unbind-key "C-SPC")
(unbind-key "C-SPC l")
(setq doom-leader-alt-key "C-SPC")
(setq doom-localleader-alt-key "C-SPC l")
(set-popup-rules!
'(("^\\*\\([Hh]elp\\|Apropos\\)"
:slot 20 :side right :size 0.5 :select t :quit t)
("^\\*Org Src"
:slot 20 :side right :size 0.5 :select t)
("^\\*info\\*$"
:slot 20 :side right :size 0.5 :select t :quit t)))
(map! :leader (:desc "Enlarge window"
:prefix "w"
:g "o" #'doom/window-enlargen)
:map global-map "C-SPC" #'execute-extended-command)
(setq global-org-directory "~/org/")
(load "~/git/bhankas.el/bhankas.el")
(after! org
(remove-hook 'org-tab-first-hook #'+org-cycle-only-current-subtree-h))
(after! org
(setq org-directory global-org-directory
org-archive-location (concat org-directory "archive/%s_archive::")
org-agenda-files (directory-files-recursively org-directory "\\.org$")
org-ellipsis ""
org-adapt-indentation t
org-hide-leading-stars t
org-hide-emphasis-markers t
org-hide-macro-markers t
org-startup-indented t
org-hide-block-startup t
org-startup-folded t
org-todo-keywords '((sequencep "TODO(t!)" "WAIT(w@/!)" "|" "DONE(d!)" "CANCELED(c@/!)"))
org-log-into-drawer t
org-log-done 'time
org-log-done-with-time t
org-id-method 'ts
org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id
org-attach-id-to-path-function-list '(org-attach-id-ts-folder-format
org-attach-id-uuid-folder-format)
org-export-in-background 't
org-deadline-warning-days 2))
(require 'ox-publish)
(load "~/org/blog/ox-rss.el")
(setq org-publish-project-alist
'(("blog-posts"
:base-directory "~/org/blog/src/posts/"
:base-extension "org"
:publishing-directory "~/org/blog/docs/posts/"
:recursive t
:publishing-function org-html-publish-to-html
:headline-levels 3
:org-html-preamble nil
:html-self-link-headlines nil
:org-export-with-title nil
:org-export-with-toc nil
:org-export-with-section-numbers nil
:org-export-with-properties nil
:org-export-with-tags nil
:org-export-with-date t
:org-export-with-time-stamp-file t
:org-export-with-tables t
:org-html-table-use-header-tags-for-first-column nil)
("blog-pages"
:base-directory "~/org/blog/src/"
:base-extension "org"
:publishing-directory "~/org/blog/docs/"
:exclude "rss.org"
:recursive t
:publishing-function org-html-publish-to-html
:headline-levels 4
:org-html-preamble nil
:html-self-link-headlines nil
:org-export-with-title nil
:org-export-with-toc nil
:org-export-with-section-numbers nil
:org-export-with-tags nil
:org-html-table-use-header-tags-for-first-column nil)
("blog-static"
:base-directory "~/org/blog/src/"
:base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|swf"
:publishing-directory "~/org/blog/docs/"
:recursive t
:publishing-function org-publish-attachment)
("blog-rss"
:base-directory "~/org/blog/src/posts/"
:base-extension "src"
:recursive nil
:exclude ".*"
:include ("../rss.org")
:publishing-function (org-rss-publish-to-rss)
:publishing-directory "~/org/blog/docs/"
:with-toc nil
:section-numbers nil
:title "Bhankas")
("blog"
:components ("blog-posts" "blog-pages" "blog-static" "blog-rss"))))
(map! (:map org-mode-map
:localleader
:prefix ("P" . "publish")
"f" #'bhankas-blog-force-publish))
(after! org-roam
(setq org-roam-directory global-org-directory
org-roam-dailies-directory (concat global-org-directory "daily")
org-roam-dailies-capture-templates
`(("d" "default" entry "* %?"
:if-new
(file+head "%<%y-%m-%d>.org"
,(bhankas-newline-append-concat-loop
"#+title: %<%Y-%m-%d>"
"#+TODO: TODO(t!) WAIT(w@/!) | CANCELLED(c@/!) DONE(d!)\n"))))
org-roam-capture-templates
`(("d" "default" plain "%?"
:if-new
(file+head "%<%y%m%d%H%M%S>-${slug}.org"
,(bhankas-newline-append-concat-loop
"#+title: ${title}"
"#+DATE: "
"#+TODO: TODO(t!) WAIT(w@/!) | CANCELLED(c@/!) DONE(d!)"
"- tags :: " ""
"* What" ""
"* Why"))
:unnarrowed t)
("s" "social" plain "%?"
:if-new
(file+head "%<%y%m%d%H%M%S>-${slug}.org"
,(bhankas-newline-append-concat-loop
"#+title: ${title}"
"#+DATE: "
"#+TODO: TODO(t!) WAIT(w@/!) | CANCELLED(c@/!) DONE(d!)"
"- tags :: " ""
"* Person" ""
"** Profession" ""
"* Interactions" ""
"* Notes" ""))
:unnarrowed t)
("b" "blog-draft" plain "%?"
:if-new
(file+head "~/org/blog/src/draft/posts/${slug}-draft.org"
,(bhankas-newline-append-concat-loop
"#+TITLE: ${title}-DRAFT"
"#+SLUG: ${slug}-DRAFT"
"#+DATE: "
"#+TODO: TODO(t!) | CANCELLED(c@/!) DONE(d!)"
"#+FILENAME: ${slug}-draft"
"#+SETUPFILE: ~/org/blog/org-templates/level-1.org"
"#+INCLUDE: \"../html-templates/header.html\" export html"
"%<%Y-%m-%d>"
""
"* ${title}"))
:unnarrowed t)
("r" "blog-release" plain "%?"
:if-new
(file+head "~/org/blog/src/posts/${slug}.org"
,(bhankas-newline-append-concat-loop
"#+TITLE: ${title}"
"#+SLUG: ${slug}"
"#+DATE: %t"
"#+TODO: TODO(t!) | CANCELLED(c@/!) DONE(d!)"
"#+FILENAME: ${slug}"
"#+SETUPFILE: ~/org/blog/org-templates/level-1.org"
"#+INCLUDE: \"../html-templates/header.html\" export html"
"%<%Y-%m-%d>"
""
"* ${title}"))
:unnarrowed t))))
(map! :leader (:desc "elfeed"
:prefix ("1" . "elfeed")
:g "e" #'elfeed
:g "u" #'elfeed-update))
(after! elfeed
(setq elfeed-db-directory (concat global-org-directory "elfeed")
elfeed-search-title-max-width 120
elfeed-search-remain-on-entry t)
(setq-default elfeed-search-filter "@4-week-ago +unread")
(elfeed-set-timeout 30)
(add-hook! 'elfeed-search-mode-hook #'elfeed-update)
(defun elfeed-show-eww-open (&optional use-generic-p)
"open with eww"
(interactive "P")
(let ((browse-url-browser-function #'eww-browse-url))
(elfeed-show-visit use-generic-p)
(doom/window-enlargen)))
(defun elfeed-search-eww-open (&optional use-generic-p)
"open with eww"
(interactive "P")
(let ((browse-url-browser-function #'eww-browse-url))
(elfeed-search-browse-url use-generic-p)
(doom/window-enlargen)))
(map! (:map elfeed-search-mode-map
:localleader
:desc "Open in EWW" "1 1" #'elfeed-search-eww-open)
(:map elfeed-show-mode-map
:localleader
:desc "Open in EWW" "1 1" #'elfeed-show-eww-open)))
;; Elfeed feed list
(setq rmh-elfeed-org-files (list "~/org/elisp-fu/elfeed.org"))
(after! consult
(setq consult-ripgrep-args (string-replace "--null" "--no-ignore --null" consult-ripgrep-args))
(defun consult-ripgrep-org ()
(interactive)
(consult-ripgrep "~/org/"))
(map! :leader (:desc "ripgrep"
:prefix ("r" . "consult-ripgrep")
:g "r" #'consult-ripgrep
:g "o" #'consult-ripgrep-org)))
(after! (:and consult vertico)
(setq +vertico-consult-fd-args (string-replace "fd " "fd --no-ignore " +vertico-consult-fd-args)))
(setq magit-blame-echo-style 'margin
magit-repository-directories `(("~/.doom.d" . 0)
("~/org/elisp-fu" . 0)
("/etc/nixos" . 0)
("~/git" . 1)))
(map! :leader (:prefix "g"
:g "g" #'magit-status
:g "e" #'magit-blame-echo))
(setq dired-recursive-copies 'always
dired-recursive-deletes 'always
dired-dwim-target t
dired-kill-when-opening-new-dired-buffer t)
(add-hook 'dired-mode-hook
(lambda ()
(dired-hide-details-mode t)))
(add-to-ordered-list 'global-hl-line-modes 'dired-mode)
;; Each path is relative to `+mu4e-mu4e-mail-path', which is ~/.mail by default
(after! mu4e
:config
(set-email-account! "Gmail"
'((mu4e-sent-folder . "/Gmail/[Gmail]/Sent Mail")
(mu4e-drafts-folder . "/Gmail/[Gmail]/Drafts")
(mu4e-trash-folder . "/Gmail/[Gmail]/Trash")
(mu4e-refile-folder . "/Gmail/[Gmail]/All Mail")
(smtpmail-smtp-user . "relekarpayas@gmail.com")
(user-mail-address . "relekarpayas@gmail.com") ;; only needed for mu < 1.4
(mu4e-compose-signature . ""))
t)
;; Since I currently use gmail only, tune mu4e for it exclusively
;; below excerpt taken from doom module wiki for mu4e
;; don't need to run cleanup after indexing for gmail
(setq mu4e-index-cleanup nil
;; because gmail uses labels as folders we can use lazy check since
;; messages don't really "move"
mu4e-index-lazy-check t
mu4e-update-interval 120
+mu4e-main-bullet "")
(setq sendmail-program (executable-find "msmtp")
send-mail-function #'smtpmail-send-it
message-sendmail-f-is-evil t
message-sendmail-extra-arguments '("--read-envelope-from")
message-send-mail-function #'message-send-mail-with-sendmail
mu4e-view-html-plaintext-ratio-heuristic most-positive-fixnum)
(add-hook! '(mu4e-main-mode mu4e-headers-mode) #'mu4e-update-index)
(map! (:map (mu4e-main-mode-map mu4e-headers-mode-map mu4e-view-mode-map)
:localleader
:desc "Update index" "1 1" #'mu4e-update-index)))
;; Add mu4e bookmarks from separate file
;; Separate file in separate repo is made so as to maintain privacy
;; This way, if in future this repo is to be open sourced, history can be maintained
(load "~/org/elisp-fu/mu4e-fu.el")
(setq pdf-view-continuous t)
(setq company-idle-delay 0)
(setq tramp-default-method "ssh")
(customize-set-variable 'nix-nixfmt-bin "nixpkgs-fmt")
(after! citar
(let ((bib-dir (concat global-org-directory "bib/")))
(setq! citar-bibliography `(,(concat bib-dir "references.bib"))
citar-library-paths `(,bib-dir)
citar-notes-paths `(,bib-dir))))
(setq ispell-personal-dictionary "~/.doom.d/ispell-personal-dictionary")
;; WSL-specific setup
(when (and (eq system-type 'gnu/linux)
(getenv "WSLENV"))
;; Teach Emacs how to open links in your default Windows browser
(let ((cmd-exe "/mnt/c/Windows/System32/cmd.exe")
(cmd-args '("/c" "start")))
(when (file-exists-p cmd-exe)
(setq browse-url-generic-program cmd-exe
browse-url-generic-args cmd-args
browse-url-browser-function 'browse-url-generic
search-web-default-browser 'browse-url-generic))))

View file

@ -0,0 +1,782 @@
#+TITLE: Literate Emacs Config
#+AUTHOR: Payas Relekar
#+EMAIL: relekarpayas@gmail.com
* Table of Contents
:PROPERTIES:
:ID: 20220401T201746.752847
:END:
- [[#what][What]]
- [[#why][Why]]
- [[#gnu-emacs][GNU Emacs]]
- [[#packages-el][packages.el]]
- [[#modus-themes][Modus-themes]]
- [[#doom][Doom]]
- [[#ui][UI]]
- [[#common][Common]]
- [[#org-mode][Org-mode]]
+ [[#org-mode/stock][org-mode/stock]]
+ [[#org-mode/publish][org-mode/publish]]
+ [[#org-mode/org-roam][org-mode/roam]]
- [[#elfeed][Elfeed]]
- [[#ripgrep][Ripgrep]]
- [[#magit][Magit]]
- [[#dired][Dired]]
- [[#email][Email]]
- [[#bunch-of-small-stuff][Bunch of Small Stuff]]
+ [[#pdftools][PDFTools]]
+ [[#company][Company]]
+ [[#tramp][TRAMP]]
+ [[#nix][Nix]]
+ [[#WSL][WSL]]
* What
:PROPERTIES:
:CUSTOM_ID: what
:ID: 20220401T201746.777077
:END:
** What is this?
:PROPERTIES:
:ID: 20220401T201746.783616
:END:
- This is a configuration for Emacs (a programmable text editor/Lisp evaluation environment)
- It is written in Emacs-Lisp: A dialect of Lisp programming language (or a language within Lisp family of programming languages)
- TODO Explain more
** What is this Not?
:PROPERTIES:
:ID: 20220401T201746.790561
:END:
- A cure for COVID-19
- A good example of Emacs config
- A good example of Emacs-lisp programming
- A good example of any kind of config or programming
- TODO Add disclaimer with absolutely no support guaranteed.
* Why
:PROPERTIES:
:CUSTOM_ID: why
:ID: 20220401T201746.796918
:END:
This section lists my personal general thoughts about Why this file exists, bootstrapped from own Personal Computing needs all the way to Why this file exists the way it does (literate config)
** Why Emacs
:PROPERTIES:
:ID: 20220401T201746.800635
:END:
- This is a topic too big for single subsection in a file not intended for this purpose. But in short, Emacs is the only software I've found that actually empowers the *user* to control their own computing experience. There are few reasons why I think so:
- Emacs is architected unlike most Unix programs. It is largely not a compiled blob, but an 'image'. This image is a live thing that can be evolved during runtime using a full featured programming language: Emacs-lisp. This means I don't have to rely on Emacs developers to provide something. I also don't have to compile the full build every time I have a feature to add and use for myself.
- To extend Emacs as mentioned above, the language has extensive documentation, provided within Emacs.
- All the tools to start developing using this language are included with stock Emacs, without any need for configuration. These tools include documentation, REPL, debugger, compiler (both byte-code and native-compilation as of Emacs 28), profiler and of course, an editor.
- Starting developing Emacs-lisp is practically as easy as it gets. One can start writing Emacs-lisp expressions literally everywhere and single keystroke adds the result of expression into running Emacs image.
- Emacs is introspectable. Every Emacs function can be looked up, including its source code right from within a running Emacs.
- Emacs is the first software from GNU project. Which means:
- It has survived for ~40 years so far (1983-2021). If it survived this far, it has a high chance of being around for 40 more years.
- Emacs is free and open source. It is in no danger to be closed off or changed or locked off by shutdown of any organization or their changing interests, as long as the community is around.
- The culture around Emacs due to above factors strongly favors all the ecosystem around it is also open source.
** Why Doom-Emacs
:PROPERTIES:
:ID: 20220401T201746.806116
:END:
- Something like Emacs with its wide range of uses eventually gathers a lot of config, and a large number of external modules.
- After all, the benefit of Emacs with its built-in utilities for creating modes would be of little use if a user wouldn't actually use them.
- It makes little sense to write everything by hand for every single purpose. It makes one very informed about his own code when its written by himself, but ongoing maintenance is no joke.
- There is a truly enormous ecosystem of packages around Emacs. It would be foolish not to take advantage of it, especially since many of them are super-optimized by people who understand Emacs and elisp much better than I do.
- Doom-Emacs is very active, very modular, very easy to get started with, very optimized for performance and very responsive to user queries.
- Enabling new modules and experimenting is easier, so I spent less time fiddling with Doom and more time on getting up with whatever new language/tool I'm experimenting with.
- Over time, my doom-Emacs use has reduced it to be a library/framework of macros and custom functions for improving Emacs performance and convenience, something I probably would have done myself, but now I get to share the maintenance burden across all the Doom users.
** Why literate config (and why org-mode)
:PROPERTIES:
:ID: 20220401T201746.811040
:END:
- Short version, it was too easy to do with Doom and helped with my (lack of) focus
- Long version, configs are there for a reason. The reason being the defaults either weren't sufficient in terms of features or in terms of usability
- When a user (in this case myself) starts about configuring something like Emacs he eventually and almost unmistakably ends up with an unmaintainable monstrosity, thus leading to infamous [[https://www.emacswiki.org/emacs/DotEmacsBankruptcy]['Emacs Bankruptcy']].
- This is because at certain point, the code becomes large enough that it becomes impossible have all the logically related pieces close to each other.
- A personal config also consists of large number of variables set with values, instead of a singular code-flow, that can help a person focus their attention at particular point of interest at the time.
- Over time, usage patterns change. For Emacs, it means the selection of external packages and custom code that is used changes. Newer packages and code get added, but because of above mentioned reasons, old packages and code isn't always cleaned up. So the code at runtime has a tendency of increasing but gains from it follow a a plateau or even a bell curve.
- And so, we come back to literate config. Literate config is meant to be written for Humans to understand, instead of computers. Computers can then derive the spec out of meaning and work it.
- This way, the code is written and structured from the beginning with the consideration of being understood by a human. Extensive documentation becomes a primary focus of the document, with code being the secondary, bonus side-effect.
- I wasn't really sold on benefits of literate config. Why would I want to add an extra step in compiling my config when I can just add comments, after all? What changed my mind was reading [[https://protesilaos.com/emacs/dotemacs][GNU Emacs integrated computing environment | Protesilaos Stavrou]]. It was apparent to me for a while that both code comments, and untethered documentation (blog posts, wiki, notes) are inadequate in transferring 'intent'. Intent here refers to the original reasons and the process that lead to config being what it is beginning from first principles.
- Literate config like that of /Protesilaos Stavrou/ are excellent showcases where original intentions can be transferred to future reader of the config, making them fully aware of the reasons and the process. As someone who suffers from focus loss over time and is quite forgetful of problems that he supposedly 'solved' years ago, having to revisit the solutions without context is as painful as learning it from scratch.
- Reasons for picking org-mode:
+ I fell for org-mode pretty much immediately. The simple collapsible headings make things much much easier, focus wise. It is also easier to find the relevant section by eye-balling instead of relying on imperfect grep.
+ org-babel is fantastic as I can experiment and watch results instantly from within Emacs.
+ org-mode comes built into Emacs. No need to add another module
+ Doom makes it extremely convenient to switch to literate config. A single flag in =init.el= switches doom to fetch config from org file instead of default init file.
* GNU Emacs
:PROPERTIES:
:CUSTOM_ID: gnu-emacs
:ID: 20220401T201746.816982
:END:
- Display line numbers by default
- Display line numbers
- Make Emacs use entire screen. This also makes Emacs play nice with tiling WMs
- Create and use separate directory for all temp files and buffers
- Do not create lockfiles by default. They're more nuisance than help, at current stage.
- Disable white-space mode globally
- Show menu-bar by default
- Stop asking if I want to quit!
- Lazy load most files from previous session, except the most recent ones
- Minor optimizations to speed up loading buffers with long lines
- Default to left-to-right script
- Disable Bidirectional Parentheses algorithm
- Show both line number and column number of cursor in mode-line
- Show trailing white-space at the end of a line. Should come handy in org-mode or latex-mode.
- Enable smooth scrolling! (Added in Emacs 29)
Keyboard initiated scrolling is still line-based, because that makes sense, but mouse scrolling is now smooth and pixel-based.
Slowly, but surely, Emacs is becoming Almost Modern™
#+begin_src emacs-lisp :lexical t
;-*- lexical-binding: t; -*-
(setq display-line-numbers-type t
backup-by-copying t
auto-save-file-name-transforms '((".*" "~/.emacs.d/tmp/auto-save/" t))
backup-directory-alist '(("." . "~/.emacs.d/tmp/"))
delete-old-versions t
kept-new-versions 3
kept-old-versions 3
version-control t
create-lockfiles nil
confirm-kill-emacs nil
bidi-inhibit-bpa t
pixel-scroll-precision-interpolate-page t ; only works when pixel-scroll-precision-mode is active
show-trailing-whitespace t)
(setq-default bidi-paragraph-direction 'letf-to-right)
(add-to-list 'initial-frame-alist '(fullscreen . maximized))
(global-whitespace-mode 0)
(column-number-mode)
(pixel-scroll-precision-mode)
#+end_src
* packages.el
:PROPERTIES:
:CUSTOM_ID: packages-el
:ID: 20220401T201746.820211
:END:
Tangle ~packages.el~ from within org-mode.
- Disable lot of packages I do not need.
- Add few packages:
1. typit : For touch-typing practice
2. minions : Hide minor modes from mode-line, because I do not like nor use doom-modeline
#+begin_src emacs-lisp :lexical t :tangle packages.el
(disable-packages! elfeed-goodies
code-review
mu4e-alert
dired-git-info
swiper
ivy
hydra
lv
org-gcal
markdown-mode)
(package! typit
:recipe (:host github :repo "mrkkrp/typit"))
(package! minions)
(package! pdf-tools :built-in 'prefer)
#+end_src
* Modus-themes
:PROPERTIES:
:CUSTOM_ID: modus-themes
:ID: 20220401T201746.823786
:END:
Customize modus-themes a little to make it more peppy and vibrant. (It might also appear a bit crowded, so this is open for change)
These options, according to modus-themes wiki should be set and defined /before/ loading the theme. Many options when set multiple times, retain precedence by earlier set value
Customized parts:
- Modeline
- Parenthesis match
- Org-mode headings
- selected region : make its color match that of selected line.
- completions
Add a keybinding to toggle modus themes (between modus-operandi and modus-vivendi).
Enable and activate =minions-mode=.
Since I've reverted to using stock Emacs modeline, all the minor modes get very crowded and distracting.
minions-mode hides them under single menu item, and things look much cleaner.
#+begin_src emacs-lisp :lexical t
(setq modus-themes-paren-match '(bold intense underline)
modus-themes-mode-line '(borderless (padding 1) (height 0.95))
modus-themes-headings '((t . (rainbow overline)))
modus-themes-region '(bg-only accented)
modus-themes-completions '((matches . (intense italic regular text-also))
(t . (regular)))
modus-themes-syntax '(green-strings yellow-comments)
modus-themes-subtle-line-numbers t
modus-themes-markup '(background intense)
modus-themes-italic-constructs t
modus-themes-bold-constructs t
modus-themes-fringes 'subtle
modus-themes-box-buttons '(flat accented faint variable-pitch)
modus-themes-org-blocks 'gray-background)
(map! :leader (:desc "Switch Modus-theme"
:prefix "t"
:g "m" #'modus-themes-toggle))
(use-package! minions
:config
(setq minions-mode-line-lighter ";")
(minions-mode 1))
#+end_src
* bhankas
#+begin_src emacs-lisp :lexical
(map!
:map global-map
"C-<" #'bhankas-scroll-up-half-page
"C->" #'bhankas-scroll-down-half-page)
#+end_src
* Doom
:PROPERTIES:
:CUSTOM_ID: doom
:ID: 20220401T201746.826965
:END:
- Set font to =JetBrains Mono=
I used to use =Iosevka Extended= before, which was very good, but didn't have many curvatures. It was little jarring on eyes for big round letters (eg. capital C).
After that I was using =Roboto Mono=. It was better with curves, but bit too crowded. Line and character spacing made it seem to fill in more than it actually did.
Since then, I tried out =Fira Code= fonts and been liking so far. They are not too spread out like Source Code Pro, not boxy or vertical like Iosevka and not too crowded like Roboto Mono. They almost appear as normal text, and have just a touch of typewriter-esque personality.
Nerd font variant isn't exactly needed, but NixOS supports it without much fuss, so I just went with it.
Either way, its an experiment. (Started after coming across [[https://teddit.net/r/OrgRoam/comments/pz86n1/orgroamtimestamps_keep_track_of_creation_and/hf3ad8d/#c][this]] thread.
My current favorite monospace font is =JetBrains Mono=. It is bit taller than FiraCode and doesn't have ligatures by default (I think), but it also doesn't have the extra edges of FiraCode and looks slightly cleaner. Its Regular variant is a tad bit thicker than FiraCode, so combined with height it is bit non-appealing for long-form text like this document, but it is an excellent candidate for pure code. So, I made it my default terminal font :)
- Switch variable pitch font to =Work Sans=.
I tried replacing variable pitch font before, but default KDE font (=Noto Sans=) is good enough and makes Emacs look better integrated).
- Before I tried =Roboto Sans=, but it was OK-ish, not really to my liking. Noto Sans has full support for all Unicode scripts, so its always preferred, but looks like it is always a fallback if glyphs aren't fount in current font. need to investigate this more.
Anyway, I tried out Work Sans and liked it. It has proper l's and i's and O's and 0's, that just aren't distinguishable in Noto Sans. It is a bit flat compared to Noto Sans but not yet annoying. It also made the modeline shorter by couple pixels :)
- Set default theme to =modus vivendi= from =modus-themes= by /Protesilaos Stavrou/
These themes are made with extreme attention to detail, have been thoroughly tested and been integrated into Emacs since 28.0 (I'm still on 27.2 as of this writing)
Most significant criterion of these themes is accessibility. Every visible element must be at minimum 7:1 luminance ratio, according to the standard. There are some options for red-green color blindness, but thankfully I don't suffer from it.
These themes also have /a lot/ of customizable option, all documented in utmost detail on their website as well as in-package documentation/manual
Frankly, I have never found a better designed, tested, maintained, documented and customizable theme, or a better theme ever for any software, period.
And so, they now adorn my Emacs by default and get a whole paragraph to sing their praise.
- Set =which-key= popup delay to 0.1 sec.
Default value of 1.0 sec is a bit too long for my taste, and I don't (yet) mind seeing the popups often.
#+begin_src emacs-lisp :lexical t
(setq doom-font (font-spec :family "Cascadia Code PL SemiLight" :size 28)
doom-variable-pitch-font (font-spec :family "Work Sans" :size 28)
doom-unicode-font (font-spec :family "JuliaMono")
doom-serif-font (font-spec :family "IBM Plex Mono" :weight 'light)
doom-theme 'modus-vivendi
which-key-idle-delay 0.1)
#+end_src
- Unbind ~C-SPC~ from set-mark. I almost never use marks manually and this keybind is too valuable as leader key than its default (similar to ~SPC-SPC~ in evil+leader)
#+begin_src emacs-lisp :lexical t
(unbind-key "C-SPC")
(unbind-key "C-SPC l")
(setq doom-leader-alt-key "C-SPC")
(setq doom-localleader-alt-key "C-SPC l")
#+end_src
- Tame some popups to my will.
Doom has its own defaults set for popup behaviors, positions and sizes. It works, mostly, but often doesn't not to my liking.
I prefer to open help and info buffers as well as quick source edits from org mode using full height, with vertical split, and automatically get selected to boot.
Doom's macro for setting these rules is /very/ good and extensive, with knobs and lever to adjust position, size, preference, automatic selection and quick quitting.
This example here is another reminder on why I am using Doom.
#+begin_src emacs-lisp :lexical t
(set-popup-rules!
'(("^\\*\\([Hh]elp\\|Apropos\\)"
:slot 20 :side right :size 0.5 :select t :quit t)
("^\\*Org Src"
:slot 20 :side right :size 0.5 :select t)
("^\\*info\\*$"
:slot 20 :side right :size 0.5 :select t :quit t)))
#+end_src
- Add keybindings for some doom functions that are present in evil mode but missing from stock keybindings
#+begin_src emacs-lisp :lexical t
(map! :leader (:desc "Enlarge window"
:prefix "w"
:g "o" #'doom/window-enlargen)
:map global-map "C-SPC" #'execute-extended-command)
#+end_src
* Common
:PROPERTIES:
:CUSTOM_ID: common
:ID: 20220401T201746.833168
:END:
Define global variables that can be used and optionally modified across multiple packages.
Simple example is =global-org-directory=, which is a central place where my personal text files are kept. However, it is organized in a shallow hierarchy, specified for modes/purposes. So, it makes sense to set global variable and let modes append it to set their specified sub-directories.
One reason to separate these values into global variables is for lazy config evaluation. A lot of mode specific variables should and often can be only set after initializing mode.
As such, relying on imperative config evaluation can turn into gotchas. While this way is still imperative (relies on variables being set before package evaluation), it is much safer than relying on habits, especially since doom config sync sets up Emacs config in fairly declarative manner.
#+begin_src emacs-lisp :lexical t
(setq global-org-directory "~/org/")
(load "~/git/bhankas.el/bhankas.el")
#+end_src
* Org-mode
:PROPERTIES:
:CUSTOM_ID: org-mode
:ID: 20220401T201746.836200
:END:
** org-mode/stock
:PROPERTIES:
:CUSTOM_ID: org-mode/stock
:ID: 20220401T201746.839828
:END:
- Set default directory for org files
- move archive for org files to separate directory, so as to not crowd default directory
- set org-mode agenda to look for files recursively in default org directory
- restore default org-mode tree cycle behavior
- change the character that displays on collapsed headings
- use timestamps instead of UUID for org-id (resolved to microsecond, and has not been an issue even while generating id for dozens of heading at once. It seems to be as unique as needed)
- Almost always create org-id for every heading operated in interactive mode
#+begin_src emacs-lisp :lexical t
(after! org
(remove-hook 'org-tab-first-hook #'+org-cycle-only-current-subtree-h))
(after! org
(setq org-directory global-org-directory
org-archive-location (concat org-directory "archive/%s_archive::")
org-agenda-files (directory-files-recursively org-directory "\\.org$")
org-ellipsis " …"
org-adapt-indentation t
org-hide-leading-stars t
org-hide-emphasis-markers t
org-hide-macro-markers t
org-startup-indented t
org-hide-block-startup t
org-startup-folded t
org-todo-keywords '((sequencep "TODO(t!)" "WAIT(w@/!)" "|" "DONE(d!)" "CANCELED(c@/!)"))
org-log-into-drawer t
org-log-done 'time
org-log-done-with-time t
org-id-method 'ts
org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id
org-attach-id-to-path-function-list '(org-attach-id-ts-folder-format
org-attach-id-uuid-folder-format)
org-export-in-background 't
org-deadline-warning-days 2))
#+END_SRC
** org-publish
:PROPERTIES:
:CUSTOM_ID: org-mode/publish
:ID: 20220514T195618.099446
:END:
#+begin_src emacs-lisp :lexical t
(require 'ox-publish)
(load "~/org/blog/ox-rss.el")
(setq org-publish-project-alist
'(("blog-posts"
:base-directory "~/org/blog/src/posts/"
:base-extension "org"
:publishing-directory "~/org/blog/docs/posts/"
:recursive t
:publishing-function org-html-publish-to-html
:headline-levels 3
:org-html-preamble nil
:html-self-link-headlines nil
:org-export-with-title nil
:org-export-with-toc nil
:org-export-with-section-numbers nil
:org-export-with-properties nil
:org-export-with-tags nil
:org-export-with-date t
:org-export-with-time-stamp-file t
:org-export-with-tables t
:org-html-table-use-header-tags-for-first-column nil)
("blog-pages"
:base-directory "~/org/blog/src/"
:base-extension "org"
:publishing-directory "~/org/blog/docs/"
:exclude "rss.org"
:recursive t
:publishing-function org-html-publish-to-html
:headline-levels 4
:org-html-preamble nil
:html-self-link-headlines nil
:org-export-with-title nil
:org-export-with-toc nil
:org-export-with-section-numbers nil
:org-export-with-tags nil
:org-html-table-use-header-tags-for-first-column nil)
("blog-static"
:base-directory "~/org/blog/src/"
:base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|swf"
:publishing-directory "~/org/blog/docs/"
:recursive t
:publishing-function org-publish-attachment)
("blog-rss"
:base-directory "~/org/blog/src/posts/"
:base-extension "src"
:recursive nil
:exclude ".*"
:include ("../rss.org")
:publishing-function (org-rss-publish-to-rss)
:publishing-directory "~/org/blog/docs/"
:with-toc nil
:section-numbers nil
:title "Bhankas")
("blog"
:components ("blog-posts" "blog-pages" "blog-static" "blog-rss"))))
(map! (:map org-mode-map
:localleader
:prefix ("P" . "publish")
"f" #'bhankas-blog-force-publish))
#+end_src
** org-mode/org-roam
:PROPERTIES:
:CUSTOM_ID: org-mode/org-roam
:ID: 20220401T201746.842960
:END:
#+begin_src emacs-lisp :lexical t
(after! org-roam
(setq org-roam-directory global-org-directory
org-roam-dailies-directory (concat global-org-directory "daily")
org-roam-dailies-capture-templates
`(("d" "default" entry "* %?"
:if-new
(file+head "%<%y-%m-%d>.org"
,(bhankas-newline-append-concat-loop
"#+title: %<%Y-%m-%d>"
"#+TODO: TODO(t!) WAIT(w@/!) | CANCELLED(c@/!) DONE(d!)\n"))))
org-roam-capture-templates
`(("d" "default" plain "%?"
:if-new
(file+head "%<%y%m%d%H%M%S>-${slug}.org"
,(bhankas-newline-append-concat-loop
"#+title: ${title}"
"#+DATE: "
"#+TODO: TODO(t!) WAIT(w@/!) | CANCELLED(c@/!) DONE(d!)"
"- tags :: " ""
"* What" ""
"* Why"))
:unnarrowed t)
("s" "social" plain "%?"
:if-new
(file+head "%<%y%m%d%H%M%S>-${slug}.org"
,(bhankas-newline-append-concat-loop
"#+title: ${title}"
"#+DATE: "
"#+TODO: TODO(t!) WAIT(w@/!) | CANCELLED(c@/!) DONE(d!)"
"- tags :: " ""
"* Person" ""
"** Profession" ""
"* Interactions" ""
"* Notes" ""))
:unnarrowed t)
("b" "blog-draft" plain "%?"
:if-new
(file+head "~/org/blog/src/draft/posts/${slug}-draft.org"
,(bhankas-newline-append-concat-loop
"#+TITLE: ${title}-DRAFT"
"#+SLUG: ${slug}-DRAFT"
"#+DATE: "
"#+TODO: TODO(t!) | CANCELLED(c@/!) DONE(d!)"
"#+FILENAME: ${slug}-draft"
"#+SETUPFILE: ~/org/blog/org-templates/level-1.org"
"#+INCLUDE: \"../html-templates/header.html\" export html"
"%<%Y-%m-%d>"
""
"* ${title}"))
:unnarrowed t)
("r" "blog-release" plain "%?"
:if-new
(file+head "~/org/blog/src/posts/${slug}.org"
,(bhankas-newline-append-concat-loop
"#+TITLE: ${title}"
"#+SLUG: ${slug}"
"#+DATE: %t"
"#+TODO: TODO(t!) | CANCELLED(c@/!) DONE(d!)"
"#+FILENAME: ${slug}"
"#+SETUPFILE: ~/org/blog/org-templates/level-1.org"
"#+INCLUDE: \"../html-templates/header.html\" export html"
"%<%Y-%m-%d>"
""
"* ${title}"))
:unnarrowed t))))
#+end_src
* Elfeed
:PROPERTIES:
:CUSTOM_ID: elfeed
:ID: 20220401T201746.854677
:END:
- Elfeed is RSS feed reader from within Emacs
- Elfeed can read a list of feeds from an elisp variable as done below, or from an org file with hierarchical structure for tags and feeds under them. The elisp way causes more duplication, since some tags get repeated for multiple feeds, but, in my experience, my feed list is not perfectly hierarchical, and so I prefer it this way.
- Set elfeed db directory to withing =org-directory=. This is done so Syncthing will sync elfeed read/delete status as well.
- Set global shortcuts to open and update elfeed feed
+ =C-SPC 1 e= Open elfeed
+ =C-SPC 1 u= Update elfeed feeds
- Extra room for post titles
- Leave point on current entry in elfeed-search
- Set default elfeed search to show 4 weeks of entries
- Set default feed timeout to 30 seconds
- Auto-update feeds every time elfeed-search is opened
- Couple of functions and their keybindings to open given entry with EWW. This way I can give those rude feeds with just links or excerpts a go within Emacs. If I need a browser I can always just press ~&~ and open it in regular browser. These functions also make those windows larger. It is not perfect, can be refined bit more, but for now it works well enough.
- Finally, a giant list of elfeed feeds is loaded from separate repo.
#+begin_src emacs-lisp :lexical t
(map! :leader (:desc "elfeed"
:prefix ("1" . "elfeed")
:g "e" #'elfeed
:g "u" #'elfeed-update))
(after! elfeed
(setq elfeed-db-directory (concat global-org-directory "elfeed")
elfeed-search-title-max-width 120
elfeed-search-remain-on-entry t)
(setq-default elfeed-search-filter "@4-week-ago +unread")
(elfeed-set-timeout 30)
(add-hook! 'elfeed-search-mode-hook #'elfeed-update)
(defun elfeed-show-eww-open (&optional use-generic-p)
"open with eww"
(interactive "P")
(let ((browse-url-browser-function #'eww-browse-url))
(elfeed-show-visit use-generic-p)
(doom/window-enlargen)))
(defun elfeed-search-eww-open (&optional use-generic-p)
"open with eww"
(interactive "P")
(let ((browse-url-browser-function #'eww-browse-url))
(elfeed-search-browse-url use-generic-p)
(doom/window-enlargen)))
(map! (:map elfeed-search-mode-map
:localleader
:desc "Open in EWW" "1 1" #'elfeed-search-eww-open)
(:map elfeed-show-mode-map
:localleader
:desc "Open in EWW" "1 1" #'elfeed-show-eww-open)))
;; Elfeed feed list
(setq rmh-elfeed-org-files (list "~/org/elisp-fu/elfeed.org"))
#+end_src
* Ripgrep
:PROPERTIES:
:CUSTOM_ID: ripgrep
:ID: 20220401T201746.857751
:END:
Because default search for org-mode (=org-search-view=) is *painfully* slow.
ripgrep is indeed fast, but lacks couple of features from =org-search-view= which I should try to fix for my own.
Native-compilation in Emacs 28+ is a significant progress towards making built-in search useful and actually returns results on same day, but still slow compared to rg.
It is slow especially on large number of small .org files, which is my preferred setup, but I'll see how it goes.
Before it used to be =rg.el= package, but its search was not very useful. I could make it useful, or I could simply change arguments for =consult-ripgrep= to also include ignored files. This can be a tiny bit problematic in few scenarios, but I can always just drop to terminal in such cases.
#+begin_src emacs-lisp :lexical t
(after! consult
(setq consult-ripgrep-args (string-replace "--null" "--no-ignore --null" consult-ripgrep-args))
(defun consult-ripgrep-org ()
(interactive)
(consult-ripgrep "~/org/"))
(map! :leader (:desc "ripgrep"
:prefix ("r" . "consult-ripgrep")
:g "r" #'consult-ripgrep
:g "o" #'consult-ripgrep-org)))
(after! (:and consult vertico)
(setq +vertico-consult-fd-args (string-replace "fd " "fd --no-ignore " +vertico-consult-fd-args)))
#+end_src
* Magit
:PROPERTIES:
:CUSTOM_ID: magit
:ID: 20220401T201746.860755
:END:
- Set default project directories for magit:
+ =~= for dotfiles
+ =/etc/nixos= for NixOS configuration
+ All sub-directories of =~/git/= as top-level projects
- Set default magit blame style to margin
- Add keybinding for =magit-blame-echo= (Doom's default keybinding =C-SPC g B= is for =magit-blame-additions=)
#+begin_src emacs-lisp :lexical t
(setq magit-blame-echo-style 'margin
magit-repository-directories `(("~/.doom.d" . 0)
("~/org/elisp-fu" . 0)
("/etc/nixos" . 0)
("~/git" . 1)))
(map! :leader (:prefix "g"
:g "g" #'magit-status
:g "e" #'magit-blame-echo))
#+end_src
* Dired
:PROPERTIES:
:CUSTOM_ID: dired
:ID: 20220401T201746.863692
:END:
A lot of below configurations are stolen verbatim from [[https://protesilaos.com/dotemacs/#h:c519300f-8a9a-472b-b26d-c2f49adbdb5d][GNU Emacs integrated computing environment | Protesilaos Stavrou]]
- Do recursive copy and delete by default
- Reuse dired buffer for opening subsequent directories. This variable becomes available in Emacs 28.1, but added so as to not forget ([[https://www.manueluberti.eu/emacs/2021/07/14/dired/][source]])
- Enable =hl-line-mode= for Dired.
For some reason, doom has a list of modes where hl-line-mode is enabled. So, my options were to enable =global-hl-line-mode=, or add =dired-mode= to doom's list.
It does mean I now have a hard dependency for this function on Doom-Emacs, but considering how much I'm getting familiar with doom and its env, I think it'll be maybe fine.
#+begin_src emacs-lisp :lexical t
(setq dired-recursive-copies 'always
dired-recursive-deletes 'always
dired-dwim-target t
dired-kill-when-opening-new-dired-buffer t)
(add-hook 'dired-mode-hook
(lambda ()
(dired-hide-details-mode t)))
(add-to-ordered-list 'global-hl-line-modes 'dired-mode)
#+end_src
* Email
:PROPERTIES:
:CUSTOM_ID: email
:ID: 20220401T201746.866660
:END:
mu4e + mbsync + msmtp
- mbsync
+ Emails, when you get down to it, are dumb text files stored on disk. They are like any other unix directory, nested in tree-like structure, with the top-most directory in the structure identifying with particular email address.
+ mbsync is the utility that actually manages this maildir on local machine and keeps it in sync with the mail service provider (I think via IMAP, but need to check).
+ mbsync setup and configuration in my case is taken care of by =Nix= via =home-manager= module.
+ mbsync also auto-syncs with mail provider, currently configured to do so at every 15 min.
- mu
+ mu is the command line utility that can interact with the maildir synced by =mbsync=
+ It is a comfortable tool to make precise or bulk operations on the maildir, like search, delete, transfer between different dirs etc
+ mu is the hands and brains behind every email interaction taking place via Emacs
- mu4e
+ mu4e, as the name might suggest, is the =Emacs= interface for command line =mu= and =msmtp=
+ It has nice UX, and keybindings and functions that can be approached from within Emacs to search, read, send and generally operate upon emails from within Emacs.
- msmtp
+ msmtp is the command line utility to /send/ emails
+ msmtp is the last piece of the puzzle for minimal email setup with Emacs.
+ msmtp sends the emails to mail service provider who then relays it to appropriate destination
- Set default directories matching Gmail folders
- Set default mail address for Gmail maildir.
- No/empty default signature for now
- Set sending mail via msmtp directly (lifted from doom module wiki)
- Always prefer text/plain over HTML mail. By default if HTML mail is longer than 5 times that of text, HTML is preferred. But text is always nicer, so text is always preferable ([[https://200ok.ch/posts/2018-10-25_disable_mu4e_html_over_plain_text_heuristic.html][link]]).
- Configure mu4e for gmail-optimized mail fetch, because I only use gmail (lifted from doom module wiki) (I know, I should be changing to something not evil)
- Add a convenient keybinding to invoke ~mu4e-update-index~. This is because apparently mu4e does not auto-index after changing stuff, and that sometimes conflicts with the daemon.
So, I do it manually, but Doom does not have a keybinding for it, so I added one.
- Finally, a number of custom queries and bookmarks for mu4e. These are loaded from external repository while loading the config. Reason to keep the repo separate is that these filters are quite fine-grained and I'm not comfortable sharing any information about my email other than email id. This repo is open on =sr.ht= already, so separate repo is better choice.
#+begin_src emacs-lisp :lexical t
;; Each path is relative to `+mu4e-mu4e-mail-path', which is ~/.mail by default
(after! mu4e
:config
(set-email-account! "Gmail"
'((mu4e-sent-folder . "/Gmail/[Gmail]/Sent Mail")
(mu4e-drafts-folder . "/Gmail/[Gmail]/Drafts")
(mu4e-trash-folder . "/Gmail/[Gmail]/Trash")
(mu4e-refile-folder . "/Gmail/[Gmail]/All Mail")
(smtpmail-smtp-user . "relekarpayas@gmail.com")
(user-mail-address . "relekarpayas@gmail.com") ;; only needed for mu < 1.4
(mu4e-compose-signature . ""))
t)
;; Since I currently use gmail only, tune mu4e for it exclusively
;; below excerpt taken from doom module wiki for mu4e
;; don't need to run cleanup after indexing for gmail
(setq mu4e-index-cleanup nil
;; because gmail uses labels as folders we can use lazy check since
;; messages don't really "move"
mu4e-index-lazy-check t
mu4e-update-interval 120
+mu4e-main-bullet "∘")
(setq sendmail-program (executable-find "msmtp")
send-mail-function #'smtpmail-send-it
message-sendmail-f-is-evil t
message-sendmail-extra-arguments '("--read-envelope-from")
message-send-mail-function #'message-send-mail-with-sendmail
mu4e-view-html-plaintext-ratio-heuristic most-positive-fixnum)
(add-hook! '(mu4e-main-mode mu4e-headers-mode) #'mu4e-update-index)
(map! (:map (mu4e-main-mode-map mu4e-headers-mode-map mu4e-view-mode-map)
:localleader
:desc "Update index" "1 1" #'mu4e-update-index)))
;; Add mu4e bookmarks from separate file
;; Separate file in separate repo is made so as to maintain privacy
;; This way, if in future this repo is to be open sourced, history can be maintained
(load "~/org/elisp-fu/mu4e-fu.el")
#+end_src
* Bunch of small stuff
:PROPERTIES:
:CUSTOM_ID: bunch-of-small-stuff
:ID: 20220401T201746.870106
:END:
All the modifications that are necessary enough to exist, but not big enough to justify a top-level heading.
** PDFTools
:PROPERTIES:
:CUSTOM_ID: pdftools
:ID: 20220401T201746.873376
:END:
- Set Continuous mode by default
#+begin_src emacs-lisp :lexical t
(setq pdf-view-continuous t)
#+end_src
** Company
:PROPERTIES:
:CUSTOM_ID: company
:ID: 20220401T201746.876701
:END:
- Reduce auto-complete prompt wait duration
#+begin_src emacs-lisp :lexical t
(setq company-idle-delay 0)
#+end_src
** TRAMP
:PROPERTIES:
:CUSTOM_ID: tramp
:ID: 20220401T201746.879788
:END:
- use SSH by default while connecting to remote destinations via TRAMP
#+begin_src emacs-lisp :lexical t
(setq tramp-default-method "ssh")
#+end_src
** Nix
:PROPERTIES:
:CUSTOM_ID: nix
:ID: 20220401T201746.882716
:END:
- Use ~nixpkgs-fmt~ for .nix file formatting
Nixpkgs PRs use this instead of ~nixfmt~ and gave me many a wondering annoyances on my PRs. So fudge it, I'm switching to it full-time.
#+begin_src emacs-lisp :lexical t
(customize-set-variable 'nix-nixfmt-bin "nixpkgs-fmt")
#+end_src
** Bibtex
#+begin_src emacs-lisp
(after! citar
(let ((bib-dir (concat global-org-directory "bib/")))
(setq! citar-bibliography `(,(concat bib-dir "references.bib"))
citar-library-paths `(,bib-dir)
citar-notes-paths `(,bib-dir))))
#+end_src
** Ispell
#+begin_src emacs-lisp :lexical t
(setq ispell-personal-dictionary "~/.doom.d/ispell-personal-dictionary")
#+end_src
** WSL
When Emacs is opened in Windows Subsystem for Linux, open web links in Firefox on Windows.
#+begin_src emacs-lisp :lexical t
;; WSL-specific setup
(when (and (eq system-type 'gnu/linux)
(getenv "WSLENV"))
;; Teach Emacs how to open links in your default Windows browser
(let ((cmd-exe "/mnt/c/Windows/System32/cmd.exe")
(cmd-args '("/c" "start")))
(when (file-exists-p cmd-exe)
(setq browse-url-generic-program cmd-exe
browse-url-generic-args cmd-args
browse-url-browser-function 'browse-url-generic
search-web-default-browser 'browse-url-generic))))
#+end_src

208
hosts/hermes/doom.d/init.el Executable file
View file

@ -0,0 +1,208 @@
;;; init.el -*- lexical-binding: t; -*-
;; This file controls what Doom modules are enabled and what order they load
;; in. Remember to run 'doom sync' after modifying it!
;; NOTE Press 'SPC h d h' (or 'C-h d h' for non-vim users) to access Doom's
;; documentation. There you'll find a "Module Index" link where you'll find
;; a comprehensive list of Doom's modules and what flags they support.
;; NOTE Move your cursor over a module's name (or its flags) and press 'K' (or
;; 'C-c c k' for non-vim users) to view its documentation. This works on
;; flags as well (those symbols that start with a plus).
;;
;; Alternatively, press 'gd' (or 'C-c c d') on a module to browse its
;; directory (for easy access to its source code).
(doom! :input
;;chinese
;;japanese
;;layout ; auie,ctsrnm is the superior home row
:completion
company ; the ultimate code completion backend
;;helm ; the *other* search engine for love and life
;;ido ; the other *other* search engine...
;;(ivy ; a search engine for love and life
;; +fuzzy
;; +icons)
vertico
:ui
;; deft ; notational velocity for Emacs
;; doom ; what makes DOOM look the way it does
;;doom-dashboard ; a nifty splash screen for Emacs
;;doom-quit ; DOOM quit-message prompts when you quit Emacs
;;fill-column ; a `fill-column' indicator
;; hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW
;;hydra
;; indent-guides ; highlighted indent columns
;; ligatures ; ligatures and symbols to make your code pretty again
;;minimap ; show a map of the code on the side
;; modeline ; snazzy, Atom-inspired modeline, plus API
nav-flash ; blink cursor line after big motions
;;neotree ; a project drawer, like NERDTree for vim
ophints ; highlight the region an operation acts on
(popup +defaults) ; tame sudden yet inevitable temporary windows
;;+all ; catch all popups that start with asterisk
;;tabs ; a tab bar for Emacs
;;treemacs ; a project drawer, like neotree but cooler
;; unicode ; extended unicode support for various languages
;; vc-gutter ; vcs diff in the fringe
;;tilde-vi-fringe ; fringe tildes to mark beyond EOB
window-select ; visually switch windows
;;workspaces ; tab emulation, persistence & separate workspaces
;;zen ; distraction-free coding or writing
:editor
;; (evil +everywhere) ; come to the dark side, we have cookies
;;file-templates ; auto-snippets for empty files
;;fold ; (nigh) universal code folding
;;(format +onsave) ; automated prettiness
;;god ; run Emacs commands without modifier keys
;; lispy ; vim for lisp, for people who don't like vim
;; multiple-cursors ; editing in many places at once
;;objed ; text object editing for the innocent
;;(parinfer
;; +rust) ; turn lisp into python, sort of
;;rotate-text ; cycle region at point between text candidates
snippets ; my elves. They type so I don't have to
;;word-wrap ; soft wrapping with language-aware indent
:emacs
(dired) ; making dired pretty [functional]
electric ; smarter, keyword-based electric-indent
(ibuffer) ; interactive buffer management
(undo ; persistent, smarter undo for your inevitable mistakes
+tree)
;; vc ; version-control and Emacs, sitting in a tree
:term
;;eshell ; the elisp shell that works everywhere
;;shell ; simple shell REPL for Emacs
;;term ; basic terminal emulator for Emacs
vterm ; the best terminal emulation in Emacs
:checkers
(syntax ; tasing you for every semicolon you forget
+childframe)
(spell ; tasing you for misspelling mispelling
+aspell
+flyspell)
;;grammar ; tasing grammar mistake every you make
:tools
;;ansible
biblio
;; (debugger ; FIXME stepping through code, to help you add bugs
;; +lsp)
direnv
;; docker
;;editorconfig ; let someone else argue about tabs vs spaces
;;ein ; tame Jupyter notebooks with emacs
(eval +overlay) ; run code, run (also, repls)
;; gist ; interacting with github gists
;; lookup ; navigate your code and its documentation
(lsp
+eglot)
magit ; a git porcelain for Emacs
;;make ; run make tasks from Emacs
;;pass ; password manager for nerds
pdf ; pdf enhancements
;;prodigy ; FIXME managing external services & code builders
;;rgb ; creating color strings
;;taskrunner ; taskrunner for all your projects
;;terraform ; infrastructure as code
;;tmux ; an API for interacting with tmux
;;upload ; map local to remote projects via ssh/ftp
tree-sitter
:os
;;(:if IS-MAC macos); improve compatibility with macOS
;;tty ; improve the terminal Emacs experience
:lang
;;agda ; types of types of types of types...
beancount ; mind the GAAP
;;cc ; C/C++/Obj-C madness
;; clojure ; java with a lisp
;; common-lisp ; if you've seen one lisp, you've seen them all
;;coq ; proofs-as-programs
;;crystal ; ruby at the speed of c
;;csharp ; unity, .NET, and mono shenanigans
;;data ; config/data formats
;;(dart +flutter) ; paint ui and not much else
;;elixir ; erlang done right
;;elm ; care for a cup of TEA?
emacs-lisp ; drown in parentheses
;;erlang ; an elegant language for a more civilized age
;;ess ; emacs speaks statistics
;;faust ; dsp, but you get to keep your soul
;;fsharp ; ML stands for Microsoft's Language
;;fstar ; (dependent) types and (monadic) effects and Z3
(gdscript +lsp) ; the language you waited for
;;(go +lsp) ; the hipster dialect
;;(haskell +dante) ; a language that's lazier than I am
;;hy ; readability of scheme w/ speed of python
;;idris ;
;; json ; At least it ain't XML
;;(java +meghanada) ; the poster child for carpal tunnel syndrome
;;javascript ; all(hope(abandon(ye(who(enter(here))))))
;;julia ; a better, faster MATLAB
;;kotlin ; a better, slicker Java(Script)
latex ; writing papers in Emacs has never been so fun
;;lean
;;factor
;; ledger ; an accounting system in Emacs
;;lua ; one-based indices? one-based indices
;;markdown ; writing docs for people to ignore
;;nim ; python + lisp at the speed of c
(nix +lsp) ; I hereby declare "nix geht mehr!"
;;ocaml ; an objective camel
(org ; organize your plain life in plain text
+babel ; run inline code from org files
+capture ; org-capture in and outside of emacs
+roam2 ; bidirectional linking like roam-research
+noter
+pandoc)
;;php ; perl's insecure younger brother
;;plantuml ; diagrams for confusing people more
;;purescript ; javascript, but functional
;; (python ; beautiful is better than ugly
;; +lsp
;; +pyenv
;; +poetry)
;;qt ; the 'cutest' gui framework ever
;;racket ; a DSL for DSLs
;;raku ; the artist formerly known as perl6
;;rest ; Emacs as a REST client
;;rst ; ReST in peace
;;(ruby +rails) ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"}
;; (rust ; Fe2O3.unwrap().unwrap().unwrap().unwrap()
;; +lsp)
;;scala ; java, but good
;;scheme ; a fully conniving family of lisps
(sh +fish) ; she sells {ba,z,fi}sh shells on the C xor
;;sml
;;solidity ; do you need a blockchain? No.
;;swift ; who asked for emoji variables?
;;terra ; Earth and Moon in alignment for performance.
web ; the tubes
;;yaml ; JSON, but readable
:email
(mu4e +gmail +org)
;;notmuch
;;(wanderlust +gmail)
:app
calendar
;;irc ; how neckbeards socialize
(rss ; emacs as an RSS reader
+org)
;;twitter ; twitter client https://twitter.com/vnought
:config
literate
(default +bindings +smartparens))

View file

@ -0,0 +1,17 @@
(disable-packages! elfeed-goodies
code-review
mu4e-alert
dired-git-info
swiper
ivy
hydra
lv
org-gcal
markdown-mode)
(package! typit
:recipe (:host github :repo "mrkkrp/typit"))
(package! minions)
(package! pdf-tools :built-in 'prefer)

View file

@ -1,4 +1,4 @@
{ config, pkgs, emacs-overlay, ... }:
{ config, pkgs, emacs-overlay, nix-doom-emacs, ... }:
{
nixpkgs.overlays = [ emacs-overlay.overlay ];
@ -6,28 +6,29 @@
programs = {
# Emacs Git (master branch, currently 29.0) with extra packages (that require native component)
# Built via nix-community/emacs-overlay expressions
emacs = {
doom-emacs = {
enable = true;
package = pkgs.emacsPgtkNativeComp;
extraPackages = epkgs: with epkgs; [
pdf-tools
org-pdftools
emacsql
emacsql-sqlite
emacsql-sqlite-builtin
vterm
(tree-sitter-langs.withPlugins (p: [
p.tree-sitter-bash
p.tree-sitter-css
p.tree-sitter-html
p.tree-sitter-java
p.tree-sitter-javascript
p.tree-sitter-json
p.tree-sitter-nix
p.tree-sitter-python
p.tree-sitter-beancount
]))
];
emacsPackage = pkgs.emacsPgtkNativeComp;
doomPrivateDir = ./doom.d;
# extraPackages = epkgs: with epkgs; [
# pdf-tools
# org-pdftools
# emacsql
# emacsql-sqlite
# emacsql-sqlite-builtin
# vterm
# (tree-sitter-langs.withPlugins (p: [
# p.tree-sitter-bash
# p.tree-sitter-css
# p.tree-sitter-html
# p.tree-sitter-java
# p.tree-sitter-javascript
# p.tree-sitter-json
# p.tree-sitter-nix
# p.tree-sitter-python
# p.tree-sitter-beancount
# ]))
# ];
};
direnv = {