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)
(package-install-upgrade-built-in 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 "srijan4@gmail.com")
;; 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)
(setq visible-bell t)
(setq save-interprogram-paste-before-kill t)
;; 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"
)
(iawriter-regular
:default-family "iMWritingMono Nerd Font"
:default-height 120
:line-spacing 0.1
:variable-pitch-family "iMWritingDuo Nerd Font Propo"
;; :variable-pitch-family "Merriweather Sans Light"
;; :variable-pitch-height 0.96
)
(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)
)
(use-package emoji
:straight (:type built-in)
:bind (("C-c e" . emoji-search))
)
;; 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-maris-light ef-maris-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-maris-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"))))
(winner-mode 1)
(use-package intuitive-tab-line
:disabled t
: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)
(defun my-tab-buffers-fun (&rest _args)
"Create a tab for the current buffer."
(interactive)
(if
(and
(not (seq-contains-p intuitive-tab-line--current-tab-list (current-buffer))) ;;Exclude if already has a tab
;; (not (string-match (rx "magit") (buffer-name (current-buffer)))) ;;Exclude magit
;; (not (string-match (rx "COMMIT_EDITMSG") (buffer-name (current-buffer)))) ;;Exclude magit and edit msg
;; (not (string-match (rx "CAPTURE-") (buffer-name (current-buffer)))) ;;Exclude capture buffer
;; (not (string-match (rx "*org-roam*") (buffer-name (current-buffer)))) ;;Exclude org-roam buffer
(or
;;Define any buffers you would always like to be given their own tab here.
(buffer-file-name (current-buffer)) ;;Include all file buffers
(buffer-local-value 'list-buffers-directory (current-buffer)) ;;Include Dired Buffers
(string-match (rx "*help") (buffer-name (current-buffer))) ;;Include Help Buffers
(string-match (rx "*mu4e") (buffer-name (current-buffer))) ;;Include mu4e buffers
(string-match (rx "*elfeed") (buffer-name (current-buffer))) ;;Include elfeed buffers
(string-match (rx "*Org") (buffer-name (current-buffer))) ;;Include org buffers
(buffer-base-buffer (current-buffer)) ;;Include Indirect Buffers
))
(setq intuitive-tab-line--current-tab-list (append intuitive-tab-line--current-tab-list (list (current-buffer)))))
(setq intuitive-tab-line--current-tab-list (seq-remove (lambda (elt) (not (buffer-name elt))) intuitive-tab-line--current-tab-list))
(force-mode-line-update))
(advice-add 'intuitive-tab-line-add-current-buffer-to-tab :override #'my-tab-buffers-fun)
(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
))
(use-package tab-line
:demand t
:bind
(("C-<iso-lefttab>" . tab-line-switch-to-prev-tab)
("C-<tab>" . tab-line-switch-to-next-tab))
:config
(global-tab-line-mode 1)
(setq
tab-line-new-button-show nil
tab-line-close-button-show nil))
;; (global-set-key (kbd "C-<iso-lefttab>") 'tab-line-switch-to-prev-tab)
;; (global-set-key (kbd "C-<tab>") 'tab-line-switch-to-next-tab)
;; (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)
;; 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)
remote-file-name-inhibit-auto-save t
remote-file-name-inhibit-locks t
create-lockfiles nil
)
(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)
("@tz-ist") ("@tz-est") ("@anytime")
(:endgroup . nil)
("@fun") ("@agenda") ("@home") ("@anywhere")
))
(org-capture-templates
'(
("i" "Inbox" entry (file org-gtd-inbox-path) "* %?\n%U\n%i"
:kill-buffer t)
("l" "Inbox with link" entry (file org-gtd-inbox-path) "* %?\n%U\n%i\n%a"
:kill-buffer t)))
:config
(require 'org-tempo)
;; (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-gtd-capture nil "i"))
(defun org-capture-mail ()
(interactive)
(call-interactively 'org-store-link)
(org-capture nil "@"))
(defun org-open-inbox ()
(interactive)
(find-file "~/ndxrd-uxxs3/org/inbox.org")
)
:bind
("C-c i" . org-capture-inbox)
("C-c j" . org-open-inbox)
("C-c a" . org-agenda)
("C-c l" . org-store-link)
)
(use-package org-protocol
:straight (:type built-in)
:ensure org-protocol
:custom
(org-protocol-default-template-key "l")
)
(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-contrib)
(require 'ox-confluence)
(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)
(org-gtd-capture-templates org-capture-templates)
: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)
))
;;;; Run commands in a popup frame
(defun prot-window-delete-popup-frame (&rest _)
"Kill selected selected frame if it has parameter `prot-window-popup-frame`.
Use this function via a hook."
(when (frame-parameter nil 'prot-window-popup-frame)
(delete-frame)))
(defmacro prot-window-define-with-popup-frame (command)
"Define interactive function which calls COMMAND in a new frame.
Make the new frame have the `prot-window-popup-frame' parameter."
`(defun ,(intern (format "prot-window-popup-%s" command)) ()
,(format "Run `%s' in a popup frame with `prot-window-popup-frame' parameter.
Also see `prot-window-delete-popup-frame'." command)
(interactive)
(let ((frame (make-frame '((prot-window-popup-frame . t)))))
(select-frame frame)
(switch-to-buffer " prot-window-hidden-buffer-for-popup-frame")
(condition-case nil
(call-interactively ',command)
((quit error user-error)
(delete-frame frame))))))
(declare-function org-capture "org-capture" (&optional goto keys))
(defvar org-capture-after-finalize-hook)
;;;###autoload (autoload 'prot-window-popup-org-capture "prot-window")
(prot-window-define-with-popup-frame org-capture)
(add-hook 'org-capture-after-finalize-hook #'prot-window-delete-popup-frame)
;; (declare-function tmr "tmr" (time &optional description acknowledgep))
;; (defvar tmr-timer-created-functions)
;;;###autoload (autoload 'prot-window-popup-tmr "prot-window")
;; (prot-window-define-with-popup-frame tmr)
;; (add-hook 'tmr-timer-created-functions #'prot-window-delete-popup-frame)C
(use-package denote
;; :demand
:init
(require 'denote-journal-extras)
:custom
(denote-directory (expand-file-name "~/ndxrd-uxxs3/notes/"))
(denote-journal-extras-directory (expand-file-name "~/ndxrd-uxxs3/notes/journals/"))
(denote-known-keywords '("emacs" "philosophy" "politics" "economics"))
(denote-journal-extras-title-format 'day-date-month-year)
(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)))
(journal . "")))
: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 'title week))
(files (denote-directory-files 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)))))
: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" . denote-journal-extras-new-or-existing-entry)
("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)
("C-c n s" . consult-notes-search-in-all-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 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 . (lambda ()
(interactive)
(unless (file-remote-p default-directory)
(copilot-mode))))
:custom
(copilot-max-char 1000000)
: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 mermaid-mode)
(use-package sql-indent)
(editorconfig-mode 1)
(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)
(use-package js
:straight (:type built-in)
:custom
(js-indent-level 2))
(when my-windows-p
(use-package ahk-mode))
(use-package php-mode)
;; (use-package jsonnet-mode)
(use-package hierarchy)
(use-package tree-mode)
(use-package json-navigator)
(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 . display-line-numbers-mode)
(erlang-mode . column-number-mode))
:init
)
(require 'erlang-start)
(use-package indy
:disabled
:custom
(setq indy-rules
'((erlang-mode . (
;; ((indy--current 'indy--starts-with "]") (indy--prev-tab -1))
;; ((indy--prev 'indy--ends-on "[") (indy--prev-tab 1))
;; ((indy--prev 'indy--ends-on ",") (indy--prev-tab))
((and (indy--current 'indy--starts-with "end")
(indy--prev 'indy--ends-on ") ->")) (indy--prev-tab))
((indy--current 'indy--starts-with "end") (indy--prev-tab -1))
((indy--prev 'indy--ends-on ") ->") (indy--prev-tab 1))
((indy--current 'indy--starts-with "]") (indy--prev-tab -1))
((indy--prev 'indy--ends-on "[") (indy--prev-tab 1))
((indy--prev 'indy--ends-on ",") (indy--prev-tab))
))
)
))
(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 gnus
:straight nil
:custom
(gnus-inhibit-mime-unbuttonizing t)
(mm-discouraged-alternatives '("text/html" "text/richtext")))
(use-package mu4e
:straight nil
:if my-linux-p
:demand t
:hook (evil-collection-setup . (lambda (&rest a)
(evil-define-key 'normal mu4e-headers-mode-map "z%" 'mu4e-headers-mark-thread)
))
:config
(global-set-key (kbd "C-c m") 'mu4e)
(setq
;; mu4e-use-maildirs-extension nil
mu4e-get-mail-command "systemctl --user start mbsync.service" ;; "mbsync fastmail-all"
mu4e-view-prefer-html nil
;; mu4e-update-interval 180
mu4e-headers-auto-update t
mu4e-search-include-related t
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
shr-color-visible-luminance-min 80
)
(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 "Memos"
:query "\"maildir:/fastmail/Memos\""
:key ?m))
(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) "srijan@fastmail.com")))
:vars '((user-mail-address . "srijan@fastmail.com")
(mu4e-compose-signature . (concat "Srijan Choudhary\n" "https://srijan.ch\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) "srijan4@gmail.com")))
:vars '((user-mail-address . "srijan4@gmail.com")
(mu4e-compose-signature . (concat "Srijan Choudhary\n" "https://srijan.ch\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) "srijan.c@greyorange.com")))
:vars '((user-mail-address . "srijan.c@greyorange.com")
(mu4e-compose-signature . "Srijan Choudhary\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)
(mu4e t) ;; Start mu4e in the background
)
(use-package mu4e-views
:disabled
)
(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
;; Issues with mu 1.12 right now
:disabled
: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))))