Skip to content

Latest commit

 

History

History
executable file
·
1635 lines (1396 loc) · 52.1 KB

config.org

File metadata and controls

executable file
·
1635 lines (1396 loc) · 52.1 KB

Emacs Configuration

I have been using Emacs since winter of 2000 at the The Ohio State University and i have declared Emacs Bankruptcy many times. It has always been a learning experience. Mostly it works best when I stick with it.

Personal Information

(setq user-full-name "Shantanu Bhardwaj"
      user-mail-address "[email protected]")

Setup Packages

;; Add only the MELPA archive
(setq package-archives '(("melpa" . "https://melpa.org/packages/")
                         ("elpa" . "https://elpa.gnu.org/packages/")))

(package-initialize)

(require 'use-package)

(use-package exec-path-from-shell
  :ensure t
  :config
  (exec-path-from-shell-initialize))

;; Configure a package
(use-package org
  :ensure t
  :config
  (setq org-log-done 'time))

(use-package auto-package-update
  :defer t
  :custom
  (setq auto-package-update-interval 7
        auto-package-update-prompt-before-update t
        auto-package-update-hide-results nil))

(let* ((dir (expand-file-name (concat user-emacs-directory "local-packages")))
       (default-directory dir))
  (when (file-directory-p dir)
    (add-to-list 'load-path dir)
    (if (fboundp 'normal-top-level-add-subdirs-to-load-path)
        (normal-top-level-add-subdirs-to-load-path))))

Customize settings

Set up the customize file to its own separate file, instead of saving customize settings in init.el.

(setq max-lisp-eval-depth 10000)
(setq custom-file (expand-file-name "custom.el" user-emacs-directory))
(load custom-file)
(menu-bar-mode -1)
(display-battery-mode -1)        ;; Show battery.
(display-time-mode t)           ;; Show time.
(fset 'yes-or-no-p 'y-or-n-p)   ;; Set yes or no to y/n
(global-auto-revert-mode)       ;; Refresh a buffer if changed on disk
(global-hl-line-mode 1)         ;; Highlight current line
(blink-cursor-mode -1)          ;; Disable blingking cursor
(recentf-mode t)                ;; Turn on recent files mode

;; (pixel-scroll-precision-mode 1)
;; Enable pixel-based scrolling
;; (require 'pixel-scroll)
;; (pixel-scroll-mode 1)

;; Customize pixel-based scrolling
;; (setq pixel-scroll-precision-large-scroll-height 10)
;; (setq pixel-scroll-precision-interpolate-page t)
;; (setq pixel-scroll-precision-use-momentum t)

(setq ad-redefinition-action            'accept
      global-auto-revert-non-file-buffers t
      auto-revert-check-vc-info         t
      backup-by-copying                 t
      backup-directory-alist            '(("." . "~/.emacs.d/backups"))
      cursor-in-non-selected-windows    nil
      byte-compile-warnings             '(ck-functions)
      confirm-kill-processes            nil
      create-lockfiles                  nil
      echo-keystrokes                   0.2
      column-number-mode                t
      find-file-visit-truename          t
      font-lock-maximum-decoration      t
      highlight-nonselected-windows     t
      fast-but-imprecise-scrolling      t
      jit-lock-defer-time               nil
      kill-buffer-query-functions       nil    ;; Dont ask for closing spawned processes
      scroll-margin                     0   ;; scroll N to screen edge
      load-prefer-newer                 t
      use-dialog-box                    nil
      visible-bell                      nil
      word-wrap                         nil
      auto-mode-case-fold               nil
      truncate-lines                    t
      truncate-string-ellipsis          ".."
      undo-limit                        6710886400 ;; 64mb
      undo-strong-limit                 100663296 ;; x 1.5 (96mb)
      undo-outer-limit                  1006632960) ;; x 10 (960mb), (Emacs uses x100), but this seems too high.

Custom functions

(defun align-values (start end)
  "Vertically aligns region based on lengths of the first value of each line.
Example output:

        foo        bar
        foofoo     bar
        foofoofoo  bar"
  (interactive "r")
  (align-regexp start end
                "\\([a-z_]+: \\)"
                -1 1 nil))
;; (defun fontify-frame (frame)
;;   (interactive)
;;   (if sys/macp
;;       (progn
;;         (if (> (x-display-pixel-width) 4000)
;;             (set-frame-parameter frame 'font "Monaco 14") ;; 5k Display
;;           (set-frame-parameter frame 'font "Monaco 12")))))

;; ;; Fontify current frame
;; (fontify-frame nil)

;; ;; Fontify any future frames
;; (push 'fontify-frame after-make-frame-functions)

UI + Theme

Icons

(use-package spacious-padding
  :ensure t
  :config
  ;; (setq spacious-padding-widths
  ;;       '( :internal-border-width 15
  ;;          :header-line-width 4
  ;;          :mode-line-width 6
  ;;          :tab-width 4
  ;;          :right-divider-width 30
  ;;          :scroll-bar-width 8))
  (spacious-padding-mode 1)
  )

;; Install and configure modus-themes
(use-package ef-themes
  :ensure t
  :config
  (load-theme 'ef-spring t)
  )

(use-package auto-dark
  :ensure t
  :custom
  (auto-dark-themes '((ef-dream) (ef-spring)))
  (auto-dark-polling-interval-seconds 300)
  (auto-dark-allow-osascript t)
  (auto-dark-allow-powershell nil)
  ;; (auto-dark-detection-method nil) ;; dangerous to be set manually
  :hook
  (auto-dark-dark-mode
   . (lambda ()
       ;; something to execute when dark mode is detected
       ))
  (auto-dark-light-mode
   . (lambda ()
       ;; something to execute when light mode is detected
       ))
  :init (auto-dark-mode))

(use-package nerd-icons
  :ensure t)

(use-package nerd-icons-completion
  :ensure t
  :after marginalia
  ;; FIXME 2024-09-01: For some reason this stopped working because it
  ;; macroexpands to `marginalia-mode' instead of
  ;; `marginalia-mode-hook'.  What is more puzzling is that this does
  ;; not happen in the next :hook...
  ;; :hook (marginalia-mode . nerd-icons-completion-marginalia-setup))
  :config
  (add-hook 'marginalia-mode-hook #'nerd-icons-completion-marginalia-setup))

(use-package nerd-icons-dired
  :hook (dired-mode . nerd-icons-dired-mode))

(use-package nerd-icons-corfu
  :ensure t
  :after corfu
  :config
  (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter)
  ;; Optionally:
  (setq nerd-icons-corfu-mapping
        '((array :style "cod" :icon "symbol_array" :face font-lock-type-face)
          (boolean :style "cod" :icon "symbol_boolean" :face font-lock-builtin-face)
          ;; ...
          (t :style "cod" :icon "code" :face font-lock-warning-face)))
  ;; Remember to add an entry for `t', the library uses that as default.
  )

Convenient theme functions

  ;;  (load-theme 'gruvbox-dark-hard t)

  (defun reset-modeline()
    "Reset the modeline to 12pt font"
    (interactive)
    (set-face-attribute 'mode-line nil :height 100)
    (set-face-attribute 'mode-line-inactive nil :height 100)
    (setq doom-modeline-height 12)
    (set-face-attribute 'line-number nil :font "Monaco-10")
    (set-face-attribute 'line-number-current-line nil :font "Monaco-10")
    )

  (defun switch-theme (theme)
    "Disables any currently active themes and loads THEME."
    ;; This interactive call is taken from `load-theme'
    (interactive
     (list
      (intern (completing-read "Load custom theme: "
                               (mapc 'symbol-name
                                     (custom-available-themes))))))
    (let ((enabled-themes custom-enabled-themes))
      (mapc #'disable-theme custom-enabled-themes)
      (load-theme theme t)
      (reset-modeline)
      ))

(defun disable-active-themes ()
  "Disables any currently active themes listed in `custom-enabled-themes'."
  (interactive)
  (mapc #'disable-theme custom-enabled-themes))

(bind-key "s-<f12>" 'consult-theme)
(bind-key "s-<f11>" 'disable-active-themes)

Modeline

(use-package doom-modeline
  :hook (after-init . doom-modeline-mode)
  :custom    
  (doom-modeline-height 20)
  (doom-modeline-bar-width 1)
  (doom-modeline-icon t)
  (doom-modeline-major-mode-icon t)
  (doom-modeline-major-mode-color-icon t)
  (doom-modeline-time-analogue-clock nil)
  (doom-modeline-buffer-file-name-style 'truncate-upto-project)
  (doom-modeline-buffer-state-icon t)
  (doom-modeline-buffer-modification-icon t)
  (doom-modeline-minor-modes nil)
  (doom-modeline-enable-word-count nil)
  (doom-modeline-buffer-encoding t)
  (doom-modeline-indent-info nil)
  (doom-modeline-checker-simple-format t)
  (doom-modeline-vcs-max-length 12)
  (doom-modeline-env-version t)
  (doom-modeline-irc-stylize 'identity)
  (setq doom-modeline-github t)
  (setq doom-modeline-battery-icon nil)
  (setq doom-modeline-mu4e t)
  (doom-modeline-github-timer nil)
  (doom-modeline-gnus-timer nil))

Font

;; (set-face-attribute 'default nil :font "Iosevka Comfy" :height 140 :weight 'regular) 
(set-face-attribute 'default nil :font "CaskaydiaMono Nerd Font" :height 140 :weight 'regular) 

Note: To view all fonts that are available to use, run the following:

(font-family-list)

Custom Mode faces

Echo Area

(with-current-buffer " *Echo Area 0*" (face-remap-add-relative 'default '(:family "Monaco" :height 110)))

Term Faces

;; Use monospaced font faces in current buffer
(defun my-term-mode-face ()
  "Sets a fixed width (monospace) font in current buffer"
  (interactive)
  (setq buffer-face-mode-face '(:family "Monaco" :height 100))
  (buffer-face-mode))

Sane defaults

(setq-default display-line-numbers-width    3       ;; Set so we can display thousands of lines
              c-basic-offset                2            ;; Set tab indent for c/c++ to 4 tabs
              ediff-forward-word-function   'forward-char
              ediff-split-window-function   'split-window-horizontally
              tab-width                     2            ;: Use four tabs
              indent-tabs-mode              nil			 ;; Never use tabs. Use spaces instead
              truncate-lines                t
              indent-line-function          'insert-tab  ;; Use function to insert tabs
              history-length                100
              uniquify-buffer-name-style    'forward)

;; These functions are useful. Activate them.
(put 'downcase-region 'disabled nil)
(put 'upcase-region 'disabled nil)
(put 'narrow-to-region 'disabled nil)
(put 'dired-find-alternate-file 'disabled nil)

;; UTF-8 please
(setq locale-coding-system 'utf-8) ; pretty
(set-terminal-coding-system 'utf-8) ; pretty
(set-keyboard-coding-system 'utf-8) ; pretty
(set-selection-coding-system 'utf-8) ; please
(prefer-coding-system 'utf-8) ; with sugar on top
(setq-default indent-tabs-mode nil)

(setq-default indent-tabs-mode nil)
(setq-default indicate-empty-lines t)

;; Don't count two spaces after a period as the end of a sentence.
;; Just one space is needed.
(setq sentence-end-double-space nil)

;; delete the region when typing, just like as we expect nowadays.
(delete-selection-mode t)
(show-paren-mode t)
(column-number-mode t)

;; (global-visual-line-mode -1)
(remove-hook 'text-mode-hook #'turn-on-auto-fill)
(add-hook 'text-mode-hook 'turn-on-visual-line-mode)
(diminish 'visual-line-mode)

(setq uniquify-buffer-name-style 'forward)

;; -i gets alias definitions from .bash_profile
(setq shell-command-switch "-ic")

(global-unset-key (kbd "M-m"))
(global-set-key (kbd "C-+") 'text-scale-increase)
(global-set-key (kbd "C--") 'text-scale-decrease)
;; Bind C-c i to open init.el
(global-set-key (kbd "C-c e") (lambda () (interactive) (find-file "~/.emacs.d/init.el")))


(windmove-default-keybindings 'super)
(setq native-comp-async-report-warnings-errors 'silent)

Mac customizations

There are configurations to make when running Emacs on macOS (hence the “darwin” system-type check).

(when (string-equal system-type "darwin")

(setq mac-option-key-is-meta nil
      mac-command-key-is-meta t
      mac-command-modifier 'meta
      mac-option-modifier 'super
      mac-function-modifier 'hyper
      dired-use-ls-dired nil)

;; Fullscreen!
(setq ns-use-native-fullscreen nil) ; Not Lion style
(bind-key "<s-return>" 'toggle-frame-fullscreen)

;; buffer switching
(bind-key "s-[" 'previous-buffer)
(bind-key "s-]" 'next-buffer)

(bind-key "M-C-w" 'restart-emacs)


  ;; delete files by moving them to the trash
  (setq delete-by-moving-to-trash t)
  (setq trash-directory "~/.Trash")
  (setq ns-pop-up-frames nil)

  ;; Compiling
  (bind-key "H-c" 'compile)
  (bind-key "H-r" 'recompile)
  (bind-key "H-s" (defun save-and-recompile () (interactive) (save-buffer) (recompile))))

MELPA / ELPA

DAbbrev

(use-package dabbrev
  :ensure nil
  :custom
  (dabbrev-ignored-buffer-regexps '("\\.\\(?:pdf\\|jpe?g\\|png\\)\\'")))

Expand Region

(use-package expand-region
  :bind ("C-=" . er/expand-region))

Indent

(use-package indent-bars
  :ensure nil
  :config
  (setq
   indent-bars-color '(highlight :face-bg t :blend 0.3)
   indent-bars-pattern " . . . . ." ; play with the number of dots for your usual font size
   indent-bars-width-frac 0.25
   indent-bars-pad-frac 0.1)
  :custom
  (indent-bars-treesit-support t)
  (indent-bars-no-descend-string t)
  (indent-bars-treesit-ignore-blank-lines-types '("module"))
  (indent-bars-treesit-wrap '((python argument_list parameters ; for python, as an example
				                              list list_comprehension
				                              dictionary dictionary_comprehension
				                              parenthesized_expression subscript)))
  :hook (prog-mode . indent-bars-mode))

SVG Tags

;; (use-package svg-tag-mode
;;   :hook (prog-mode . svg-tag-mode)
;;   :config
;;   (plist-put svg-lib-style-default :font-family "Monaco Nerd Font Mono")
;;   (plist-put svg-lib-style-default :font-size 14)
;;   ;; (require 'periphery)
;;   ;; (setq svg-tag-tags (periphery-svg-tags))
;;   )

Misc

(use-package toml)
(use-package gcmh
  :diminish
  :hook (after-init . gcmh-mode))
(use-package diminish
  :ensure t)

Helpful

(use-package helpful
  :ensure t
  :commands (helpful-callable helpful-variable helpful-command helpful-key)
  :bind (("C-h f" . helpful-callable)
         ("C-h v" . helpful-variable)
         ("C-h k" . helpful-key)
         ("C-h x" . helpful-command)
         ("C-c C-d" . helpful-at-point)
         ("C-c F" . helpful-function)))

HL Todo

(use-package hl-todo
  :ensure t
  :defer t
  :custom-face (hl-todo ((t (:box t :inherit))))
  :bind (:map hl-todo-mode-map
              ([C-f3] . hl-todo-occur)
              ("C-c t p" . hl-todo-previous)
              ("C-c t n" . hl-todo-next)
              ("C-c t o" . hl-todo-occur))
  :hook (after-init . global-hl-todo-mode))

No Littering

(use-package no-littering
  :ensure t
  :config
  (setq custom-file (expand-file-name "custom.el" user-emacs-directory))
  (require 'recentf)
  (add-to-list 'recentf-exclude
               (recentf-expand-file-name no-littering-var-directory))
  (add-to-list 'recentf-exclude
               (recentf-expand-file-name no-littering-etc-directory))
  ) 

Multiple cursors

We’ll also need to (require 'multiple-cusors) because of an autoload issue.

(use-package multiple-cursors
  :ensure t
  :defer t
  :bind (("C-S-c C-S-c" . mc/edit-lines)
         ("C->"         . mc/mark-next-like-this)
         ("C-<"         . mc/mark-previous-like-this)
         ("C-c C-<"     . mc/mark-all-like-this)
         ("C-!"         . mc/mark-next-symbol-like-this)
         ("s-d"         . mc/mark-all-dwim)))

Rainbow mode + delimiters

(use-package rainbow-delimiters
  :ensure t
  :diminish
  :hook (prog-mode . rainbow-delimiters-mode))

(use-package rainbow-mode
  :ensure t
  :diminish
  :hook (prog-mode . rainbow-mode)
  :config
  (setq rainbow-x-colors nil))

Savehist

;; Further reading: https://protesilaos.com/emacs/dotemacs#h:25765797-27a5-431e-8aa4-cc890a6a913a
;;;; `savehist' (minibuffer and related histories)
(use-package savehist
  :ensure nil
  :hook (after-init . savehist-mode)
  :config
  (setq savehist-file (locate-user-emacs-file "savehist"))
  (setq history-length 100)
  (setq history-delete-duplicates t)
  (setq savehist-save-minibuffer-history t)
  (add-to-list 'savehist-additional-variables 'kill-ring))

Smoothscrolling

This makes it so C-n-ing and C-p-ing won’t make the buffer jump around so much.

(use-package smooth-scrolling
  :ensure t)

Scratch

Convenient package to create *scratch* buffers that are based on the current buffer’s major mode. This is more convienent than manually creating a buffer to do some scratch work or reusing the initial *scratch* buffer.

(use-package scratch
  :ensure t
  :commands scratch)

(use-package persistent-scratch
  :ensure t
  :init
  (persistent-scratch-setup-default))

Smartparens

(use-package smartparens
  :ensure t
  :defer t
  :diminish smartparens-mode
  :hook (prog-mode . smartparens-mode))

Super Save

(use-package super-save
  :ensure t
  :defer t
  :config
  ;; (super-save-mode +1)
  )

Undo Redo

(use-package undo-fu
  :ensure t
  :config
  (setq undo-fu-allow-undo-in-region t)
  (global-unset-key (kbd "M-z"))
  (global-set-key (kbd "M-z")   'undo-fu-only-undo)
  (global-set-key (kbd "M-S-z") 'undo-fu-only-redo))

(global-unset-key (kbd "C-z"))

(use-package vundo
  :ensure t
  :bind ("C-M-z" . vundo))

;; (set-face-attribute 'mode-line nil
;;                     :background "LightSteelBlue1"
;;                     :foreground "black"
;;                     :box "SkyBlue2")

  ;; (use-package undo-tree
  ;;   :ensure t
  ;;   :defer t
  ;;   :diminish
  ;;   :init
  ;;   (global-undo-tree-mode))

Which Key

(use-package which-key
  :ensure t
  :defer t
  :diminish which-key-mode
  :hook (after-init . which-key-mode))

Wgrep

;; The `wgrep' packages lets us edit the results of a grep search
;; while inside a `grep-mode' buffer.  All we need is to toggle the
;; editable mode, make the changes, and then type C-c C-c to confirm
;; or C-c C-k to abort.
;;
;; Further reading: https://protesilaos.com/emacs/dotemacs#h:9a3581df-ab18-4266-815e-2edd7f7e4852
(use-package wgrep
  :ensure t
  :bind ( :map grep-mode-map
          ("e" . wgrep-change-to-wgrep-mode)
          ("C-x C-q" . wgrep-change-to-wgrep-mode)
          ("C-c C-c" . wgrep-finish-edit)))

Org mode

Installation

(use-package org
  :config
  (require 'org-tempo)
  )

(use-package org-auto-tangle
  :defer t
  :hook (org-mode . org-auto-tangle-mode)
    :config
    (setq org-auto-tangle-babel-safelist '(
                                           "~/.emacs.d/config.org"
                                           )))

Org activation bindings

Set up some global key bindings that integrate with Org Mode features.

(bind-key "C-c l" 'org-store-link)
(bind-key "C-c c" 'org-capture)
(bind-key "C-c a" 'org-agenda)

Org agenda

Learned about this delq and mapcar trick from Sacha Chua’s config.

(setq org-agenda-files
      (delq nil
            (mapcar (lambda (x) (and (file-exists-p x) x))
                    '("~/Documents/Agenda"))))

Org capture

(bind-key "C-c c" 'org-capture)
(setq org-default-notes-file "~/Documents/Notes/notes.org")

Org setup

Speed commands are a nice and quick way to perform certain actions while at the beginning of a heading. It’s not activated by default.

See the doc for speed keys by checking out the documentation for speed keys in Org mode.

(setq org-use-speed-commands t)
(setq org-image-actual-width 550)
(setq org-highlight-latex-and-related '(latex script entities))

(setq org-startup-indented 'f)
(setq org-directory "~/Documents/Apps/Org")
(setq org-special-ctrl-a/e 't)
(setq org-default-notes-file (concat org-directory "/Notes.org"))
(define-key global-map "\C-cc" 'org-capture)
(setq org-mobile-directory "~/Documents/Apps/MobileOrg")
(setq org-src-fontify-natively 't)
(setq org-src-tab-acts-natively t)
(setq org-src-window-setup 'current-window)

(setq org-agenda-files (quote ("~/Documents/Apps/Org/Inbox.org"
                               ;;                                "~/Documents/Apps/Org/Addval.org"
                               ;;                                "~/Documents/Apps/Org/Brandbin.org"
                               ;;                                "~/Documents/Apps/Org/Kulcare.org"
                               )))

Org tags

The default value is -77, which is weird for smaller width windows. I’d rather have the tags align horizontally with the header. 45 is a good column number to do that.

(setq org-tags-column 45)

Org babel languages

(org-babel-do-load-languages
 'org-babel-load-languages
 '((python . t)
   (C . t)
   (calc . t)
   (latex . t)
   (java . t)
   (ruby . t)
   (lisp . t)
   (scheme . t)
   (shell . t)
   (sqlite . t)
   (js . t)))

(defun my-org-confirm-babel-evaluate (lang body)
  "Do not confirm evaluation for these languages."
  (not (or (string= lang "C")
           (string= lang "java")
           (string= lang "python")
           (string= lang "emacs-lisp")
           (string= lang "sqlite"))))
(setq org-confirm-babel-evaluate 'my-org-confirm-babel-evaluate)

Org babel/source blocks

I like to have source blocks properly syntax highlighted and with the editing popup window staying within the same window so all the windows don’t jump around. Also, having the top and bottom trailing lines in the block is a waste of space, so we can remove them.

I noticed that fontification doesn’t work with markdown mode when the block is indented after editing it in the org src buffer—the leading #s for headers don’t get fontified properly because they appear as Org comments. Setting org-src-preserve-indentation makes things consistent as it doesn’t pad source blocks with leading spaces.

(setq org-src-fontify-natively t
      org-src-window-setup 'current-window
      org-src-strip-leading-and-trailing-blank-lines t
      org-src-preserve-indentation t
      org-src-tab-acts-natively t)

Org templates

Source block templates

(add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp" ))
(add-to-list 'org-structure-template-alist '("rb" . "src ruby" ))
(add-to-list 'org-structure-template-alist '("sh" . "src sh" ))
(add-to-list 'org-structure-template-alist '("md" . "src markdown"))

Completions

Consult

;; The `consult' package provides lots of commands that are enhanced
;; variants of basic, built-in functionality.  One of the headline
;; features of `consult' is its preview facility, where it shows in
;; another Emacs window the context of what is currently matched in
;; the minibuffer.  Here I define key bindings for some commands you
;; may find useful.  The mnemonic for their prefix is "alternative
;; search" (as opposed to the basic C-s or C-r keys).
;;
;; Further reading: https://protesilaos.com/emacs/dotemacs#h:22e97b4c-d88d-4deb-9ab3-f80631f9ff1d
(use-package consult
  :ensure t
  :bind (;; A recursive grep
         ("M-s M-g" . consult-grep)
         ;; Search for files names recursively
         ("M-s M-f" . consult-find)
         ;; Search through the outline (headings) of the file
         ("M-s M-o" . consult-outline)
         ;; Search the current buffer
         ("M-s M-l" . consult-line)
         ;; Switch to another buffer, or bookmarked file, or recently
         ;; opened file.
         ("M-s M-b" . consult-buffer)))

(use-package consult-project-extra
  :defer t
  :bind
  (("C-c p f" . consult-project-extra-find)
   ("C-c p o" . consult-project-extra-find-other-window)))

(use-package consult-todo
  :demand t)

Embark

;; The `embark' package lets you target the thing or context at point
;; and select an action to perform on it.  Use the `embark-act'
;; command while over something to find relevant commands.
;;
;; When inside the minibuffer, `embark' can collect/export the
;; contents to a fully fledged Emacs buffer.  The `embark-collect'
;; command retains the original behaviour of the minibuffer, meaning
;; that if you navigate over the candidate at hit RET, it will do what
;; the minibuffer would have done.  In contrast, the `embark-export'
;; command reads the metadata to figure out what category this is and
;; places them in a buffer whose major mode is specialised for that
;; type of content.  For example, when we are completing against
;; files, the export will take us to a `dired-mode' buffer; when we
;; preview the results of a grep, the export will put us in a
;; `grep-mode' buffer.
;;
;; Further reading: https://protesilaos.com/emacs/dotemacs#h:61863da4-8739-42ae-a30f-6e9d686e1995
(use-package embark
  :ensure t
  :bind (("C-." . embark-act)
         :map minibuffer-local-map
         ("C-c C-c" . embark-collect)
         ("C-c C-e" . embark-export)))

;; The `embark-consult' package is glue code to tie together `embark'
;; and `consult'.
(use-package embark-consult
  :ensure t)

Vertico

(use-package vertico
:ensure t
:bind (("C-x M-r" . vertico-repeat)
:map vertico-map
;; M- keys for changing view:
("M-v"     . vertico-multiform-vertical)
("M-g"     . vertico-multiform-grid)
("M-f"     . vertico-multiform-flat)
("M-r"     . vertico-multiform-reverse)
("M-u"     . vertico-multiform-unobtrusive))
:init (vertico-mode 1)
:config (progn
(add-hook 'minibuffer-setup-hook #'vertico-repeat-save)
(vertico-mouse-mode 1)
(vertico-multiform-mode 1)
(setq vertico-count 20)
(setq vertico-cycle t)
(setq vertico-resize nil)))

;; Configure directory extension.
(use-package vertico-directory
  :after vertico
  :ensure nil
  ;; More convenient directory navigation commands
  :bind (:map vertico-map
              ("RET" . vertico-directory-enter)
              ("DEL" . vertico-directory-delete-char)
              ("M-DEL" . vertico-directory-delete-word))
  ;; Tidy shadowed file names
  :hook (rfn-eshadow-update-overlay . vertico-directory-tidy))

Marginalia

;; The `marginalia' package provides helpful annotations next to
;; completion candidates in the minibuffer.  The information on
;; display depends on the type of content.  If it is about files, it
;; shows file permissions and the last modified date.  If it is a
;; buffer, it shows the buffer's size, major mode, and the like.
;;
;; Further reading: https://protesilaos.com/emacs/dotemacs#h:bd3f7a1d-a53d-4d3e-860e-25c5b35d8e7e
(use-package marginalia
  :ensure t
  :config
  (marginalia-mode 1))

Orderless

;; https://github.com/oantolin/orderless
(use-package orderless
:ensure t
:after vertico
:config (progn
(setq orderless-matching-styles '(orderless-regexp
orderless-initialism
orderless-prefixes)
orderless-component-separator #'orderless-escapable-split-on-space)

;; Use the built-in "partial-completion" style to complete
;; file inputs such as "/e/ni/co.nix" into
;; "/etc/nixos/configuration.nix".  The "basic" style is
;; needed to support the hostname completion in the TRAMP
;; inputs such as "/sshx:HOSTNAME".
(setq completion-category-defaults nil
completion-category-overrides '((file (styles basic partial-completion))))
(setq completion-styles '(orderless basic))))

Cape

;; Add extensions
(use-package cape
  :defer t
  :bind (("C-c p p" . completion-at-point) ;; capf
         ("C-c p d" . cape-dabbrev)        ;; or dabbrev-completion
         ("C-c p h" . cape-history)
         ("C-c p f" . cape-file)
         ("C-c p k" . cape-keyword)
         ("C-c p a" . cape-abbrev)
         ("C-c p i" . cape-ispell)
         ("C-c p l" . cape-line)
         ("C-c p w" . cape-dict)
         ("C-c p r" . cape-rfc1345))
  :custom
  (setq cape-dabbrev-check-other-buffers t
        cape-dabbrev-min-length 4)
  :init
  (add-to-list 'completion-at-point-functions #'cape-dabbrev)
  (add-to-list 'completion-at-point-functions #'cape-file)
  (add-to-list 'completion-at-point-functions #'cape-keyword))

Corfu

;;; Corfu (in-buffer completion popup)
(use-package corfu
  :ensure t
  :hook (after-init . global-corfu-mode)
  ;; I also have (setq tab-always-indent 'complete) for TAB to complete
  ;; when it does not need to perform an indentation change.
  :bind (:map corfu-map ("<tab>" . corfu-complete))
  :config
  (setq corfu-preview-current nil)
  (setq corfu-min-width 20)

  (setq corfu-popupinfo-delay '(1.25 . 0.5))
  (corfu-popupinfo-mode 1) ; shows documentation after `corfu-popupinfo-delay'

  ;; Sort by input history (no need to modify `corfu-sort-function').
  (with-eval-after-load 'savehist
    (corfu-history-mode 1)
    (add-to-list 'savehist-additional-variables 'corfu-history)))

Coding

Aphelia: prettify buffer

(use-package apheleia
  :ensure t
  :diminish ""
  :defines
  apheleia-formatters
  apheleia-mode-alist
  :functions
  apheleia-global-mode
  :config
  (setf (alist-get 'prettier-json apheleia-formatters)
        '("prettier" "--stdin-filepath" filepath))
  (apheleia-global-mode +1))

General

;; Enable display-line-numbers-mode for prog-mode
(add-hook 'prog-mode-hook 'display-line-numbers-mode)

;; Enable flymake-mode for prog-mode
(add-hook 'prog-mode-hook 'flymake-mode)

;; Customize line number display
(setq display-line-numbers-type 'relative) ; Use relative line numbers

;; Customize flymake-mode
(setq flymake-no-changes-timeout 0.5) ; Set the timeout for flymake to 0.5 seconds

Git / Magit

(use-package magit
  :ensure t
  :commands (magit-status magit-ediff-show-working-tree)
  :bind ("C-c C-d" . magit-ediff-show-working-tree)
  :custom
  (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1))

(use-package magit-todos
  :ensure t
  :commands (magit-todos-mode)
  :hook (magit-mode . magit-todos-mode)
  :config
  (setq magit-todos-recursive t
        magit-todos-depth 10
        magit-todos-exclude-globs '("*Pods*" ".git/" "*elpa*" "*var/lsp/*"))
  (custom-set-variables
   '(magit-todos-keywords (list "TODO" "FIXME" "HACK"))))

(use-package blamer
  :ensure t
  :commands (blamer-mode)
  :config
  (setq blamer-view 'overlay-right
        blamer-type 'visual
        blamer-max-commit-message-length 70
        blamer-force-truncate-long-line nil
        blamer-author-formatter " ✎ %s "
        blamer-commit-formatter "\'%s\'")
  :custom
  (blamer-idle-time 1.0)
  :custom-face
  (blamer-face ((t :foreground "#E46876"
                   :height 130
                   :bold t
                   :italic t))))

(use-package forge
  :ensure t
  :after magit
  :defer t)

(use-package orgit-forge
  :ensure t
  :after forge)

(use-package git-timemachine
  :ensure t
  :defer t
  )

(use-package git-link
  :ensure t
  :defer t)

(use-package git-gutter
  :ensure t
  :defer t
  :hook (prog-mode . git-gutter-mode)
  :diminish git-gutter-mode
  :config
  (setq git-gutter:update-interval 1))

(use-package git-gutter-fringe
  :after git-gutter
  :config
  (setq git-gutter-fr:side 'left-fringe)
  (define-fringe-bitmap 'git-gutter-fr:added [224] nil nil '(center repeated))
  (define-fringe-bitmap 'git-gutter-fr:modified [224] nil nil '(center repeated))
  (define-fringe-bitmap 'git-gutter-fr:deleted [224] nil nil '(center repeated)))

Mise

(use-package mise
  :ensure t
  :config
  (add-hook 'after-init-hook #'global-mise-mode)) 

Treemacs

(use-package treemacs
  :ensure t
  :commands (treemacs treemacs-select-window)
  :hook (treemacs-mode . treemacs-project-follow-mode)
  :bind ("M-J" . treemacs-find-file)
  :custom-face
  (doom-themes-treemacs-file-face ((t (:weight semi-bold))))
  (treemacs-file-face ((t (:family "Monaco Nerd Font Mono"))))
  (treemacs-root-face ((t (:family "Monaco Nerd Font Mono" :height 0.9))))
  (treemacs-directory-face ((t (:family "Monaco Nerd Font Mono" :height 0.9))))
  (treemacs-directory-collapsed-face ((t (:family "Monaco Nerd Font Mono" :height 0.9))))
  (treemacs-git-ignored-face ((t (:family "Monaco Nerd Font Mono" :height 0.9))))
  (treemacs-git-unmodified-face ((t (:family "Monaco Nerd Font Mono" :height 0.9))))
  (treemacs-git-untracked-face ((t (:family "Monaco Nerd Font Mono" :height 0.9))))
  (treemacs-git-added-face ((t (:family "Monaco Nerd Font Mono" :height 0.9))))
  (treemacs-git-renamed-face ((t (:family "Monaco Nerd Font Mono" :height 0.9))))
  (treemacs-git-modified-face ((t (:family "Monaco Nerd Font Mono" :height 0.9))))
  (treemacs-tags-face ((t (:family "Monaco Nerd Font Mono" :height 0.9))))
  :config
  (setq doom-themes-treemacs-theme nil
        treemacs-window-background-color '("#221F22" . "#423f42"))
  (setq treemacs-follow-after-init t
        treemacs-collapse-dirs 1
        treemacs-directory-name-transformer #'identity
        treemacs-file-name-transformer #'identity
        treemacs-show-cursor nil
        treemacs-display-current-project-exclusively t
        treemacs-filewatch-mode t
        treemacs-follow-mode nil
        treemacs-hide-dot-git-directory t
        treemacs-git-integration t
        treemacs-space-between-root-nodes t
        treemacs-hide-gitignored-files-mode t
        treemacs-git-mode 'extended
        treemacs-indentation 1
        treemacs-is-never-other-window t
        treemacs-silent-refresh	t
        treemacs-sorting 'treemacs--sort-alphabetic-case-insensitive-asc
        treemacs-width 30))

(use-package treemacs-magit
  :after treemacs magit)

(use-package project-treemacs
  :demand t
  :after treemacs
  )

(use-package treemacs-nerd-icons
  :after treemacs
  :config
  (treemacs-load-theme "nerd-icons"))

Toggle term

(use-package toggle-term
  :bind (("M-o f" . toggle-term-find)
         ("M-o t" . toggle-term-term)
         ("M-o v" . toggle-term-vterm)
         ("M-o a" . toggle-term-eat)
         ("M-o s" . toggle-term-shell)
         ("M-o e" . toggle-term-eshell)
         ("M-o i" . toggle-term-ielm)
         ("M-o o" . toggle-term-toggle))
  :config
  (setq toggle-term-size 25)
  (setq toggle-term-switch-upon-toggle t))

Treesitter

(use-package treesit
  :mode (("\\.tsx\\'" . tsx-ts-mode)
         ("\\.js\\'"  . js-ts-mode)
         ("\\.mjs\\'" . js-ts-mode)
         ("\\.mts\\'" . js-ts-mode)
         ("\\.cjs\\'" . js-ts-mode)
         ("\\.ts\\'"  . js-ts-mode)
         ("\\.jsx\\'" . tsx-ts-mode)
         ("\\.json\\'" .  json-ts-mode)
         ("\\.Dockerfile\\'" . dockerfile-ts-mode)
         ("\\.prisma\\'" . prisma-ts-mode)
         ;; More modes defined here...
         )
  :preface
  (defun os/setup-install-grammars ()
    "Install Tree-sitter grammars if they are absent."
    (interactive)
    (dolist (grammar
             '((css . ("https://github.com/tree-sitter/tree-sitter-css" "v0.20.0"))
               (bash "https://github.com/tree-sitter/tree-sitter-bash")
               (html . ("https://github.com/tree-sitter/tree-sitter-html" "v0.20.1"))
               (javascript . ("https://github.com/tree-sitter/tree-sitter-javascript" "v0.21.2" "src"))
               (json . ("https://github.com/tree-sitter/tree-sitter-json" "v0.20.2"))
               (python . ("https://github.com/tree-sitter/tree-sitter-python" "v0.20.4"))
               (go "https://github.com/tree-sitter/tree-sitter-go" "v0.20.0")
               (markdown "https://github.com/ikatyang/tree-sitter-markdown")
               (make "https://github.com/alemuller/tree-sitter-make")
               (elisp "https://github.com/Wilfred/tree-sitter-elisp")
               (cmake "https://github.com/uyha/tree-sitter-cmake")
               (c "https://github.com/tree-sitter/tree-sitter-c")
               (cpp "https://github.com/tree-sitter/tree-sitter-cpp")
               (ruby "https://github.com/tree-sitter/tree-sitter-ruby")
               (toml "https://github.com/tree-sitter/tree-sitter-toml")
               (tsx . ("https://github.com/tree-sitter/tree-sitter-typescript" "v0.20.3" "tsx/src"))
               (typescript . ("https://github.com/tree-sitter/tree-sitter-typescript" "v0.20.3" "typescript/src"))
               (yaml . ("https://github.com/ikatyang/tree-sitter-yaml" "v0.5.0"))
               (prisma "https://github.com/victorhqc/tree-sitter-prisma")))
      (add-to-list 'treesit-language-source-alist grammar)
      ;; Only install `grammar' if we don't already have it
      ;; installed. However, if you want to *update* a grammar then
      ;; this obviously prevents that from happening.
      (unless (treesit-language-available-p (car grammar))
        (treesit-install-language-grammar (car grammar)))))

  ;; Optional, but recommended. Tree-sitter enabled major modes are
  ;; distinct from their ordinary counterparts.
  ;;
  ;; You can remap major modes with `major-mode-remap-alist'. Note
  ;; that this does *not* extend to hooks! Make sure you migrate them
  ;; also
  (dolist (mapping
           '((python-mode . python-ts-mode)
             (css-mode . css-ts-mode)
             (typescript-mode . js-ts-mode)
             (js-mode . js-ts-mode)
             (js2-mode . js-ts-mode)
             (c-mode . c-ts-mode)
             (c++-mode . c++-ts-mode)
             (c-or-c++-mode . c-or-c++-ts-mode)
             (bash-mode . bash-ts-mode)
             (css-mode . css-ts-mode)
             (json-mode . json-ts-mode)
             (js-json-mode . json-ts-mode)
             (ruby-mode . ruby-ts-mode)
             (sh-mode . bash-ts-mode)
             (sh-base-mode . bash-ts-mode)))
    (add-to-list 'major-mode-remap-alist mapping))
  :config
  (os/setup-install-grammars))

LSP Mode

(use-package lsp-mode
  :diminish "LSP"
  :ensure t
  :hook ((lsp-mode . lsp-diagnostics-mode)
         (lsp-mode . lsp-enable-which-key-integration)
         ((tsx-ts-mode
           js-ts-mode
           js-ts-mode
           js-mode) . lsp-deferred))
  :custom
  (lsp-keymap-prefix "C-c l")           ; Prefix for LSP actions
  (lsp-completion-provider :none)       ; Using Corfu as the provider
  (lsp-diagnostics-provider :flymake)
  (lsp-session-file (locate-user-emacs-file ".lsp-session"))
  (lsp-log-io nil)                      ; IMPORTANT! Use only for debugging! Drastically affects performance
  (lsp-keep-workspace-alive nil)        ; Close LSP server if all project buffers are closed
  (lsp-idle-delay 0.5)                  ; Debounce timer for `after-change-function'
  ;; core
  (lsp-enable-xref t)                   ; Use xref to find references
  (lsp-auto-configure t)                ; Used to decide between current active servers
  (lsp-eldoc-enable-hover t)            ; Display signature information in the echo area
  (lsp-enable-dap-auto-configure t)     ; Debug support
  (lsp-enable-file-watchers nil)
  (lsp-enable-folding nil)              ; I disable folding since I use origami
  (lsp-enable-imenu t)
  (lsp-enable-indentation nil)          ; I use prettier
  (lsp-enable-links nil)                ; No need since we have `browse-url'
  (lsp-enable-on-type-formatting nil)   ; Prettier handles this
  (lsp-enable-suggest-server-download t) ; Useful prompt to download LSP providers
  (lsp-enable-symbol-highlighting t)     ; Shows usages of symbol at point in the current buffer
  (lsp-enable-text-document-color nil)   ; This is Treesitter's job

  (lsp-ui-sideline-show-hover nil)      ; Sideline used only for diagnostics
  (lsp-ui-sideline-diagnostic-max-lines 20) ; 20 lines since typescript errors can be quite big
  ;; completion
  (lsp-completion-enable t)
  (lsp-completion-enable-additional-text-edit t) ; Ex: auto-insert an import for a completion candidate
  (lsp-enable-snippet t)                         ; Important to provide full JSX completion
  (lsp-completion-show-kind t)                   ; Optional
  ;; headerline
  (lsp-headerline-breadcrumb-enable t)  ; Optional, I like the breadcrumbs
  (lsp-headerline-breadcrumb-enable-diagnostics nil) ; Don't make them red, too noisy
  (lsp-headerline-breadcrumb-enable-symbol-numbers nil)
  (lsp-headerline-breadcrumb-icons-enable nil)
  ;; modeline
  (lsp-modeline-code-actions-enable nil) ; Modeline should be relatively clean
  (lsp-modeline-diagnostics-enable nil)  ; Already supported through `flycheck'
  (lsp-modeline-workspace-status-enable nil) ; Modeline displays "LSP" when lsp-mode is enabled
  (lsp-signature-doc-lines 1)                ; Don't raise the echo area. It's distracting
  (lsp-ui-doc-use-childframe t)              ; Show docs for symbol at point
  (lsp-eldoc-render-all nil)            ; This would be very useful if it would respect `lsp-signature-doc-lines', currently it's distracting
  ;; lens
  (lsp-lens-enable nil)                 ; Optional, I don't need it
  ;; semantic
  (lsp-semantic-tokens-enable nil)      ; Related to highlighting, and we defer to treesitter

  :init
  (setq lsp-use-plists t)

  :config
  ;; (lsp-register-client
  ;;  (make-lsp-client :new-connection (lsp-stdio-connection '("typescript-language-server" "--stdio"))
  ;;                   :major-modes '(js-ts-mode)
  ;;                   :server-id 'ts-ls))
  :preface
  (defun lsp-booster--advice-json-parse (old-fn &rest args)
    "Try to parse bytecode instead of json."
    (or
     (when (equal (following-char) ?#)

       (let ((bytecode (read (current-buffer))))
         (when (byte-code-function-p bytecode)
           (funcall bytecode))))
     (apply old-fn args)))
  (defun lsp-booster--advice-final-command (old-fn cmd &optional test?)
    "Prepend emacs-lsp-booster command to lsp CMD."
    (let ((orig-result (funcall old-fn cmd test?)))
      (if (and (not test?)                             ;; for check lsp-server-present?
               (not (file-remote-p default-directory)) ;; see lsp-resolve-final-command, it would add extra shell wrapper
               lsp-use-plists
               (not (functionp 'json-rpc-connection))  ;; native json-rpc
               (executable-find "emacs-lsp-booster"))
          (progn
            (message "Using emacs-lsp-booster for %s!" orig-result)
            (cons "emacs-lsp-booster" orig-result))
        orig-result)))
  :init
  (setq lsp-use-plists t)
  ;; Initiate https://github.com/blahgeek/emacs-lsp-booster for performance
  (advice-add (if (progn (require 'json)
                         (fboundp 'json-parse-buffer))
                  'json-parse-buffer
                'json-read)
              :around
              #'lsp-booster--advice-json-parse)
  (advice-add 'lsp-resolve-final-command :around #'lsp-booster--advice-final-command))

;; ====== end lsp-mode 

;; (use-package lsp-mode
;;   :ensure t
;;   :init
;;   (setq lsp-keymap-prefix "C-c l")
;;   :hook ((typescript-mode . lsp-deferred)
;;          (js-ts-mode . lsp-deferred)
;;          (js-mode . lsp-deferred)
;;          (lsp-mode . lsp-enable-which-key-integration))
;;   :config
;;   (setq lsp-typescript-server 'typescript-javascript-server)
;;   ;; Optional: Specify the path to the TypeScript language server
;;   (setq lsp-typescript-server-path "/opt/homebrew/bin/typescript-language-server")
;;   ;; Optional: Enable logging for troubleshooting
;;   (setq lsp-log-level 'debug))


(use-package lsp-ui
  :ensure t
  :commands
  (lsp-ui-doc-show
   lsp-ui-doc-glance)
  :bind (:map lsp-mode-map
              ("C-c C-d" . 'lsp-ui-doc-glance))
  :after (lsp-mode evil)
  :config (setq lsp-ui-doc-enable t
                evil-lookup-func #'lsp-ui-doc-glance ; Makes K in evil-mode toggle the doc for symbol at point
                lsp-ui-doc-show-with-cursor nil      ; Don't show doc when cursor is over symbol - too distracting
                lsp-ui-doc-include-signature t       ; Show signature
                lsp-ui-doc-position 'at-point))

(use-package lsp-eslint
  :demand t
  :after lsp-mode
  :config
  (setq lsp-eslint-server-command '("eslint-lsp" "--stdio")))

(use-package lsp-tailwindcss
  :init (setq lsp-tailwindcss-add-on-mode t)
  :config
  (dolist (tw-major-mode
           '(css-mode
             css-ts-mode
             js-ts-mode
             tsx-ts-mode
             clojure-mode))
    (add-to-list 'lsp-tailwindcss-major-modes tw-major-mode)))

Restclient

(use-package restclient
  :commands (restclient))

Yasnippet

(use-package yasnippet
  :ensure t
  :diminish
  :defer t
  :config
  (setq yas-snippet-dirs (concat user-emacs-directory "snippets"))
  (setq yas-indent-line 'fixed)
  (yas-global-mode)
  (global-set-key (kbd "M-/") 'company-yasnippet))

Mail

Mu4e setup

(use-package mu4e
  :load-path  "/opt/homebrew/Cellar/mu/1.12.6/share/emacs/site-lisp/mu/mu4e/"
  :custom
  (mu4e-use-fancy-chars nil)
  (mu4e-mu-binary (executable-find "mu"))
  (mu4e-get-command (concat (executable-find "mbsync") " -a"))
  (mu4e-update-interval 300)
  (mu4e-maildir "~/Mail")
  (mu4e-attachment-dir "~/Downloads")
  (mu4e-change-filenames-when-moving t)
  ;; === send email ===
  (mu4e-compose-format-flowed t)
  (message-kill-buffer-on-exit t)
  (mu4e-compose-context-policy 'ask-if-none)
  (send-mail-function 'sendmail-send-it
                      message-send-mail-function 'sendmail-send-it)
  (sendmail-program (executable-find "msmtp"))
  (message-sendmail-envelope-from 'header)
  :hook
  ((mu4e-view-mode . visual-line-mode)
   (mu4e-compose-mode . (lambda ()
                          (use-hard-newlines -1)
                          (flyspell-mode)))
   (mu4e-headers-mode . (lambda ()
                          (interactive)
                          (setq mu4e-headers-fields
                                `((:human-date . 25) ;; alternatively, use :date
                                  (:flags . 6)
                                  (:from . 25)
                                  (:thread-subject . ,(- (window-body-width) 75)) ;; alternatively, use :subject
                                  (:size . 7))))))
  :init
  (use-package mu4e-thread-folding
    :load-path (lambda () (expand-file-name "site-elisp/mu4e-thread-folding/" user-emacs-directory))
    :after mu4e
    :bind
    ((:map mu4e-headers-mode-map
           ("TAB" . mu4e-headers-toggle-at-point)
           ("C-<tab>" . mu4e-headers-toggle-fold-all))
     (:map mu4e-search-minor-mode-map
           ("S" . mu4e-kill-update-mail)))
    :custom
    (mu4e-thread-folding-default-view `folded)
    (mu4e-headers-fields '((:empty         .    2)
                           (:human-date    .   12)
                           (:flags         .    6)
                           (:mailing-list  .   10)
                           (:from          .   25)
                           (:subject       .   nil))))
  :config  
  ;; list of your email adresses:
  (setq mu4e-user-mail-address-list '("[email protected]"
                                      "[email protected]"
                                      "[email protected]")))

(require 'mu4e)

(setq mu4e-maildir-shortcuts
      '(("/Kulcare/Inbox"             . ?k)
        ("/Addval/Inbox"              . ?a)
        ("/Gmail/Inbox"               . ?g)
        ("/Kulcare/[Gmail]/Sent Mail" . ?s)
        ("/Kulcare/[Gmail]/Trash"     . ?t)
        ("/Kulcare/[Gmail]/Drafts"    . ?d)
        ("/Kulcare/[Gmail]/All Mail"  . ?l)))

Mu4e bookmarks

;; the following is to show shortcuts in the main view.
(add-to-list 'mu4e-bookmarks
             '(:name "Inbox - Gmail"
                     :query "maildir:/gmail/INBOX"
                     :key ?g))
(add-to-list 'mu4e-bookmarks
             '(:name "Inbox - Addval"
                     :query "maildir:/addval/INBOX"
                     :key ?a))
(add-to-list 'mu4e-bookmarks
             '(:name "Inbox - Kulcare"
                     :query "maildir:/kulcare/INBOX"
                     :key ?k))

Mu4e contexts

;; Kulcare account
,(make-mu4e-context
  :name "Kulcare"
  :match-func
  (lambda (msg)
    (when msg
      (string-prefix-p "/Kulcare" (mu4e-message-field msg :maildir))))
  :vars '((user-mail-address . "[email protected]")
          (user-full-name    . "Shantanu Bhardwaj")
          (smtpmail-smtp-server  . "smtp.gmail.com")
          (smtpmail-smtp-service . 465)
          (smtpmail-stream-type  . ssl)
          (mu4e-drafts-folder  . "/Kulcare/[Gmail]/Drafts")
          (mu4e-sent-folder  . "/Kulcare/[Gmail]/Sent Mail")
          (mu4e-refile-folder  . "/Kulcare/[Gmail]/All Mail")
          (mu4e-trash-folder  . "/Kulcare/[Gmail]/Trash")))

;; Codetiger account
,(make-mu4e-context
 :name "Codetiger"
 :match-func
 (lambda (msg)
   (when msg
     (string-prefix-p "/Codetiger" (mu4e-message-field msg :maildir))))
 :vars '((user-mail-address . "[email protected]")
         (user-full-name    . "Shan Bhardwaj")
         (smtpmail-smtp-server  . "smtp.gmail.com")
         (smtpmail-smtp-service . 465)
         (smtpmail-stream-type  . ssl)
         (mu4e-drafts-folder  . "/Codetiger/[Gmail]/Drafts")
         (mu4e-sent-folder  . "/Codetiger/[Gmail]/Sent Mail")
         (mu4e-refile-folder  . "/Codetiger/[Gmail]/All Mail")
         (mu4e-trash-folder  . "/Codetiger/[Gmail]/Trash")))

;; Gmail account
,(make-mu4e-context
  :name "Gmail"
  :match-func
  (lambda (msg)
    (when msg
      (string-prefix-p "/Gmail" (mu4e-message-field msg :maildir))))
  :vars '((user-mail-address . "[email protected]")
          (user-full-name    . "Shantanu Bhardwaj")
          (smtpmail-smtp-server  . "smtp.gmail.com")
          (smtpmail-smtp-service . 465)
          (smtpmail-stream-type  . ssl)
          (mu4e-drafts-folder  . "/Gmail/[Gmail]/Drafts")
          (mu4e-sent-folder  . "/Gmail/[Gmail]/Sent Mail")
          (mu4e-refile-folder  . "/Gmail/[Gmail]/All Mail")
          (mu4e-trash-folder  . "/Gmail/[Gmail]/Trash")))
))

Sending email

Mu4e UI

(use-package mu4e-alert
  :hook (after-init-hook . mu4e-alert-enable-mode-line-display)
  :config
  (setq mu4e-alert-email-notification-types '(count)))

(use-package mu4e-marker-icons)
(use-package mu4e-column-faces
  :after mu4e
  :config (mu4e-column-faces-mode))

;; (use-package mu4e-dashboard
;;    )

(use-package mu4e-views
  :after mu4e)

Misc