This will generate a header at the top of the tangled file to indicate it is generated and is not meant to be modified directly.
;; -*- lexical-binding: t -*-
;; This file has been generated from config.org file. DO NOT EDIT.
Here’s how we start:
;; For speedup.
;; (setq straight-check-for-modifications nil)
;; Setup straight
(defvar bootstrap-version)
(let ((bootstrap-file
(expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
(bootstrap-version 5))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
(url-retrieve-synchronously
"https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
'silent 'inhibit-cookies)
(goto-char (point-max))
(eval-print-last-sexp)))
(load bootstrap-file nil 'nomessage))
(straight-use-package 'use-package)
(use-package straight
:custom
(straight-use-package-by-default t)
(straight-host-usernames '((github . "srijan"))))
;; Move customization variables to a separate file and load it
(setq custom-file (locate-user-emacs-file "custom-vars.el"))
(load custom-file 'noerror 'nomessage)
(setq-default native-comp-async-report-warnings-errors 'silent)
(defvar my-linux-p (equal (system-name) "GGN001944"))
(defvar my-windows-p (equal (system-name) "SHADOW"))
;; (defvar my-server-p (and (equal (system-name) "localhost") (equal user-login-name "sacha")))
(defvar my-phone-p (not (null (getenv "ANDROID_ROOT")))
"If non-nil, GNU Emacs is running on Termux.")
(when my-phone-p (setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3"))
(global-auto-revert-mode) ; simplifies syncing
(setq user-full-name "Srijan Choudhary"
user-mail-address "[email protected]")
;; Recent files
(recentf-mode 1)
;; Minibuffer history
(setq history-length 100)
(savehist-mode 1)
;; Remember and restore the last cursor location in opened files
(save-place-mode 1)
;; Revert buffers when the underlying file has changed
(global-auto-revert-mode 1)
;; Revert Dired and other buffers
(setq global-auto-revert-non-file-buffers t)
;; Kill current buffer (instead of asking first buffer name)
(global-set-key (kbd "C-x k") 'kill-current-buffer)
;; M-n for new frame (M-n is unbound in vanilla emacs)
(defun new-frame ()
(interactive)
(select-frame (make-frame))
(switch-to-buffer "*scratch*"))
(global-set-key (kbd "M-n") 'new-frame)
;; Fill column at 120
(setq fill-column 120)
(add-hook 'text-mode-hook
'variable-pitch-mode)
;; Basic Visuals
(setq inhibit-startup-message t)
(tool-bar-mode -1)
(tooltip-mode -1)
(scroll-bar-mode -1)
(menu-bar-mode -1)
(set-fringe-mode 10)
(hl-line-mode 1)
(blink-cursor-mode -1)
(add-to-list 'default-frame-alist '(height . 35))
(add-to-list 'default-frame-alist '(width . 140))
;; Fonts
;; (set-face-attribute 'default nil :font "RobotoMono Nerd Font" :height 140)
;; (set-face-attribute 'default nil :font "FiraCode Nerd Font Mono" :height 140)
;; (set-face-attribute 'default nil :font "Hack Nerd Font Mono" :height 140)
;; (set-face-attribute 'default nil :font "Iosevka Comfy Duo" :height 140)
;; (when my-linux-p
;; (set-face-attribute 'default nil :font "Berkeley Mono" :height 140))
(use-package fontaine
:custom
(fontaine-presets
'(
(iosevka-regular
:default-family "Iosevka Comfy"
:default-height 120
:variable-pitch-family "Iosevka Comfy Duo"
)
(berkeley-regular
:default-family "Berkeley Mono"
:default-height 120
:line-spacing 0.1
:variable-pitch-family "Berkeley Mono Variable"
;; :variable-pitch-family "Merriweather Sans Light"
;; :variable-pitch-height 0.96
)
(berkeley-large
:inherit berkeley-regular
:default-height 160
)
(t
:default-family "Iosevka Comfy"
:default-weight regular
:default-height 120
:fixed-pitch-family nil ; falls back to :default-family
:fixed-pitch-weight nil ; falls back to :default-weight
:fixed-pitch-height 1.0
:fixed-pitch-serif-family nil ; falls back to :default-family
:fixed-pitch-serif-weight nil ; falls back to :default-weight
:fixed-pitch-serif-height 1.0
:variable-pitch-family "Iosevka Comfy Duo"
:variable-pitch-weight nil
:variable-pitch-height 1.0
:bold-family nil ; use whatever the underlying face has
:bold-weight bold
:italic-family nil
:italic-slant italic
:line-spacing nil)))
:config
(fontaine-set-preset 'berkeley-regular)
)
;; Themes
;; (use-package doom-themes
;; :disabled t
;; ;; :ensure t
;; :config
;; (setq doom-themes-enable-bold t ; if nil, bold is universally disabled
;; doom-themes-enable-italic t) ; if nil, italics is universally disabled
;; ;; (load-theme 'doom-Iosvkem t)
;; (doom-themes-visual-bell-config)
;; (setq doom-themes-treemacs-theme "doom-atom") ; use "doom-colors" for less minimal icon theme
;; (doom-themes-treemacs-config)
;; ;; Corrects (and improves) org-mode's native fontification.
;; (doom-themes-org-config))
;; (use-package catppuccin-theme
;; :straight (:type git :host github :repo "catppuccin/emacs"))
;; (load-theme 'modus-operandi t)
;; (load-theme 'modus-operandi-tinted t)
(use-package ef-themes
:demand
:custom
(ef-themes-to-toggle '(ef-elea-light ef-elea-dark))
(ef-themes-headings
'((0 . (variable-pitch semibold 1.2))
(1 . (variable-pitch semibold 1.1))
(agenda-date . (variable-pitch 1.2))
(agenda-structure . (variable-pitch 1.4))
(t . (variable-pitch))
))
(ef-themes-mixed-fonts t)
(ef-themes-variable-pitch-ui t)
:hook ((ef-themes-post-load . my-ef-themes-mode-line)
(ef-themes-post-load . fontaine-apply-current-preset))
:config
(defun my-ef-themes-mode-line ()
"Tweak the style of the mode lines."
(ef-themes-with-colors
(custom-set-faces
`(mode-line ((,c :background ,bg-mode-line :foreground ,fg-mode-line :box (:line-width 1 :color ,fg-dim))))
`(mode-line-inactive ((,c :box (:line-width 1 :color ,bg-active)))))))
)
(ef-themes-select 'ef-elea-dark)
(use-package olivetti
:custom
(olivetti-style 'fancy)
(setq olivetti-fringe '(:background "#e5e5e5"))
)
(use-package spacious-padding)
;; (use-package nano-theme
;; :custom
;; (nano-fonts-use nil)
;; :config
;; (load-theme 'nano t)
;; (nano-mode)
;; (nano-dark)
;; )
;; No message in scratch buffer
(setq initial-scratch-message nil)
;; Switching between windows. Use `ace-window`, configure using :init and :bind
(use-package ace-window
:ensure t
:init
(setq aw-scope 'frame)
:bind ("M-o" . ace-window))
;; Open the config file
(global-set-key (kbd "C-x ,") (lambda() (interactive) (find-file (locate-user-emacs-file "config.org"))))
;; Backup
(setq backup-directory-alist '(("." . "~/.backups"))
make-backup-files t ; backup of a file the first time it is saved.
backup-by-copying t ; don't clobber symlinks
version-control t ; version numbers for backup files
delete-old-versions t ; delete excess backup files silently
kept-old-versions 6 ; oldest versions to keep when a new numbered
; backup is made (default: 2)
kept-new-versions 9 ; newest versions to keep when a new numbered
; backup is made (default: 2)
auto-save-default t ; auto-save every buffer that visits a file
auto-save-timeout 20 ; number of seconds idle time before auto-save
; (default: 30)
auto-save-interval 200) ; number of keystrokes between auto-saves
; (default: 300)
(use-package undo-fu)
(use-package evil
:init
(setq evil-respect-visual-line-mode t)
(setq evil-want-integration t) ;; This is optional since it's already set to t by default.
(setq evil-want-keybinding nil)
(setq evil-undo-system 'undo-fu)
:config
(evil-mode 1)
;; Prevents esc-key from translating to meta-key in terminal mode.
(setq evil-esc-delay 0)
(setq-default evil-shift-width 2)
(setq-default evil-symbol-word-search t)
(customize-set-variable 'evil-want-Y-yank-to-eol t)
(evil-add-command-properties #'org-open-at-point :jump t)
(evil-declare-key 'normal org-mode-map
"gk" 'outline-up-heading
"gj" 'outline-next-visible-heading
"H" 'org-beginning-of-line
"L" 'org-end-of-line
"t" 'org-todo
(kbd "<tab>") 'org-cycle
",c" 'org-cycle
",e" 'org-export-dispatch
",n" 'outline-next-visible-heading
",p" 'outline-previous-visible-heading
",t" 'org-set-tags-command
",u" 'outline-up-heading
"$" 'org-end-of-line
"^" 'org-beginning-of-line
"-" 'org-ctrl-c-minus ; change bullet style
))
(use-package evil-collection
:straight (:type git :host github :repo "emacs-evil/evil-collection")
:diminish (evil-collection-unimpaired-mode)
:after evil mu4e
:ensure t
:config
(evil-collection-init))
(use-package evil-org
:ensure t
:after org
:hook (org-mode . (lambda () evil-org-mode))
:config
(require 'evil-org-agenda)
(evil-org-agenda-set-keys))
(defun bb/setup-term-mode ()
(evil-local-set-key 'insert (kbd "C-r") 'bb/send-C-r))
(defun bb/send-C-r ()
(interactive)
(term-send-raw-string "\C-r"))
(add-hook 'term-mode-hook 'bb/setup-term-mode)
(when my-linux-p
(use-package vterm))
(when my-windows-p
(use-package powershell))
(use-package diminish
:config (require 'diminish))
(use-package eldoc :diminish eldoc-mode)
(use-package all-the-icons)
(use-package nerd-icons)
(use-package doom-modeline
:ensure t
:init
(doom-modeline-mode 1))
(use-package dirvish
:init
(dirvish-override-dired-mode)
:custom
(dirvish-quick-access-entries ; It's a custom option, `setq' won't work
'(("h" "~/" "Home")
("d" "~/Downloads/" "Downloads")
("n" "~/ndxrd-uxxs3/notes/" "Notes")
("o" "~/ndxrd-uxxs3/org/" "GTD Org")
("c" "~/.config/s-emacs/" "Config")))
:config
;; (dirvish-peek-mode) ; Preview files in minibuffer
;; (dirvish-side-follow-mode) ; similar to `treemacs-follow-mode'
(setq dirvish-mode-line-format
'(:left (sort symlink) :right (omit yank index)))
(setq dirvish-attributes
'(all-the-icons file-time file-size collapse subtree-state vc-state git-msg))
(setq delete-by-moving-to-trash t)
(setq dired-listing-switches
"-l --almost-all --human-readable --group-directories-first --no-group")
(evil-make-overriding-map dirvish-mode-map 'normal)
:bind ; Bind `dirvish|dirvish-side|dirvish-dwim' as you see fit
(("C-c f" . dirvish)
:map dirvish-mode-map ; Dirvish inherits `dired-mode-map'
("a" . dirvish-quick-access)
("f" . dirvish-file-info-menu)
("y" . dirvish-yank-menu)
("N" . dirvish-narrow)
("^" . dirvish-history-last)
("h" . dirvish-history-jump) ; remapped `describe-mode'
("s" . dirvish-quicksort) ; remapped `dired-sort-toggle-or-edit'
("v" . dirvish-vc-menu) ; remapped `dired-view-file'
("TAB" . dirvish-subtree-toggle)
("M-f" . dirvish-history-go-forward)
("M-b" . dirvish-history-go-backward)
("M-l" . dirvish-ls-switches-menu)
("M-m" . dirvish-mark-menu)
("M-t" . dirvish-layout-toggle)
("M-s" . dirvish-setup-menu)
("M-e" . dirvish-emerge-menu)
("M-j" . dirvish-fd-jump)))
(use-package org
:straight (:type built-in)
:ensure org-plus-contrib
:hook ((org-capture-mode . delete-other-windows)
(org-capture-mode . evil-insert-state))
:custom
(org-support-shift-select t)
(org-agenda-files nil) ;; Will be set automatically by org-gtd
(org-ellipsis " ▼")
(org-cycle-separator-lines 1)
;; (org-pretty-entities t)
(org-agenda-start-with-log-mode t)
(org-agenda-window-setup 'only-window)
(org-startup-folded 'content)
(org-startup-indented t)
(org-startup-with-inline-images t)
(org-clock-persist 'history)
(org-log-into-drawer t)
(org-log-done 'time)
(org-tag-persistent-alist '((:startgroup . nil)
("@computer") ("@mail") ("@errands") ("@calls")
(:endgroup . nil) (:startgroup . nil)
("@home") ("@office") ("@anywhere")
(:endgroup . nil)
("@fun") ("@agenda")
))
:config
;; (setq org-agenda-prefix-format '((agenda . " %i %-12:c%?-12t%-6e% s")))
;; So that we can jump back
(advice-add 'org-open-at-point :before #'evil-set-jump)
;; Clock stuff
(when my-linux-p
(org-clock-persistence-insinuate)
(defun current-clock-time-to-file ()
(interactive)
(with-temp-file "~/.local/state/task"
(if (org-clocking-p)
(insert (org-clock-get-clock-string))
(insert "No Task"))))
(run-with-timer 1 60 'current-clock-time-to-file)
(add-hook 'org-clock-in-hook 'current-clock-time-to-file)
(add-hook 'org-clock-out-hook 'current-clock-time-to-file))
;; Custom functions
(defun org-capture-inbox ()
(interactive)
(call-interactively 'org-store-link)
(org-capture nil "i"))
(defun org-capture-mail ()
(interactive)
(call-interactively 'org-store-link)
(org-capture nil "@"))
:bind
("C-c i" . org-capture-inbox)
("C-c a" . org-agenda)
("C-c l" . org-store-link)
)
(defun my/org-gtd-maybe-set-tags ()
"Use as a hook when decorating items after clarifying them."
(unless (org-gtd-organize-type-member-p '(trash knowledge quick-action incubated project-heading))
(org-set-tags-command)))
(defun my/org-gtd-maybe-set-effort ()
"Use as a hook when decorating items after clarifying them."
(unless (org-gtd-organize-type-member-p '(trash knowledge quick-action incubated project-heading))
(org-set-effort)))
(use-package org-gtd
:straight (:type git :host github :repo "Trevoke/org-gtd.el")
:after org
;; :ensure t
:demand t
:init
(setq org-gtd-update-ack "3.0.0")
(setq org-gtd-areas-of-focus '("Work Leadership" "Work Architecture" "Work Support"
"Productivity" "Personal Development" "Personal Services"
"Family" "Health" "Finances"))
:custom
(org-gtd-directory "~/ndxrd-uxxs3/org/")
(org-edna-use-inheritance t)
(org-gtd-organize-hooks '(org-gtd-areas-of-focus--set my/org-gtd-maybe-set-tags my/org-gtd-maybe-set-effort))
(org-gtd-refile-to-any-target nil)
(org-gtd-engage-prefix-width 24)
:config
(org-edna-mode 1)
(org-gtd-mode 1)
:bind
(("C-c d c" . org-gtd-capture)
("C-c c" . org-gtd-capture)
("C-c d e" . org-gtd-engage)
("C-c d p" . org-gtd-process-inbox)
("C-c d n" . org-gtd-show-all-next)
("C-c d x" . org-gtd-clarify-item)
("C-c d w" . org-gtd-delegate-item-at-point)
("C-c d a" . org-gtd-area-of-focus-set-on-item-at-point)
("C-c d s" . org-save-all-org-buffers)
:map org-gtd-clarify-map
("C-c c" . org-gtd-organize)
:map org-agenda-mode-map
("C-c d a" . org-gtd-area-of-focus-set-on-agenda-item)
("C-c d x" . org-gtd-clarify-agenda-item)
))
(use-package denote
;; :demand
:custom
(denote-directory (expand-file-name "~/ndxrd-uxxs3/notes/"))
(denote-known-keywords '("emacs" "philosophy" "politics" "economics"))
(denote-file-type 'markdown-yaml)
(denote-infer-keywords t)
(denote-sort-keywords t)
(denote-date-prompt-use-org-read-date t)
(denote-backlinks-show-context t)
(denote-templates
`((weekly-review . ,(f-read (expand-file-name
"templates/weekly-review.md"
user-emacs-directory)))))
:config
(defun my-weekly-review-journal ()
"Create an entry tagged 'weeklyreview' with the year and week as
its title using the 'weekly-review' template. If a note for
the current week exists, visit it. If multiple entries
exist, prompt with completion for a choice between them.
Else create a new file."
(interactive)
(let* ((denote-directory (concat denote-directory "journals/"))
;; Year corresponding to ISO week + ISO week
(week (format-time-string "%G W%V"))
(string (denote-sluggify week))
(files (denote-directory-files-matching-regexp string))
)
(cond
((> (length files) 1)
(find-file (completing-read "Select file: " files nil :require-match)))
(files
(find-file (car files)))
(t
(denote week '("weeklyreview") nil nil nil 'weekly-review)))))
(defun my-denote-journal ()
"Create an entry tagged 'journal' with the date as its title.
If a journal for the current day exists, visit it. If multiple
entries exist, prompt with completion for a choice between them.
Else create a new file."
(interactive)
(let* ((denote-directory (concat denote-directory "journals/"))
(today (format-time-string "%A %e %B %Y"))
(string (denote-sluggify today))
(files (denote-directory-files-matching-regexp string)))
(cond
((> (length files) 1)
(find-file (completing-read "Select file: " files nil :require-match)))
(files
(find-file (car files)))
(t
(denote today '("journal"))))))
:hook (dired-mode . denote-dired-mode)
;; :bind (map :global-map
;; ("C-c n d" . (dired-jump denote-directory)))
:bind
("C-c n n" . denote)
("C-c n j" . my-denote-journal)
("C-c n r" . my-weekly-review-journal)
)
(use-package denote-menu
:after denote)
(use-package consult-notes
:init
(require 'denote)
:config
(consult-notes-denote-mode 1)
:bind
("C-c n f" . consult-notes)
)
(use-package ediff
:config
(setq ediff-split-window-function 'split-window-horizontally)
(setq ediff-window-setup-function 'ediff-setup-windows-plain)
(defun my/command-line-diff (switch)
(setq initial-buffer-choice nil)
(let ((file1 (pop command-line-args-left))
(file2 (pop command-line-args-left)))
(ediff file1 file2)))
;; show the ediff command buffer in the same frame
(add-to-list 'command-switch-alist '("-diff" . my/command-line-diff)))
(use-package treemacs
:init
(with-eval-after-load 'winum
(define-key winum-keymap (kbd "M-0") #'treemacs-select-window))
:config
(defun my-treemacs-toggle ()
"Initialize or toggle treemacs.
Ensures that only the current project is present and all other projects have
been removed.
Use `treemacs' command for old functionality."
(interactive)
(pcase (treemacs-current-visibility)
(`visible (delete-window (treemacs-get-local-window)))
(_ (treemacs-add-and-display-current-project))))
:custom
(treemacs-follow-after-init t)
(treemacs-is-never-other-window t)
(treemacs-follow-mode -1)
:bind
(:map global-map
("M-0" . treemacs-select-window)
("C-x t 1" . treemacs-delete-other-windows)
("C-x t t" . my-treemacs-toggle)
("C-x t d" . treemacs-select-directory)
("C-x t B" . treemacs-bookmark)
("C-x t C-t" . treemacs-find-file)
("C-x t M-t" . treemacs-find-tag))
)
(use-package treemacs-evil
:after (treemacs evil)
:ensure t)
(use-package treemacs-icons-dired
:hook (dired-mode . treemacs-icons-dired-enable-once)
:ensure t)
(use-package treemacs-magit
:after (treemacs magit)
:ensure t)
(use-package org-tree-slide)
(use-package visual-fill-column
:custom
(visual-fill-column-width 90)
(visual-fill-column-center-text t))
(defun my/org-present-start ()
;; Center the presentation and wrap lines
(visual-fill-column-mode 1)
(visual-line-mode 1)
(setq-local face-remapping-alist
'((default (:height 1.5) variable-pitch)
(header-line (:height 4.0) variable-pitch)
(org-document-title (:height 1.75) org-document-title)
(org-code (:height 1.55) org-code)
(org-verbatim (:height 1.55) org-verbatim)
(org-block (:height 1.25) org-block)
(org-block-begin-line (:height 0.7) org-block)))
(setq header-line-format " ")
)
(defun my/org-present-end ()
;; Stop centering the document
(visual-fill-column-mode 0)
(visual-line-mode 0)
;; (setq-local face-remapping-alist '((default variable-pitch default)))
(setq-local face-remapping-alist 'nil)
(setq header-line-format nil)
)
(use-package org-present
:hook
(org-present-mode . my/org-present-start)
(org-present-mode-quit . my/org-present-end)
)
(use-package intuitive-tab-line
:straight (:type git :host github :repo "thread314/intuitive-tab-line-mode")
:custom
(tab-line-tabs-function 'intuitive-tab-line-buffers-list)
(tab-line-switch-cycling t)
:config
(global-tab-line-mode 1)
(recentf-mode 1)
(setq
tab-line-new-button-show nil ;; do not show add-new button
tab-line-close-button-show nil ;; do not show close button
tab-line-separator " " ;; delimitation between tabs
))
(global-set-key (kbd "C-<prior>") 'tab-line-switch-to-prev-tab)
(global-set-key (kbd "C-<iso-lefttab>") 'tab-line-switch-to-prev-tab)
(global-set-key (kbd "C-<next>") 'tab-line-switch-to-next-tab)
(global-set-key (kbd "C-<tab>") 'tab-line-switch-to-next-tab)
(global-set-key (kbd "C-S-<prior>") 'intuitive-tab-line-shift-tab-left)
(global-set-key (kbd "C-S-<next>") 'intuitive-tab-line-shift-tab-right)
(global-set-key (kbd "C-S-t") 'recentf-open-most-recent-file)
(use-package beframe
:demand
:custom
(beframe-functions-in-frames '(project-prompt-project-dir))
:config
(beframe-mode 1)
(defvar consult-buffer-sources)
(declare-function consult--buffer-state "consult")
(with-eval-after-load 'consult
(defface beframe-buffer
'((t :inherit font-lock-string-face))
"Face for `consult' framed buffers.")
(defun my-beframe-buffer-names-sorted (&optional frame)
"Return the list of buffers from `beframe-buffer-names' sorted by visibility.
With optional argument FRAME, return the list of buffers of FRAME."
(beframe-buffer-names frame :sort #'beframe-buffer-sort-visibility))
(defvar beframe-consult-source
`( :name "Frame-specific buffers (current frame)"
:narrow ?F
:category buffer
:face beframe-buffer
:history beframe-history
:items ,#'my-beframe-buffer-names-sorted
:action ,#'switch-to-buffer
:state ,#'consult--buffer-state))
(add-to-list 'consult-buffer-sources 'beframe-consult-source))
(define-key global-map (kbd "C-c b") #'beframe-prefix-map)
(global-set-key (kbd "C-b") 'consult-buffer)
(define-key evil-normal-state-map (kbd "C-b") 'consult-buffer)
)
(use-package command-log-mode
:config
(global-command-log-mode))
(use-package which-key
:config (which-key-mode 1))
(defun my-reload-emacs-configuration ()
(interactive)
(load-file "~/.config/s-emacs/init.el"))
(use-package savehist
:config
(setq history-length 25)
(savehist-mode 1))
(defun dw/minibuffer-backward-kill (arg)
"When minibuffer is completing a file name delete up to parent
folder, otherwise delete a word"
(interactive "p")
(if minibuffer-completing-file-name
;; Borrowed from https://github.com/raxod502/selectrum/issues/498#issuecomment-803283608
(if (string-match-p "/." (minibuffer-contents))
(zap-up-to-char (- arg) ?/)
(delete-minibuffer-contents))
(backward-kill-word arg)))
(use-package vertico
:straight '(vertico :host github
:repo "minad/vertico"
:branch "main")
:bind (:map vertico-map
("C-j" . vertico-next)
("C-k" . vertico-previous)
("C-f" . vertico-exit)
:map minibuffer-local-map
("M-h" . dw/minibuffer-backward-kill))
:custom
(vertico-cycle t)
;; :custom-face
;; (vertico-current ((t (:background "#3a3f5a"))))
:init
(vertico-mode))
(use-package corfu
:straight '(corfu :host github
:repo "minad/corfu")
:bind (:map corfu-map
("C-j" . corfu-next)
("C-k" . corfu-previous)
("C-f" . corfu-insert))
:custom
(corfu-cycle t)
:config
(corfu-global-mode))
(use-package orderless
:custom
;; (completion-styles '(orderless))
;; (completion-category-defaults nil)
;; (completion-category-overrides '((file (styles . (partial-completion)))))
(completion-styles '(orderless basic))
(completion-category-overrides '((file (styles basic partial-completion))))
)
(defun dw/get-project-root ()
(when (fboundp 'projectile-project-root)
(projectile-project-root)))
(use-package consult
:straight t
:demand t
;; Replace bindings. Lazily loaded due by `use-package'.
:bind (
;; My bindings
("C-s" . consult-line)
;; C-c bindings in `mode-specific-map'
("C-c M-x" . consult-mode-command)
("C-c h" . consult-history)
("C-c k" . consult-kmacro)
("C-c m" . consult-man)
("C-c i" . consult-info)
([remap Info-search] . consult-info)
;; C-x bindings in `ctl-x-map'
("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command
("C-x b" . consult-buffer) ;; orig. switch-to-buffer
("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window
("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame
("C-x r b" . consult-bookmark) ;; orig. bookmark-jump
("C-x p b" . consult-project-buffer) ;; orig. project-switch-to-buffer
;; Custom M-# bindings for fast register access
("M-#" . consult-register-load)
("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated)
("C-M-#" . consult-register)
;; Other custom bindings
("M-y" . consult-yank-pop) ;; orig. yank-pop
;; M-g bindings in `goto-map'
("M-g e" . consult-compile-error)
("M-g f" . consult-flymake) ;; Alternative: consult-flycheck
("M-g g" . consult-goto-line) ;; orig. goto-line
("M-g M-g" . consult-goto-line) ;; orig. goto-line
("M-g o" . consult-outline) ;; Alternative: consult-org-heading
("M-g m" . consult-mark)
("M-g k" . consult-global-mark)
("M-g i" . consult-imenu)
("M-g I" . consult-imenu-multi)
;; M-s bindings in `search-map'
("M-s d" . consult-find)
("M-s D" . consult-locate)
("M-s g" . consult-grep)
("M-s G" . consult-git-grep)
("M-s r" . consult-ripgrep)
("M-s l" . consult-line)
("M-s L" . consult-line-multi)
("M-s k" . consult-keep-lines)
("M-s u" . consult-focus-lines)
;; Isearch integration
("M-s e" . consult-isearch-history)
:map isearch-mode-map
("M-e" . consult-isearch-history) ;; orig. isearch-edit-string
("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string
("M-s l" . consult-line) ;; needed by consult-line to detect isearch
("M-s L" . consult-line-multi) ;; needed by consult-line to detect isearch
;; Minibuffer history
:map minibuffer-local-map
("M-s" . consult-history) ;; orig. next-matching-history-element
("M-r" . consult-history)) ;; orig. previous-matching-history-element
;; Enable automatic preview at point in the *Completions* buffer. This is
;; relevant when you use the default completion UI.
:hook (completion-list-mode . consult-preview-at-point-mode)
;; The :init configuration is always executed (Not lazy)
:init
;; Optionally configure the register formatting. This improves the register
;; preview for `consult-register', `consult-register-load',
;; `consult-register-store' and the Emacs built-ins.
(setq register-preview-delay 0.5
register-preview-function #'consult-register-format)
;; Optionally tweak the register preview window.
;; This adds thin lines, sorting and hides the mode line of the window.
(advice-add #'register-preview :override #'consult-register-window)
;; Use Consult to select xref locations with preview
(setq xref-show-xrefs-function #'consult-xref
xref-show-definitions-function #'consult-xref)
:custom
(consult-project-root-function #'dw/get-project-root)
(completion-in-region-function #'consult-completion-in-region)
;; Configure other variables and modes in the :config section,
;; after lazily loading the package.
:config
;; Optionally configure preview. The default value
;; is 'any, such that any key triggers the preview.
;; (setq consult-preview-key 'any)
;; (setq consult-preview-key "M-.")
;; (setq consult-preview-key '("S-<down>" "S-<up>"))
;; For some commands and buffer sources it is useful to configure the
;; :preview-key on a per-command basis using the `consult-customize' macro.
(consult-customize
consult-theme :preview-key '(:debounce 0.2 any)
consult-ripgrep consult-git-grep consult-grep
consult-bookmark consult-recent-file consult-xref
consult--source-bookmark consult--source-file-register
consult--source-recent-file consult--source-project-recent-file
;; :preview-key "M-."
:preview-key '(:debounce 0.4 any))
;; Optionally configure the narrowing key.
;; Both < and C-+ work reasonably well.
(setq consult-narrow-key "<") ;; "C-+"
;; Optionally make narrowing help available in the minibuffer.
;; You may want to use `embark-prefix-help-command' or which-key instead.
;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help)
)
(use-package marginalia
:after vertico
:straight t
:custom
(marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light nil))
:init
(marginalia-mode))
(use-package embark
:straight t
:bind (("C-S-a" . embark-act)
:map minibuffer-local-map
("C-d" . embark-act))
:config
;; Show Embark actions via which-key
(setq embark-action-indicator
(lambda (map)
(which-key--show-keymap "Embark" map nil nil 'no-paging)
#'which-key--hide-popup-ignore-command)
embark-become-indicator embark-action-indicator))
From: https://andreyorst.gitlab.io/posts/2022-07-16-project-el-enhancements/ WARN: This makes emacs on Windows extremely slow
(when my-linux-p
(use-package project
:config
(defcustom project-root-markers
'(".project")
"Files or directories that indicate the root of a project."
:type '(repeat string)
:group 'project)
(defun project-root-p (path)
"Check if the current PATH has any of the project root markers."
(catch 'found
(dolist (marker project-root-markers)
(when (file-exists-p (concat path marker))
(throw 'found marker)))))
;; (defun project-find-root (path)
;; "Search up the PATH for `project-root-markers'."
;; (when-let ((root (locate-dominating-file path #'project-root-p)))
;; (cons 'transient (expand-file-name root))))
(defun project-find-root (path)
"Search up the PATH for `project-root-markers'."
(let ((path (expand-file-name path)))
(catch 'found
(while (not (equal "/" path))
(if (not (project-root-p path))
(setq path (file-name-directory (directory-file-name path)))
(throw 'found (cons 'transient path)))))))
(add-to-list 'project-find-functions #'project-find-root)
))
(when my-linux-p
(setq dictionary-server "localhost")
(use-package flyspell
:hook ((text-mode . flyspell-mode)
(org-mode . flyspell-mode)
(prog-mode . flyspell-prog-mode)))
)
(use-package copilot
:diminish
:straight (:host github :repo "zerolfx/copilot.el" :files ("dist" "*.el"))
:ensure t
:hook (prog-mode . copilot-mode)
:bind (
;; ("C-TAB" . 'copilot-accept-completion-by-word)
;; ("C-<tab>" . 'copilot-accept-completion-by-word)
:map copilot-completion-map
("<tab>" . 'copilot-accept-completion)
("TAB" . 'copilot-accept-completion))
)
(use-package auth-source-1password
:config
(auth-source-1password-enable))
(use-package chatgpt-shell
:ensure t
:custom
((chatgpt-shell-openai-key
(lambda ()
(auth-source-pick-first-password :host "openai-key" :user "credential")))))
(use-package markdown-mode
:mode ("README\\.md\\'" . gfm-mode)
:init (setq markdown-command '("pandoc" "--from=markdown" "--to=html5"))
)
(use-package magit)
(use-package json-mode)
(when my-windows-p
(use-package ahk-mode))
(use-package php-mode)
(use-package yasnippet
:diminish (yas-minor-mode)
:config
(yas-global-mode t)
)
;; Install the official Erlang mode
(when my-linux-p
(add-to-list
'load-path (car (file-expand-wildcards
"/usr/lib/erlang/lib/tools-*/emacs"))))
(when my-windows-p
(add-to-list
'load-path (car (file-expand-wildcards
"/Program Files/Erlang OTP/lib/tools-*/emacs"))))
(use-package erlang
:straight nil
:hook ((erlang-mode . linum-mode)
(erlang-mode . column-number-mode))
:init
)
(require 'erlang-start)
(use-package elixir-mode)
(use-package eglot
:hook (erlang-mode . eglot-ensure)
:config
(add-hook 'eglot-managed-mode-hook
(lambda ()
;; Show flymake diagnostics first.
(setq eldoc-documentation-functions
(cons #'flymake-eldoc-function
(remove #'flymake-eldoc-function eldoc-documentation-functions)))
;; Show all eldoc feedback.
(setq eldoc-documentation-strategy #'eldoc-documentation-compose)))
)
(use-package dockerfile-mode)
(use-package yaml-mode)
(use-package kubernetes
:ensure t
:commands (kubernetes-overview)
:config
(setq kubernetes-poll-frequency 3600
kubernetes-redraw-frequency 3600))
(use-package kubernetes-evil
:ensure t
:after kubernetes)
(use-package emojify)
;; (:hook (after-init . global-emojify-mode))
(use-package mastodon
:straight (:package mastodon :host nil :type git :repo "https://codeberg.org/martianh/mastodon.el.git" :branch "develop")
:ensure t
:config
(setq mastodon-instance-url "https://fedi.srijan.dev"
mastodon-active-user "srijan")
)
(use-package mu4e
:straight nil
:if my-linux-p
:hook (evil-collection-setup . (lambda (&rest a)
(evil-define-key 'normal mu4e-headers-mode-map "z%" 'mu4e-headers-mark-thread)
))
:config
(setq
;; mu4e-use-maildirs-extension nil
mu4e-get-mail-command "systemctl --user start mbsync.service" ;; "mbsync fastmail-all"
mu4e-view-prefer-html t
;; mu4e-update-interval 180
mu4e-headers-auto-update t
mu4e-search-include-related nil
mu4e-compose-signature-auto-include nil
mu4e-compose-format-flowed t
mu4e-use-fancy-chars t
mu4e-headers-visible-flags '(draft flagged new passed replied trashed attach encrypted signed)
mu4e-headers-fields '((:human-date . 12)
(:flags . 6)
(:from-or-to . 32)
(:subject))
mu4e-headers-date-format "%Y-%m-%d"
mu4e-headers-from-or-to-prefix '("" . "To: ")
mu4e-headers-leave-behavior 'apply
mu4e-hide-index-messages t
message-kill-buffer-on-exit t
)
(defun my-mu4e-refile-folder-fun (msg)
"Set the refile folder for MSG."
(let ((date (mu4e-message-field msg :date)))
(cond
(date
(format "/fastmail/Archive/%s" (format-time-string "%Y" date)))
(t
"/fastmail/Archive"))))
(setq user-full-name "Srijan Choudhary"
mu4e-sent-folder "/fastmail/Sent Items"
mu4e-drafts-folder "/fastmail/Drafts"
mu4e-trash-folder "/fastmail/Trash"
;; mu4e-refile-folder "/fastmail/Archive"
mu4e-refile-folder 'my-mu4e-refile-folder-fun
mu4e-attachment-dir "~/Downloads"
)
;; enable inline images
(setq mu4e-view-show-images t)
;; use imagemagick, if available
(when (fboundp 'imagemagick-register-types)
(imagemagick-register-types))
;; every new email composition gets its own frame!
;; (setq mu4e-compose-in-new-frame t)
;; don't save message to Sent Messages, IMAP takes care of this
(setq mu4e-sent-messages-behavior 'sent)
(add-hook 'mu4e-view-mode-hook #'visual-line-mode)
;; <tab> to navigate to links, <RET> to open them in browser
(add-hook 'mu4e-view-mode-hook
(lambda()
;; try to emulate some of the eww key-bindings
(local-set-key (kbd "<RET>") 'mu4e~view-browse-url-from-binding)
(local-set-key (kbd "<tab>") 'shr-next-link)
(local-set-key (kbd "<backtab>") 'shr-previous-link)))
;; spell check
(add-hook 'mu4e-compose-mode-hook
(defun my-do-compose-stuff ()
"My settings for message composition."
(visual-line-mode)
;; (org-mu4e-compose-org-mode)
(use-hard-newlines -1)
;; (flyspell-mode)
))
;;rename files when moving
;;NEEDED FOR MBSYNC
(setq mu4e-change-filenames-when-moving t)
;; bookmarks
(add-to-list 'mu4e-bookmarks
'( :name "Inbox GO"
:query "maildir:\"/fastmail/Inbox GO\""
:key ?g))
(add-to-list 'mu4e-bookmarks
'( :name "Inbox Personal"
:query "maildir:\"/fastmail/Inbox\""
:key ?p))
(add-to-list 'mu4e-bookmarks
'( :name "Sent Items"
:query "maildir:\"/fastmail/Sent Items\""
:key ?s))
(add-to-list 'mu4e-bookmarks
'( :name "Waiting For Support"
:query "\"maildir:/fastmail/@Waiting For Support\""
:key ?f))
(add-to-list 'mu4e-bookmarks
'( :name "Action Support"
:query "\"maildir:/fastmail/@Action Support\""
:key ?a))
(add-to-list 'mu4e-bookmarks
'( :name "Inbox"
:query "\"maildir:/fastmail/Inbox\" or \"maildir:/fastmail/Inbox GO\""
:key ?i))
;; set mail user agent
(setq mail-user-agent 'mu4e-user-agent
message-mail-user-agent 'mu4e-user-agent)
;; Setup mu4e contexts. This is to enable adding multiple email contexts if needed in the future.
;; I will initially only enable my fastmail context but adding a new one shouldn't be harder than copying
;; the existing context and modifying the settings.
(setq mu4e-context-policy 'pick-first)
(setq mu4e-compose-context-policy 'ask)
(setq mu4e-contexts
(list
(make-mu4e-context
:name "fastmail"
:enter-func (lambda () (mu4e-message "Entering context fastmail"))
:leave-func (lambda () (mu4e-message "Leaving context fastmail"))
:match-func (lambda (msg)
(when msg
(mu4e-message-contact-field-matches
msg '(:from :to :cc :bcc) "[email protected]")))
:vars '((user-mail-address . "[email protected]")
;; (mu4e-compose-signature . (concat "Srijan Choudhary\n" "https://www.srijn.net\n"))
(mu4e-compose-format-flowed . t)
))
(make-mu4e-context
:name "personal"
:enter-func (lambda () (mu4e-message "Entering context personal"))
:leave-func (lambda () (mu4e-message "Leaving context personal"))
:match-func (lambda (msg)
(when msg
(mu4e-message-contact-field-matches
msg '(:from :to :cc :bcc) "[email protected]")))
:vars '((user-mail-address . "[email protected]")
;; (mu4e-compose-signature . (concat "Srijan Choudhary\n" "https://www.srijn.net\n"))
(mu4e-compose-format-flowed . t)
))
(make-mu4e-context
:name "greyorange"
:enter-func (lambda () (mu4e-message "Entering context greyorange"))
:leave-func (lambda () (mu4e-message "Leaving context greyorange"))
:match-func (lambda (msg)
(when msg
(mu4e-message-contact-field-matches
msg '(:from :to :cc :bcc) "[email protected]")))
:vars '((user-mail-address . "[email protected]")
;; (mu4e-compose-signature . (concat "Srijan Choudhary\n" "https://www.srijn.net\n"))
(mu4e-compose-format-flowed . t)
))
))
;; Allow replying to calendar events
;; https://www.djcbsoftware.nl/code/mu/mu4e/iCalendar.html
(require 'mu4e-icalendar)
(mu4e-icalendar-setup)
(setq mu4e-icalendar-trash-after-reply t)
)
(use-package org
:if my-linux-p
:bind (
:map mu4e-headers-mode-map
("C-c i" . org-capture-mail)
;; ("z m" . mu4e-view-mark-thread)
:map mu4e-view-mode-map
("C-c i" . org-capture-mail))
)
(use-package org-msg
:if my-linux-p
:config
(setq org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil \\n:t"
org-msg-startup "hidestars indent inlineimages"
org-msg-default-alternatives '((new . (text html))
(reply-to-html . (text html))
(reply-to-text . (text)))
org-msg-convert-citation t
org-msg-signature "
#+begin_signature
--
*Srijan Choudhary*
#+end_signature")
(org-msg-mode)
)
(use-package smtpmail
:if my-linux-p
:config
(setq sendmail-program "/usr/bin/msmtp"
send-mail-function 'smtpmail-send-it
message-sendmail-f-is-evil t
;; This allows msmtp to automatically choose the correct account
;; based on from header.
message-sendmail-extra-arguments '("--read-envelope-from")
message-send-mail-function 'message-send-mail-with-sendmail
smtpmail-debug-info t
smtpmail-debug-verbose t
)
(setq smtpmail-queue-mail nil)
(setq smtpmail-queue-dir "~/Maildir/queue/cur")
)
(setq gc-cons-threshold (* 2 1000 1000))
(add-hook 'emacs-startup-hook
(lambda ()
(message "Emacs ready in %s with %d garbage collections."
(format "%.2f seconds"
(float-time
(time-subtract after-init-time before-init-time)))
gcs-done)))
(let ((inhibit-message t))
(message "Welcome to GNU Emacs / N Λ N O edition")
(message (format "Initialization time: %s" (emacs-init-time))))