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