Adithya Chari


Sourcehut: adchari

LinkedIn: adithyachari

Résumé: Click Here


;; Let's start with some things that directly change how Emacs works...
;; Increase GC limit to 10MB and enable garbage collection on loss of focus
(setq gc-cons-threshold 100000000)
(add-function :after after-focus-change-function 'garbage-collect)

;; Natively compile .emacs.el when the file is saved
(defun autocompile nil
  "Compile itself if ~/.emacs.el."
  (require 'comp)
  (let ((dotemacs (file-truename user-init-file)))
    (if (string= (buffer-file-name) (file-chase-links dotemacs))
		(native-compile dotemacs))))
(add-hook 'after-save-hook 'autocompile)

;; Store all backup and autosave files in the tmp dir
(setq backup-directory-alist `((".*" . ,temporary-file-directory))
	  auto-save-file-name-transforms `((".*" ,temporary-file-directory t)))

;; Make sure Emacs auto-reverts files

;; Move custom.el bindings to an .emacs.d/ file
(setq custom-file "~/.emacs.d/custom.el")
(load custom-file :noerror)

;; Enable some disabled features
(put 'narrow-to-region 'disabled nil)

;; Now, time to configure package management...
;; Add MELPA support and require use-package
(require 'package)
(require 'use-package)
(add-to-list 'package-archives '("melpa" . "") t)

;; Enable no-littering to clean up .emacs.d
(use-package no-littering)

;; Aaand, let's make things look pretty...
;; First, maximize Emacs on open
(setq initial-frame-alist '((fullscreen . maximized))
	  default-frame-alist '((fullscreen . maximized)))

;; Now, let's get rid of the cruft
(tool-bar-mode -1)
(scroll-bar-mode -1)
(menu-bar-mode -1)

(setq inhibit-startup-screen t
	  initial-major-mode 'fundamental-mode
	  use-short-answers t)
(setq-default cursor-type 'bar
			  indent-tabs-mode nil
			  tab-width 4)

;; Emacs 29 comes with fancy smooth-scrolling, enable it
(setq pixel-scroll-precision-large-scroll-height 40.0
	  pixel-scroll-precision-interpolation-factor 30)

;; Emacs 28+ has modus-vivendi, set up dark mode theme
(setq modus-themes-italic-constructs t
      modus-themes-toggle '(modus-vivendi modus-operandi))
(load-theme 'modus-vivendi)

;; The bell sound is horrible, give a visual cue instead
(setq visible-bell nil
	  ring-bell-function 'flash-mode-line)
(defun flash-mode-line ()
  "Temporarily invert mode line."
  (invert-face 'mode-line)
  (run-with-timer 0.1 nil #'invert-face 'mode-line))

;; How about some quality-of-life keybindings...
(global-set-key (kbd "C-c r") #'rgrep) 	; Get easy access to rgrep
(global-set-key (kbd "C-c q") #'modus-themes-toggle) ; Flip the theme to light-mode and back
(global-set-key (kbd "C-c y") #'calc) ; Quick call to the calculator
(global-set-key (kbd "C-c #") #'display-line-numbers-mode) ; Create a toggle for line numbers
(global-set-key (kbd "C-x C-b") #'ibuffer) ; Use ibuffer over the regular buffer menu

;; Package time, let's start with necessities...
;; Ace-Window makes it very easy to jump between buffers
  :bind ("C-<tab>" . ace-window)
  :init (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)))

;; Aggressive-indent is self-explanatory, always indent everything
  (global-aggressive-indent-mode 1))

;; Avy allows a bunch of different jump commands
  :bind (("C-c j j" . avy-goto-char-2)
		 ("C-c j l" . avy-goto-line)))

;; bm enables visual bookmarks that you can jump to
  :bind (("C-c b b" . bm-toggle)
		 ("C-c b n" . bm-next)
		 ("C-c b p" . bm-previous)
		 ("C-c b l" . bm-show-all)
		 ("C-c b s" . bm-buffer-save))
  (setq-default bm-buffer-persistence t)
  (setq bm-highlight-style 'bm-highlight-only-fringe
		bm-restore-repository-on-load t
		bm-repository-file "~/.emacs.d/bm-repository"
		bm-cycle-all-buffers t))

;; Cape to extend emacs' completion-at-point capabilities
  (add-to-list 'completion-at-point-functions #'cape-file)
  (add-to-list 'completion-at-point-functions #'cape-dabbrev)
  (add-to-list 'completion-at-point-functions #'cape-keyword)
  (add-to-list 'completion-at-point-functions #'cape-history)
  (add-to-list 'completion-at-point-functions #'cape-dict))

;; Corfu as a light auto-complete platform
  (setq corfu-auto t
		corfu-quit-no-match 'separator
		tab-always-indent 'complete
		completion-cycle-threshold 5)

;; Deadgrep (requires ripgrep) is a fast file search tool
  :commands deadgrep
  :bind ("C-c s" . deadgrep))

;; eglot is a LSP program for Emacs-lisp-mode
(use-package eglot)

;; God Mode makes it easy to enter long command strings
  :bind (([escape] . god-mode-all)
		 :map god-local-mode-map
		 ("." . repeat))
  :init (setq god-mode-enable-function-key-translation nil)
  (add-hook 'god-mode-enabled-hook (lambda () (setq cursor-type 'hbar)))
  (add-hook 'god-mode-disabled-hook (lambda () (setq cursor-type 'bar))))

;; Magit for git integration because it's amazing
  :bind ("C-c g" . magit-status)
  :init (setq smerge-command-prefix "\C-cv"))

;; Multiple-cursors is self explanatory
  :bind (("C-c m" . mc/edit-lines)
		 ("C->" . mc/mark-next-like-this)
		 ("C-<" . mc/mark-previous-like-this)
		 ("C-c C->" . mc/mark-all-like-this)))

;; Neotree is a sidebar file window
  :bind ("C-c n" . neotree-toggle)
  (setq neo-window-fixed-size t
		neo-theme 'arrow))

;; Smartparens pairs all parentheses for you and highlights them
  :config (smartparens-global-mode t))

;; Vterm is a better Emacs terminal
  :bind (("C-c t" . vterm-other-window)
         :map vterm-mode-map
         ("C-q" . vterm-send-next-key)))

;; Vundo exposes a visual tree of all the available undo paths
  :commands vundo
  :bind ("C-c u" . vundo)
  :init (setq vundo-compact-display t))

;; Which-key pops up a buffer with command completions

;; Yasnippet lets you make little text snippets and insert them everywhere
  :init (setq yas-snippet-dirs '("~/.emacs.d/snippets/"))
  :config (yas-global-mode 1))

;; Zoom-mode automatically resizes windows to focus on the point
  (setq zoom-size '(0.618 . 0.618)
		zoom-ignored-major-modes '(dired-mode vundo-mode)
		zoom-ignored-buffer-name-regexps '("^*calc"))
  :config (zoom-mode 1))

;; Now, let's get some language support for writing code...
;; First, let's set up Rust support
  :mode ("\\.rs\\'")
  :hook (rust-mode . eglot-ensure)
  (setq rust-format-on-save t)
  (add-hook 'flycheck-mode-hook #'flycheck-rust-setup)

;; Setting up Python support
  :mode ("\\.py\\'" . python-mode)
  :hook (python-mode . eglot-ensure))

;; Set up ein for iPython notebooks
  :commands (ein:run ein:login)
  :init (setq ein:output-area-inlined-images t))

;; Set up Julia support
  :mode ("\\.jl\\'")
  :hook (julia-mode . eglot-ensure))

  :hook (julia-repl-mode . julia-mode))

  :config (eglot-jl-init))

;; Set up LaTeX mode
  :mode ("\\.tex\\'" . latex-mode)
  :hook (latex-mode . eglot-ensure)
  (setq TeX-auto-save t
		TeX-parse-self t
		TeX-save-query nil)
  (TeX-global-PDF-mode t)

;; Markup Language Modes
  :mode ("\\.csv\\'"))

  :mode ("\\.json\\'")
  :init (setq js-indent-level 2))

  :mode ("\\.yaml\\'"))

;; PDF/EPUB support
  :mode ("\\.epub\\'" . nov-mode))

  :mode ("\\.pdf\\'" . pdf-view-mode)
  :config (pdf-tools-install))

;; Finally, set up all the other applications I use Emacs for...
;; Org mode is a all-in-one life management system
  :mode ("\\.org\\'" . org-mode)
  :bind (("C-c l" . org-store-link)
		 ("C-c a" . org-agenda)
		 ("C-c c" . org-capture))
  (setq org-agenda-files '("~/org")
		org-default-notes-file "~/org/"
		org-refile-targets '((org-agenda-files :maxlevel . 2))
		org-support-shift-select t
		org-startup-indented t
		org-agenda-skip-deadline-prewarning-if-scheduled t
		org-agenda-skip-deadline-if-done t)
  (setq org-agenda-time-grid
		'((daily today require-timed remove-match)
		  (800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000)
		  "......" "----------------"))

  (setq org-babel-load-languages
        '((python . t)
          (emacs-lisp . t)
          (latex . t)))
  (setq org-capture-templates
		'(("t" "todo" entry (file+headline "~/org/" "Inbox")
		   "*** TODO %?\nSCHEDULED: %t")
		  ("l" "Linked todo" entry (file+headline "~/org/" "Inbox")
		   "*** TODO %?\nSCHEDULED: %t\n%a")
		  ("s" "Scheduled todo" entry (file+headline "~/org/" "Inbox")
		   "*** TODO %?\nSCHEDULED: %^t")
		  ("a" "Assignment" entry (file+headline "~/org/" "Inbox")
		   "*** TODO %?\nDEADLINE: %^t SCHEDULED: %^t")
		  ("c" "Calendar Event" entry (file+headline "~/org/" "Inbox")
		   "*** %?\n%^T")
		  ("g" "Weekly Goal" entry (file+headline "~/org/" "Weekly")
		   "*** Goal %(org-insert-time-stamp (org-read-date nil t \"+1w\"))\n - [ ] %?")
		  ("n" "Note" entry (file+olp+datetree "~/org/")
		   "* %? %^G\n%U")))
  (setq org-agenda-custom-commands
		'(("T" "Tasks" agenda ""
		   ((org-agenda-overriding-header "Tasks")
			(org-agenda-span 'week)
			(org-agenda-time-grid nil)
			(org-agenda-show-all-dates nil)
			 '(:deadline :scheduled))))
		  ("W" "Upcoming Week" agenda ""
		   ((org-agenda-overriding-header "Upcoming Week")
			(org-agenda-span 'week)
			(org-agenda-start-on-weekday nil)
		  ("M" "Upcoming Month" agenda ""
		   ((org-agenda-overriding-header "Upcoming Month")
			(org-agenda-span 'month)
			(org-agenda-show-all-dates nil)
		  ("L" "Look Around" agenda ""
		   ((org-agenda-overriding-header "Look Around")
			(org-agenda-span 5)
			(org-agenda-start-on-weekday nil)
			(org-agenda-start-day "-2d")

;; Ledger mode allows financial tracking in Emacs
  :mode ("\\.dat\\'"
  (setq ledger-clear-whole-transactions t
		ledger-complete-in-steps t)
  (setq ledger-reports
		'(("NetBudget" "%(binary) -f %(ledger-file) -p \"this year\" --budget bal expenses")
		  ("Expenses" "%(binary) -f %(ledger-file) -p \"this month\" bal Expenses")
		  ("ThisMonth" "%(binary) -f %(ledger-file) -p \"this month\" --monthly --budget bal expenses")
		  ("Balance" "%(binary) -f %(ledger-file) -V --price-db prices.db --cleared bal")
		  ("SOTU" "%(binary) -f %(ledger-file) -V --price-db prices.db --sort \"-abs(T)\" --cleared bal Assets Liabilities")
		  ("LastMonth" "%(binary) -f %(ledger-file) -p \"last month\" --monthly --budget bal expenses")
		  ("equity" "%(binary) -f %(ledger-file) equity")
		  ("bal" "%(binary) -f %(ledger-file) bal")
		  ("reg" "%(binary) -f %(ledger-file) reg")
		  ("payee" "%(binary) -f %(ledger-file) reg @%(payee)")
		  ("account" "%(binary) -f %(ledger-file) reg %(account)"))))

;; Notmuch is an email client for Emacs
(use-package notmuch
  :commands notmuch
  :bind ("C-c e" . notmuch)
  (setq user-full-name "Adithya Chari"
		user-mail-address ""
		mail-user-agent 'message-user-agent
		smtpmail-smtp-server ""
        smtpmail-stream-type 'ssl
        smtpmail-smtp-service 465
		smtpmail-debug-info t
		message-directory "~/mail/"
		message-auto-save-directory "~/mail/drafts"
		message-default-mail-headers "Cc: \nBcc: \n"
		message-send-mail-function 'message-smtpmail-send-it
		message-kill-buffer-on-exit t
		notmuch-show-logo nil)
  (define-key notmuch-show-mode-map "d"
			  (lambda () (interactive)
				(if (member "trash" (notmuch-show-get-tags))
					(notmuch-show-tag (list "-trash"))
				  (notmuch-show-tag (list "+trash")))))
  (define-key notmuch-search-mode-map "d"
			  (lambda (&optional beg end)
				"toggle deleted tag for message"
				(interactive (notmuch-interactive-region))
				(if (member "trash" (notmuch-search-get-tags))
					(notmuch-search-tag (list "-trash") beg end)
				  (notmuch-search-tag (list "+trash") beg end))))

  (setq notmuch-saved-searches
		'((:name "inbox" :query "tag:inbox" :key "i")
		  (:name "unread" :query "tag:unread" :key "u")
		  (:name "action" :query "tag:action" :key "a")
		  (:name "receipt" :query "tag:receipt" :key "r")
		  (:name "cal" :query "tag:cal" :key "c")
		  (:name "notifications" :query "tag:notifications" :key "n")
		  (:name "drafts" :query "tag:drafts" :key "d")
		  (:name "all mail" :query "*" :key "m"))))

;; Elfeed is a newsfeed/RSS reader
  :commands elfeed
  :bind ("C-c w" . elfeed)
  (setq-default elfeed-search-filter "@1-day-ago +unread -list #50 ")
  (define-key elfeed-search-mode-map "l" #'(lambda () (interactive) (elfeed-search-set-filter "+unread +list ")))
  (define-key elfeed-search-mode-map "k" #'(lambda () (interactive) (elfeed-search-set-filter nil)))
  (define-key elfeed-search-mode-map "m" #'(lambda () (interactive) (elfeed-search-tag-all 'list)))
  (define-key elfeed-search-mode-map "," #'(lambda () (interactive) (elfeed-search-untag-all 'list)))
  (define-key elfeed-search-mode-map (kbd "SPC") #'elfeed-search-untag-all-unread)
  (setq elfeed-feeds
        '(("" news NYT)
          ("" news NYT)
          ("" news NYT)
          ("" news NYT)
          ("" economy NYT)
          ("" tech NYT)
          ("" NYT)
          ("" NYT)
          ("" NYT ThomasFriedman)
          ("" NYT EzraKlein)
          ("" NYT PaulKrugman)
          ("" news WSJ)
          ("" economy WSJ)
          ("" economy WSJ)
          ("" tech WSJ)
          ("" opinion WSJ)
          ("" Reddit)
          ("" emacs Reddit)
          ("" news Reddit)
          ("" economy Reddit)
          ("" tech Reddit)
          ("" HN)
          ("" AstralCodexTen)
          ("" NotBoring)
          ("" economy MattLevine)
          ("" emacs SachaChua)
          ("" economy BradDelong)
          ("" ZeroHedge)
          ("" tech BeffJezos)
          ("" tech Chamath)
          ("" politics RobReich)
          ("" politics DanPfeiffer)
          ("" economics ChartBook)
          ("" history DanJones))))