My Emacs Config

Table of Contents

unload-feature will help you unload a package and all it’s functions and keybindings.

Need to work on it. Org roam link export

(require 'ox-hugo)
(require 'org-roam)

;; Define custom export function for Org-roam links
(org-link-set-parameters
 "id"
 :export (lambda (path desc backend)
           (cond
            ((eq backend 'hugo)
             (or desc path)))))  ;; Export description or path as plain text for Hugo

;; Optionally handle Org-roam's roam: links if used
(org-link-set-parameters
 "roam"
 :export (lambda (path desc backend)
           (cond
            ((eq backend 'hugo)
             (or desc path)))))  ;; Export description or path as plain text for Hugo

Startup

Measure startup time

Make startup faster by reducing the frequency of garbage collection and then use a hook to measure Emacs startup time.

;; The default is 800 kilobytes.  Measured in bytes.
(setq gc-cons-threshold (* 50 1000 1000))

;; Profile emacs startup
(add-hook 'emacs-startup-hook
          (lambda ()
            (message "*** Emacs loaded in %s with %d garbage collections."
                     (format "%.2f seconds"
                             (float-time
                              (time-subtract after-init-time before-init-time)))
                     gcs-done)))

Native Compilation


;;Silence compiler warnings as they can be pretty disruptive
(setq comp-async-report-warnings-errors nil)
(setq native-comp-async-report-warnings-errors nil)
(setq package-native-compile t)
(setq comp-deferred-compilation nil)
(setq native-comp-speed -1)
(setq native-comp-eln-load-path '("~/.cache/emacs/eln-cache"))
(setq native-comp-async-jobs-number 1)
(setq no-native-compile t)
(setq straight-disable-native-comp t)

See also warning-minimun-level

No idea what this is. Something to do with native compilation.


(when (fboundp 'native-compile-async)
  (setq comp-deferred-compilation t
        comp-deferred-compilation-black-list '("/mu4e.*\\.el$")))
(if (and (fboundp 'native-comp-available-p)
       (native-comp-available-p))
  (message "Native compilation is available")
(message "Native complation is *not* available"))

(if (functionp 'json-serialize)
  (message "Native JSON is available")
(message "Native JSON is *not* available"))

Emacs Environment variable


;; (setq debug-on-error t)
(setenv "PATH" (concat (getenv "PATH") "/home/shuvro/.local/bin"))
(setq exec-path (append exec-path '("/home/shuvro/.local/bin")))

(setq user-full-name    "Shuvrojit Biswas"
      user-mail-address "jsuvro17@gmail.com")

Custom file

 ;; Define the init file
  (setq custom-file (expand-file-name "custom.el" user-emacs-directory))
  (when (file-exists-p custom-file)
    (load custom-file))

Package Management

straight.el

;; Bootstrap straight.el
(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/raxod502/straight.el/develop/install.el"
      'silent 'inhibit-cookies)
     (goto-char (point-max))
     (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

;; Always use straight to install on systems other than Linux
(setq straight-use-package-by-default t)

;; Use straight.el for use-package expressions

(straight-use-package 'use-package)
(setq use-package-always-ensure t)

;; Load the helper package for commands like `straight-x-clean-unused-repos'
(require 'straight-x)

Auto update

(straight-use-package 'org)
(use-package auto-package-update
  :defer 10
  :config
  ;; Delete residual old versions
  (setq auto-package-update-delete-old-versions t)
  ;; Do not bother me when updates have taken place.
  (setq auto-package-update-hide-results t)
  ;; Update installed packages at startup if there is an update pending.
  (auto-package-update-maybe))

Mode Diminishing

The minions package hides pesky minor modes from the modelines. diminish package didn’t work?

(use-package minions
  :config
  (minions-mode 1))

Which-key

Which-key will tell us the command name in the minibuffer for all the commands in emacs.

(use-package which-key
  :init (which-key-mode)
  :config
  (setq which-key-idle-delay 0.1))

User Interface

Hide ugliness

(setq
 inhibit-startup-message t
 visible-bell t
 initial-scratch-message nil
 ;; Save existing clipboard text into the kill ring before replacing it.
 save-interprogram-paste-before-kill t
 ;; when I say to quit, I mean quit
 confirm-kill-processes nil
 )

(setq x-select-enable-clipboard t)
(global-prettify-symbols-mode t)

;; (setq electric-pair-pairs '(
                            ;; (?\{ . ?\})
                            ;; (?\( . ?\))
                            ;; (?\[ . ?\])
                            ;; (?\" . ?\")
                            ;; ))
(add-hook 'prog-mode-hook 'hl-line-mode)

;; non fancy ui
(scroll-bar-mode -1)
(tool-bar-mode -1)
(tooltip-mode -1)
(menu-bar-mode -1)

Improve Scrolling

(setq mouse-wheel-scroll-amount '(1 ((shift) . 1))) ;; one line at a time
(setq mouse-wheel-progressive-speed nil) ;; don't accelerate scrolling
(setq mouse-wheel-follow-mouse 't) ;; scroll window under mouse
(setq scroll-step 1) ;; keyboard scroll one line at a time

Frame transparency

When using emacs from the terminal, by using default theme we can get transparency and terminal colors for emacs.

(set-frame-parameter nil 'alpha-background 95)
(add-to-list 'default-frame-alist '(alpha-background . 95))
;; (set-frame-parameter (selected-frame) 'alpha '(99 . 99))
;; (add-to-list 'default-frame-alist '(alpha . (99 . 99)))
;; (set-frame-parameter (selected-frame) 'fullscreen 'maximized)
;; (add-to-list 'default-frame-alist '(fullscreen . maximized))

Line numbers

(column-number-mode)

;; Enable line numbers for some modes
(dolist (mode '(text-mode-hook
                prog-mode-hook
                conf-mode-hook))
  (add-hook mode (lambda () (display-line-numbers-mode t))))

;; Override some modes which derive from the above
(dolist (mode '(org-mode-hook))
  (add-hook mode (lambda () (display-line-numbers-mode 0))))
;Don't warn for large files (shows up when launching videos)
(setq large-file-warning-threshold nil)

;;Don't warn for following symlinked files
(setq vc-follow-symlinks t)

;Don't warn when advice is added for functions
;;(setq ad-redefinition-action 'accept)

Modeline

(use-package telephone-line)
(setq telephone-line-primary-left-separator 'telephone-line-cubed-left
      telephone-line-secondary-left-separator 'telephone-line-cubed-hollow-left
      telephone-line-primary-right-separator 'telephone-line-cubed-right
      telephone-line-secondary-right-separator 'telephone-line-cubed-hollow-right)
(setq telephone-line-height 24
      telephone-line-evil-use-short-tag t)
(telephone-line-mode 1)

Font

When running the server emacs is not going to pick up whatever fonts worked back. We need to set default-frame-alist for the font to work in the graphical version of emacs server.

(setq default-frame-alist '((font . "Hack-16")))
(add-to-list 'default-frame-alist '(font . "Hack-16"))
;; Set the fixed pitch face
;; sets up org source blocks
(set-face-attribute 'fixed-pitch nil
                    :font "Hack"
                    :weight 'light
                    :height 150
                    )
;;sets up modeline text, code text
(set-face-attribute 'default nil
                    :font "Hack"
                    ;; :font "Cascadia Code"
                    :height 150
                    )

;; Set the variable pitch face
;;sets up org mode header
(set-face-attribute 'variable-pitch nil
                    ;; :font "Cantarell"
                    ;; :font "Inconsolata"
                    ;; :font "ETbookOT"
                    :font "Fira Code"
                    ;; :font "Times New Roman"
                    :weight 'light
                    :height 170)

themes

(use-package gruvbox-theme)
(load-theme 'gruvbox t)
;; (require 'ef-themes)
;; The themes we provide:
;;
;; Light: `ef-day', `ef-light', `ef-spring', `ef-summer'.
;; Dark:  `ef-autumn', `ef-dark', `ef-night', `ef-winter'.

;; We also provide these commands, but do not assign them to any key:
;;
;; - `ef-themes-select'
;; - `ef-themes-load-random'
;; - `ef-themes-preview-colors'
;; - `ef-themes-preview-colors-current'

(when (display-graphic-p)

(use-package ef-themes
  :config
  ;; Disable all other themes to avoid awkward blending:
  (mapc #'disable-theme custom-enabled-themes)

  ;; Load the theme of choice:
  (load-theme 'ef-spring' :no-confirm)
  (load-theme 'ef-winter' :no-confirm)
  (load-theme 'ef-summer' :no-confirm)
  (load-theme 'ef-night' :no-confirm)
  (load-theme 'ef-day' :no-confirm)
  (load-theme 'ef-autumn' :no-confirm)
  )

(ef-themes-load-random 'dark)
)
(if (not (display-graphic-p)) (load-theme 'default t))

Beacon

A beacon shinning on your point man.

(use-package beacon
  :init
  (setq beacon-blink-when-point-moves t)
  (setq beacon-blink-when-window-change t)
  (setq beacon-blink-when-window-scrolls t)
  (beacon-mode 1))

Emoji

Emoji support on emacs. :)

(use-package emojify
  :hook (erc-mode . emojify-mode))
(add-hook 'after-init-hook #'global-emojify-mode)

All the icons

(use-package all-the-icons
  :straight (all-the-icons :type git :host github :repo "domtronn/all-the-icons.el" :branch "svg" :files (:defaults "svg"))
  :if (display-graphic-p))

Dashboard

A dashboard that’s gonna open everytime you open emacs

(use-package dashboard
  :ensure t
  :config
  (dashboard-setup-startup-hook))

Solarized Theme+Modeline

;;; module-solarized.el --- solarized module for my emacs

;; Author: Mark Feller <mark.feller@member.fsf.org>

;; This file is not part of GNU Emacs.

;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.

;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this file.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:

;;; Code:

(use-package solarized-theme
  :config
  (progn (setq solarized-emphasize-indicators nil
               solarized-high-contrast-mode-line nil
               solarized-scale-org-headlines nil
               solarized-use-less-bold t
               solarized-use-variable-pitch nil
               solarized-distinct-fringe-background nil)))

(use-package all-the-icons
  :demand
  :init
  (progn (defun -custom-modeline-github-vc ()
           (let ((branch (mapconcat 'concat (cdr (split-string vc-mode "[:-]")) "-")))
             (concat
              (propertize (format " %s" (all-the-icons-octicon "git-branch"))
                          'face `(:height 1 :family ,(all-the-icons-octicon-family))
                          'display '(raise 0))
              (propertize (format " %s" branch))
              (propertize "  "))))

         (defun -custom-modeline-svn-vc ()
           (let ((revision (cadr (split-string vc-mode "-"))))
             (concat
              (propertize (format " %s" (all-the-icons-faicon "cloud"))
                          'face `(:height 1)
                          'display '(raise 0))
              (propertize (format " %s" revision) 'face `(:height 0.9)))))

         (defvar mode-line-my-vc
           '(:propertize
             (:eval (when vc-mode
                      (cond
                       ((string-match "Git[:-]" vc-mode) (-custom-modeline-github-vc))
                       ((string-match "SVN-" vc-mode) (-custom-modeline-svn-vc))
                       (t (format "%s" vc-mode)))))
             face mode-line-directory)
           "Formats the current directory."))
  :config
  (progn
    ;; (setq-default mode-line-format
    ;;               (list
    ;;                evil-mode-line-tag
    ;;                mode-line-front-space
    ;;                mode-line-mule-info
    ;;                mode-line-modified
    ;;                mode-line-frame-identification
    ;;                mode-line-buffer-identification
    ;;                " "
    ;;                mode-line-position
    ;;                mode-line-my-vc
    ;;                mode-line-modes))
    ;; (concat evil-mode-line-tag)
    ))


;; (bind-keys ("C-c tl" . (lambda () (interactive) (load-theme 'solarized-light)))
;;            ("C-c td" . (lambda () (interactive) (load-theme 'solarized-dark))))

(load-theme 'solarized-light t)

(set-face-attribute 'mode-line nil
                    :background "#eee8d5"
                    :foreground "#657b83"
                    :box '(:line-width 4 :color "#eee8d5")
                    :overline nil
                    :underline nil)

(set-face-attribute 'mode-line-inactive nil
                    :background "#fdf6e3"
                    :foreground "#93a1a1"
                    :box '(:line-width 4 :color "#eee8d5")
                    :overline nil
                    :underline nil)

(define-minor-mode minor-mode-blackout-mode
  "Hides minor modes from the mode line."
  t)

(catch 'done
  (mapc (lambda (x)
          (when (and (consp x)
                     (equal (cadr x) '("" minor-mode-alist)))
            (let ((original (copy-sequence x)))
              (setcar x 'minor-mode-blackout-mode)
              (setcdr x (list "" original)))
            (throw 'done t)))
        mode-line-modes))

(global-set-key (kbd "C-c m") 'minor-mode-blackout-mode)
;; ;; window dividers
;; (window-divider-mode t)
;; (setq window-divider-default-right-width 2)

;; (set-face-attribute 'window-divider nil :foreground "#eee8d5")
;; (set-face-attribute 'window-divider-first-pixel nil :foreground "#eee8d5")
;; (set-face-attribute 'window-divider-last-pixel nil :foreground "#eee8d5")

(provide 'module-solarized)

;;; module-solarized.el ends here

Ewal

(use-package ewal
  :init (setq ewal-use-built-in-always-p nil
              ewal-use-built-in-on-failure-p t
              ewal-built-in-palette "sexy-material"))
(use-package ewal-spacemacs-themes
  :init (progn
          (setq spacemacs-theme-underline-parens t
                my:rice:font (font-spec
                              :family "Source Code Pro"
                              :weight 'semi-bold
                              :size 11.0))
          (show-paren-mode +1)
          (global-hl-line-mode)
          (set-frame-font my:rice:font nil t)
          (add-to-list  'default-frame-alist
                        `(font . ,(font-xlfd-name my:rice:font))))
  :config (progn
            (load-theme 'ewal-spacemacs-modern t)
            (enable-theme 'ewal-spacemacs-modern)))
(use-package ewal-evil-cursors
  :after (ewal-spacemacs-themes)
  :config (ewal-evil-cursors-get-colors
           :apply t :spaceline t))
(use-package spaceline
  :after (ewal-evil-cursors winum)
  :init (setq powerline-default-separator nil)
  :config (spaceline-spacemacs-theme))

Emacs Mini frame

(use-package mini-frame)
(setq x-gtk-resize-child-frames 'resize-mode)
(custom-set-variables
 '(mini-frame-show-parameters
   '((top . 400)
     (width . 0.7)
     (left . 0.5))))
(mini-frame-mode 1)

Base Config

Evil mode

Set evil-want-keybinding variable to nil before initializing evil mode or it will produce and error. Evil collection is not going to work without doing that.

 (defun em/evil-hook ()
  (dolist (mode '(custom-mode
                  eshell-mode
                  vterm-mode
                  git-rebase-mode
                  ;; erc-mode
                  ;; circe-server-mode
                  ;; circe-chat-mode
                  ;; circe-query-mode
                  ;; sauron-mode
                  term-mode))
  (add-to-list 'evil-emacs-state-modes mode)))


(use-package evil
  :init
  (setq evil-want-integration t)
  (setq evil-want-keybinding nil)
  (setq evil-want-C-u-scroll t)
  (setq evil-want-C-i-jump nil)
  (setq evil-respect-visual-line-mode t)
  (setq evil-undo-system 'undo-tree)
  :config
  (add-hook 'evil-mode-hook 'em/evil-hook)
  (evil-mode 1)
  (setcdr evil-insert-state-map nil)
  (define-key evil-insert-state-map [escape] 'evil-normal-state)
  (define-key evil-normal-state-map (kbd "C-t") 'shell-pop)
(define-key evil-normal-state-map (kbd "M-.") 'xref-find-definitions)

  (define-key evil-normal-state-map (kbd "C-.") 'nil)
  ;; Use visual line motions even outside of visual-line-mode buffers
  (evil-global-set-key 'motion "j" 'evil-next-visual-line)

  (evil-global-set-key 'motion "U" 'evil-redo)

  (evil-global-set-key 'motion "t" (dired "./"))


  (evil-global-set-key 'motion "k" 'evil-previous-visual-line)


  (evil-set-initial-state 'messages-buffer-mode 'normal)
  (evil-set-initial-state 'dashboard-mode 'normal))

(use-package evil-collection
  :after evil
  :init
  (setq evil-collection-company-use-tng nil)  ;; Is this a bug in evil-collection?
  :custom
  (evil-collection-outline-bind-tab-p nil)
  :config
  (setq evil-collection-mode-list
        (remove 'lispy evil-collection-mode-list))
  (evil-collection-init))


(define-key evil-normal-state-map (kbd "C-e") 'end-of-line)

(use-package general
  :config
  (general-evil-setup t)

  (general-create-definer evil/leader-keys
                          :keymaps '(normal
                                     ;; insert visual emacs
                                     )
                          :prefix "SPC"
                          ;; :global-prefix "C-SPC"
                          )

  (evil/leader-keys
   "t" '(:ignore t :which-key "toggles")
   ;; "tt"'(counsel-load-theme :which-key "choose theme")
   "a" '(org-agenda :which-key "Org Agenda")
   "w" '(evil-window-map :which-key "Evil window map")
   ;;files
   "f" '(:ignore f :which-key "files")
   "ff"'(find-file :which-key "find file")
   "fs"'(save-buffer :which-key "save buffer")
   "h" '(help-command :which-key "help command")
                                        ;buffers
   "b" '(:ignore b :which-key "buffers")
   "br"'(revert-buffer :which-key "revert buffer")
   "bk"'(previous-buffer :which-key "previous buffer")
   "bj"'(next-buffer :which-key "next buffer")
   "be"'(eval-buffer :which-key "Eval Buffer")
   "s" '(bookmark-map s :which-key "bookmark")

   ))

(evil/leader-keys
 "n" '(:which-key "org roam")
 "na"'(org-roam-buffer-toggle :which-key "org roam toggle")
 "nf"'(org-roam-node-find :which-key "org roam find")
 "ni"'(org-roam-node-insert :which-key "org roam node insert")
 )
(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))
(setq evil-want-C-i-jump nil)

Surround Vim


(use-package evil-surround
  :after evil
  :defer 2
  :config
  (global-evil-surround-mode 1))

Keep Backup files clean


;; backup files directory for per project
;;(setq backup-directory-alist `(("." . ,(expand-file-name "tmp/backups/" user-emacs-directory))))

;; Auto save files
;; New location for backups.
(setq backup-directory-alist '(("." . "~/.config/emacs/backups")))

;; Silently delete execess backup versions
(setq delete-old-versions t)

;; Only keep the last 1000 backups of a file.
(setq kept-old-versions 100)

;; Even version controlled files get to be backed up.
(setq vc-make-backup-files t)

;; Use version numbers for backup files.
(setq version-control t)

;; Change the user-emacs-directory to keep unwanted things out of ~/.emacs.d
(setq user-emacs-directory (expand-file-name "~/.cache/emacs/")
      url-history-file (expand-file-name "url/history" user-emacs-directory))

;; Use no-littering to automatically set common paths to the new user-emacs-directory
(use-package no-littering)

;; Keep customization settings in a temporary file (thanks Ambrevar!)
(setq custom-file
      (if (boundp 'server-socket-dir)
          (expand-file-name "custom.el" server-socket-dir)
        (expand-file-name (format "emacs-custom-%s.el" (user-uid)) temporary-file-directory)))
(load custom-file t)

an elementary diff system for backups.

(use-package backup-walker
  :commands backup-walker-start)

Make backups everytime

Emacs only makes a backup the very first time a buffer is saved; I’d prefer Emacs makes backups everytime I save! —If I saved, that means I’m at an important checkpoint, so please check what I have so far as a backup!

(defun force-backup-of-buffer ()
  (setq buffer-backed-up nil))

(add-hook 'before-save-hook  'force-backup-of-buffer)

;;alternative
;;(defun backup-and-save ()
 ;; (interactive)
 ;; (setq filename (buffer-file-name))
 ;; (write-file (concat filename (format-time-string "_" "%Y%m%d%H%M%S")))
 ;; (write-file filename)
 ;; )

Auto-Reverting Changed Files

;; Revert Dired and other buffers
(setq global-auto-revert-non-file-buffers t)

;; Revert buffers when the underlying file has changed
(global-auto-revert-mode 1)

Matching Braces

(use-package paren
  :config
  (set-face-attribute 'show-paren-match-expression nil :background "#363e4a")
  (show-paren-mode 1))

Tab width

(setq-default tab-width 4)
(setq-default indent-tabs-mode nil)
;; Make tab key do indent first then completion.
(setq-default tab-always-indent 'complete)

Comments

comment-dwim-2 is a package that extends the functionality of built-in comment-dwim.

(use-package comment-dwim-2
  :bind (("M-;" . comment-dwim-2)
         (:map org-mode-map
               ("M-;" . org-comment-dwim-2))))

evil-nerd-commenter is a better option if you’re from vim style keybindings and workflow. It has extra functionality like a bunch of extra function. Read it in the github page.

(use-package evil-nerd-commenter
  :bind (("M-;" . evilnc-comment-or-uncomment-lines)))

Editing Text

Subword mode recognizes camelcase words when editing words. There’s also a version called glasses mode which visually places a underscore between camelcase words but doesn’t affect the buffer. Then there’s superword mode. Electric layout mode automatically inserts a newline with {}, ; etc. Autofill mode indents newline.

Hideshow mode is pretty amazing. It’s just like code folding. Customize the variable hs-isearch-open. Search for folding editing for working on org or outline mode.


;; makes the completion ignore case
(setq completion-ignore-case  t)
;; two more functions like this: read-file-name-completion-ignore-case
;; read-buffer-completion-ignore-case

;;(subword-mode 1)

(add-hook 'prog-mode-hook 'subword-mode)
;; (add-hook 'prog-mode-hook 'electric-pair-mode)
;; (add-hook 'org-mode-hook
          ;; (lambda ()
            ;; (electric-pair-mode nil)))

;; (add-hook 'prog-mode-hook 'electric-layout-mode)
(add-hook 'prog-mode-hook 'hs-minor-mode)
(define-key evil-normal-state-map (kbd "C-r") 'hs-hide-all)
(define-key evil-normal-state-map (kbd ";") 'hs-toggle-hiding)
(define-key evil-normal-state-map (kbd "C-y") 'hs-show-all)

(global-set-key (kbd "C-x w") 'hs-hide-all)
(global-set-key (kbd "C-x e") 'hs-show-all)
(global-set-key (kbd "C-x ;") 'hs-toggle-hiding)

Auto clean whitespace

(use-package ws-butler
  :hook ((text-mode . ws-butler-mode)
         (prog-mode . ws-butler-mode)))

Auto-Saving Changed Files

(use-package super-save
  :defer 1
  :config
  (super-save-mode +1)
  (setq super-save-auto-save-when-idle nil))

;; (use-package multiple-cursors)

Smart Parens

(use-package smartparens
  :hook (prog-mode . smartparens-mode))

Rainbow Mode

Sets the background of HTML color strings in buffers to be the color mentioned.

(use-package rainbow-mode
  :defer t
  :hook (org-mode
         emacs-lisp-mode
         web-mode
         python-mode
         prog-mode))

Rainbow Delimiters

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

openwith

(use-package openwith
  :config
  (setq openwith-associations
        (list
          (list (openwith-make-extension-regexp
                '("mpg" "mpeg" "mp3" "mp4"
                  "avi" "wmv" "wav" "mov" "flv"
                  "ogm" "ogg" "mkv"))
                "mpv"
                '(file))
          (list (openwith-make-extension-regexp
                '("xbm" "pbm" "pgm" "ppm" "pnm"
                  "png" "gif" "bmp" "tif" "jpeg")) ;; Removed jpg because Telega was
                  ;; causing feh to be opened...
                  "sxiv"
                  '(file))
          (list (openwith-make-extension-regexp
                '("pdf"))
                "zathura"
                '(file)))))

Restart Emacs

;; Provides only the command “restart-emacs”.
(use-package restart-emacs
  :bind ("C-x C-c" . restart-emacs)
  :config (defalias 'emacs-restart #'restart-emacs))

;; Keep open files open across sessions.
;;(desktop-save-mode 1)
;;(setq desktop-restore-eager 10)
(global-set-key (kbd "C-x c") 'save-buffers-kill-emacs)

;; saves the last place the point was on a buffer during visit.
(save-place-mode 1)
(setq save-place-forget-unreadable-files nil)

Undo

Undo-tree

;; (setq split-height-threshold 0)


(use-package undo-tree
  :ensure t
  :init
  (global-undo-tree-mode 1)
  :custom
  (undo-tree-visualizer-diff t)
  (undo-tree-timer t)
  (undo-tree-visualizer-timestamps t)
  (undo-tree-visualizer-relative-timestamps t)
  (undo-tree-auto-save-history t)
  (undo-tree-visualizer-lazy-drawing t)
  (undo-tree-mode-lighter t)
  :config
  (defalias 'redo 'undo-tree-redo)
  ;;setting the default backed up file list for undo
  (setq undo-tree-history-directory-alist '(("." . "~/.config/emacs/undo")))
  :bind (("C-z" . undo-tree-undo)     ; Zap to character isn't helpful
         ("C-S-z" . undo-tree-redo))
         )

(defun split-side-by-side (original-function &rest args)
  "Split undo-tree side-by-side"
  (let ((split-height-threshold nil)
        (split-width-threshold 0))
    (apply original-function args)))

(advice-add 'undo-tree-visualize :around #'split-side-by-side)

Undo-fu

(use-package undo-fu
  :config
  (global-unset-key (kbd "C-z"))
  (global-set-key (kbd "C-z")   'undo-fu-only-undo)
  (global-set-key (kbd "C-S-z") 'undo-fu-only-redo))

Magit

Sometimes for large repos magit can get a little bit slow. What to do then? Use magit-refresh-verbose to see what magit is starting when we see magit-status. It should give us what is going on in the message buffer.

(setq magit-refresh-verbose t)

So if we think some process or hook is stalling or taking a lot of time we can disable it with remove hook. When magit-status is called it calls a lot of other hooks. Remove performance bloating hooks with remove hooks from magit-status-sections-hooks.

(use-package magit
  :bind ("C-x g" . magit-status)
  :commands (magit-status magit-get-current-branch)
  :custom
  (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1))

(when (equal ""
(shell-command-to-string "git config user.name"))
  (shell-command "git config --global user.name \"Shuvrojit Biswas\"")
  (shell-command "git config --global user.email \"jsuvro17@gmail.com\""))

(use-package git-timemachine :defer t)
(evil/leader-keys
  "g"   '(:ignore t :which-key "git")
  "gs"  'magit-status
  "gd"  'magit-diff-unstaged
  "gc"  'magit-branch-or-checkout
  "gl"   '(:ignore t :which-key "log")
  "glc" 'magit-log-current
  "glf" 'magit-log-buffer-file
  "gb"  'magit-branch
  "gP"  'magit-push-current
  "gp"  'magit-pull-branch
  "gf"  'magit-fetch
  "gF"  'magit-fetch-all
  "gr"  'magit-rebase)

(use-package magit-todos
  :after magit
  :config (magit-todos-mode 1)
  )
(use-package forge
  :after magit)
;; need to set up

;; little tooltip for commit messages on each line.
(use-package popup)
(use-package git-messenger
  :after popup
  :bind (("C-x v m" . git-messenger:popup-message))
  :init
  (setq git-messenger:use-magit-popup t))

;; shadow base on edit date
(use-package smeargle
  :bind (("C-x v s" . smeargle)
         ("C-x v c" . smeargle-commits))
  :hook ((find-file-hook . smeargle)
         (after-save-hook .smeargle))
  :init
  (setq smeargle-colors '((older-than-1day   . "red")
                          (older-than-3day   . "green")
                          (older-than-1week  . "yellow")
                          (older-than-2week  . "brown")
                          (older-than-1month . "orange")
                          (older-than-3month . "pink")
                          (older-than-6month . "cyan")
                          (older-than-1year . "grey50"))))

(use-package orgit)

;; colorfull commits in the diff view buffers
(use-package magit-delta
  :after magit
  :hook (magit-mode-hook . magit-delta-mode))

Git Gutter

(use-package git-gutter
  :hook (prog-mode . git-gutter-mode)
  :config
  (setq git-gutter:update-interval 0.02))

(use-package git-gutter-fringe
  :config
  (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 [128 192 224 240] nil nil 'bottom))
(define-fringe-bitmap 'git-gutter-fr:added [#b11100000] nil nil '(center repeated))
(define-fringe-bitmap 'git-gutter-fr:modified [#b11100000] nil nil '(center repeated))
(define-fringe-bitmap 'git-gutter-fr:deleted
  [#b10000000
   #b11000000
   #b11100000
   #b11110000] nil nil 'bottom)

Dired

(use-package all-the-icons-dired)
(use-package dired
  :ensure nil
  :straight nil
  :defer 1
  :commands (dired dired-jump)
  :config
  ;; (setq dired-listing-switches "-agho --group-directories-first"
  ;;       dired-omit-files "^\\.[^.].*"
  ;;       dired-omit-verbose nil
  ;;       dired-hide-details-hide-symlink-targets nil
  ;;       delete-by-moving-to-trash t)

  (autoload 'dired-omit-mode "dired-x")

  (add-hook 'dired-load-hook
            (lambda ()
              (interactive)
              (dired-collapse)))

  (add-hook 'dired-mode-hook
            (lambda ()
              (interactive)
              (dired-omit-mode 1)
              (dired-hide-details-mode 1)
              (all-the-icons-dired-mode 1))
              (hl-line-mode 1))

  (use-package dired-rainbow
    :defer 2
    :config
    (dired-rainbow-define-chmod directory "#6cb2eb" "d.*")
    (dired-rainbow-define html "#eb5286" ("css" "less" "sass" "scss" "htm" "html" "jhtm" "mht" "eml" "mustache" "xhtml"))
    (dired-rainbow-define xml "#f2d024" ("xml" "xsd" "xsl" "xslt" "wsdl" "bib" "json" "msg" "pgn" "rss" "yaml" "yml" "rdata"))
    (dired-rainbow-define document "#9561e2" ("docm" "doc" "docx" "odb" "odt" "pdb" "pdf" "ps" "rtf" "djvu" "epub" "odp" "ppt" "pptx"))
    (dired-rainbow-define markdown "#ffed4a" ("org" "etx" "info" "markdown" "md" "mkd" "nfo" "pod" "rst" "tex" "textfile" "txt"))
    (dired-rainbow-define database "#6574cd" ("xlsx" "xls" "csv" "accdb" "db" "mdb" "sqlite" "nc"))
    (dired-rainbow-define media "#de751f" ("mp3" "mp4" "mkv" "MP3" "MP4" "avi" "mpeg" "mpg" "flv" "ogg" "mov" "mid" "midi" "wav" "aiff" "flac"))
    (dired-rainbow-define image "#f66d9b" ("tiff" "tif" "cdr" "gif" "ico" "jpeg" "jpg" "png" "psd" "eps" "svg"))
    (dired-rainbow-define log "#c17d11" ("log"))
    (dired-rainbow-define shell "#f6993f" ("awk" "bash" "bat" "sed" "sh" "zsh" "vim"))
    (dired-rainbow-define interpreted "#38c172" ("py" "ipynb" "rb" "pl" "t" "msql" "mysql" "pgsql" "sql" "r" "clj" "cljs" "scala" "js"))
    (dired-rainbow-define compiled "#4dc0b5" ("asm" "cl" "lisp" "el" "c" "h" "c++" "h++" "hpp" "hxx" "m" "cc" "cs" "cp" "cpp" "go" "f" "for" "ftn" "f90" "f95" "f03" "f08" "s" "rs" "hi" "hs" "pyc" ".java"))
    (dired-rainbow-define executable "#8cc4ff" ("exe" "msi"))
    (dired-rainbow-define compressed "#51d88a" ("7z" "zip" "bz2" "tgz" "txz" "gz" "xz" "z" "Z" "jar" "war" "ear" "rar" "sar" "xpi" "apk" "xz" "tar"))
    (dired-rainbow-define packaged "#faad63" ("deb" "rpm" "apk" "jad" "jar" "cab" "pak" "pk3" "vdf" "vpk" "bsp"))
    (dired-rainbow-define encrypted "#ffed4a" ("gpg" "pgp" "asc" "bfe" "enc" "signature" "sig" "p12" "pem"))
    (dired-rainbow-define fonts "#6cb2eb" ("afm" "fon" "fnt" "pfb" "pfm" "ttf" "otf"))
    (dired-rainbow-define partition "#e3342f" ("dmg" "iso" "bin" "nrg" "qcow" "toast" "vcd" "vmdk" "bak"))
    (dired-rainbow-define vc "#0074d9" ("git" "gitignore" "gitattributes" "gitmodules"))
    (dired-rainbow-define-chmod executable-unix "#38c172" "-.*x.*"))

  (use-package dired-single
    :defer t)

  (use-package dired-ranger
    :defer t)

  (use-package dired-collapse
    :defer t)

  (evil-collection-define-key 'normal 'dired-mode-map
    "h" 'dired-single-up-directory
    "H" 'dired-omit-mode
    "l" 'dired-single-buffer
    "y" 'dired-ranger-copy
    "d" 'dired-ranger-move
    "p" 'dired-ranger-paste))

  ;; (defun em/dired-link (path)
  ;;   (lexical-binding ((target path))
  ;;    (lambda () (interactive) (message "Path: %s" target) (dired target))))

  ;; (evil/leader-keys
  ;;  "d"   '(:ignore t :which-key "dired")
  ;;   "dd"  '(dired :which-key "Here")
  ;;   "dh"  `(,(em/dired-link "~") :which-key "Home")
  ;;   "dn"  `(,(em/dired-link "~/Desktop") :which-key "Desktop")
  ;;   "db"   ((em/dired-link "~/Desktop/books/"):which-key "Books")
  ;;   "do"  `(,(em/dired-link "~/Downloads") :which-key "Downloads")
  ;;   "d."  `(,(em/dired-link "~/repos/.dotfiles") :which-key "dotfiles"))
  ;;   "de"  `(,(em/dired-link "~/.config/emacs") :which-key ".emacs.d"))

(setq dired-recursive-copies 'top)

(setq dired-recursive-deletes 'top)
(setq dired-dwim-target t)

;; (use-package dired-plus)

Wiki

Search org roam directory with ripgrep. Two ways to do this.

;; (global-set-key (kbd "C-c w") (consult-ripgrep "~/Desktop/repos/braindump"))

(defun sh/search-braindump()
  (interactive)
(let ((default-directory "~/Desktop/repos/braindump"))
  (consult-ripgrep)
  ))
(global-set-key (kbd "C-c w") 'sh/search-braindump)

Workspace

(global-set-key (kbd "M-n") 'forward-paragraph)
(global-set-key (kbd "M-p") 'backward-paragraph)

Subword

Subword mode for camelCase and snakecase usgae.

(subword-mode 1)

Buffer

Projectile will take care of the project buffers. But I need something to work on non project things. Like when I am not in project mode and and just opening a file. I need the old buffer system of emacs.

(global-unset-key (kbd "C-x l"))

Perspective

(use-package perspective
  :init
  (setq-default persp-suppress-no-prefix-key-warning t)
  (persp-mode)
  (persp-turn-on-modestring))

(global-set-key (kbd "C-M-i") 'persp-switch-last)

(defun persp1()
  (interactive)
  (persp-switch-by-number 1))

(defun persp2()
  (interactive)
  (persp-switch-by-number 2))

(defun persp3()
  (interactive)
  (persp-switch-by-number 3))

(defun persp4()
  (interactive)
  (persp-switch-by-number 4))

(global-set-key (kbd "M-1") 'persp1)
(global-set-key (kbd "M-2") 'persp2)
(global-set-key (kbd "M-3") 'persp3)
(global-set-key (kbd "M-4") 'persp4)

Projectile

  (defun em/switch-project-action ()
    "Switch to a workspace with the project name and start `magit-status'."
    (persp-switch (projectile-project-name))
    (magit-status))

  (defun sh/projectile-reset-nd-switch()
    (interactive)
    (projectile-reset-known-projects)
    (projectile-switch-project))

  (use-package projectile
    :config (projectile-mode)
    :demand t
    :bind-keymap
    ("C-c p" . projectile-command-map)
    ;; ("C-x ;" . projectile-find-file)
    :bind
    ;; (:map projectile-mode-map
          ;; ("p" . sh/projectile-reset-nd-swtich))
          ;; ("p" . self-insert-command))
    :init
    (setq projectile-track-down-projects-automatically nil)
    (when (file-directory-p "~/Desktop/projects/")
      (setq projectile-project-search-path '("~/Desktop/projects/")))
    (setq projectile-switch-project-action #'em/switch-project-action))

  ;; add another project search path
  (when (file-directory-p "~/Desktop/blog/")
  (add-to-list 'projectile-project-search-path "~/Desktop/blog/"))

  (when (file-directory-p "~/Desktop/jobs/")
  (add-to-list 'projectile-project-search-path "~/Desktop/jobs/"))



(when (file-directory-p "~/Desktop/experiment/")
  (add-to-list 'projectile-project-search-path "~/Desktop/experiment/"))


  ;; for re-discovering projects at runtime
  (define-key projectile-command-map (kbd "p") 'sh/projectile-reset-nd-switch)

  ;; (defun sh/projectile-shell-pop()
  ;; (interactive)
  ;; (setq shell-pop-default-direcotry (projectile-project-root))
  ;; (shell-pop (vc-root-dir)))

  ;; (define-key projectile-command-map (kbd "t") 'sh/projectile-shell-pop)

  ;; (let ((buffer (get-buffer "fname")))
  ;;   (when buffer
  ;;     (with-current-buffer buffer
  ;;       (vc-root-dir))))

  (defun sh/close-project()
    (interactive)
    (persp-kill (persp-current-name))
    )

  (define-key projectile-command-map (kbd "q") 'sh/close-project)
(global-set-key (kbd "C-x f") 'project-find-file)
(advice-add 'projectile-find-file-other-window :around #'split-side-by-side)
(advice-add 'projectile-find-file-dwim-other-window :around #'split-side-by-side)
(global-set-key (kbd "C-c l") 'consult-locate)
(global-set-key (kbd "C-c f") 'consult-flymake)

Treemacs

(use-package treemacs
  :ensure t
  :defer t
  :init
  (with-eval-after-load 'winum
    (define-key winum-keymap (kbd "M-0") #'treemacs-select-window))
  :config
  (progn
    (setq treemacs-collapse-dirs                   (if treemacs-python-executable 3 0)
          treemacs-deferred-git-apply-delay        0.5
          treemacs-directory-name-transformer      #'identity
          treemacs-display-in-side-window          t
          treemacs-eldoc-display                   'simple
          treemacs-file-event-delay                2000
          treemacs-file-extension-regex            treemacs-last-period-regex-value
          treemacs-file-follow-delay               0.2
          treemacs-file-name-transformer           #'identity
          treemacs-follow-after-init               t
          treemacs-expand-after-init               t
          treemacs-find-workspace-method           'find-for-file-or-pick-first
          treemacs-git-command-pipe                ""
          treemacs-goto-tag-strategy               'refetch-index
          treemacs-header-scroll-indicators        '(nil . "^^^^^^")
          treemacs-hide-dot-git-directory          t
          treemacs-indentation                     2
          treemacs-indentation-string              " "
          treemacs-is-never-other-window           nil
          treemacs-max-git-entries                 5000
          treemacs-missing-project-action          'ask
          treemacs-move-forward-on-expand          nil
          treemacs-no-png-images                   nil
          treemacs-no-delete-other-windows         t
          treemacs-project-follow-cleanup          nil
          treemacs-persist-file                    (expand-file-name ".cache/treemacs-persist" user-emacs-directory)
          treemacs-position                        'left
          treemacs-read-string-input               'from-child-frame
          treemacs-recenter-distance               0.1
          treemacs-recenter-after-file-follow      nil
          treemacs-recenter-after-tag-follow       nil
          treemacs-recenter-after-project-jump     'always
          treemacs-recenter-after-project-expand   'on-distance
          treemacs-litter-directories              '("/node_modules" "/.venv" "/.cask")
          treemacs-project-follow-into-home        nil
          treemacs-show-cursor                     nil
          treemacs-show-hidden-files               t
          treemacs-silent-filewatch                nil
          treemacs-silent-refresh                  nil
          treemacs-sorting                         'alphabetic-asc
          treemacs-select-when-already-in-treemacs 'move-back
          treemacs-space-between-root-nodes        t
          treemacs-tag-follow-cleanup              t
          treemacs-tag-follow-delay                1.5
          treemacs-text-scale                      nil
          treemacs-user-mode-line-format           nil
          treemacs-user-header-line-format         nil
          treemacs-wide-toggle-width               70
          treemacs-width                           35
          treemacs-width-increment                 1
          treemacs-width-is-initially-locked       t
          treemacs-workspace-switch-cleanup        nil)

    ;; The default width and height of the icons is 22 pixels. If you are
    ;; using a Hi-DPI display, uncomment this to double the icon size.
    ;;(treemacs-resize-icons 44)

    (treemacs-follow-mode t)
    (treemacs-filewatch-mode t)
    (treemacs-fringe-indicator-mode 'always)
    (when treemacs-python-executable
      (treemacs-git-commit-diff-mode t))

    (pcase (cons (not (null (executable-find "git")))
                 (not (null treemacs-python-executable)))
      (`(t . t)
       (treemacs-git-mode 'deferred))
      (`(t . _)
       (treemacs-git-mode 'simple)))

    (treemacs-hide-gitignored-files-mode nil))
  ;; :bind
  ;; (:map global-map
  ;;       ("M-0"       . treemacs-select-window)
  ;;       ("C-x t 1"   . treemacs-delete-other-windows)
  ;;       ("C-x t t"   . treemacs)
  ;;       ("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-projectile
  :after (treemacs projectile)
  :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 treemacs-persp ;;treemacs-perspective if you use perspective.el vs. persp-mode
  :after (treemacs persp-mode) ;;or perspective vs. persp-mode
  :ensure t
  :config (treemacs-set-scope-type 'Perspectives))

(use-package treemacs-tab-bar ;;treemacs-tab-bar if you use tab-bar-mode
  :after (treemacs)
  :ensure t
  :config (treemacs-set-scope-type 'Tabs))

  (with-eval-after-load 'treemacs
    (treemacs-resize-icons 15))

Window

Golden ratio for automatic window resizing.

(use-package golden-ratio
:config
(golden-ratio-mode 1))

(global-set-key (kbd "C-+") 'text-scale-increase)
(global-set-key (kbd "C-=") 'text-scale-adjust)
(global-set-key (kbd "C--") 'text-scale-increase)

Ace Window

(use-package ace-window
  :config
(setq aw-ignore-current t)
  )
(global-set-key (kbd "C-x o") 'ace-window)

Window history with winner.

(use-package winner
  :after evil
  :config
  (winner-mode)
  (define-key evil-window-map "u" 'winner-undo)
  (define-key evil-window-map "U" 'winner-redo))

Calendar

calfw is a gorgeous calendar UI that is able to show all of my scheduled Org Agenda items.

(use-package calfw
  :commands cfw:open-org-calendar
  :config
  (setq cfw:fchar-junction ?╋
        cfw:fchar-vertical-line ?┃
        cfw:fchar-horizontal-line ?━
        cfw:fchar-left-junction ?┣
        cfw:fchar-right-junction ?┫
        cfw:fchar-top-junction ?┯
        cfw:fchar-top-left-corner ?┏
        cfw:fchar-top-right-corner ?┓)

  (use-package calfw-org
    :config
    (setq cfw:org-agenda-schedule-args '(:timestamp))))

(evil/leader-keys
  "cc"  '(cfw:open-org-calendar :which-key "calendar"))

Indent style


(use-package highlight-indent-guides
  :init (setq highlight-indent-guides-method 'character)
        (setq highlight-indent-guides-responsive 'stack)
  :hook (prog-mode . highlight-indent-guides-mode))

Bookmark

(use-package bookmark+)

(global-set-key (kbd "C-w") 'evil-window-map)
(global-set-key (kbd "C-w") 'evil-window-map)
(global-set-key (kbd "C-x C-r") 'consult-recent-file)
(define-key evil-window-map (kbd "r") 'bmkp-desktop-jump)
(define-key evil-window-map (kbd "d") 'bmkp-desktop-delete)
(define-key evil-window-map (kbd "a") 'bmkp-set-desktop-bookmark)
(define-key evil-window-map (kbd "q") 'delete-other-windows)
(define-key evil-window-map (kbd "p") 'projectile-find-file-dwim-other-window)
(define-key evil-window-map (kbd "q") 'evil-window-delete)
;; (define-key evil-normal-state-map (kbd "C-x r") 'consult-recent-file)
;; Auto save bookmark
(setq bookmark-save-flag 1)

(use-package goto-chg
  :bind (
         ("M-k" . goto-last-change)
         ("M-j" . goto-last-change-reverse)
         ))


(use-package bm
         :ensure t
         :demand t

         :init
         ;; restore on load (even before you require bm)
         (setq bm-restore-repository-on-load t)


         :config
         ;; Allow cross-buffer 'next'
         (setq bm-cycle-all-buffers t)

         ;; where to store persistant files
         (setq bm-repository-file "~/.emacs.d/bm-repository")

         ;; save bookmarks
         (setq-default bm-buffer-persistence t)

         ;; Loading the repository from file when on start up.
         (add-hook 'after-init-hook 'bm-repository-load)

         ;; Saving bookmarks
         (add-hook 'kill-buffer-hook #'bm-buffer-save)

         ;; Saving the repository to file when on exit.
         ;; kill-buffer-hook is not called when Emacs is killed, so we
         ;; must save all bookmarks first.
         (add-hook 'kill-emacs-hook #'(lambda nil
                                          (bm-buffer-save-all)
                                          (bm-repository-save)))

         ;; The `after-save-hook' is not necessary to use to achieve persistence,
         ;; but it makes the bookmark data in repository more in sync with the file
         ;; state.
         (add-hook 'after-save-hook #'bm-buffer-save)

         ;; Restoring bookmarks
         (add-hook 'find-file-hooks   #'bm-buffer-restore)
         (add-hook 'after-revert-hook #'bm-buffer-restore)

         ;; The `after-revert-hook' is not necessary to use to achieve persistence,
         ;; but it makes the bookmark data in repository more in sync with the file
         ;; state. This hook might cause trouble when using packages
         ;; that automatically reverts the buffer (like vc after a check-in).
         ;; This can easily be avoided if the package provides a hook that is
         ;; called before the buffer is reverted (like `vc-before-checkin-hook').
         ;; Then new bookmarks can be saved before the buffer is reverted.
         ;; Make sure bookmarks is saved before check-in (and revert-buffer)
         (add-hook 'vc-before-checkin-hook #'bm-buffer-save)


         :bind (
                ;; ("M-j" . bm-next)
                ;; ("M-k" . bm-previous)
                ("M-h" . bm-toggle))
         ("M-l" . bm-show-all)
         )

Folding

Use hideshow minor mode for this.

(use-package origami
  :config
  (global-origami-mode 1))

(use-package vimish-fold
  :bind (("C-x w" . vimish-fold)
         ("C-x y" . vimish-fold-delete-all)))

Register

C-c C-c uses mode-specific-command-prefix. It can be used to bind other keymaps prefix. Because it doesn’t do anything by itself.

  (global-unset-key (kbd "C-q"))
(global-unset-key (kbd "C-r"))
(define-key evil-normal-state-map (kbd "C-r") 'nil)
(global-set-key (kbd "C-r") 'mode-specific-command-prefix)
  ;; (global-set-key (kbd "C-r r") 'point-to-register)
  ;; (global-set-key (kbd "C-r w") 'window-configuration-to-register)
  ;; (global-set-key (kbd "C-r e") 'copy-to-register)

(global-set-key (kbd "C-r r") 'recentf)

Avy

(use-package goto-last-change)
(use-package avy
  :config
  (global-set-key (kbd "M-o") 'avy-goto-char-timer)
)

Shell

emacs-eat is a terminal emaulator wrapper.

(straight-use-package
 '(eat :type git
       :host codeberg
       :repo "akib/emacs-eat"
       :files ("*.el" ("term" "term/*.el") "*.texi"
               "*.ti" ("terminfo/e" "terminfo/e/*")
               ("terminfo/65" "terminfo/65/*")
               ("integration" "integration/*")
               (:exclude ".dir-locals.el" "*-tests.el"))))
;; ansi term colors
(add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)
(global-set-key (kbd "C-M-i") 'persp-switch-last)
(global-set-key (kbd "C-w") 'evil-window-map)

(use-package vterm
  :commands vterm
:bind (:map vterm-mode-map
            ("M-1" . persp1)
            ("M-2" . persp2)
            ("M-3" . persp3)
            ("M-4" . persp4)
            ("C-M-i" . persp-switch-last)
("C-w" . nil)
            ("C-w" . evil-window-mode-map)
            )
  :config
  (setq vterm-max-scrollback 10000))
(use-package shell-pop
  :bind (("C-t" . shell-pop))
  :custom
  (setq shell-pop-autocd-to-working-directory nil)
  (setq shell-pop-shell-type (quote ("vterm" "*vterm*" (lambda nil (vterm shell-pop-term-shell)))))
  (setq shell-pop-set-internal-mode "vterm")
  (setq shell-pop-term-shell "/bin/zsh")
  ;; need to do this manually or not picked up by `shell-pop'
  (shell-pop--set-shell-type 'shell-pop-shell-type shell-pop-shell-type))

(defun sh/shell-pop-setup()
 "Changes shell pop directory to projectile root on pop in"
  (interactive)
  (setq-local shell-pop-default-directory (projectile-project-root)))

;; (add-hook 'shell-pop-in-hook #'shell-pop-setup)
(setq shell-pop-internal-mode (quote ("shell" "*shell*" (lambda () (projectile-project-root)))))
(setq shell-pop-cleanup-buffer-at-process-exit t)


(defun my-update-shell-pop-project ()
  "Update Shell Pop configuration based on the current Projectile project."
  (setq shell-pop-internal-mode
        `(,(intern (if (projectile-project-p)
                        "projectile"
                      "shell"))
          "*Shell Pop*"
          ,(lambda () (projectile-project-root)))))

(add-hook 'projectile-after-switch-project-hook #'my-update-shell-pop-project)

Tools

Restclient

(use-package restclient)
(use-package ob-restclient)

Docker


;; for managing docker within emacs
(use-package docker
  :ensure t
  :bind ("C-c d" . docker))

;; for dockerfile
(use-package dockerfile-mode)
(use-package docker-compose-mode)
(use-package ob-docker-build
  :ensure t
  :defer t
  :straight (ob-docker-build :type git
                             :host github
                             :repo "ifitzpat/ob-docker-build")
  :config
  (add-to-list 'org-babel-load-languages '(docker-build . t))
  (org-babel-do-load-languages 'org-babel-load-languages org-babel-load-languages)
)

Live Reload

For live reloading of the files Impatient-mode is amazing. You just need to install two packages. After that you enable impatient mode on html files and additional css files and go to localhost:8080/imp/ and select the buffer you want to edit. And it’s that easy. Just start httpd-start before doing any of this.

(use-package simple-httpd)
;; (use-package js2-mode)
;; (use-package skewer-mode)
;; (add-hook 'js2-mode-hook 'skewer-mode)
;; (add-hook 'css-mode-hook 'skewer-css-mode)
;; (add-hook 'html-mode-hook 'skewer-html-mode)


(use-package impatient-mode)

Elfeed

(use-package elfeed
  :commands elfeed
  :config
  (setq elfeed-feeds
    '("https://nullprogram.com/feed/"
      "https://ambrevar.xyz/atom.xml"
      "https://guix.gnu.org/feeds/blog.atom"
      "https://valdyas.org/fading/feed/"
      "https://www.reddit.com/r/emacs/.rss")))

Pdf viewer

(use-package pdf-tools
  :defer t
  ; :init   (system-packages-ensure "pdf-tools")
  :custom (pdf-tools-handle-upgrades nil)
          (pdf-info-epdfinfo-program "/usr/local/bin/epdfinfo")
  :config (pdf-tools-install))

Sauron

Sauron mode for managing emacs notifications.

(use-package sauron)

IRC

Internet Relay Chat.

(defvar weechat-formatting-regex
  (rx-let ((attr (in "*!/_|"))   ;NOTE:  is not documented
         (std  (= 2 digit))
         (astd (seq attr (= 2 digit)))
         (ext  (seq "@" (= 5 digit)))
         (aext (seq "@" attr (= 5 digit))))
    (rx
     (or (seq ""
               (or std
                   ext
                   (seq "F" (or std astd ext aext))
                   (seq "B" (or std ext))
                   (seq "*" (or std
                                astd
                                ext
                                aext
                                (seq (or std astd ext aext)
                                     ","
                                     (or std astd ext aext))))
                   (seq "b" (in "-FDB#_il"))
                   ""))
          (seq "" attr)
          (seq "" attr)
          ""))))

(use-package weechat)
(use-package circe)

(setq circe-network-options
      '(("Libera"
         :tls t
         :nick "testing"
         :sasl-username "testing"
         :sasl-password "my-password"
         :channels ("#emacs-circe","#emacs")
         )))

Keycast

To show which keys you’re pressing right now. Taken from emacswiki.

    ;; (keycast-tab-bar-mode 1)
    ;; (keycast-log-mode 1)

  (use-package keycast
    :init
    (add-to-list 'global-mode-string '("" mode-line-keycast))
    )

Watch mode

Works with activity watcher. Great for tracking user activity.

(use-package activity-watch-mode)
(global-activity-watch-mode 1)

OrgMode

(use-package hl-todo)
(setq hl-todo-keyword-faces
      '(("TODO"   . "#FF0000")
        ("FIXME"  . "#FF0000")
        ("DEBUG"  . "#A020F0")
        ("GOTCHA" . "#FF4500")
        ("STUB"   . "#1E90FF")))
;; (use-package fixme-mode)
;; (use-package wcheck-mode)

Appearance

org-hidden-keywords org-hide-leading-stars

org-fontify-todo-headline org-fontify-done-headline org highlight latex and related org hide macro markers

(straight-use-package '(org-appear :type git :host github :repo "awth13/org-appear"))

(add-hook 'org-mode-hook 'org-appear-mode)


(setq org-appear-trigger 'manual)
(add-hook 'org-mode-hook (lambda ()
                           (add-hook 'evil-insert-state-entry-hook
                                     #'org-appear-manual-start
                                     nil
                                     t)
                           (add-hook 'evil-insert-state-exit-hook
                                     #'org-appear-manual-stop
                                     nil
                                     t)))


(setq org-return-follows-link t
      org-use-speed-commands t
      org-deadline-warning-days 7
      org-fontify-todo-headline t
      org-hide-leading-stars t
      )

(defvar my-org-hidden-keywords
  '(title author date email tags options))

(defun org-hide-keywords ()
  (save-excursion
    (let (beg end ov)
      (goto-char (point-min))
      (while (re-search-forward
              (concat "\\(^[ \t]*#\\+\\)\\("
                      (mapconcat (lambda (kw)
                                   (format "%s:\s"(symbol-name kw)))
                                 my-org-hidden-keywords "\\|")
                      "\\)")
              nil t)
        (setq beg (match-beginning 1)
              end (match-end 2)
              ov  (make-overlay beg end))
    (overlay-put ov 'invisible t)))))

(add-hook 'org-mode-hook 'org-hide-keywords)

(setq org-startup-indented t
      org-bullets-bullet-list '(" ") ;; no bullets, needs org-bullets package
      org-ellipsis "  " ;; folding symbol
      org-pretty-entities t
      org-hide-emphasis-markers t
      ;; show actually italicized text instead of /italicized text/
      ;; org-agenda-block-separator ""
      org-fontify-whole-heading-line t
      org-fontify-done-headline t
      org-fontify-quote-and-verse-blocks t)
(lambda () (progn
  (setq left-margin-width 8)
  (setq right-margin-width 8)
  (set-window-buffer nil (current-buffer))))
(setq header-line-format " ")

Agenda

(setq org-todo-keywords
  '((sequence "TODO(t)" "NEXT(n)" "|" "DONE(d!)")
    (sequence "BACKLOG(b)" "IDEA(i)" "PLAN(p)" "READY(r)" "ACTIVE(a)" "REVIEW(v)" "WAIT(w@/!)" "HOLD(h)" "|" "COMPLETED(c)" "CANC(k@)")))

(setq org-agenda-start-with-log-mode t)
(setq org-log-done 'time)
(setq org-log-into-drawer t)
(global-set-key (kbd "C-c a") 'org-agenda)
(global-set-key (kbd "C-c t") 'consult-org-agenda)

;; (setq org-directory "~/Desktop/tasks")
;; (setq org-agenda-files '("tasks.org" "personal.org" "busineess.org"))
(setq org-agenda-files '("~/Desktop/org/"))


(defun air-org-skip-subtree-if-priority (priority)
  "Skip an agenda subtree if it has a priority of PRIORITY.

PRIORITY may be one of the characters ?A, ?B, or ?C."
  (let ((subtree-end (save-excursion (org-end-of-subtree t)))
        (pri-value (* 1000 (- org-lowest-priority priority)))
        (pri-current (org-get-priority (thing-at-point 'line t))))
    (if (= pri-value pri-current)
        subtree-end
      nil)))

(defun air-org-skip-subtree-if-habit ()
  "Skip an agenda entry if it has a STYLE property equal to \"habit\"."
  (let ((subtree-end (save-excursion (org-end-of-subtree t))))
    (if (string= (org-entry-get nil "STYLE") "habit")
        subtree-end
      nil)))
;; Configure custom agenda views
(setq org-agenda-custom-commands
  '(("s" "Simple agenda view"
         ((tags "PRIORITY=\"A\""
                ((org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
                 (org-agenda-overriding-header "High-priority unfinished tasks:")))
          (todo "ACTIVE" ((org-agenda-overriding-header "Active:")))
          (todo "NEXT" ((org-agenda-overriding-header "Actions:")))
          (agenda "" ((org-deadline-warning-days 7)))
          (alltodo "")))

    ;; ("d" "Dashboard"
    ;; ;; ( (agenda "" ((org-deadline-warning-days 7)))
    ;;   ((alltodo " ")
    ;;   (todo "NEXT"
    ;;     ((org-agenda-overriding-header "Next Tasks")))
    ;;   (tags-todo "agenda/ACTIVE" ((org-agenda-overriding-header "Active Projects")))))
    ("i" "Ideas"
     ((todo "IDEA"
            ((org-agenda-overriding-header "Ideas")))))

    ("n" "Next Actions"
     ((todo "NEXT"
        ((org-agenda-overriding-header "Next Tasks")))))

    ;; ("W" "Work Tasks" tags-todo "+work")

    ;; ;; Low-effort next actions
    ;; ("e" tags-todo "+TODO=\"NEXT\"+Effort<15&+Effort>0"
    ;;  ((org-agenda-overriding-header "Low Effort Tasks")
    ;;   (org-agenda-max-todos 20)
    ;;   (org-agenda-files org-agenda-files)))

    ("w" "Workflow Status"
     ((todo "WAIT"
            ((org-agenda-overriding-header "Waiting on External")
             (org-agenda-files org-agenda-files)))
      (todo "REVIEW"
            ((org-agenda-overriding-header "In Review")
             (org-agenda-files org-agenda-files)))
      (todo "PLAN"
            ((org-agenda-overriding-header "In Planning")
             (org-agenda-todo-list-sublevels nil)
             (org-agenda-files org-agenda-files)))
      (todo "BACKLOG"
            ((org-agenda-overriding-header "Project Backlog")
             (org-agenda-todo-list-sublevels nil)
             (org-agenda-files org-agenda-files)))
      (todo "READY"
            ((org-agenda-overriding-header "Ready for Work")
             (org-agenda-files org-agenda-files)))
      (todo "ACTIVE"
            ((org-agenda-overriding-header "Active Projects")
             (org-agenda-files org-agenda-files)))
      (todo "COMPLETED"
            ((org-agenda-overriding-header "Completed Projects")
             (org-agenda-files org-agenda-files)))
      (todo "CANC"
            ((org-agenda-overriding-header "Cancelled Projects")
             (org-agenda-files org-agenda-files)))))))


(setq org-refile-targets
      '(("Archive.org" :maxlevel . 1)))

;; Save Org buffers after refiling!
(advice-add 'org-refile :after 'org-save-all-org-buffers)

Capture

(setq org-default-directory "~/Desktop/org")
(setq org-directory "~/Desktop/org")
(setq org-default-notes-file (concat org-directory "/notes.org"))

 (setq org-capture-templates
           '(("t" "Todo" entry (file "~/Desktop/org/gtd.org")
              "* TODO %?\n  %i\n  %a")
             ("p" "Personal" entry (file "~/Desktop/org/personal.org") "* TODO %?\nCreated At: %U\n %i")
             ("l" "Learn" entry (file "~/Desktop/org/learn.org") "* TODO %?\nCreated At: %U\n %i")
             ("b" "Business" entry (file "~/Desktop/org/business.org") "* TODO %?\nCreated At: %U\n %i")
             ("n" "Notes" entry (file "~/Desktop/org/notes.org") "* %?\nCreated At: %U\n %i")
             ("c" "Capture" entry (file "~/Desktop/org/capture.org") "* %?\nCreated At: %u\n %i %a")
             ("i" "Idea" entry (file "~/Desktop/org/ideas.org") "* IDEA %?\nCreated At: %U\n %a")
             ("w" "work/jobs" entry (file "~/Desktop/org/jobs.org") "* TODO [#A] %?\nCreated At: %U\n")
             ("j" "Journal" entry (file+datetree "~/Desktop/org/journal.org")
              "* %?\nEntered on %U\n  %i\n  %a")))

(global-set-key (kbd "C-c c") 'org-capture)

Org Refile

Organize your files into files after taking notes quickly.

(setq org-refile-targets '((org-agenda-files :maxlevel . 3)))

Org alert

Org alert is good for simplicity. But Org notifier is really good.

(use-package org-alert
  :custom
  (alert-default-style 'notifications)
  :config
  (setq org-alert-interval 1800
        org-alert-notification-title "Agenda Reminder!!")
  (org-alert-enable))

You can add notify add which can be used with property drawer.

(use-package org
  :ensure org-plus-contrib)

(use-package org-notify
  :after org
  :config
  (org-notify-start)

  (org-notify-add
   'rem '(:time "3d" :actions -notify/window
                     :period "5s" :duration 10800)
   'imp '(:time "1d" :actions -notify/window
                      :preriod "10s" :duration 3600)
   'default '(:time "1h" :actions -notify/window
                :period "10s" :duration 600)
   ))

UI

(setq org-hide-emphasis-markers t)
(add-hook 'org-mode-hook (lambda ()
                           "Beautify Org Checkbox Symbol"
                           (push '("[ ]" .  "☐") prettify-symbols-alist)
                           (push '("[X]" . "☑" ) prettify-symbols-alist)
                           (push '("[-]" . "❍" ) prettify-symbols-alist)
                           (push '("#+BEGIN_SRC" . "↦" ) prettify-symbols-alist)
                           (push '("#+END_SRC" . "⇤" ) prettify-symbols-alist)
                           (push '("#+BEGIN_EXAMPLE" . "↦" ) prettify-symbols-alist)
                           (push '("#+END_EXAMPLE" . "⇤" ) prettify-symbols-alist)
                           (push '("#+BEGIN_QUOTE" . "" ) prettify-symbols-alist)
                           (push '("#+END_QUOTE" . "" ) prettify-symbols-alist)
                           (push '("#+begin_quote" . "" ) prettify-symbols-alist)
                           (push '("#+end_quote" . "" ) prettify-symbols-alist)
                           (push '("#+begin_example" . "↦" ) prettify-symbols-alist)
                           (push '("#+end_example" . "⇤" ) prettify-symbols-alist)
                           (push '("#+begin_src" . "↦" ) prettify-symbols-alist)
                           (push '("#+end_src" . "⇤" ) prettify-symbols-alist)
                           (prettify-symbols-mode)))



(font-lock-add-keywords 'org-mode
                        '(("^ +\\([-*]\\) "
                           (0 (prog1 () (compose-region (match-beginning 1) (match-end 1) "•"))))))

(add-hook 'org-mode-hook 'variable-pitch-mode)
(add-hook 'org-mode-hook 'visual-line-mode)


(setq org-startup-indented t
      org-src-tab-acts-natively t)

Heading colors

(defun col-strip (col-str)
    (butlast (split-string (mapconcat (lambda (x) (concat "#" x " "))
                                      (split-string col-str "-")
                                      "") " ")))

  (setq color-schemes (list
                       (col-strip "AAADC4-EEC584-D6EEFF-EDF060-56cb7d-df5252-707efa") ; red blue purple study
                       (col-strip "2278bf-e15554-3bb273-507c6d-6e5775-598d91-7768ae") ; blue red green okay
                       ))
  (setq pick-color 0)
   (setq color-theme (nth pick-color color-schemes))


    (set-face-attribute 'org-level-1 nil
                        :height 1.3
                        :foreground (nth 0 color-theme))
    (set-face-attribute 'org-level-2 nil
                        :height 1.2
                        :foreground (nth 1 color-theme))
    (set-face-attribute 'org-level-3 nil
                        :height 1.1
                        :foreground (nth 2 color-theme))
    (set-face-attribute 'org-level-4 nil
                        :height 1.05
                        :foreground (nth 3 color-theme))
    (set-face-attribute 'org-level-5 nil
                        :foreground (nth 4 color-theme))
    (set-face-attribute 'org-level-6 nil
                        :foreground (nth 5 color-theme))

Font


  (use-package org
  :bind (("C-M-i" . nil)))


    (when (display-graphic-p)
    (let* ((variable-tuple (cond ((x-list-fonts "ETBookOT")   '(:font "ETBookOT"))
                                 ((x-list-fonts "Source Sans Pro") '(:font "Source Sans Pro"))
                                 ((x-list-fonts "Verdana")         '(:font "Verdana"))
                                 ((x-family-fonts "Sans Serif")    '(:family "Sans Serif"))
                                 (nil (warn "Cannot find a Sans Serif Font.  Install Source Sans Pro."))))
           (base-font-color     (face-foreground 'default nil 'default))
           (headline           `(:inherit default :weight bold :foreground ,base-font-color)))

      (custom-theme-set-faces 'user
                              `(org-level-4 ((t (,@headline ,@variable-tuple :height 1.1))))
                              `(org-level-3 ((t (,@headline ,@variable-tuple :height 1.15))))
                              `(org-level-2 ((t (,@headline ,@variable-tuple :height 1.20))))
                              `(org-level-1 ((t (,@headline ,@variable-tuple :height 1.25))))
                              `(org-document-title ((t (,@headline ,@variable-tuple :height 1.3 :underline nil))))))

    (use-package org-bullets
      :custom
      (org-bullets-bullet-list '( "●" "◯" "☉" "⊛"   ))
      (org-ellipsis " ▼")
      :hook (org-mode . org-bullets-mode))

    (custom-theme-set-faces
     'user
     '(variable-pitch ((t (:family "ETBembo" :height 180 :weight normal))))
     '(fixed-pitch ((t ( :family "Fira Code Retina" :height 150)))))

    (custom-theme-set-faces
     'user
     '(org-block ((t (:inherit fixed-pitch))))
     '(org-code ((t (:inherit (shadow fixed-pitch)))))
     '(org-document-info ((t (:foreground "dark orange"))))
     '(org-document-info-keyword ((t (:inherit (shadow fixed-pitch)))))
     '(org-indent ((t (:inherit (org-hide fixed-pitch)))))
     '(org-link ((t (:foreground "royal blue" :underline t))))
     '(org-meta-line ((t (:inherit (font-lock-comment-face fixed-pitch)))))
     '(org-property-value ((t (:inherit fixed-pitch))) t)
     '(org-special-keyword ((t (:inherit (font-lock-comment-face fixed-pitch)))))
     '(org-table ((t (:inherit fixed-pitch :foreground "#83a598"))))
     '(org-tag ((t (:inherit (shadow fixed-pitch) :weight bold :height 0.8))))
     '(org-verbatim ((t (:inherit (shadow fixed-pitch))))))

    (setq org-emphasis-alist
          (quote (("*" bold)
                  ("/" italic)
                  ("_" underline)
                  ("=" (:foreground "#616161" :background "#fff59d"))
                  ("~" org-verbatim verbatim)
                  ("+"
                   (:strike-through t))
                  )))
    )

Org Roam

(use-package org-roam
  :ensure t
  :init
  (setq org-roam-v2-ack t)
  :custom
  (org-roam-directory "~/Desktop/repos/braindump")
  (org-roam-dailies-directory "journal/")
  (org-roam-completion-everywhere nil)
  :bind (("C-c n l" . org-roam-buffer-toggle)
         ("C-c n f" . org-roam-node-find)
         ("C-c n i" . org-roam-node-insert)
         ("C-c n r" . org-roam-node-random)
         ;; :map org-mode-map
         ;; ("C-M-i" . completion-at-point)
         :map org-roam-dailies-map
         ("Y" . org-roam-dailies-capture-yesterday)
         ("T" . org-roam-dailies-capture-tomorrow)
         )
  :bind-keymap
  ("C-c n d" . org-roam-dailies-map)
  :config
  (require 'org-roam-dailies)
  (org-roam-db-autosync-mode)
  ;; (setq org-roam-database-connector 'sqlite3)
  (org-roam-setup))

Org Roam UI

(use-package org-roam-ui
  :straight
  (:host github :repo "org-roam/org-roam-ui" :branch "main" :files ("*.el" "out"))
  :after org-roam
  ;;         normally we'd recommend hooking orui after org-roam, but since org-roam does not have
  ;;         a hookable mode anymore, you're advised to pick something yourself
  ;;         if you don't care about startup time, use
  ;;  :hook (after-init . org-roam-ui-mode)
  :config
  (setq org-roam-ui-sync-theme t
        org-roam-ui-follow t
        org-roam-ui-update-on-save t
        org-roam-ui-open-on-start t))

Org babel

Ob-browser


(use-package ob-html-chrome
  :ensure t
  :init
  (setq org-babel-html-chrome-chrome-executable "/usr/bin/google-chrome-stable")
  :config (setq org-confirm-babel-evaluate
      (lambda (lang body)
        (not (string= lang "html-chrome")))))

(setq org-confirm-babel-evaluate nil)
(use-package ob-rust)
(use-package ob-typescript)
(use-package ob-go)
(require 'ob-js)
  ;; load org bable languages emacs lisp and python
  (org-babel-do-load-languages
   'org-babel-load-languages
   '((emacs-lisp . t)
     (python . t)
     (shell . t)
     (rust . t)
     (typescript . t)
     (go . t)
    (html-chrome . t)
    (restclient . t)
    (js . t)
    (C . t)
     ))

  ;; org-babel confirmation msg hide
  ;; org-babel src block indentation level
  (setq org-src-preserve-indentation t)

Org tempo

(require 'org-tempo)
(require 'ob-css)
(require 'ob-latex)

;; shortcut for org-source blog template
(add-to-list 'org-structure-template-alist '("sh" . "src sh"))
(add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
(add-to-list 'org-structure-template-alist '("p" . "src python"))
(add-to-list 'org-structure-template-alist '("r" . "src rust"))
(add-to-list 'org-structure-template-alist '("cl" . "src C"))
(add-to-list 'org-structure-template-alist '("cp" . "src cpp"))
(add-to-list 'org-structure-template-alist '("ts" . "src typescript"))
(add-to-list 'org-structure-template-alist '("g" . "src go"))
(add-to-list 'org-structure-template-alist '("hb" . "src html-chrome"))
(add-to-list 'org-structure-template-alist '("cs" . "src css"))
(add-to-list 'org-structure-template-alist '("db" . "src docker-build"))
(add-to-list 'org-structure-template-alist '("yml" . "src yml"))
(add-to-list 'org-structure-template-alist '("ss" . "src sass"))
(add-to-list 'org-structure-template-alist '("rc" . "src restclient"))
(add-to-list 'org-structure-template-alist '("js" . "src js"))
(add-to-list 'org-structure-template-alist '("jp" . "src jupyter-python"))
(add-to-list 'org-structure-template-alist '("lt" . "src latex"))
(add-to-list 'org-structure-template-alist '("mk" . "src makefile"))

;; ob-C, awk, calc, makefile, org, sed, sql, sqlite, table, biblatex, bibtex, ol-eww, gnus,org lint,

Set Margins for Modes


;; (defun dw/center-buffer-with-margins ()
;;   (let ((margin-size (/ (- (frame-width) 80) 3)))
;;     (set-window-margins nil margin-size margin-size)))

(defun em/org-mode-visual-fill ()
  (setq visual-fill-column-width 80
        visual-fill-column-center-text t)
  (advice-add 'text-scale-adjust :after #'visual-fill-column-adjust)

  (adaptive-wrap-prefix-mode 1)
  (visual-fill-column-mode 1))


(use-package adaptive-wrap)
(use-package visual-fill-column
  :defer t
  :hook (org-mode . em/org-mode-visual-fill))

Ox-hugo

(use-package ox-hugo
  :config
  (setq org-hugo-front-matter-format "toml")
  :after ox)

Images


(setq org-startup-with-inline-images t)
(add-hook 'org-babel-after-execute-hook
	  'org-redisplay-inline-images)

;; (defun shk-fix-inline-images ()
;;   (when org-inline-image-overlays
;;     (org-redisplay-inline-images)))

;; (with-eval-after-load 'org
;;   (add-hook 'org-babel-after-execute-hook 'shk-fix-inline-images))

;; (with-eval-after-load 'org
;;   (add-hook 'org-babel-after-execute-hook 'org-redisplay-inline-images))

;;; Scrolling.
;; Good speed and allow scrolling through large images (pixel-scroll).
;; Note: Scroll lags when point must be moved but increasing the number
;;       of lines that point moves in pixel-scroll.el ruins large image
;;       scrolling. So unfortunately I think we'll just have to live with
;;       this.
(pixel-scroll-mode)
(setq pixel-dead-time 0) ; Never go back to the old scrolling behaviour.
(setq pixel-resolution-fine-flag t) ; Scroll by number of pixels instead of lines (t = frame-char-height pixels).
(setq mouse-wheel-scroll-amount '(1)) ; Distance in pixel-resolution to scroll each mouse wheel event.
(setq mouse-wheel-progressive-speed nil) ; Progressive speed is too fast for me.

Org copy blocks

Little snippet for copying org source block. Cannot differentiate between different blocks. Only work with self heading block.

(defun org-copy-blocks ()
  (interactive)
  (let ((code ""))
    (save-restriction
      (org-narrow-to-subtree)
      (org-babel-map-src-blocks nil
    (setq code (concat code (org-no-properties body)))))
    (kill-new code)))

(define-key evil-window-map (kbd "C-y") 'org-copy-blocks)

Completion

Preserver Mini buffer history with savehist-mode

(use-package savehist
  :config
  (setq history-length 25)
  (savehist-mode 1))

;; Individual history elements can be configured separately
;;(put 'minibuffer-history 'history-length 25)
;;(put 'evil-ex-history 'history-length 50)
;;(put 'kill-ring 'history-length 25)

vertico for compilation

(use-package vertico
  :init
  (vertico-mode)

  :bind (:map vertico-map
              ("C-j" . vertico-next)
              ("C-k" . vertico-previous)
              ("C-f" . vertico-exit)
              :map minibuffer-local-map
              ("C-h" . minibuffer-backward-kill)
              ("M-h" . backward-kill-word))


  :custom
  (vertico-cycle t)
  (vertico-resize t)
  :custom-face
  (vertico-current ((t (:background "#3a3f5a"))))
  :init
  (vertico-mode))

;; (use-package vertico-posframe)
;; (vertico-posframe-mode 1)
;; (setq vertico-posframe-parameters
;;       '((left-fringe . 8)
;;         (right-fringe . 8)))

Marginalia replacement for ivy-rich

(use-package marginalia
  :after vertico
  :straight t
  :custom
  (marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light nil))
  :init
  (marginalia-mode))

Company

I set company-minimum-prefix-lenght to 3 for not messing with my <sh or <el keybinding in org-mode. It doesn’t if you use smarter-tab-to-complete. company-box for using icons in the completions.

Do you wanna keep using tabnine or not it’s your own preference. I don’t think I need it If I have copilot

Company is setup correctly with my workflow.

(use-package company
:hook ((prog-mode LaTeX-mode latex-mode ess-r-mode) . company-mode)
:bind
(:map company-active-map
    ([tab] . smarter-tab-to-complete)
    ;; ("C-e" . company-complete-selection)
    ("C-j" . company-select-next)
    ("C-k" . company-select-previous)
    )

:custom
(company-minimum-prefix-length 1)
(company-tooltip-align-annotations t)
(company-require-match 'never)
;; Don't use company in the following modes
(company-global-modes '(not shell-mode eaf-mode))
;; Trigger completion immediately.
(company-idle-delay 0.0)
;; Number the candidates (use M-1, M-2 etc to select completions).
(company-show-numbers nil)

:config
(global-company-mode 1)
(add-to-list 'company-backends #'company-tabnine)

(defun smarter-tab-to-complete ()
"Try to `org-cycle', `yas-expand', and `yas-next-field' at current cursor position.

If all failed, try to complete the common part with `company-complete-common'"
(interactive)
(when yas-minor-mode
    (let ((old-point (point))
        (old-tick (buffer-chars-modified-tick))
        (func-list
            (if (equal major-mode 'org-mode) '(org-cycle yas-expand yas-next-field)
            '(yas-expand yas-next-field))))
    (catch 'func-suceed
        (dolist (func func-list)
        (ignore-errors (call-interactively func))
        (unless (and (eq old-point (point))

                        (eq old-tick (buffer-chars-modified-tick)))
            (throw 'func-suceed t)))
        (company-complete-selection))))))

(with-eval-after-load 'company
  (define-key company-active-map (kbd "<return>") nil)
  (define-key company-active-map (kbd "RET") nil)
  (define-key company-active-map (kbd "C-SPC") #'company-complete-selection))


(use-package company-quickhelp :ensure t)
(company-quickhelp-mode 1)

(eval-after-load 'company
  '(define-key company-active-map (kbd "C-c h") #'company-quickhelp-manual-begin))

(use-package company-statistics)
(add-hook 'after-init-hook 'company-statistics-mode)
(use-package eglot
  :ensure t
  :config
  (add-to-list 'eglot-server-programs '((c++-mode c-mode) . ("clangd")))
  ;; Add other language servers as needed

  ;; Define a function to set up TabNine parameters after opening a TabNine session
  (defun eglot-after-open-tabnine ()
    "Hook to attach to `eglot-after-open'."
    (setq-local company-tabnine-max-num-results 3) ; Limit TabNine to return only 3 suggestions
    (add-to-list 'company-transformers 'company//sort-by-tabnine t) ; Prioritize completion suggestions as defined in company//sort-by-tabnine
    (add-to-list 'company-backends '(company-capf :with company-tabnine :separate))) ; Add company-capf backend with company-tabnine to company-backends

  ;; Define a function to toggle TabNine
  (defun company-tabnine-toggle (&optional enable)
    "Enable/Disable TabNine. If ENABLE is non-nil, definitely enable it."
    (interactive)
    (if (or enable (not (memq 'company-tabnine company-backends)))
        (progn
          (add-hook 'eglot-managed-mode-hook #'eglot-after-open-tabnine) ; Add eglot-managed-mode-hook to set TabNine parameters after opening a TabNine session
          (add-to-list 'company-backends #'company-tabnine) ; Add company-tabnine to company-backends
          (when (bound-and-true-p eglot--managed-mode) (eglot-after-open-tabnine)) ; Call eglot-after-open-tabnine if eglot-mode is active
          (message "TabNine enabled."))
      (setq company-backends (delete 'company-tabnine company-backends)) ; Remove company-tabnine from company-backends
      (setq company-backends (delete '(company-capf :with company-tabnine :separate) company-backends)) ; Remove company-capf backend with company-tabnine from company-backends
      (remove-hook 'eglot-managed-mode-hook #'eglot-after-open-tabnine) ; Remove eglot-managed-mode-hook
      (company-tabnine-kill-process) ; Kill TabNine process
      (message "TabNine disabled."))))

(use-package company-tabnine
  :defer 1
  :ensure t
  :custom
  (company-tabnine-max-num-results 9)
  :bind
  (("M-q" . company-other-backend))
  :init
  ;; Define a function to prioritize completion suggestions from eglot before those from company-tabnine
  (defun company//sort-by-tabnine (candidates)
    "Integrate company-tabnine with eglot"
    (if (or (functionp company-backend)
            (not (and (listp company-backend) (memq 'company-tabnine company-backends))))
        candidates
      (let ((candidates-table (make-hash-table :test #'equal))
            candidates-eglot
            candidates-tabnine)
        (dolist (candidate candidates)
          (if (eq (get-text-property 0 'company-backend candidate)
                  'company-tabnine)
              (unless (gethash candidate candidates-table)
                (push candidate candidates-tabnine))
            (push candidate candidates-eglot)
            (puthash candidate t candidates-table)))
        (setq candidates-eglot (nreverse candidates-eglot))
        (setq candidates-tabnine (nreverse candidates-tabnine))
        (nconc (seq-take candidates-eglot 3) ; Prioritize eglot by taking the first 3 candidates
               (seq-take candidates-tabnine 6))))) ; Then add top 6 candidates from company-tabnine

  :config
  (company-tabnine-toggle t))
(defun my-company-sort-by-project (candidates)
  "Sort COMPANY CANDIDATES with those from the current project first."
  (let ((current-project-files (projectile-current-project-files)))
    (sort candidates
          (lambda (c1 c2)
            (let ((c1-in-project (member c1 current-project-files))
                  (c2-in-project (member c2 current-project-files)))
              (cond
               ((and c1-in-project (not c2-in-project)) t)
               ((and (not c1-in-project) c2-in-project) nil)
               (t (string< c1 c2))))))))

(add-hook 'company-completion-finished-hook
          (lambda (buffer str)
            (when (and (eq major-mode 'prog-mode)
                       (derived-mode-p 'lsp-mode)
                       (company-manual-begin)
                       (not company-candidates)
                       (not company-candidates-cache))
              (let ((buffer (buffer-name)))
                (company-abort)
                (company-lsp 'interactive (substring-no-properties str))))))

(setq company-transformers '(my-company-sort-by-project company-sort-by-occurrence))

(defun my-eglot-sort-by-project (candidates)
  "Sort EGLot CANDIDATES with those from the current project first."
  (let ((current-project-files (projectile-current-project-files)))
    (sort candidates
          (lambda (c1 c2)
            (let ((c1-in-project (member c1 current-project-files))
                  (c2-in-project (member c2 current-project-files)))
              (cond
               ((and c1-in-project (not c2-in-project)) t)
               ((and (not c1-in-project) c2-in-project) nil)
               (t (string< c1 c2))))))))

(advice-add 'eglot-completion-at-point :filter-return #'my-eglot-sort-by-project)
(advice-remove 'eglot-completion-at-point #'my-eglot-sort-by-project)

(defun my-company-transformer (candidates)
  "Transform COMPANY CANDIDATES to show project exports first, then TabNine suggestions."
  (let ((project-exports (eglot-project-exported-items))
        (tabnine-suggestions (tabnine-company (company-tabnine--grab-context))))
    (append project-exports tabnine-suggestions)))

(setq company-transformers '(my-company-transformer company-sort-by-occurrence))

(defun my-company-transformer (candidates)
  "Transform COMPANY CANDIDATES to prioritize eglot exports over TabNine suggestions."
  (let ((eglot-candidates (all-completions "" (nth 2 (eglot-completion-at-point))))
        (tabnine-suggestions (company-tabnine (company-tabnine--grab-context))))
    (if eglot-candidates
        eglot-candidates
      (if tabnine-suggestions
          tabnine-suggestions
        candidates))))

(setq company-transformers '(my-company-transformer company-sort-by-occurrence))
(use-package company-tabnine
  :defer 1
  :custom
  (company-tabnine-max-num-results 9)
  :bind
  (("M-q" . company-other-backend))
   ;; ("C-z t" . company-tabnine))
  :init
  ;;first shows tabnine then shows lsp
  ;; (defun company//sort-by-tabnine (candidates)
  ;;   "Integrate company-tabnine with lsp-mode"
  ;;   (if (or (functionp company-backend)
  ;;           (not (and (listp company-backend) (memq 'company-tabnine company-backends))))
  ;;       candidates
  ;;     (let ((candidates-table (make-hash-table :test #'equal))
  ;;           candidates-lsp
  ;;           candidates-tabnine)
  ;;       (dolist (candidate candidates)
  ;;         (if (eq (get-text-property 0 'company-backend candidate)
  ;;                 'company-tabnine)
  ;;             (unless (gethash candidate candidates-table)
  ;;               (push candidate candidates-tabnine))
  ;;           (push candidate candidates-lsp)
  ;;           (puthash candidate t candidates-table)))
  ;;       (setq candidates-lsp (nreverse candidates-lsp))
  ;;       (setq candidates-tabnine (nreverse candidates-tabnine))
  ;;       (nconc (seq-take candidates-tabnine 3)
  ;;              (seq-take candidates-lsp 6)))))


;; reverse of the previous function. firt shows lsp and then shows tabnine
(defun company//sort-by-tabnine (candidates)
  "Integrate company-tabnine with lsp-mode"
  (if (or (functionp company-backend)
          (not (and (listp company-backend) (memq 'company-tabnine company-backends))))
      candidates
    (let ((candidates-table (make-hash-table :test #'equal))
          candidates-lsp
          candidates-tabnine)
      (dolist (candidate candidates)
        (if (eq (get-text-property 0 'company-backend candidate)
                'company-tabnine)
            (unless (gethash candidate candidates-table)
              (push candidate candidates-tabnine))
          (push candidate candidates-lsp)
          (puthash candidate t candidates-table)))
      (setq candidates-lsp (nreverse candidates-lsp))
      (setq candidates-tabnine (nreverse candidates-tabnine))
      (nconc (seq-take candidates-lsp 3) ; Prioritize lsp-mode by taking the first 6 candidates
             (seq-take candidates-tabnine 6))))) ; Then add top 3 candidates from company-tabnine


  (defun lsp-after-open-tabnine ()
    "Hook to attach to `lsp-after-open'."
    (setq-local company-tabnine-max-num-results 3)
    (add-to-list 'company-transformers 'company//sort-by-tabnine t)
    (add-to-list 'company-backends '(company-capf :with company-tabnine :separate)))
  (defun company-tabnine-toggle (&optional enable)
    "Enable/Disable TabNine. If ENABLE is non-nil, definitely enable it."
    (interactive)
    (if (or enable (not (memq 'company-tabnine company-backends)))
        (progn
          (add-hook 'lsp-after-open-hook #'lsp-after-open-tabnine)
          (add-to-list 'company-backends #'company-tabnine)
          (when (bound-and-true-p lsp-mode) (lsp-after-open-tabnine))
          (message "TabNine enabled."))
      (setq company-backends (delete 'company-tabnine company-backends))
      (setq company-backends (delete '(company-capf :with company-tabnine :separate) company-backends))
      (remove-hook 'lsp-after-open-hook #'lsp-after-open-tabnine)
      (company-tabnine-kill-process)
      (message "TabNine disabled.")))
  :hook
  (kill-emacs . company-tabnine-kill-process)
  :config
  (company-tabnine-toggle t))
(use-package company-box
:if (display-graphic-p)
:defines company-box-icons-all-the-icons
:hook (company-mode . company-box-mode)
:custom
(company-box-backends-colors nil)
:config
(with-no-warnings
;; Prettify icons
(defun my-company-box-icons--elisp (candidate)
    (when (derived-mode-p 'emacs-lisp-mode)
    (let ((sym (intern candidate)))
        (cond ((fboundp sym) 'Function)
            ((featurep sym) 'Module)
            ((facep sym) 'Color)
            ((boundp sym) 'Variable)
            ((symbolp sym) 'Text)
            (t . nil)))))
(advice-add #'company-box-icons--elisp :override #'my-company-box-icons--elisp))

(when (and (display-graphic-p)
            (require 'all-the-icons nil t))
(declare-function all-the-icons-faicon 'all-the-icons)
(declare-function all-the-icons-material 'all-the-icons)
(declare-function all-the-icons-octicon 'all-the-icons)
(setq company-box-icons-all-the-icons
        `((Unknown . ,(all-the-icons-faicon "bolt" :height 0.8 :v-adjust -0.15))
        (Text . ,(all-the-icons-faicon "text-width" :height 0.8 :v-adjust -0.02))
        (Method . ,(all-the-icons-faicon "cube" :height 0.8 :v-adjust -0.02 :face 'all-the-icons-purple))
        (Function . ,(all-the-icons-faicon "cube" :height 0.8 :v-adjust -0.02 :face 'all-the-icons-purple))
        (Constructor . ,(all-the-icons-faicon "cube" :height 0.8 :v-adjust -0.02 :face 'all-the-icons-purple))
        (Field . ,(all-the-icons-octicon "tag" :height 0.85 :v-adjust 0 :face 'all-the-icons-lblue))
        (Variable . ,(all-the-icons-octicon "tag" :height 0.85 :v-adjust 0 :face 'all-the-icons-lblue))
        (Class . ,(all-the-icons-material "settings_input_component" :height 0.8 :v-adjust -0.15 :face 'all-the-icons-orange))
        (Interface . ,(all-the-icons-material "share" :height 0.8 :v-adjust -0.15 :face 'all-the-icons-lblue))
        (Module . ,(all-the-icons-material "view_module" :height 0.8 :v-adjust -0.15 :face 'all-the-icons-lblue))
        (Property . ,(all-the-icons-faicon "wrench" :height 0.8 :v-adjust -0.02))
        (Unit . ,(all-the-icons-material "settings_system_daydream" :height 0.8 :v-adjust -0.15))
        (Value . ,(all-the-icons-material "format_align_right" :height 0.8 :v-adjust -0.15 :face 'all-the-icons-lblue))
        (Enum . ,(all-the-icons-material "storage" :height 0.8 :v-adjust -0.15 :face 'all-the-icons-orange))
        (Keyword . ,(all-the-icons-material "filter_center_focus" :height 0.8 :v-adjust -0.15))
        (Snippet . ,(all-the-icons-material "format_align_center" :height 0.8 :v-adjust -0.15))
        (Color . ,(all-the-icons-material "palette" :height 0.8 :v-adjust -0.15))
        (File . ,(all-the-icons-faicon "file-o" :height 0.8 :v-adjust -0.02))
        (Reference . ,(all-the-icons-material "collections_bookmark" :height 0.8 :v-adjust -0.15))
        (Folder . ,(all-the-icons-faicon "folder-open" :height 0.8 :v-adjust -0.02))
        (EnumMember . ,(all-the-icons-material "format_align_right" :height 0.8 :v-adjust -0.15))
        (Constant . ,(all-the-icons-faicon "square-o" :height 0.8 :v-adjust -0.1))
        (Struct . ,(all-the-icons-material "settings_input_component" :height 0.8 :v-adjust -0.15 :face 'all-the-icons-orange))
        (Event . ,(all-the-icons-octicon "zap" :height 0.8 :v-adjust 0 :face 'all-the-icons-orange))
        (Operator . ,(all-the-icons-material "control_point" :height 0.8 :v-adjust -0.15))
        (TypeParameter . ,(all-the-icons-faicon "arrows" :height 0.8 :v-adjust -0.02))
        (Template . ,(all-the-icons-material "format_align_left" :height 0.8 :v-adjust -0.15)))
        company-box-icons-alist 'company-box-icons-all-the-icons)))

custom completion function

(defun my-smart-c-e ()
  "Move to end of line if there is a character after point,
otherwise trigger company's smarter tab."
  (interactive)
  (if (eolp)
      (copilot-accept-completion-by-line)
    (move-end-of-line 1)
    ))
;; Define a key binding for the function nickname.
(global-set-key (kbd "C-e") 'my-smart-c-e)

;; minibuffer always stays the same size no matter what
;; It can only grow
(setq resize-mini-windows 'grow-only)

crux

(global-unset-key (kbd "S-<return>"))
(global-set-key (kbd "S-<return>") #'crux-smart-open-line-above)
(global-set-key (kbd "S-o") #'crux-smart-open-line-above)
(global-set-key (kbd "C-<return>") #'crux-smart-open-line)
;; (global-set-key [(shift return)] #'crux-smart-open-line-above)

Consult

(use-package all-the-icons-completion
  :init
  (all-the-icons-completion-mode))
(add-hook 'marginalia-mode-hook #'all-the-icons-completion-marginalia-setup)

Consult has a lot of functionality. You need to discover it userself and use it as you need. consult-locate will use the systemwide locate to locate files.

(defun em/get-project-root ()
  (when (fboundp 'projectile-project-root)
    (projectile-project-root)))

(use-package consult
  :straight t
  :demand t
  :bind (("C-s" . consult-line)
         ("C-M-l" . consult-imenu)
         ;; ("C-M-j" . persp-switch-to-buffer*)
         ("C-x b" . consult-project-buffer)
         ("C-x l" . consult-buffer)
         ("C-;" . consult-register)
         ("C-q" . consult-bookmark)
         ("C-M-j" . consult-buffer-other-window)
         ("M-s" . consult-ripgrep)
         ("C-x t" . consult-theme)
         ;; ("C-y" . consult-yank-pop)
         ;; ("M-y" . consult-yank-replace)
         :map minibuffer-local-map
         ("C-r" . consult-history))
  :custom
  (consult-project-root-function #'em/get-project-root)
  (completion-in-region-function #'consult-completion-in-region)
  :config
  (consult-preview-at-point-mode))

Consult-dir

(use-package consult-dir
  :ensure t
  :bind (("C-x C-d" . consult-dir-dired)
         ("C-x d" . consult-dir)
         ("C-c l" . consult-locate)
         ;; ("C-x C-f" . consult-find) ;; replaced by projectile-find-file
         :map vertico-map
         ("C-x d" . consult-dir)
         ("C-x C-f" . consult-dir-jump-file)))

Corfu + Cape

(use-package corfu
  :init
  (global-corfu-mode)
  :custom
  (corfu-cycle t)                ;; Enable cycling for `corfu-next/previous'
  (corfu-auto-prefix 0)
  (completion-styles '(basic))
  ;; (corfu-min-width 60)
  ;; (corfu-count 8)
  (corfu-auto t)                 ;; Enable auto completion
  (corfu-commit-predicate nil)   ;; Do not commit selected candidates on next input
  (corfu-quit-at-boundary 'separator)     ;; Automatically quit at word boundary
  (corfu-quit-no-match t)        ;; Automatically quit if there is no match
  (corfu-preview-current t)    ;; Disable current candidate preview
  (corfu-preselect-first t)    ;; Disable candidate preselection
  (corfu-echo-documentation nil) ;; Disable documentation in the echo area
  (corfu-scroll-margin 5)        ;; Use scroll margin
  (corfu-atuo t)
  (corfu-auto-delay 0)
  (corfu-auto-prefix 0)

  :config
  ;; Make Evil and Corfu play nice
  (evil-make-overriding-map corfu-map)
  (advice-add 'corfu--setup :after 'evil-normalize-keymaps)
  (advice-add 'corfu--teardown :after 'evil-normalize-keymaps)

  ;;(corfu-history-mode 1)
  (savehist-mode 1)
  (add-to-list 'savehist-additional-variables 'corfu-history)

  (defun corfu-enable-always-in-minibuffer ()
    (setq-local corfu-auto nil)
    (corfu-mode 1))
  (add-hook 'minibuffer-setup-hook #'corfu-enable-always-in-minibuffer 1)

  :general
  (:keymaps 'corfu-map
            :states 'insert
            "C-n" 'corfu-next
            "C-p" 'corfu-previous
            "C-j" 'corfu-next
            "C-k" 'corfu-previous
            "RET" 'corfu-complete
            "<escape>" 'corfu-quit
            ))

; (use-package kind-icon
;;   :config
;;   (setq kind-icon-default-face 'corfu-default)
;;   (setq kind-icon-default-style '(:padding 0 :stroke 0 :margin 0 :radius 0 :height 0.9 :scale 1))
;;   (setq kind-icon-blend-frac 0.08)
;;   (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter)
;;   (add-hook 'counsel-load-theme #'(lambda () (interactive) (kind-icon-reset-cache))))
(add-hook 'load-theme #'(lambda () (interactive) (kind-icon-reset-cache)))

(setq-default pgtk-wait-for-event-timeout 0)

(use-package cape
  ;; Bind dedicated completion commands
  ;;:bind (("C-c p p" . completion-at-point) ;; capf
   ;;      ("C-c p t" . complete-tag)        ;; etags
    ;;     ("C-c p d" . cape-dabbrev)        ;; or dabbrev-completion
     ;;    ("C-c p f" . cape-file)
      ;;   ("C-c p k" . cape-keyword)
       ;;  ("C-c p s" . cape-symbol)
        ;; ("C-c p a" . cape-abbrev)
        ;; ("C-c p i" . cape-ispell)
        ;; ("C-c p l" . cape-line)
        ;; ("C-c p w" . cape-dict))
  :init
  ;; Add `completion-at-point-functions', used by `completion-at-point'.
  (add-to-list 'completion-at-point-functions #'cape-line)
  (add-to-list 'completion-at-point-functions #'cape-ispell)
  (add-to-list 'completion-at-point-functions #'cape-dict)
  (add-to-list 'completion-at-point-functions #'cape-file)
  (add-to-list 'completion-at-point-functions #'cape-symbol)
  (add-to-list 'completion-at-point-functions #'cape-abbrev)
  (add-to-list 'completion-at-point-functions #'cape-keyword)
  (add-to-list 'completion-at-point-functions #'cape-dabbrev)
)

;; ;; Use Company backends as Capfs.
;; (add-to-list 'completion-at-point-functions
;;    (mapcar #'cape-company-to-capf
;;      (list #'company-files #'company-ispell #'company-dabbrev)))

;; (setq company-dabbrev-downcase nil)

(use-package kind-icon
  :after corfu
  :config
  (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter))
(use-package corfu
  :straight (:files (:defaults "extensions/*"))
  :init
  (global-corfu-mode)
  (corfu-popupinfo-mode)
  (corfu-history-mode)
  (corfu-indexed-mode)
  (corfu-terminal-mode)
  (corfu-echo-mode)

  :custom
  (corfu-cycle t)
  (corfu-auto t)
  (corfu-quit-at-boundary 'separator)
  (corfu-quit-no-match 'separator)
  (corfu-auto-delay 0)
  ;; (corfu-min-width 60)
  (corfu-popupinfo-delay t)
  (corfu-auto-prefix 1)
  (completion-styles '(basic))
  (corfu-preselect 'prompt)
  (corfu-preview-current t)    ;; Disable current candidate preview
  (corfu-preselect-first t)    ;; Disable candidate preselection
  (corfu-echo-documentation t) ;; Disable documentation in the echo area
  ;; (corfu-scroll-margin 5)        ;;

  :config
 (define-key corfu-map (kbd "<tab>") #'corfu-complete)
  ;; Make Evil and Corfu play nice
  (evil-make-overriding-map corfu-map)
  (advice-add 'corfu--setup :after 'evil-normalize-keymaps)
  (advice-add 'corfu--teardown :after 'evil-normalize-keymaps)

  (savehist-mode 1)
  (add-to-list 'savehist-additional-variables 'corfu-history)
)

(use-package corfu
  ;; TAB-and-Go customizations
  :custom
  (corfu-cycle t)           ;; Enable cycling for `corfu-next/previous'
  (corfu-preselect 'prompt) ;; Always preselect the prompt

  ;; Use TAB for cycling, default is `corfu-complete'.
  :bind
  (:map corfu-map
        ("C-n" . corfu-next)
        ([tab] . corfu-complete)
        ("C-p" . corfu-previous)
        ;; ([backtab] . corfu-previous))
)

  :init
  (global-corfu-mode))

(defun corfu-enable-always-in-minibuffer ()
    (setq-local corfu-auto nil)
    (corfu-mode 1))
(add-hook 'minibuffer-setup-hook #'corfu-enable-always-in-minibuffer 1)


(use-package emacs
  :init
  ;; TAB cycle if there are only few candidates
  (setq completion-cycle-threshold 3)

  ;; Enable indentation+completion using the TAB key.
  ;; `completion-at-point' is often bound to M-TAB.
  (setq tab-always-indent 'complete))


;; Use Dabbrev with Corfu!
(use-package dabbrev
  ;; Swap M-/ and C-M-/
  :bind (("M-/" . dabbrev-completion)
         ("C-M-/" . dabbrev-expand))
  :config
  (add-to-list 'dabbrev-ignored-buffer-regexps "\\` ")
  ;; Since 29.1, use `dabbrev-ignored-buffer-regexps' on older.
  (add-to-list 'dabbrev-ignored-buffer-modes 'doc-view-mode)
  (add-to-list 'dabbrev-ignored-buffer-modes 'pdf-view-mode))


(use-package cape
  :after corfu
  :init
  (add-to-list 'completion-at-point-functions #'cape-file)
  (add-to-list 'completion-at-point-functions #'cape-keyword))

(advice-add 'eglot-completion-at-point :around #'cape-wrap-buster)

;; Option 1: Specify explicitly to use Orderless for Eglot
(setq completion-category-overrides '((eglot (styles orderless))
                                      (eglot-capf (styles orderless))))

;; Option 2: Undo the Eglot modification of completion-category-defaults
(with-eval-after-load 'eglot
   (setq completion-category-defaults nil))

;; Enable cache busting, depending on if your server returns
;; sufficiently many candidates in the first place.
(advice-add 'eglot-completion-at-point :around #'cape-wrap-buster)

(setq-default eglot-workspace-configuration
      '((haskell (maxCompletions . 200))))

(defun my/eglot-capf ()
  (setq-local completion-at-point-functions
              (list (cape-capf-super
                     #'eglot-completion-at-point
                     #'tempel-expand
                     #'cape-file))))

(add-hook 'eglot-managed-mode-hook #'my/eglot-capf)

(use-package svg-lib)

(use-package kind-icon
  :after corfu
  :custom
  (kind-icon-blend-background t)
  (kind-icon-default-face 'corfu-default)
  :config
  (setq kind-icon-use-icons t)
  (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter))

(use-package corfu-terminal
  :after corfu
  :init (corfu-terminal-mode))

orderless

;; Use the `orderless' completion style. Additionally enable
;; `partial-completion' for file path expansion. `partial-completion' is
;; important for wildcard support. Multiple files can be opened at once
;; with `find-file' if you enter a wildcard. You may also give the
;; `initials' completion style a try.

(use-package orderless
  :ensure t
  :demand t
  :custom
  (completion-styles '(orderless basic))
  (completion-category-overrides '((file (styles basic partial-completion)))))

(defun orderless-fast-dispatch (word index total)
  (and (= index 0) (= total 1) (length< word 4)
       `(orderless-regexp . ,(concat "^" (regexp-quote word)))))

(orderless-define-completion-style orderless-fast
  (orderless-style-dispatchers '(orderless-fast-dispatch))
  (orderless-matching-styles '(orderless-literal orderless-regexp)))

(use-package emacs
  :init
  ;; Add prompt indicator to `completing-read-multiple'.
  ;; Alternatively try `consult-completing-read-multiple'.
  (defun crm-indicator (args)
    (cons (concat "[CRM] " (car args)) (cdr args)))
  (advice-add #'completing-read-multiple :filter-args #'crm-indicator)

  ;; Do not allow the cursor in the minibuffer prompt
  (setq minibuffer-prompt-properties
        '(read-only t cursor-intangible t face minibuffer-prompt))
  (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)

  ;; Emacs 28: Hide commands in M-x which do not work in the current mode.
  ;; Vertico commands are hidden in normal buffers.
  (setq read-extended-command-predicate
        #'command-completion-default-include-p)

  ;; Enable recursive minibuffers
  (setq enable-recursive-minibuffers t))

Completion Actions with Embark


(use-package embark
  :straight t
  :bind (("C-." . embark-act)
         :map minibuffer-local-map
         ("C-." . 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))

;; (use-package embark-consult
;;   :straight '(embark-consult :host github
;;                              :repo "oantolin/embark"
;;                              :files ("embark-consult.el"))
;;   :after (embark consult)
;;   :demand t
;;   :hook
;;   (embark-collect-mode . embark-consult-preview-minor-mode))

(use-package casual-dired
  :straight'(casual-dired
             :type git
             :host github
             :repo "kickingvegas/casual-dired"
             :branch "main")
  :after (dired)
  :demand t
  :bind (:map dired-mode-map ("?" . 'casual-dired-tmenu)))

(define-key dired-mode-map (kbd "?") nil)
(define-key dired-mode-map (kbd "?") 'casual-dired-tmenu)

Flycheck

(use-package flycheck
:defer t
:hook (after-init . global-flycheck-mode)
:commands (flycheck-add-mode)
:custom
(flycheck-global-modes
'(not outline-mode diff-mode shell-mode eshell-mode term-mode))
(flycheck-emacs-lisp-load-path 'inherit)
(flycheck-indication-mode (if (display-graphic-p) 'right-fringe 'right-margin))
:init
(if (display-graphic-p)
    (use-package flycheck-posframe
    :custom-face
    (flycheck-posframe-face ((t (:foreground ,(face-foreground 'success)))))
    (flycheck-posframe-info-face ((t (:foreground ,(face-foreground 'success)))))
    :hook (flycheck-mode . flycheck-posframe-mode)
    :custom
    (flycheck-posframe-position 'window-bottom-left-corner)
    (flycheck-posframe-border-width 3)
    (flycheck-posframe-inhibit-functions
        '((lambda (&rest _) (bound-and-true-p company-backend)))))
(use-package flycheck-pos-tip
    :defines flycheck-pos-tip-timeout
    :hook (flycheck-mode . flycheck-pos-tip-mode)
    :custom (flycheck-pos-tip-timeout 30)))
:config
(use-package flycheck-popup-tip
:hook (flycheck-mode . flycheck-popup-tip-mode))
(when (fboundp 'define-fringe-bitmap)
(define-fringe-bitmap 'flycheck-fringe-bitmap-double-arrow
    [16 48 112 240 112 48 16] nil nil 'center))
(when (executable-find "vale")
(use-package flycheck-vale
    :config
    (flycheck-vale-setup)
    (flycheck-add-mode 'vale 'latex-mode))))


(use-package flycheck-inline)
(with-eval-after-load 'flycheck
(add-hook 'flycheck-mode-hook #'flycheck-inline-mode))

Snippets

How to create new snippets? Invoke the command yas-new-snippet then create it. $0 means the end of the pointer. $1 first one, $2 second one and so on. For placeholder purposes use ${1:name}, ${2:title}.

(use-package yasnippet
:ensure t
:hook ((lsp-mode . yas-minor-mode))
:config
(setq yas-snippet-dirs '("~/.config/emacs/snippets/"))
(yas-global-mode 1)
)

(use-package yasnippet-snippets)

Auto format

(use-package apheleia
:straight (apheleia :host github :repo "raxod502/apheleia")
:bind (
            ("C-=" . apheleia-format-buffer))
:config
(setf (alist-get 'prettier apheleia-formatters)
    '(npx "prettier"
            "--trailing-comma"  "es5"
            "--bracket-spacing" "true"
            "--single-quote"    "true"
            "--semi"            "false"
            "--print-width"     "100"
            file)
    )

(add-to-list 'apheleia-mode-alist '((typescript-ts-mode . prettier) ))
(add-to-list 'apheleia-mode-alist '((typescript-tsx-ts-mode . prettier) ))
(add-to-list 'apheleia-mode-alist '((js-ts-mode . prettier) ))
(add-to-list 'apheleia-mode-alist '((yaml-ts-mode . yq) ))

;; install go-yq from arch repo
(setq apheleia-yaml-mode-formatter "yq")
(add-hook 'yaml-ts-mode-hook #'apheleia-mode)

(apheleia-global-mode t))

lorem-ipsum

(use-package lorem-ipsum)

Emmet

(use-package emmet-mode)
(add-hook 'html-mode-hook 'emmet-mode)
(add-hook 'web-mode-hook 'emmet-mode)

Sudo edit

(use-package crux
:bind (("C-a" . crux-move-beginning-of-line)
        ("C-o" . crux-smart-open-line)
        ;; ("C-i" . crux-smart-open-line-above)
        ))

Language

Yuck

(use-package yuck-mode)

Yaml

(use-package yaml-mode
:mode "\\.ya?ml\\'")

Devdocs

Devdocs.io documentation lookup.

(use-package devdocs)
(global-set-key (kbd "C-h w") 'devdocs-lookup)
;; (add-hook 'typescript-ts-mode-hook
          ;; (lambda () (setq-local devdocs-current-docs '("typescript;javascript"))))

(add-hook 'tsx-ts-mode-hook
          (lambda () (setq-local devdocs-current-docs '("typescript,javascript,react,css,html"))))

Python

This pyvenv-mode 1 part is essential. This will automatically make the venv activate when the variable pyvenv-activate is changed.

So, now leverage .dir-locals.el to set that for my projects.

((nil . ((pyvenv-activate . "~/repos/my_proj/.venv"))))

Now when I open a file in my project, that virtual environment is activated!

(use-package pipenv
:hook (python-ts-mode . pipenv-mode)
:init
(setq
pipenv-projectile-after-switch-function
#'pipenv-projectile-after-switch-extended))
(setq python-indent-offset 4)

Org as jupyter notebook.

(use-package jupyter)
(require 'ob-jupyter)
(add-to-list 'org-babel-load-languages '(jupyter . t))
  (org-babel-do-load-languages 'org-babel-load-languages org-babel-load-languages)

(use-package ob-async)
(setq org-babel-default-header-args:jupyter-python '((:async . "yes")
                                                    (:session . "ml")
                                                    (:kernel . "python3")))

(setq ob-async-no-async-languages-alist '("python" "jupyter-python" "sh"))
;; Disable editing source code in dedicated buffer
;; (defun org-edit-src-code nil)
(use-package ob-ipython)
(add-to-list 'org-babel-load-languages '(ipython . t))
(use-package jupyter
  :straight t)
  (add-to-list 'org-babel-load-languages '(jupyter . t))
(org-babel-jupyter-override-src-block "python")

;; (setq org-babel-jupyter-override-src-block "python")
(use-package ob-async)
(setq ob-async-no-async-languages-alist '("python" "jupyter-python"))
(add-hook 'org-babel-after-execute-hook 'org-redisplay-inline-images)

;; (add-to-list 'org-babel-load-languages '(ipython . t))
;; (use-package ob-ipython)

Rust

(use-package rustic)
(defun rustic-mode-auto-save-hook ()
  "Enable auto-saving in rustic-mode buffers."
  (when buffer-file-name
    (setq-local compilation-ask-about-save nil)))
(add-hook 'rustic-mode-hook 'rustic-mode-auto-save-hook)
(setq rustic-lsp-server 'rust-analyzer)
(use-package rustic
  :ensure
  :bind (:map rustic-mode-map
              ("M-j" . lsp-ui-imenu)
              ("M-?" . lsp-find-references)
              ("C-c C-c l" . flycheck-list-errors)
              ("C-c C-c a" . lsp-execute-code-action)
              ("C-c C-c r" . lsp-rename)
              ("C-c C-c q" . lsp-workspace-restart)
              ("C-c C-c Q" . lsp-workspace-shutdown)
              ("C-c C-c s" . lsp-rust-analyzer-status))
  :config
  ;; uncomment for less flashiness
  ;; (setq lsp-eldoc-hook nil)
  ;; (setq lsp-enable-symbol-highlighting nil)
  ;; (setq lsp-signature-auto-activate nil)

  ;; comment to disable rustfmt on save
  (setq rustic-format-on-save t)
  (add-hook 'rustic-mode-hook 'rk/rustic-mode-hook))

(defun rk/rustic-mode-hook ()
  ;; so that run C-c C-c C-r works without having to confirm, but don't try to
  ;; save rust buffers that are not file visiting. Once
  ;; https://github.com/brotzeit/rustic/issues/253 has been resolved this should
  ;; no longer be necessary.
  (when buffer-file-name
    (setq-local buffer-save-without-query t))
  (add-hook 'before-save-hook 'lsp-format-buffer nil t))
(use-package lsp-mode
  :ensure
  :commands lsp
  :custom
  ;; what to use when checking on-save. "check" is default, I prefer clippy
  (lsp-rust-analyzer-cargo-watch-command "clippy")
  (lsp-eldoc-render-all t)
  (lsp-idle-delay 0.6)
  ;; enable / disable the hints as you prefer:
  (lsp-inlay-hint-enable t)
  ;; These are optional configurations. See https://emacs-lsp.github.io/lsp-mode/page/lsp-rust-analyzer/#lsp-rust-analyzer-display-chaining-hints for a full list
  (lsp-rust-analyzer-display-lifetime-elision-hints-enable "skip_trivial")
  (lsp-rust-analyzer-display-chaining-hints t)
  (lsp-rust-analyzer-display-lifetime-elision-hints-use-parameter-names nil)
  (lsp-rust-analyzer-display-closure-return-type-hints t)
  (lsp-rust-analyzer-display-parameter-hints nil)
  (lsp-rust-analyzer-display-reborrow-hints nil)
  :config
  (add-hook 'lsp-mode-hook 'lsp-ui-mode))

(use-package lsp-ui
  :ensure
  :commands lsp-ui-mode
  :custom
  (lsp-ui-peek-always-show t)
  (lsp-ui-sideline-show-hover t)
  (lsp-ui-doc-enable nil))

Go mode

(use-package go-mode)
(use-package gotest)
(use-package go-projectile)

(defun lsp-go-install-save-hooks ()
  (add-hook 'before-save-hook #'lsp-format-buffer t t)
  (add-hook 'before-save-hook #'lsp-organize-imports t t)
  (add-hook 'go-ts-mode-hook #'lsp-go-install-save-hooks)
)

(defun my-go-mode-hook ()
    ; eldoc shows the signature of the function at point in the status bar.
    (local-set-key (kbd "M-.") #'godef-jump)

    (let ((map go-mode-map))
    (define-key map (kbd "C-c a") 'go-test-current-project) ;; current package, really
    (define-key map (kbd "C-c m") 'go-test-current-file)
    (define-key map (kbd "C-c .") 'go-test-current-test)
    (define-key map (kbd "C-c C-c") 'go-run)))

(let ((goimports (executable-find "goimports")))
    (when goimports
    (setq gofmt-command goimports)))

;; stop whitespace being highlighted
(whitespace-toggle-options '(tabs))
(setq go-ts-mode-indent-offset 4)

(add-hook 'go-ts-mode-hook 'my-go-mode-hook)

Liquid

;; (use-package emacs-liquid)

Typescript

Tide is typescript code manager or something like that. It works great for emacs.

(use-package prettier-js)
(setq js-indent-level 2)
(use-package typescript-mode
:after tree-sitter
:init (setq typescript-indent-level 2))

Node repl setup for ts & js

;; (use-package js-comint)
(defun inferior-typescript-ts-mode-hook-setup ()
  (add-hook 'comint-output-filter-functions 'ts-comint-process-output))
(add-hook 'inferior-ts-mode-hook 'inferior-typescript-ts-mode-hook-setup t)

;; You can also customize `js-comint-drop-regexp' to filter output
;; (setq js-comint-program-command "node")
;; (setq js-comint-program-arguments '("--interactive"))

;; (js-do-use-nvm)

;; (add-hook typescript-ts-mode-hook '(lambda ()
;; 			    (local-set-key "\C-x\C-e" 'js-send-last-sexp)
;; 			    (local-set-key "\C-\M-x" 'js-send-last-sexp-and-go)
;; 			    (local-set-key "\C-cb" 'js-send-buffer)
;; 			    (local-set-key "\C-c\C-b" 'js-send-buffer-and-go)
;; 			    (local-set-key "\C-cl" 'js-load-file-and-go)
;; 			    ))

(use-package ts-comint)
(add-hook 'typescript-mode-hook
          (lambda ()
            (local-set-key (kbd "C-x C-e") 'ts-send-last-sexp)
            (local-set-key (kbd "C-M-x") 'ts-send-last-sexp-and-go)
            (local-set-key (kbd "C-c b") 'ts-send-buffer)
            (local-set-key (kbd "C-c C-b") 'ts-send-buffer-and-go)
            (local-set-key (kbd "C-c l") 'ts-load-file-and-go)))

(use-package repl-toggle)
;; when configuring all repl toggle mapping
(setq rtog/mode-repl-alist '((typescript-ts-mode . run-ts)))
;; or later
(push '(typescript-ts-mode . run-ts) rtog/mode-repl-alist)
(setq rtog/mode-repl-alist '((typescript-ts-mode . tsun) ))

Dart & Flutter

;; Assuming usage with dart-mode
(use-package dart-mode
  ;; Optional
  :hook (dart-mode . flutter-test-mode))

(use-package flutter
  :after dart-mode
  :bind (:map dart-mode-map
              ("C-M-x" . #'flutter-run-or-hot-reload))
  :custom
  (flutter-sdk-path "/Applications/flutter/"))

JSON

(use-package json-mode)

Web mode

(use-package web-mode
;; :ensure t
:mode (("\\.html\\'" . web-mode))
        ;; ("\\.js\\'" . web-mode)
        ;; ("\\.mjs\\'" . web-mode)
        ;; ("\\.tsx\\'" . web-mode)
        ;; ("\\.jsx\\'" . web-mode)
        ;; ("\\.liquid\\'" . web-mode))
:config
(setq web-mode-code-indent-offset 2)
(setq web-mode-css-indent-offset 2)
(setq web-mode-markup-indent-offset 2)
(setq web-mode-content-types-alist
'(("jsx" . "\\.js[x]?\\'")
    ("tsx" . "\\.ts[x]?\\'"))))

;; (add-to-list 'auto-mode-alist '("\\.tsx\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.mdx\\'" . markdown-mode))

;; (defun switch-to-mdx-typescript ()
;;   "Switch to TypeScript mode in MDX files."
;;   (when (and (buffer-file-name)
;;              (string= (file-name-extension (buffer-file-name)) "mdx"))
;;     (markdown-mode)  ; Activate Markdown mode
;;     (typescript-tsx-mode)))  ; Activate TypeScript (TSX) mode as minor mode

;; (add-hook 'markdown-mode-hook 'switch-to-mdx-typescript)


;;; Directory Local Variables
;;; For more information see (info "(emacs) Directory Variables")

;; ((auto-mode-alist . (("\\.mdx\\'" . markdown-mode)))
;;  (markdown-mode . ((fill-column . 80)
;;                    (eval . (prettier-js-mode 1))))
;;  (typescript-mode . ((typescript-indent-level . 2))))



;; (add-to-list 'auto-mode-alist '("\\.liquid\\'" . (lambda () (lsp-mode nil))))
(setq lsp-warn-no-matched-clients t)
;; (add-hook 'web-mode-hook
;;           (lambda ()
;;             (when (string-equal "tsx" (file-name-extension buffer-file-name))
;;               (setup-tide-mode))))

;; enable typescript - tslint checker
(flycheck-add-mode 'typescript-tslint 'web-mode)

Eslint

(use-package eslint-rc)
(add-hook 'typescript-ts-mode-hook 'eslint-rc-mode)
(add-hook 'tsx-ts-mode-hook 'eslint-rc-mode)
;; (add-hook 'js2-mode-hook 'eslint-rc-mode)
;; (add-hook 'web-mode-hook 'eslint-rc-mode)

Prisma for Node database ORM.


(use-package dotenv-mode)

(straight-use-package
 '(emacs-prisma-mode :type git :host github :repo "pimeys/emacs-prisma-mode"))

Tree-sitter

If something doesn’t work always downgrade packages. Install tree-sitter and tree-sitter-cli to compile and build. Maybe you don’t even need the cli tool because the emacs package tree-sitter-langs provide a much better experience when downloading and compiling sources.

prepend_string="new_prefix_"
for file in *; do
    if [ -f "$file" ]; then  # Check if it's a regular file
        new_filename="${prepend_string}${file}"
        mv "$file" "$new_filename"
        echo "Renamed '$file' to '$new_filename'"
    fi
done

Download tree-sitter-module from github and install all the libaries in a go. Then use it. (treesitter-extra-load-path) variable has some more information about where the libaries should go. Treesitter install all it’s compiled binaries in .cache/emacs.

;; (use-package tree-sitter)

;; (setq tree-sitter-load-path "~./config/emacs/")

(use-package tree-sitter-langs
  :after tree-sitter
  :config
  (global-tree-sitter-mode)
  :hook ((tree-sitter-after-on-hook . tree-sitter-hl-mode)))


(setq treesit-language-source-alist
  '((typescript "https://github.com/tree-sitter/tree-sitter-typescript" "v0.20.3" "typescript/src")
(tsx "https://github.com/tree-sitter/tree-sitter-typescript" "v0.20.3" "tsx/src")
    ))

(setq major-mode-remap-alist
      '((yaml-mode . yaml-ts-mode)
        (bash-mode . bash-ts-mode)
        (mhtml-mode . html-ts-mode)
        (sql-mode . sql-ts-mode)
        (make-mode . make-ts-mode)
        (elisp-mode . elisp-ts-mode)
        (dockerfile-mode . dockerfile-ts-mode)
        (cmake-mode . cmake-ts-mode)
        (toml-mode . toml-ts-mode)
        (scss-mode . scss-ts-mode)
        (rust-mode . rust-ts-mode)
        (json-mode . json-ts-mode)
        (js2-mode . js-ts-mode)
        (typescript-mode . typescript-ts-mode)
        (css-mode . css-ts-mode)
        (go-mode . go-ts-mode)
        (go-mod-mode . go-mod-ts-mode)
        (python-mode . python-ts-mode)))


(add-to-list 'auto-mode-alist '("\\.tsx?\\'" . typescriptreact-mode))
(add-to-list 'auto-mode-alist '("\\.tsx?\\'" . tsx-ts-mode))
(add-to-list 'auto-mode-alist '("\\.sql?\\'" . sql-ts-mode))

(add-to-list 'auto-mode-alist '("\\.jsx?\\'" . tsx-ts-mode))
(use-package ts-fold
  :straight (ts-fold :type git :host github :repo "emacs-tree-sitter/ts-fold"))
;; doesn't need this if compiled with emacs
;;(use-package tree-sitter)
  ;; :hook ((prog-mode. treesit-major-mode-setup)))


(treesit-language-available-p 'typescript)




(use-package tree-sitter
:init
  (setq treesit-language-source-alist
   '((bash . ("https://github.com/tree-sitter/tree-sitter-bash"))
     (c . ("https://github.com/tree-sitter/tree-sitter-c"))
     (css . ("https://github.com/tree-sitter/tree-sitter-css"))
     (go . ("https://github.com/tree-sitter/tree-sitter-go"))
     (html . ("https://github.com/tree-sitter/tree-sitter-html"))
     (javascript . ("https://github.com/tree-sitter/tree-sitter-javascript"))
     (json . ("https://github.com/tree-sitter/tree-sitter-json"))
     (make . ("https://github.com/alemuller/tree-sitter-make"))
     (python . ("https://github.com/tree-sitter/tree-sitter-python"))
     (typescript . ("https://github.com/tree-sitter/tree-sitter-typescript" "typescript/src" "typescript"))
     (rust . ("https://github.com/tree-sitter/tree-sitter-rust"))
     (sql . ("https://github.com/m-novikov/tree-sitter-sql"))
     (toml . ("https://github.com/tree-sitter/tree-sitter-toml"))))

  :config

  (use-package tree-sitter-langs)
  (global-tree-sitter-mode)
  (add-hook 'tree-sitter-after-on-hook #'tree-sitter-hl-mode))

(use-package tree-sitter-langs
  :ensure t
  :after tree-sitter)


(mapc #'treesit-install-language-grammar (mapcar #'car treesit-language-source-alist))

(setq major-mode-remap-alist
 '((yaml-mode . yaml-ts-mode)
   (bash-mode . bash-ts-mode)
   (mhtml-mode . html-ts-mode)
   (js2-mode . js-ts-mode)
   (typescript-mode . typescript-ts-mode)
   (css-mode . css-ts-mode)
   (go-mode . go-ts-mode)
   (python-mode . python-ts-mode)))


(add-to-list 'auto-mode-alist '("\\.ts\\'" . typescript-ts-mode))
(add-to-list 'auto-mode-alist '("\\.tsx\\'" . typescript-ts-mode))
(use-package treesit-auto
  :config
  (setq treesit-auto-install 'prompt)
  (global-treesit-auto-mode))

 (setq my-js-tsauto-config
	(make-treesit-auto-recipe
	 :lang 'json
	 :ts-mode 'js-ts-mode
	 :remap '(js2-mode js-mode javascript-mode)
	 :url "https://github.com/tree-sitter/tree-sitter-javascript"
	 :revision "master"
	 :source-dir "src"))

 (add-to-list 'treesit-auto-recipe-list my-js-tsauto-config)

LSP Mode

If you have problem with json-string-format check with the project package.json that all it’s syntax is correct.

(use-package lsp-mode
  :init
  (setq lsp-enable-snippet t)
  ;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l")
  (setq lsp-keymap-prefix "C-c l")
  :hook (;; replace XXX-mode with concrete major-mode(e. g. python-mode)
         (python-ts-mode . lsp-deferred)
         (rust-ts-mode . lsp-deferred)
         (js-ts-mode . lsp-deferred)
         (typescript-ts-mode . lsp-deferred)
         (typescript-ts-mode . lsp-deferred)
         (tsx-ts-mode . lsp-deferred)
         (web-mode . lsp-deferred)
         ;; if you want which-key integration
         (html-ts-mode . lsp-deferred)
         (css-ts-mode . lsp-deferred)
         (go-ts-mode . lsp-deferred)
         (lsp-mode . lsp-enable-which-key-integration))
  :commands lsp lsp-deferred)

;; ;; optionally
;; (use-package lsp-ui
;;   :init
;;   (setq lsp-ui-doc-enable t)
;;   (setq lsp-ui-doc-header t)
;;   (setq lsp-ui-doc-include-signature t)
;;   (setq lsp-ui-doc-max-width 120)
;;   (setq lsp-ui-doc-max-height 20)
;;   (setq lsp-ui-doc-delay 0.3)
;;   (setq lsp-ui-doc-use-childframe t)
;;   (setq lsp-ui-peek-enable t)
;;   (setq lsp-ui-peek-peek-height 20)
;;   (setq lsp-ui-peek-fontify 'on-demand)
;;   (setq lsp-ui-imenu-window-width 0)
;;   (setq lsp-ui-imenu-kind-position 'top)
;;   :commands lsp-ui-mode)


;; (use-package lsp-treemacs :commands lsp-treemacs-errors-list)

(setq-default lsp-enable-indentation nil) ; Disable indentation
(setq-default lsp-enable-on-type-formatting nil) ; Disable formatting on type

Eglot

Removed eglot for 2nd time now. I don’t know what’s wrong with it.

(use-package eglot
:ensure t
:hook
(prog-mode . eglot-ensure))

(global-eldoc-mode 1)
;; (setq eldoc-echo-area-use-multiline-p t)

(use-package eldoc-box
  :after eldoc
  :diminish
  :config
  (setq eldoc-box-only-multi-line t)
  (setq eldoc-box-lighter t)
  ;; (set-face-background 'eldoc-box-border nil)
  ;; (setq eldoc-box-fringe-use-same-bg nil)

  ;; (setq eldoc-box-clear nil) ;; Ensure padding is not cleared
  ;; (setq eldoc-box-padding 25) ;; Set padding to 5 pixels (adjust as needed)
  (add-hook 'eglot--managed-mode-hook #'eldoc-box-hover-at-point-mode t)
  )

;; Flymake ========================================= ;;
(use-package flymake
  :config
  (setq flymake-fringe-indicator-position 'left-fringe)
  (setq flymake-suppress-zero-counters t)
  (setq flymake-start-on-flymake-mode t)
  (setq flymake-no-changes-timeout nil)
  (setq flymake-start-on-save-buffer t)
  ;; (setq flymake-no-changes-timeout 0.1)
  (setq flymake-proc-compilation-prevents-syntax-check t)
  (setq flymake-wrap-around nil)
  (setq flymake-mode-line-format
        '("" flymake-mode-line-exception flymake-mode-line-counters))
  (setq flymake-mode-line-counter-format
        '(" " flymake-mode-line-error-counter
          flymake-mode-line-warning-counter
          flymake-mode-line-note-counter ""))

  ;; (define-key ctl-x-x-map "m" #'flymake-mode) ; C-x x m
  ;; (let ((map flymake-mode-map))
  ;;   (define-key map (kbd "C-c f s") #'flymake-start)
  ;;   (define-key map (kbd "C-c f d") #'flymake-show-buffer-diagnostics) ; Emacs28
  ;;   (define-key map (kbd "C-c f D") #'flymake-show-project-diagnostics) ; Emacs28
  ;;   (define-key map (kbd "C-c f n") #'flymake-goto-next-error)
  ;;   (define-key map (kbd "C-c f p") #'flymake-goto-prev-error))
  :init
  (add-hook 'prog-mode-hook 'flymake-mode)
  (add-hook 'text-mode-hook 'flymake-mode)
  (add-hook 'flymake-mode-hook
            (lambda ()
              (setq eldoc-documentation-functions
                    (cons 'flymake-eldoc-function
                          (delq 'flymake-eldoc-function eldoc-documentation-functions))))))

(use-package flymake-eslint
  :config
  (add-hook 'typescript-mode-hook
            (lambda ()
              (flymake-eslint-enable))))

;; Install emacs-lsp-booster first
(use-package eglot-booster
  :ensure t
  :straight (:type git :host github :repo "jdtsmith/eglot-booster")
  :after eglot
  :config
  (eglot-booster-mode))

;; (use-package eldoc-box
;;   :after eldoc
;;   :diminish
;;   :config
;;   (add-hook 'eglot--managed-mode-hook #'eldoc-box-hover-mode t)
;;   )

(use-package eglot
  :ensure t
  :custom
  :config
  (fset #'jsonrpc--log-event #'ignore)


  :hook
  (prog-mode . eglot-ensure)
  :config
  ;; (add-to-list 'eglot-stay-out-of 'flymake)
  ;; Keybindings
  (define-key eglot-mode-map (kbd "C-c c r") 'eglot-rename)
  (define-key eglot-mode-map (kbd "C-c c f") 'eglot-format-buffer)
  (define-key eglot-mode-map (kbd "C-c c o") 'eglot-code-action-organize-imports)
  (define-key eglot-mode-map (kbd "C-c c a") 'eglot-code-actions)
  (define-key eglot-mode-map (kbd "C-c c q") 'eglot-code-action-quickfix)
  (define-key eglot-mode-map (kbd "C-c c e") 'eglot-code-action-extract)
  (define-key eglot-mode-map (kbd "C-c c j") 'eglot-code-action-inline)
  (define-key eglot-mode-map (kbd "C-c c k") 'eglot-code-action-rewrite)

  (define-key eglot-mode-map (kbd "C-c c i") 'eglot-find-implementation)
  (define-key eglot-mode-map (kbd "C-c c d") 'eglot-find-declaration)
  (define-key eglot-mode-map (kbd "C-c c t") 'eglot-find-typeDefinition)
  (define-key eglot-mode-map (kbd "C-c c h") 'eldoc))
  ;; (define-key eglot-mode-map (kbd "C-c c d") 'xref-find-definitions))

;; Language Servers
;; (add-to-list 'eglot-server-programs '(csharp-mode . ("/run/current-system/sw/bin/omnisharp" "-lsp")))
;; (add-to-list 'eglot-server-programs '(typescript-mode . ("typescript-language-server" "--stdio")))
;; (add-to-list 'eglot-server-programs '(web-mode . ("typescript-language-server" "--stdio")))

;; Automatically start
;; (add-hook 'typescript-mode-hook 'eglot-ensure)
;; (add-hook 'web-mode-hook 'eglot-ensure)
;; (add-hook 'csharp-mode-hook 'eglot-ensure)
;; (add-hook 'rust-mode-hook 'eglot-ensure)
(use-package consult-eglot)

;; Flymake ========================================= ;;
(use-package flymake
  :config
  (setq flymake-fringe-indicator-position 'left-fringe)
  (setq flymake-suppress-zero-counters t)
  (setq flymake-start-on-flymake-mode t)
  (setq flymake-no-changes-timeout nil)
  (setq flymake-start-on-save-buffer t)
  ;; (setq flymake-no-changes-timeout 0.1)
  (setq flymake-proc-compilation-prevents-syntax-check t)
  (setq flymake-wrap-around nil)
  (setq flymake-mode-line-format
        '("" flymake-mode-line-exception flymake-mode-line-counters))
  (setq flymake-mode-line-counter-format
        '(" " flymake-mode-line-error-counter
          flymake-mode-line-warning-counter
          flymake-mode-line-note-counter ""))

  (define-key ctl-x-x-map "m" #'flymake-mode) ; C-x x m
  (let ((map flymake-mode-map))
    (define-key map (kbd "C-c f s") #'flymake-start)
    (define-key map (kbd "C-c f d") #'flymake-show-buffer-diagnostics) ; Emacs28
    (define-key map (kbd "C-c f D") #'flymake-show-project-diagnostics) ; Emacs28
    (define-key map (kbd "C-c f n") #'flymake-goto-next-error)
    (define-key map (kbd "C-c f p") #'flymake-goto-prev-error))
  :init
  (add-hook 'prog-mode-hook 'flymake-mode)
  (add-hook 'text-mode-hook 'flymake-mode)
  (add-hook 'flymake-mode-hook
            (lambda ()
              (setq eldoc-documentation-functions
                    (cons 'flymake-eldoc-function
                          (delq 'flymake-eldoc-function eldoc-documentation-functions))))))

;; (use-package flymake-eslint
;;   :config
;;   (add-hook 'typescript-mode-hook
;;             (lambda ()
;;               (flymake-eslint-enable))))


;; (use-package eglot
;;   :custom
;;   (eglot-send-changes-idle-time 0.0)
;;   (eglot-events-buffer-size 0)

;;   :config
;;   (fset #'jsonrpc--log-event #'ignore)

;;   :hook
;;   (prog-mode . eglot-ensure)
;;   (((go-ts-mode typescript-ts-mode js-ts-mode) . eglot)))
(use-package eglot
  ;; no :ensure t here because it's built-in

  ;; Configure hooks to automatically turn-on eglot for selected modes
  :hook
  (((python-ts-mode typescript-ts-mode go-ts-mode) . eglot))

  :custom
  (eglot-send-changes-idle-time 0.1)
  (eglot-events-buffer-size 0)

  :config
  (fset #'jsonrpc--log-event #'ignore)  ; massive perf boost---don't log every event
  ;; Sometimes you need to tell Eglot where to find the language server
  ; (add-to-list 'eglot-server-programs
  ;              '(haskell-mode . ("haskell-language-server-wrapper" "--lsp")))
  )
(use-package eglot
:ensure t)
(with-eval-after-load 'eglot
(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))))
(add-hook 'prog-mode-hook 'eglot-ensure)

Debug Adapter Support

(use-package dap-mode
  :straight t
  :custom
  (lsp-enable-dap-auto-configure nil)
  :config
  (dap-ui-mode 1)
  (dap-tooltip-mode 1)
  (require 'dap-node)
  (require 'dap-python)
  (require 'dap-cpptools)
  (dap-node-setup))

Copilot

(use-package copilot
  :straight (:host github :repo "copilot-emacs/copilot.el" :files ("dist" "*.el"))
  :hook (prog-mode . copilot-mode)
  :bind (:map copilot-completion-map
              ("C-<tab>" . 'copilot-accept-completion)
              ;; ("TAB" . 'copilot-accept-completion)
              ;; ("M-TAB" . 'copilot-accept-completion-by-word)
              ("M-<tab>" . 'copilot-accept-completion-by-word)))
              ;; ("C-TAB" . 'copilot-accept-completion-by-line)
              ;; ("C-<tab>" . 'copilot-accept-completion-by-line)))

Dev

(setq register-preview-delay 0) ;; Show registers ASAP

;; (set-register ?i (cons 'file (concat org-directory   "/cpb.org")))

(set-register ?z (cons 'file (concat "~/.zshrc")))


;; INTERACTION -----
(setq use-short-answers t) ;; When emacs asks for "yes" or "no", let "y" or "n" suffice
(setq confirm-kill-emacs nil) ;; Confirm to quit
;; (setq initial-major-mode 'org-mode ;; Major mode of new buffers
      ;; initial-scratch-message ""
      ;; initial-buffer-choice t) ;; Blank scratch buffer

  (setq evil-emacs-state-cursor '("#649bce" box))

;; ----- Setting cursor colors
  (setq evil-emacs-state-cursor    '("#649bce" box))
  (setq evil-normal-state-cursor   '("#d9a871" box))
  (setq evil-operator-state-cursor '("#ebcb8b" hollow))
  (setq evil-visual-state-cursor   '("#677691" box))
  (setq evil-insert-state-cursor   '("#eb998b" (bar . 2)))
  (setq evil-replace-state-cursor  '("#eb998b" hbar))
  (setq evil-motion-state-cursor   '("#ad8beb" box))


; Using in Emacs 24.0
(defvar blink-cursor-colors (list  "#92c48f" "#6785c5" "#be369c" "#d9ca65")
  "On each blink the cursor will cycle to the next color in this list.")

(setq blink-cursor-count 0)
(defun blink-cursor-timer-function ()
  "Zarza wrote this cyberpunk variant of timer `blink-cursor-timer'.
Warning: overwrites original version in `frame.el'.

This one changes the cursor color on each blink. Define colors in `blink-cursor-colors'."
  (when (not (internal-show-cursor-p))
    (when (>= blink-cursor-count (length blink-cursor-colors))
      (setq blink-cursor-count 0))
    (set-cursor-color (nth blink-cursor-count blink-cursor-colors))
    (setq blink-cursor-count (+ 1 blink-cursor-count))
    )
  (internal-show-cursor nil (not (internal-show-cursor-p)))
  )
(setq register-preview-delay 0) ;; Show registers ASAP
(set-register ?z (cons 'file (concat "~/.zshrc")))

;; INTERACTION -----
(setq use-short-answers t) ;; When emacs asks for "yes" or "no", let "y" or "n" suffice
(setq confirm-kill-emacs nil) ;; Confirm to quit

; Using in Emacs 24.0
(defvar blink-cursor-colors (list  "#92c48f" "#6785c5" "#be369c" "#d9ca65")
  "On each blink the cursor will cycle to the next color in this list.")

(setq blink-cursor-count 0)
(defun blink-cursor-timer-function ()
  "Zarza wrote this cyberpunk variant of timer `blink-cursor-timer'.
Warning: overwrites original version in `frame.el'.

This one changes the cursor color on each blink. Define colors in `blink-cursor-colors'."
  (when (not (internal-show-cursor-p))
    (when (>= blink-cursor-count (length blink-cursor-colors))
      (setq blink-cursor-count 0))
    (set-cursor-color (nth blink-cursor-count blink-cursor-colors))
    (setq blink-cursor-count (+ 1 blink-cursor-count))
    )
  (internal-show-cursor nil (not (internal-show-cursor-p)))
  )

(use-package denote
  :straight t
  :commands (denote-directory)
  :bind (("C-c n w" . denote)
  ("C-c n e" . denote-open-or-create))


  :custom ((denote-directory "~/Desktop/blog")
	   ;; These are the minimum viable prompts for notes
	   (denote-prompts '(title keywords))
	   ;; I love org-mode format; reading ahead I'm setting this
	   (denote-file-type 'org)
	   ;; And `org-read-date' is an amazing bit of tech
	   (denote-date-prompt-denote-date-prompt-use-org-read-date t)))
(global-set-key (kbd "C-c y") 'org-copy-blocks)

This little snippet here for the org-roam error on ox-hugo export.

(setq org-id-extra-files (directory-files-recursively "/home/shuv40/Desktop/repos/braindump/" "org"))

Keychord

Webkit

(use-package webkit-color-picker
  :ensure t
  :bind (("C-c C-p" . webkit-color-picker-show)))

(straight-use-package
 '(webkit :type git :host github :repo "akirakyle/emacs-webkit"
          :branch "main"
          :files (:defaults "*.js" "*.css" "*.so")
          :pre-build ("make")))
(use-package webkit)
  :bind ("s-b" 'webkit)) ;; Bind to whatever global key binding you want if you want
(use-package 'webkit-ace) ;; If you want link hinting
(use-package 'webkit-dark) ;; If you want to use the simple dark mode

Nichest mongo der hta

  • nimisan