aboutsummaryrefslogtreecommitdiff
path: root/Emacs
diff options
context:
space:
mode:
authorAryadev Chavali <aryadev@aryadevchavali.com>2020-08-06 15:15:21 +0100
committerAryadev Chavali <aryadev@aryadevchavali.com>2020-08-06 15:16:02 +0100
commit28da4f06348caf62822b7966b5f266c775a17e2a (patch)
tree96ba7ebb169cb88dfd627ba4de8dab8f30bf7f90 /Emacs
parent373518c3b1412b7621b73b8358eac3ae52ddc328 (diff)
downloaddotfiles-28da4f06348caf62822b7966b5f266c775a17e2a.tar.gz
dotfiles-28da4f06348caf62822b7966b5f266c775a17e2a.tar.bz2
dotfiles-28da4f06348caf62822b7966b5f266c775a17e2a.zip
+a lot of changes
Firstly, some org stuff to make everything flat (no indents). Secondly, a lot of new packages including general. Using general to manage all binds now. Reorganised code quite a bit
Diffstat (limited to 'Emacs')
-rw-r--r--Emacs/.config/emacs/config.org1391
1 files changed, 778 insertions, 613 deletions
diff --git a/Emacs/.config/emacs/config.org b/Emacs/.config/emacs/config.org
index e5650b3..4c056cf 100644
--- a/Emacs/.config/emacs/config.org
+++ b/Emacs/.config/emacs/config.org
@@ -4,670 +4,835 @@
* Initial
** Setup straight
- Bootstrap of straight (from github)
- #+BEGIN_SRC emacs-lisp
- (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))
- #+END_SRC
+Bootstrap of straight (from github)
+#+BEGIN_SRC emacs-lisp
+(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))
+#+END_SRC
** Setup use package
- Straight clone use-package and state that all use-package statements implicity use straight.
- #+BEGIN_SRC emacs-lisp
- (straight-use-package 'use-package)
- (setq straight-use-package-by-default t)
- #+END_SRC
+Straight clone use-package and state that all use-package statements implicity use straight.
+#+BEGIN_SRC emacs-lisp
+(straight-use-package 'use-package)
+(setq straight-use-package-by-default t)
+#+END_SRC
** Setup alpha and yes-or-no-p
- This just sets the alpha to 85% and all yes or no questions to single letter responses.
- #+BEGIN_SRC emacs-lisp
- (add-to-list 'default-frame-alist '(alpha . 85))
- (fset 'yes-or-no-p 'y-or-n-p)
- #+END_SRC
+This just sets the alpha to 85% and all yes or no questions to single letter responses.
+#+BEGIN_SRC emacs-lisp
+(add-to-list 'default-frame-alist '(alpha . 85))
+(fset 'yes-or-no-p 'y-or-n-p)
+#+END_SRC
** Hs Minor mode
- Turn on hs minor mode for all prog-mode.
- #+BEGIN_SRC emacs-lisp
- (add-hook 'prog-mode-hook #'hs-minor-mode)
- #+END_SRC
+Turn on hs minor mode for all prog-mode.
+#+BEGIN_SRC emacs-lisp
+(add-hook 'prog-mode-hook #'hs-minor-mode)
+#+END_SRC
** Set backup directory
- Set the backup directory to =user-emacs-directory=/saves so I don't get those annoying '~' files.
- #+BEGIN_SRC emacs-lisp
- (setq backup-directory-alist `(("." . "~/.config/emacs/saves")))
- #+END_SRC
+Set the backup directory to =user-emacs-directory=/saves so I don't get those annoying '~' files.
+#+BEGIN_SRC emacs-lisp
+(setq backup-directory-alist `(("." . "~/.config/emacs/saves")))
+#+END_SRC
** Turn off the bars
- Turn off all the bars, don't need them anymore!
- #+BEGIN_SRC emacs-lisp
- (tool-bar-mode -1)
- (scroll-bar-mode -1)
- (menu-bar-mode -1)
- #+END_SRC
+Turn off all the bars, don't need them anymore!
+#+BEGIN_SRC emacs-lisp
+(tool-bar-mode -1)
+(scroll-bar-mode -1)
+(menu-bar-mode -1)
+#+END_SRC
** Themes
- Load my custom "Grayscale" theme (look at [[file:Grayscale-theme.el][this file]]).
- #+BEGIN_SRC emacs-lisp
- (load-theme 'Grayscale t)
- #+END_SRC
+Load my custom "Grayscale" theme (look at [[file:Grayscale-theme.el][this file]]).
+#+BEGIN_SRC emacs-lisp
+(load-theme 'Grayscale t)
+#+END_SRC
** Turn off startup buffer
- #+BEGIN_SRC emacs-lisp
- (setq inhibit-startup-screen t)
- #+END_SRC
+#+BEGIN_SRC emacs-lisp
+(setq inhibit-startup-screen t)
+#+END_SRC
* Emacs Mode-line
- Firstly, declare a variable for the number of spaces between each module in the modeline.
- #+BEGIN_SRC emacs-lisp
- (defconst +modeline/sep-spaces 4 "Number of spaces separating modules.")
- #+END_SRC
+Firstly, declare a variable for the number of spaces between each module in the modeline.
+#+BEGIN_SRC emacs-lisp
+(defconst +modeline/sep-spaces 4 "Number of spaces separating modules.")
+#+END_SRC
- Then, declare a list of reserved characters for which the previously declared seperator won't be applied when placed at the end of a module string.
- #+BEGIN_SRC emacs-lisp
- (defconst +modeline/reserved-chars (list "[" "(")
- "Characters that, when at the end of a module string, won't have the separator applied to them.")
- #+END_SRC
+Then, declare a list of reserved characters for which the previously declared seperator won't be applied when placed at the end of a module string.
+#+BEGIN_SRC emacs-lisp
+(defconst +modeline/reserved-chars (list "[" "(")
+ "Characters that, when at the end of a module string, won't have the separator applied to them.")
+#+END_SRC
- Now declare a function that applies the separator with respect to the reserved characters to any one string.
- #+BEGIN_SRC emacs-lisp
- (defun +modeline/handle-string (STR)
- (condition-case nil
- (progn
- (string-blank-p STR)
- (cond ((cl-member (car (last (split-string STR "" t))) +modeline/reserved-chars :test #'string=) STR)
- (t (concat STR (cl-reduce #'concat (cl-loop for i from 1 to +modeline/sep-spaces collect " "))))))
- (error STR)))
- #+END_SRC
+Now declare a function that applies the separator with respect to the reserved characters to any one string.
+#+BEGIN_SRC emacs-lisp
+(defun +modeline/handle-string (STR)
+ (condition-case nil
+ (progn
+ (string-blank-p STR)
+ (cond ((cl-member (car (last (split-string STR "" t))) +modeline/reserved-chars :test #'string=) STR)
+ (t (concat STR (cl-reduce #'concat (cl-loop for i from 1 to +modeline/sep-spaces collect " "))))))
+ (error STR)))
+#+END_SRC
- Finally, set the mode-line-format.
- #+BEGIN_SRC emacs-lisp
- (setq-default
- mode-line-format
- (mapcar #'+modeline/handle-string
- (list "%l:%c"
- "%p["
- '(:eval (upcase
- (substring
- (format "%s" (if (bound-and-true-p evil-state) evil-state ""))
- 0 1)))
- "]"
- "%+%b("
- '(:eval (format "%s" major-mode))
- ")"
- "%I"
- vc-mode
- mode-line-end-spaces)))
- #+END_SRC
+Finally, set the mode-line-format.
+#+BEGIN_SRC emacs-lisp
+(setq-default
+ mode-line-format
+ (mapcar #'+modeline/handle-string
+ (list "%l:%c"
+ "%p["
+ '(:eval (upcase
+ (substring
+ (format "%s" (if (bound-and-true-p evil-state) evil-state ""))
+ 0 1)))
+ "]"
+ "%+%b("
+ '(:eval (format "%s" major-mode))
+ ")"
+ "%I"
+ vc-mode
+ mode-line-end-spaces)))
+#+END_SRC
* Custom Functions
- These are custom functions I have defined
+These are custom functions I have defined
** New line function
- Vim bindings don't have a nice way of adding new lines before or after the current line while staying in normal mode.
- You can use =o/O= to enter insert mode at a new line, but this isn't the same as being able to stay in normal mode, and only adds extra keypresses if your only purpose was to open up some lines.
- As this is Emacs I can extend it as I wish, so I decided to define a new line function that won't remove me from normal state.
+Vim bindings don't have a nice way of adding new lines before or after the current line while staying in normal mode.
+You can use =o/O= to enter insert mode at a new line, but this isn't the same as being able to stay in normal mode, and only adds extra keypresses if your only purpose was to open up some lines.
+As this is Emacs I can extend it as I wish, so I decided to define a new line function that won't remove me from normal state.
- The logic is pretty simple:
- - Use the predefined vim functions for opening new lines above and below with insert mode
- - Given the argument =BACKWARD= to assess whether to open lines above or below
- - Return to previous location
- - Enter normal state
+The logic is pretty simple:
+- Use the predefined vim functions for opening new lines above and below with insert mode
+ - Given the argument =BACKWARD= to assess whether to open lines above or below
+- Return to previous location
+- Enter normal state
- #+BEGIN_SRC emacs-lisp
- (with-eval-after-load "evil"
- (defun dx:newline (&optional BACKWARD)
- (interactive)
- (let ((old (point)))
- (cond ((and BACKWARD (= BACKWARD 1)) (evil-open-below 1))
- (t (evil-open-above 1)))
- (goto-char (+ old 1))
- (evil-normal-state))))
- #+END_SRC
+ #+BEGIN_SRC emacs-lisp
+ (with-eval-after-load "evil"
+ (defun dx:newline (&optional BACKWARD)
+ (interactive)
+ (let ((old (point)))
+ (cond ((and BACKWARD (= BACKWARD 1)) (evil-open-below 1))
+ (t (evil-open-above 1)))
+ (goto-char (+ old 1))
+ (evil-normal-state))))
+ #+END_SRC
** Generate tags
- For some reason, I can't seem to rely on the =projectile-regenerate-tags= function, so define my own.
+For some reason, I can't seem to rely on the =projectile-regenerate-tags= function, so define my own.
- Steps are as follows:
- - Consider the =root= to be either =default-directory= or the =projectile-project-root= depending on if it's loaded and set.
- - Start a process (shell command) by changing to =root= and executing =ctags -Re=
- #+BEGIN_SRC emacs-lisp
- (defun dx:generate-tags ()
- (interactive)
- (let ((root (if (bound-and-true-p projectile-project-root)
- projectile-project-root
- default-directory)))
- (start-process-shell-command "" nil (format "cd %s; ctags -Re ." root))))
- #+END_SRC
-* Keybindings
-** Global map
- Any functions that are already loaded, set them to the global map.
- #+BEGIN_SRC emacs-lisp
- (bind-keys
- :map global-map
- ("<menu>" . nil)
- ("M-v" . (lambda () (interactive) (dx:newline 1)))
- ("M-V" . (lambda () (interactive) (dx:newline)))
- ("M-z" . mark-whole-buffer)
- ("C-x h" . next-buffer)
- ("C-x l" . previous-buffer)
- ("C-c !" . async-shell-command)
- ("C-c c" . compile)
- ("C-c t" . eshell)
- ("M-s i" . imenu)
- ("M-n f" . narrow-to-defun)
- ("M-n w" . widen)
- ("M-n r" . narrow-to-region))
- #+END_SRC
-** Menu map
- Any keys I want to map to <menu>, the weird little menu interaction button on some keyboards.
- #+BEGIN_SRC emacs-lisp
- (bind-keys
- :prefix "<menu>"
- :prefix-map dx:menu-map
- ("<menu>" . execute-extended-command)
- ("p" . (lambda () (interactive) (find-file (concat user-emacs-directory "config.org"))))
- ("#" . (lambda () (interactive) (projectile-find-file)))
- ("." . imenu))
- #+END_SRC
+Steps are as follows:
+- Consider the =root= to be either =default-directory= or the =projectile-project-root= depending on if it's loaded and set.
+- Start a process (shell command) by changing to =root= and executing =ctags -Re=
+ #+BEGIN_SRC emacs-lisp
+ (defun dx:generate-tags ()
+ (interactive)
+ (let ((root (if (bound-and-true-p projectile-project-root)
+ projectile-project-root
+ default-directory)))
+ (start-process-shell-command "" nil (format "cd %s; ctags -Re ." root))))
+ #+END_SRC
+* General
+Setup general, a good package for defining keys.
+#+BEGIN_SRC emacs-lisp
+(use-package general
+ :config
+ (general-def 'normal global-map "SPC" nil)
+ (general-def 'normal global-map
+ "M-V" #'dx:newline
+ "M-v" #'(lambda () (interactive) (dx:newline 1)))
+
+ (general-create-definer leader
+ :states 'normal
+ :keymaps 'override
+ :prefix "SPC")
+
+ (leader
+ "SPC" #'execute-extended-command
+ "u" #'universal-argument
+ "si" #'imenu
+ "h" #'help-command)
+
+ (leader
+ :infix "b"
+ "d" #'kill-this-buffer
+ "i" #'ibuffer
+ "b" #'switch-to-buffer)
+
+ (leader
+ :infix "f"
+ "f" #'find-file
+ "s" #'save-buffer
+ "p" #'(lambda () (interactive) (find-file (concat user-emacs-directory "config.org")))))
+#+END_SRC
* Evil
** Evil default
- Setup the evil package, with some basic keybinds.
- Also declare a leader-map at "SPC".
- #+BEGIN_SRC emacs-lisp
- (use-package evil
- :init
- (setq evil-want-keybinding nil)
- :config
- (evil-mode +1)
- (evil-define-key 'normal global-map
- "TAB" #'evil-jump-item
- "SPC" nil)
- (evil-define-key 'visual 'emacs-lisp-mode-map "gr" #'eval-region)
- (bind-keys
- :map evil-normal-state-map
- :prefix "SPC"
- :prefix-map +evil/leader-map
- ("f" . find-file)
- ("s" . save-buffer)
- ("q" . save-buffers-kill-terminal)
- ("i" . imenu)
- ("b" . switch-to-buffer)))
- #+END_SRC
+Setup the evil package, with some basic keybinds.
+Also declare a leader-map at "SPC".
+#+BEGIN_SRC emacs-lisp
+(use-package evil
+ :init
+ (setq evil-want-keybinding nil)
+ :config
+ (evil-mode +1)
+ (evil-define-key 'normal global-map
+ "TAB" #'evil-jump-item)
+ (evil-define-key 'visual 'emacs-lisp-mode-map "gr" #'eval-region))
+#+END_SRC
** Evil surround
- #+BEGIN_SRC emacs-lisp
- (use-package evil-surround
- :after evil
- :config
- (global-evil-surround-mode))
- #+END_SRC
+#+BEGIN_SRC emacs-lisp
+(use-package evil-surround
+ :after evil
+ :config
+ (global-evil-surround-mode))
+#+END_SRC
** Evil commentary
- #+BEGIN_SRC emacs-lisp
- (use-package evil-commentary
- :after evil
- :config
- (evil-commentary-mode))
- #+END_SRC
+#+BEGIN_SRC emacs-lisp
+(use-package evil-commentary
+ :after evil
+ :config
+ (evil-commentary-mode))
+#+END_SRC
** Evil mc
- Setup for multicursors in Evil mode.
- Don't let evil-mc setup it's own keymap because it uses 'gr' as its prefix, which I don't like.
- Instead, bind some useful functions to my personal =dx:evil-mc-map= which is bound to 'gz'.
- Furthermore, define a function =dx:evil-mc-cursor-here= which pauses cursors upon placing a cursor at the current position.
- #+BEGIN_SRC emacs-lisp
- (use-package evil-mc
- :after evil
- :bind (("M-p" . evil-mc-skip-and-goto-prev-cursor)
- :map dx:evil-mc-map
- ("q" . evil-mc-undo-all-cursors)
- ("d" . evil-mc-make-and-goto-next-match)
- ("j" . evil-mc-make-cursor-move-next-line)
- ("k" . evil-mc-make-cursor-move-prev-line)
- ("j" . evil-mc-make-cursor-move-next-line)
- ("m" . evil-mc-make-all-cursors)
- ("z" . dx:evil-mc-cursor-here)
- ("r" . evil-mc-resume-cursors)
- ("s" . evil-mc-pause-cursors))
- :init
- (defvar evil-mc-key-map (make-sparse-keymap))
- (define-prefix-command 'dx:evil-mc-map)
- (bind-key "gz" dx:evil-mc-map evil-normal-state-map)
- (bind-key "gz" dx:evil-mc-map evil-visual-state-map)
- :config
- (global-evil-mc-mode +1)
- (defun dx:evil-mc-cursor-here ()
- (interactive)
- (evil-mc-make-cursor-here)
- (evil-mc-pause-cursors)))
- #+END_SRC
+Setup for multicursors in Evil mode.
+Don't let evil-mc setup it's own keymap because it uses 'gr' as its prefix, which I don't like.
+Instead, bind some useful functions to my personal =dx:evil-mc-map= which is bound to 'gz'.
+Furthermore, define a function =dx:evil-mc-cursor-here= which pauses cursors upon placing a cursor at the current position.
+#+BEGIN_SRC emacs-lisp
+(use-package evil-mc
+ :after evil
+ :bind (("M-p" . evil-mc-skip-and-goto-prev-cursor)
+ :map dx:evil-mc-map
+ ("q" . evil-mc-undo-all-cursors)
+ ("d" . evil-mc-make-and-goto-next-match)
+ ("j" . evil-mc-make-cursor-move-next-line)
+ ("k" . evil-mc-make-cursor-move-prev-line)
+ ("j" . evil-mc-make-cursor-move-next-line)
+ ("m" . evil-mc-make-all-cursors)
+ ("z" . dx:evil-mc-cursor-here)
+ ("r" . evil-mc-resume-cursors)
+ ("s" . evil-mc-pause-cursors))
+ :init
+ (defvar evil-mc-key-map (make-sparse-keymap))
+ (define-prefix-command 'dx:evil-mc-map)
+ (bind-key "gz" dx:evil-mc-map evil-normal-state-map)
+ :config
+ (global-evil-mc-mode +1)
+ (defun dx:evil-mc-cursor-here ()
+ (interactive)
+ (evil-mc-make-cursor-here)
+ (evil-mc-pause-cursors)))
+#+END_SRC
** Evil collection
- Setup evil collection, but don't turn on the mode.
- Instead, I'll turn on setups for specific modes I think benefit from it.
- #+BEGIN_SRC emacs-lisp
- (use-package evil-collection
- :after evil)
- #+END_SRC
-* IBuffer
- #+BEGIN_SRC emacs-lisp
- (use-package ibuffer
- :bind ("<menu> ," . ibuffer)
- :after evil-collection
- :config
- (evil-collection-ibuffer-setup))
- #+END_SRC
+Setup evil collection, but don't turn on the mode.
+Instead, I'll turn on setups for specific modes I think benefit from it.
+#+BEGIN_SRC emacs-lisp
+(use-package evil-collection
+ :after evil)
+#+END_SRC
+* Ivy
+Ivy is a completion framework for Emacs, and my preferred (sometimes second favourite) one.
+It has a great set of features with little to no pain with setting up.
+** Ivy
+Setup for ivy, in preparation for counsel.
+Turn on ivy-mode just after init.
+Setup vim-like bindings for the minibuffer ("C-(j|k)" for down|up the selection list)
+Also setup evil-collection for ivy.
+#+BEGIN_SRC emacs-lisp
+(use-package ivy
+ :hook (after-init . ivy-mode)
+ :after evil-collection
+ :bind (:map ivy-minibuffer-map
+ ("C-j" . ivy-next-line-or-history)
+ ("C-k" . ivy-previous-line-or-history)
+ :map ivy-switch-buffer-map
+ ("C-j" . ivy-next-line-or-history)
+ ("C-k" . ivy-previous-line-or-history))
+ :general
+ (:keymaps 'ivy-minibuffer-map
+ "C-c C-e" #'ivy-occur)
+ :config
+ (require 'counsel nil t)
+ (setq ivy-height 10
+ ivy-wrap t
+ ivy-fixed-height-minibuffer t
+ ivy-use-virtual-buffers nil
+ ivy-virtual-abbreviate 'full
+ ivy-on-del-error-function #'ignore
+ ivy-use-selectable-prompt t
+ ivy-initial-inputs-alist nil)
+ (evil-collection-ivy-setup))
+#+END_SRC
+** Counsel
+Setup for counsel.
+Load after ivy and helpful.
+
+Bind:
+- Swiper to "C-s"
+- Switch buffer to "C-x b"
+- Counsel ripgrep to "M-s r" (search namespace)
+
+Along with that, set the help function and variable functions to their helpful counterparts.
+#+BEGIN_SRC emacs-lisp
+(use-package counsel
+ :defer t
+ :general
+ (leader
+ :infix "s"
+ "s" #'counsel-grep-or-swiper)
+ :init
+ (general-def
+ [remap describe-function] #'counsel-describe-function
+ [remap describe-variable] #'counsel-describe-variable
+ [remap describe-bindings] #'counsel-descbinds
+ [remap describe-face] #'counsel-faces
+ [remap execute-extended-command] #'counsel-M-x
+ [remap find-file] #'counsel-find-file
+ [remap imenu] #'counsel-imenu
+ [remap load-theme] #'counsel-load-theme)
+ :config
+ (setq ivy-initial-inputs-alist nil)
+ (setq counsel-describe-function-function #'helpful-callable
+ counsel-describe-variable-function #'helpful-variable))
+#+END_SRC
+** Counsel etags
+Counsel etags allows me to search generated tag files for tags.
+I already have a function defined [[*Generate tags][here]] to generate the tags, so it's just searching them which I find to be a bit of a hassle, and where this package comes in.
+#+BEGIN_SRC emacs-lisp
+(use-package counsel-etags
+ :after counsel
+ :bind ("M-s t" . counsel-etags-find-tag))
+#+END_SRC
+* Avy
+Setup avy with leader.
+#+BEGIN_SRC emacs-lisp
+(use-package avy
+ :after evil
+ :general
+ (leader
+ :infix "s"
+ "l" #'avy-goto-line
+ "g" #'avy-goto-char-2))
+#+END_SRC
+* Projectile
+Setup projectile, along with the tags command.
+Also bind "C-c C-p" to the projectile command map for quick access.
+#+BEGIN_SRC emacs-lisp
+(use-package projectile
+ :after evil
+ :hook (prog-mode . projectile-mode)
+ :init
+ (setq projectile-tags-command "ctags -Re -f \"%s\" %s \"%s\"")
+ :config
+ (projectile-global-mode))
+#+END_SRC
+** Counsel projectile
+Counsel projectile provides the ivy interface to projectile commands, which is really useful.
+#+BEGIN_SRC emacs-lisp
+(use-package counsel-projectile
+ :after (projectile counsel)
+ :config
+ (counsel-projectile-mode +1))
+#+END_SRC
+* Mail
+** Notmuch
+#+BEGIN_SRC emacs-lisp
+(setq +mail/signature "---------------\nAryadev Chavali")
+(use-package notmuch
+ :commands notmuch
+ :custom
+ ((notmuch-show-logo nil)
+ (message-signature +mail/signature)
+ (mail-signature +mail/signature))
+ :init
+ (defun +mail/sync-mail ()
+ "Sync mail via mbsync."
+ (interactive)
+ (start-process-shell-command "" nil "mbsync -a"))
+ :config
+ (evil-collection-notmuch-setup))
+#+END_SRC
+** Smtpmail
+#+BEGIN_SRC emacs-lisp
+(use-package smtpmail
+ :commands mail-send
+ :after notmuch
+ :custom
+ ((smtpmail-smtp-server "mail.aryadevchavali.com")
+ (smtpmail-smtp-user "aryadev")
+ (smtpmail-smtp-service 587)
+ (smtpmail-stream-type 'starttls))
+ :init
+ (setq send-mail-function #'smtpmail-send-it
+ message-send-mail-function #'smtpmail-send-it))
+#+END_SRC
+
* Dired
- Setup for dired.
- Firstly, as it's an inbuilt package don't let straight try and download it.
- Make dired-hide-details-mode the default mode when dired-mode, as it removes the clutter.
- Create a keymap =dx:dired-map= which is bound to the prefix "C-c d", binding useful dired functions.
- Setup evil collection for dired (even though dired doesn't really conflict with evil, there are some black corners I'd like to adjust)
- #+BEGIN_SRC emacs-lisp
- (use-package dired
- :straight nil
- :hook (dired-mode . dired-hide-details-mode)
- :bind (:map +evil/leader-map
- ("d" . dired-jump))
- :bind-keymap* ("C-c d" . dx:dired-map)
- :after evil-collection
- :init
- (defvar dx:dired-map (make-sparse-keymap) "dx:dired-map")
- :config
- (bind-keys
- :map dx:dired-map
- ("f" . find-dired)
- ("D" . dired-other-window)
- ("d" . dired-jump))
- (evil-collection-dired-setup))
- #+END_SRC
+Setup for dired.
+Firstly, as it's an inbuilt package don't let straight try and download it.
+Make dired-hide-details-mode the default mode when dired-mode, as it removes the clutter.
+Create a keymap =dx:dired-map= which is bound to the prefix "C-c d", binding useful dired functions.
+Setup evil collection for dired (even though dired doesn't really conflict with evil, there are some black corners I'd like to adjust)
+#+BEGIN_SRC emacs-lisp
+(use-package dired
+ :straight nil
+ :hook (dired-mode . dired-hide-details-mode)
+ :after evil-collection
+ :general
+ (leader
+ :infix "d"
+ "f" #'find-dired
+ "D" #'dired-other-window
+ "d" #'dired-jump)
+ :config
+ (evil-collection-dired-setup))
+#+END_SRC
+* Hydra
+Use hydras for stuff that I use often, currently buffer manipulation
+#+BEGIN_SRC emacs-lisp
+(use-package hydra
+ :after evil
+ :init
+ (defun dx:kill-defun ()
+ "Mark defun then kill it."
+ (interactive)
+ (mark-defun)
+ (delete-active-region t))
+
+ (defun dx:paste-section ()
+ "Paste the current kill-region content above section."
+ (interactive)
+ (open-line 1)
+ (yank))
+
+ :config
+ (defhydra hydra-buffer (evil-normal-state-map "SPC b")
+ "buffer-hydra"
+ ("j" next-buffer)
+ ("k" previous-buffer)
+ ("c" kill-this-buffer))
+
+ (defhydra hydra-code-manipulator (global-map "C-x c")
+ "code-manip"
+ ("j" evil-forward-section-begin)
+ ("k" evil-backward-section-begin)
+ ("m" mark-defun)
+ ("d" dx:kill-defun)
+ ("p" dx:paste-section)
+ ("TAB" evil-toggle-fold)))
+#+END_SRC
+* IBuffer
+#+BEGIN_SRC emacs-lisp
+(use-package ibuffer
+ :after evil-collection
+ :config
+ (evil-collection-ibuffer-setup))
+#+END_SRC
* Helpful
- Basic setup, will be fully integrated in counsel.
- #+BEGIN_SRC emacs-lisp
- (use-package helpful
- :commands (helpful-callable helpful-variable))
- #+END_SRC
+Basic setup, will be fully integrated in counsel.
+#+BEGIN_SRC emacs-lisp
+(use-package helpful
+ :commands (helpful-callable helpful-variable)
+ :init
+ (evil-define-key 'normal helpful-mode-map "q" #'quit-window))
+#+END_SRC
* Which-key
- Pretty simple, just activate after init.
- #+BEGIN_SRC emacs-lisp
- (use-package which-key
- :hook (after-init . which-key-mode))
- #+END_SRC
-* Avy
- Avy is an incredibly useful package that I have just started to understand.
- For now, I have two bindings for =avy-goto-line= and =avy-goto-char-2= as I use them often.
- #+BEGIN_SRC emacs-lisp
- (use-package avy
- :bind (("M-g" . #'avy-goto-char-2)
- ("M-l" . #'avy-goto-line)))
- #+END_SRC
-* Hydra
- I haven't found a use for it yet, so don't tangle this.
- #+BEGIN_SRC emacs-lisp :tangle no
- (use-package hydra)
- #+END_SRC
+Pretty simple, just activate after init.
+#+BEGIN_SRC emacs-lisp
+(use-package which-key
+ :hook (after-init . which-key-mode))
+#+END_SRC
* Yasnippet
- Yasnippet is a great package for snippets, which I use heavily in programming and org-mode.
- I setup here the global mode for yasnippet and a collection of snippets for ease of use.
+Yasnippet is a great package for snippets, which I use heavily in programming and org-mode.
+I setup here the global mode for yasnippet and a collection of snippets for ease of use.
** Yasnippet default
- Setup global mode after evil mode has been loaded
- #+BEGIN_SRC emacs-lisp
- (use-package yasnippet
- :after evil
- :hook (after-init . yas-global-mode)
- :bind ("C-c i" . yas-insert-snippet))
- #+END_SRC
+Setup global mode after evil mode has been loaded
+#+BEGIN_SRC emacs-lisp
+(use-package yasnippet
+ :after evil
+ :hook ((prog-mode . yas-minor-mode)
+ (text-mode . yas-minor-mode))
+ :general
+ (leader
+ "i" #'yas-insert-snippet))
+#+END_SRC
** Yasnippet snippets
- Collection of snippets, activate after yasnippet has been loaded.
- #+BEGIN_SRC emacs-lisp
- (use-package yasnippet-snippets
- :after yasnippet)
- #+END_SRC
+Collection of snippets, activate after yasnippet has been loaded.
+#+BEGIN_SRC emacs-lisp
+(use-package yasnippet-snippets
+ :after yasnippet)
+#+END_SRC
* Keychord
- Keychord is only really here for this one chord I wish to define: "jk" for exiting insert state.
- Otherwise, I don't really need it.
- #+BEGIN_SRC emacs-lisp
- (use-package key-chord
- :after evil
- :config
- (key-chord-define evil-insert-state-map "jk" #'evil-normal-state)
- (key-chord-mode +1))
- #+END_SRC
-* Ivy
- Ivy is a completion framework for Emacs, and my preferred (sometimes second favourite) one.
- It has a great set of features with little to no pain with setting up.
-** Ivy
- Setup for ivy, in preparation for counsel.
- Turn on ivy-mode just after init.
- Setup vim-like bindings for the minibuffer ("C-(j|k)" for down|up the selection list)
- Also setup evil-collection for ivy.
- #+BEGIN_SRC emacs-lisp
- (use-package ivy
- :after evil-collection
- :hook (after-init . ivy-mode)
- :bind (:map ivy-minibuffer-map
- ("C-j" . ivy-next-line-or-history)
- ("C-k" . ivy-previous-line-or-history)
- :map ivy-switch-buffer-map
- ("C-j" . ivy-next-line-or-history)
- ("C-k" . ivy-previous-line-or-history))
- :config
- (evil-collection-ivy-setup))
-
-
- #+END_SRC
-** Counsel
- Setup for counsel.
- Load after ivy and helpful.
-
- Bind:
- - Swiper to "C-s"
- - Switch buffer to "C-x b"
- - Counsel ripgrep to "M-s r" (search namespace)
-
- Along with that, set the help function and variable functions to their helpful counterparts.
- #+BEGIN_SRC emacs-lisp
- (use-package counsel
- :after (ivy helpful)
- :bind (("C-s" . counsel-grep-or-swiper)
- ("C-x b" . counsel-switch-buffer))
- :config
- (setq ivy-initial-inputs-alist nil
- counsel-describe-function-function #'helpful-callable
- counsel-describe-variable-function #'helpful-variable))
- #+END_SRC
-** Counsel etags
- Counsel etags allows me to search generated tag files for tags.
- I already have a function defined [[*Generate tags][here]] to generate the tags, so it's just searching them which I find to be a bit of a hassle, and where this package comes in.
- #+BEGIN_SRC emacs-lisp
- (use-package counsel-etags
- :after counsel
- :bind ("M-s t" . counsel-etags-find-tag))
- #+END_SRC
+Keychord is only really here for this one chord I wish to define: "jk" for exiting insert state.
+Otherwise, I don't really need it.
+#+BEGIN_SRC emacs-lisp
+(use-package key-chord
+ :after evil
+ :config
+ (key-chord-define evil-insert-state-map "jk" #'evil-normal-state)
+ (key-chord-mode +1))
+#+END_SRC
* Ripgrep
- The ripgrep package provides utilities to grep projects and files for strings via the rg tool.
- Though [[*Ivy][ivy]] comes with =counsel-rg= using it makes me dependent on the ivy framework, and this configuration is intentionally built to be modular and switchable.
- #+BEGIN_SRC emacs-lisp
- (use-package rg
- :after evil
- :bind (("M-s r" . rg)
- :map +evil/leader-map
- ("r" . rg)
- :map rg-mode-map
- ("]]" . rg-next-file)
- ("[[" . rg-prev-file))
- :init
- (setq rg-group-result t
- rg-hide-command t
- rg-show-columns nil
- rg-show-header t
- rg-custom-type-aliases nil
- rg-default-alias-fallback "all"))
- #+END_SRC
-* Projectile
-** Projectile default
- Setup projectile, along with the tags command.
- Also bind "C-c C-p" to the projectile command map for quick access.
- #+BEGIN_SRC emacs-lisp
- (use-package projectile
- :after evil
- :hook (prog-mode . projectile-mode)
- :bind (:map +evil/leader-map
- ("p" . projectile-switch-buffer))
- :bind-keymap* ("C-c C-p" . projectile-command-map)
- :init
- (setq projectile-tags-command "ctags -Re -f \"%s\" %s \"%s\"")
- :config
- (projectile-global-mode))
- #+END_SRC
-** Counsel projectile
- Counsel projectile provides the ivy interface to projectile commands, which is really useful.
- #+BEGIN_SRC emacs-lisp
- (use-package counsel-projectile
- :after (projectile counsel)
- :config
- (counsel-projectile-mode +1))
- #+END_SRC
+The ripgrep package provides utilities to grep projects and files for strings via the rg tool.
+Though [[*Ivy][ivy]] comes with =counsel-rg= using it makes me dependent on the ivy framework, and this configuration is intentionally built to be modular and switchable.
+#+BEGIN_SRC emacs-lisp
+(use-package rg
+ :after evil
+ :general
+ (leader "r" #'rg)
+ (:keymaps 'rg-mode-map
+ "]]" #'rg-next-file
+ "[[" #'rg-prev-file)
+ :init
+ (setq rg-group-result t
+ rg-hide-command t
+ rg-show-columns nil
+ rg-show-header t
+ rg-custom-type-aliases nil
+ rg-default-alias-fallback "all"))
+#+END_SRC
* Magit
- Magit is *the* git porcelain for Emacs, which perfectly encapsulates the git cli.
- In this case, I just need to setup the bindings for it.
- As magit will definitely load after evil (as it must be run by a binding, and evil will load after init), I can use evil-collection freely.
- #+BEGIN_SRC emacs-lisp
- (use-package magit
- :bind (("C-x g g" . magit-status)
- ("C-x g c" . magit-clone)
- ("C-x g l" . magit-log)
- :map +evil/leader-map
- ("g" . magit-status)))
+Magit is *the* git porcelain for Emacs, which perfectly encapsulates the git cli.
+In this case, I just need to setup the bindings for it.
+As magit will definitely load after evil (as it must be run by a binding, and evil will load after init), I can use evil-collection freely.
+#+BEGIN_SRC emacs-lisp
+(use-package magit
+ :general
+ (leader "g" #'magit-status))
- (use-package evil-magit
- :after magit)
- #+END_SRC
+(use-package evil-magit
+ :after magit)
+#+END_SRC
* Company
- Company is the auto complete system I use.
- I don't like having heavy setups for company, as it only makes it worse to use.
- In this case, just setup some evil binds for company
- #+BEGIN_SRC emacs-lisp
- (use-package company
- :hook (prog-mode . company-mode)
- :bind (("C-SPC" . company-complete)
- :map company-active-map
- ("C-j" . company-select-next)
- ("C-k" . company-select-previous)))
- #+END_SRC
+Company is the auto complete system I use.
+I don't like having heavy setups for company, as it only makes it worse to use.
+In this case, just setup some evil binds for company
+#+BEGIN_SRC emacs-lisp
+(use-package company
+ :hook (prog-mode . company-mode)
+ :bind (("C-SPC" . company-complete)
+ :map company-active-map
+ ("C-j" . company-select-next)
+ ("C-k" . company-select-previous)))
+#+END_SRC
* Elfeed
- Elfeed is the perfect RSS feed reader, integrated into Emacs perfectly.
- I've got a set of feeds that I use for a large variety of stuff, mostly media and entertainment.
- I've also bound "C-c r" to elfeed for loading the system.
- #+BEGIN_SRC emacs-lisp
- (use-package elfeed
- :bind ("C-c r" . elfeed)
- :init
- (setq +rss/feed-urls
- '(("Arch Linux" "https://www.archlinux.org/feeds/news/" Linux)
- ("LEMMiNO" "https://www.youtube.com/feeds/videos.xml?channel_id=UCRcgy6GzDeccI7dkbbBna3Q" YouTube Stories)
- ("Dark Sominium" "https://www.youtube.com/feeds/videos.xml?channel_id=UC_e39rWdkQqo5-LbiLiU10g" YouTube Stories)
- ("Dark Sominium Music" "https://www.youtube.com/feeds/videos.xml?channel_id=UCkLiZ_zLynyNd5fd62hg1Kw" YouTube Music)
- ("Nexpo" "https://www.youtube.com/feeds/videos.xml?channel_id=UCpFFItkfZz1qz5PpHpqzYBw" YouTube)
- ("Techquickie" "https://www.youtube.com/feeds/videos.xml?channel_id=UC0vBXGSyV14uvJ4hECDOl0Q" YouTube)
- ("Captain Sinbad" "https://www.youtube.com/feeds/videos.xml?channel_id=UC8XKyvQ5Ne_bvYbgv8LaIeg" YouTube)
- ("3B1B" "https://www.youtube.com/feeds/videos.xml?channel_id=UCYO_jab_esuFRV4b17AJtAw" YouTube)
- ("Fredrik Knusden" "https://www.youtube.com/feeds/videos.xml?channel_id=UCbWcXB0PoqOsAvAdfzWMf0w" YouTube Stories)
- ("Barely Sociable" "https://www.youtube.com/feeds/videos.xml?channel_id=UC9PIn6-XuRKZ5HmYeu46AIw" YouTube Stories)
- ("Atrocity Guide" "https://www.youtube.com/feeds/videos.xml?channel_id=UCn8OYopT9e8tng-CGEWzfmw" YouTube Stories)
- ("Phillip Defranco" "https://www.youtube.com/feeds/videos.xml?channel_id=UClFSU9_bUb4Rc6OYfTt5SPw" YouTube News)
- ("Hacker News" "http://morss.aryadevchavali.com/news.ycombinator.com/rss" Social)
- ("Hacker Factor" "https://www.hackerfactor.com/blog/index.php?/feeds/index.rss2" Social)
- ("BBC Top News" "http://morss.aryadevchavali.com/feeds.bbci.co.uk/news/rss.xml" News)
- ("BBC Tech News" "http://morss.aryadevchavali.com/feeds.bbci.co.uk/news/technology/rss.xml" News)))
- (setq elfeed-db-directory (concat user-emacs-directory "elfeed"))
- :config
- (evil-collection-elfeed-setup)
- (evil-define-key 'normal elfeed-search-mode-map "gr" #'elfeed-update)
- (evil-define-key 'normal elfeed-search-mode-map "s" #'elfeed-search-live-filter)
- (evil-define-key 'normal elfeed-search-mode-map "<return>" #'elfeed-search-show-entry)
- (setq elfeed-feeds (mapc #'(lambda (item) (append (list (nth 1 item)) (cdr (cdr item)))) +rss/feed-urls)))
- #+END_SRC
+Elfeed is the perfect RSS feed reader, integrated into Emacs perfectly.
+I've got a set of feeds that I use for a large variety of stuff, mostly media and entertainment.
+I've also bound "C-c r" to elfeed for loading the system.
+#+BEGIN_SRC emacs-lisp
+(use-package elfeed
+ :init
+ (setq +rss/feed-urls
+ '(("Arch Linux" "https://www.archlinux.org/feeds/news/" Linux)
+ ("LEMMiNO" "https://www.youtube.com/feeds/videos.xml?channel_id=UCRcgy6GzDeccI7dkbbBna3Q" YouTube Stories)
+ ("Dark Sominium" "https://www.youtube.com/feeds/videos.xml?channel_id=UC_e39rWdkQqo5-LbiLiU10g" YouTube Stories)
+ ("Dark Sominium Music" "https://www.youtube.com/feeds/videos.xml?channel_id=UCkLiZ_zLynyNd5fd62hg1Kw" YouTube Music)
+ ("Nexpo" "https://www.youtube.com/feeds/videos.xml?channel_id=UCpFFItkfZz1qz5PpHpqzYBw" YouTube)
+ ("Techquickie" "https://www.youtube.com/feeds/videos.xml?channel_id=UC0vBXGSyV14uvJ4hECDOl0Q" YouTube)
+ ("Captain Sinbad" "https://www.youtube.com/feeds/videos.xml?channel_id=UC8XKyvQ5Ne_bvYbgv8LaIeg" YouTube)
+ ("3B1B" "https://www.youtube.com/feeds/videos.xml?channel_id=UCYO_jab_esuFRV4b17AJtAw" YouTube)
+ ("Fredrik Knusden" "https://www.youtube.com/feeds/videos.xml?channel_id=UCbWcXB0PoqOsAvAdfzWMf0w" YouTube Stories)
+ ("Barely Sociable" "https://www.youtube.com/feeds/videos.xml?channel_id=UC9PIn6-XuRKZ5HmYeu46AIw" YouTube Stories)
+ ("Atrocity Guide" "https://www.youtube.com/feeds/videos.xml?channel_id=UCn8OYopT9e8tng-CGEWzfmw" YouTube Stories)
+ ("Philip Defranco" "https://www.youtube.com/feeds/videos.xml?channel_id=UClFSU9_bUb4Rc6OYfTt5SPw" YouTube News)
+ ("Hacker News" "http://morss.aryadevchavali.com/news.ycombinator.com/rss" Social)
+ ("Hacker Factor" "https://www.hackerfactor.com/blog/index.php?/feeds/index.rss2" Social)
+ ("BBC Top News" "http://morss.aryadevchavali.com/feeds.bbci.co.uk/news/rss.xml" News)
+ ("BBC Tech News" "http://morss.aryadevchavali.com/feeds.bbci.co.uk/news/technology/rss.xml" News)))
+ (setq elfeed-db-directory (concat user-emacs-directory "elfeed"))
+ :config
+ (evil-collection-elfeed-setup)
+ (evil-define-key 'normal elfeed-search-mode-map "gr" #'elfeed-update)
+ (evil-define-key 'normal elfeed-search-mode-map "s" #'elfeed-search-live-filter)
+ (evil-define-key 'normal elfeed-search-mode-map "<return>" #'elfeed-search-show-entry)
+ (setq elfeed-feeds (cl-map 'list #'(lambda (item) (append (list (nth 1 item)) (cdr (cdr item)))) +rss/feed-urls)))
+#+END_SRC
* Org mode
** Org default with evil
- Setup for org mode, currently basically nothing.
- Has evil-org for evil bindings.
- #+BEGIN_SRC emacs-lisp
- (use-package org
- :hook (org-mode . yas-minor-mode)
- :bind (:map org-mode-map
- ([remap imenu] . counsel-org-goto))
- :custom
- (org-src-window-setup 'current-window))
+Setup for org mode, currently basically nothing.
+Has evil-org for evil bindings.
+#+BEGIN_SRC emacs-lisp
+(use-package org
+ :hook (org-mode . yas-minor-mode)
+ :bind (:map org-mode-map
+ ([remap imenu] . counsel-org-goto))
+ :custom
+ ((org-edit-src-content-indentation 0)
+ (org-src-window-setup 'current-window)
+ (org-indirect-buffer-display 'current-window)
+ (org-eldoc-breadcrumb-separator " → ")
+ (org-enforce-todo-dependencies t)
+ (org-entities-user '(("flat" "\\flat" nil "" "" "266D" "♭") ("sharp" "\\sharp" nil "" "" "266F" "♯")))
+ (org-fontify-quote-and-verse-blocks t)
+ (org-fontify-whole-heading-line t)
+ (org-footnote-auto-label 'plain)
+ (org-hide-leading-stars t)
+ (org-image-actual-width nil)
+ (org-priority-faces '((?A . error) (?B . warning) (?C . success)))
+ (org-startup-indented t)
+ (org-tags-column 0)
+ (org-use-sub-superscripts '{})))
- (use-package evil-org
- :hook (org-mode . evil-org-mode))
- #+END_SRC
+(use-package evil-org
+ :hook (org-mode . evil-org-mode))
+#+END_SRC
** Org superstar
- #+BEGIN_SRC emacs-lisp
- (use-package org-superstar
- :hook (org-mode . org-superstar-mode))
- #+END_SRC
+#+BEGIN_SRC emacs-lisp
+(use-package org-superstar
+ :hook (org-mode . org-superstar-mode))
+#+END_SRC
** Flyspell
- #+BEGIN_SRC emacs-lisp
- (use-package flyspell
- :hook (org-mode . flyspell-mode))
+#+BEGIN_SRC emacs-lisp
+(use-package flyspell
+ :hook (org-mode . flyspell-mode))
- (use-package flyspell-correct-ivy
- :after flyspell
- :bind (:map org-mode-map
- ("C-c C-a" . flyspell-correct-at-point)))
- #+END_SRC
+(use-package flyspell-correct-ivy
+ :after flyspell
+ :bind (:map org-mode-map
+ ("C-c C-a" . flyspell-correct-at-point)))
+#+END_SRC
* Window management
- Window management is really important.
- I find the default window handling of Emacs incredibly annoying: sometimes consuming my windows, sometimes creating new ones.
- So, as Emacs is the ultimate editor, I want to configure and fine tune the window management of Emacs.
- #+BEGIN_SRC emacs-lisp
- (setq display-buffer-alist
- '(("\\*e?shell\\*"
- (display-buffer-in-side-window)
- (window-height . 0.25)
- (side . bottom)
- (slot . 0))
- ("\\*[Hh]elp.*"
- (display-buffer-in-side-window)
- (window-height . 0.25)
- (side . bottom)
- (slot . 1))
- ("magit:.*"
- (display-buffer-in-side-window)
- (side . right)
- (slot . -1)
- (window-width . 0.5))
- ("magit-diff:.*"
- (display-buffer-in-side-window)
- (side . right)
- (slot . -2)
- (window-width . 0.5))
- ("\\*compilation\\*"
- (display-buffer-in-side-window)
- (side . bottom)
- (slot . -1)
- (window-height . 0.25))
- ("\\*Flycheck.*"
- (display-buffer-in-side-window)
- (side . bottom)
- (window-height . 0.25)
- (slot . 0))
- ("\\*rg.*"
- (display-buffer-in-side-window)
- (side . bottom)
- (window-height . 0.25)
- (slot . 1))
- ))
- #+END_SRC
+Window management is really important.
+I find the default window handling of Emacs incredibly annoying: sometimes consuming my windows, sometimes creating new ones.
+So, as Emacs is the ultimate editor, I want to configure and fine tune the window management of Emacs.
+#+BEGIN_SRC emacs-lisp
+(setq display-buffer-alist
+ '(("\\*e?shell\\*"
+ (display-buffer-in-side-window)
+ (window-height . 0.25)
+ (side . bottom)
+ (slot . 0))
+ ("\\*[Hh]elp.*"
+ (display-buffer-in-side-window)
+ (window-height . 0.25)
+ (side . bottom)
+ (slot . 1))
+ ("magit:.*"
+ (display-buffer-in-side-window)
+ (side . right)
+ (slot . -1)
+ (window-width . 0.5))
+ ("magit-diff:.*"
+ (display-buffer-in-side-window)
+ (side . right)
+ (window-width . 0.5))
+ ("magit-log:.*"
+ (display-buffer-in-side-window)
+ (side . right)
+ (window-width . 0.5))
+ ("\\*compilation\\*"
+ (display-buffer-in-side-window)
+ (side . bottom)
+ (slot . -1)
+ (window-height . 0.25))
+ ("\\*Flycheck.*"
+ (display-buffer-in-side-window)
+ (side . bottom)
+ (window-height . 0.25)
+ (slot . 0))
+ ("\\*rg.*"
+ (display-buffer-in-side-window)
+ (side . bottom)
+ (window-height . 0.25)
+ (slot . 1))
+ ))
+#+END_SRC
* Major modes and Programming
- Setups for common major modes and languages
- Here are some basic packages for programming first
+Setups for common major modes and languages
+Here are some basic packages for programming first
** Smartparens
- Smartparens is a smarter electric-parens, it's much more aware of stuff and easier to use.
- #+BEGIN_SRC emacs-lisp
- (use-package smartparens
- :after evil
- :config
- (setq sp-highlight-pair-overlay nil
- sp-highlight-wrap-overlay t
- sp-highlight-wrap-tag-overlay t)
- (smartparens-global-mode))
- #+END_SRC
+Smartparens is a smarter electric-parens, it's much more aware of stuff and easier to use.
+#+BEGIN_SRC emacs-lisp
+(use-package smartparens
+ :hook (prog-mode . smartparens-mode)
+ :after evil
+ :config
+ (setq sp-highlight-pair-overlay nil
+ sp-highlight-wrap-overlay t
+ sp-highlight-wrap-tag-overlay t)
+
+ (let ((unless-list '(sp-point-before-word-p
+ sp-point-after-word-p
+ sp-point-before-same-p)))
+ (sp-pair "'" nil :unless unless-list)
+ (sp-pair "\"" nil :unless unless-list))
+ (sp-local-pair sp-lisp-modes "(" ")" :unless '(:rem sp-point-before-same-p))
+ (require 'smartparens-config))
+#+END_SRC
** Show-paren-mode
- Show parenthesis for Emacs
- #+BEGIN_SRC emacs-lisp
- (add-hook 'prog-mode-hook #'show-paren-mode)
- #+END_SRC
+Show parenthesis for Emacs
+#+BEGIN_SRC emacs-lisp
+(add-hook 'prog-mode-hook #'show-paren-mode)
+#+END_SRC
** Eldoc
- #+BEGIN_SRC emacs-lisp
- (use-package eldoc
- :hook (prog-mode . eldoc-mode))
+#+BEGIN_SRC emacs-lisp
+(use-package eldoc
+ :hook (prog-mode . eldoc-mode))
- (use-package eldoc-box
- :hook (eglot--managed-mode . eldoc-box-hover-mode)
- :custom
- ((eldoc-box-max-pixel-height 15)
- (eldoc-box-max-pixel-width 15)))
- #+END_SRC
+(use-package eldoc-box
+ :hook (eldoc-mode . eldoc-box-hover-mode))
+#+END_SRC
** Eglot
- Eglot is a library of packages to communicate with LSP servers for better programming capabilities.
- Interactions with a server provide results to the client, done through JSON.
- #+BEGIN_SRC emacs-lisp
- (use-package eglot
- :hook (c++-mode . eglot-ensure)
- :hook (c-mode . eglot-ensure)
- :bind (:map eglot-mode-map
- ("<f2>" . eglot-rename)
- ("C-c C-A" . eglot-code-actions)
- ("C-c C-f" . eglot-format))
- :config
- (add-to-list 'eglot-server-programs '((c-mode c++-mode) "clangd")))
- #+END_SRC
+Eglot is a library of packages to communicate with LSP servers for better programming capabilities.
+Interactions with a server provide results to the client, done through JSON.
+#+BEGIN_SRC emacs-lisp
+(use-package eglot
+ :hook (c++-mode . eglot-ensure)
+ :hook (c-mode . eglot-ensure)
+ :bind (:map eglot-mode-map
+ ("<f2>" . eglot-rename)
+ ("C-c C-A" . eglot-code-actions)
+ ("C-c C-f" . eglot-format))
+ :config
+ (add-to-list 'eglot-server-programs '((c-mode c++-mode) "clangd")))
+#+END_SRC
** Flycheck
- Flycheck is the checking system for Emacs.
- I don't necessarily like having all my code checked all the time, so I haven't added a hook to prog-mode as it would be better for me to decide when I want checking and when I don't.
- #+BEGIN_SRC emacs-lisp
- (use-package flycheck
- :commands flycheck-mode
- :bind ("C-c x" . +flycheck/list-errors-load-flycheck)
- :config
- (defun +flycheck/list-errors-load-flycheck ()
- "Load flycheck if not available, then list errors."
- (interactive)
- (when (not (or flycheck-mode global-flycheck-mode))
- (flycheck-mode))
- (flycheck-list-errors)))
- #+END_SRC
+Flycheck is the checking system for Emacs.
+I don't necessarily like having all my code checked all the time, so I haven't added a hook to prog-mode as it would be better for me to decide when I want checking and when I don't.
+#+BEGIN_SRC emacs-lisp
+(use-package flycheck
+ :commands flycheck-mode
+ :config
+ (defun +flycheck/list-errors-load-flycheck ()
+ "Load flycheck if not available, then list errors."
+ (interactive)
+ (when (not (or flycheck-mode global-flycheck-mode))
+ (flycheck-mode))
+ (flycheck-list-errors)))
+#+END_SRC
** Activate tabs
- Set tabs to nil by default, with normal tab size set to 2.
- #+BEGIN_SRC emacs-lisp
- (setq-default indent-tabs-mode nil
- tab-width 2)
- #+END_SRC
+Set tabs to nil by default, with normal tab size set to 2.
+#+BEGIN_SRC emacs-lisp
+(setq-default indent-tabs-mode nil
+ tab-width 2)
+#+END_SRC
- Add a function to activate tabs mode.
- #+BEGIN_SRC emacs-lisp
- (defun dx:activate-tabs ()
- (interactive)
- (setq indent-tabs-mode t))
- #+END_SRC
+Add a function to activate tabs mode.
+#+BEGIN_SRC emacs-lisp
+(defun dx:activate-tabs ()
+ (interactive)
+ (setq indent-tabs-mode t))
+#+END_SRC
** C/C++
- Setup for C and C++ modes via the cc-mode package.
- Firstly hook the C and C++ modes to activate tabs.
- Then set the offset to 2, and the general style to user.
- Finally, add a user style that mimics the Microsoft guidelines for C# (open braces everywhere).
- #+BEGIN_SRC emacs-lisp
- (use-package cc-mode
- :hook (c-mode . +dx:activate-tabs)
- :hook (c++-mode . +dx:activate-tabs)
- :init
- (setq-default c-basic-offset 2)
- (setq c-default-style '((java-mode . "java")
- (awk-mode . "awk")
- (other . "user")))
- :config
- (c-add-style
- "user"
- '((c-basic-offset . 2)
- (c-comment-only-line-offset . 0)
- (c-hanging-braces-alist (brace-list-open)
- (brace-entry-open)
- (substatement-open after)
- (block-close . c-snug-do-while)
- (arglist-cont-nonempty))
- (c-cleanup-list brace-else-brace)
- (c-offsets-alist
- (statement-block-intro . +)
- (knr-argdecl-intro . 0)
- (substatement-open . 0)
- (substatement-label . 0)
- (access-label . 0)
- (label . 0)
- (statement-cont . +)))))
- #+END_SRC
+Setup for C and C++ modes via the cc-mode package.
+Firstly hook the C and C++ modes to activate tabs.
+Then set the offset to 2, and the general style to user.
+Finally, add a user style that mimics the Microsoft guidelines for C# (open braces everywhere).
+#+BEGIN_SRC emacs-lisp
+(use-package cc-mode
+ :hook (c-mode . dx:activate-tabs)
+ :hook (c++-mode . dx:activate-tabs)
+ :init
+ (setq-default c-basic-offset 2)
+ (setq c-default-style '((java-mode . "java")
+ (awk-mode . "awk")
+ (other . "user")))
+ :config
+ (c-add-style
+ "user"
+ '((c-basic-offset . 2)
+ (c-comment-only-line-offset . 0)
+ (c-hanging-braces-alist (brace-list-open)
+ (brace-entry-open)
+ (substatement-open after)
+ (block-close . c-snug-do-while)
+ (arglist-cont-nonempty))
+ (c-cleanup-list brace-else-brace)
+ (c-offsets-alist
+ (statement-block-intro . +)
+ (knr-argdecl-intro . 0)
+ (substatement-open . 0)
+ (substatement-label . 0)
+ (access-label . 0)
+ (label . 0)
+ (statement-cont . +)))))
+#+END_SRC
*** Clang format
- use-package clang-format for ease of use formatting, binding to "C-c '" for both C and C++ mode maps.
- #+BEGIN_SRC emacs-lisp
- (use-package clang-format
- :after cc-mode
- :config
- (bind-key "C-c '" #'clang-format-region c-mode-map)
- (bind-key "C-c '" #'clang-format-region c++-mode-map))
- #+END_SRC
+use-package clang-format for ease of use formatting, binding to "C-c '" for both C and C++ mode maps.
+#+BEGIN_SRC emacs-lisp
+(use-package clang-format
+ :after cc-mode
+ :config
+ (bind-key "C-c '" #'clang-format-region c-mode-map)
+ (bind-key "C-c '" #'clang-format-region c++-mode-map))
+#+END_SRC
+** Emacs lisp
+#+BEGIN_SRC emacs-lisp
+(with-eval-after-load "lisp-mode"
+ (defun +modded/lisp-indent-function (indent-point state)
+ "This function is the normal value of the variable `lisp-indent-function'.
+The function `calculate-lisp-indent' calls this to determine
+if the arguments of a Lisp function call should be indented specially.
+INDENT-POINT is the position at which the line being indented begins.
+Point is located at the point to indent under (for default indentation);
+STATE is the `parse-partial-sexp' state for that position.
+If the current line is in a call to a Lisp function that has a non-nil
+property `lisp-indent-function' (or the deprecated `lisp-indent-hook'),
+it specifies how to indent. The property value can be:
+,* `defun', meaning indent `defun'-style
+ \(this is also the case if there is no property and the function
+ has a name that begins with \"def\", and three or more arguments);
+,* an integer N, meaning indent the first N arguments specially
+ (like ordinary function arguments), and then indent any further
+ arguments like a body;
+,* a function to call that returns the indentation (or nil).
+ `lisp-indent-function' calls this function with the same two arguments
+ that it itself received.
+This function returns either the indentation to use, or nil if the
+Lisp function does not specify a special indentation."
+ (let ((normal-indent (current-column))
+ (orig-point (point)))
+ (goto-char (1+ (elt state 1)))
+ (parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t)
+ (cond
+ ;; car of form doesn't seem to be a symbol, or is a keyword
+ ((and (elt state 2)
+ (or (not (looking-at "\\sw\\|\\s_"))
+ (looking-at ":")))
+ (if (not (> (save-excursion (forward-line 1) (point))
+ calculate-lisp-indent-last-sexp))
+ (progn (goto-char calculate-lisp-indent-last-sexp)
+ (beginning-of-line)
+ (parse-partial-sexp (point)
+ calculate-lisp-indent-last-sexp 0 t)))
+ ;; Indent under the list or under the first sexp on the same
+ ;; line as calculate-lisp-indent-last-sexp. Note that first
+ ;; thing on that line has to be complete sexp since we are
+ ;; inside the innermost containing sexp.
+ (backward-prefix-chars)
+ (current-column))
+ ((and (save-excursion
+ (goto-char indent-point)
+ (skip-syntax-forward " ")
+ (not (looking-at ":")))
+ (save-excursion
+ (goto-char orig-point)
+ (looking-at ":")))
+ (save-excursion
+ (goto-char (+ 2 (elt state 1)))
+ (current-column)))
+ (t
+ (let ((function (buffer-substring (point)
+ (progn (forward-sexp 1) (point))))
+ method)
+ (setq method (or (function-get (intern-soft function)
+ 'lisp-indent-function)
+ (get (intern-soft function) 'lisp-indent-hook)))
+ (cond ((or (eq method 'defun)
+ (and (null method)
+ (> (length function) 3)
+ (string-match "\\`def" function)))
+ (lisp-indent-defform state indent-point))
+ ((integerp method)
+ (lisp-indent-specform method state
+ indent-point normal-indent))
+ (method
+ (funcall method indent-point state))))))))
+ (add-hook 'emacs-lisp-mode-hook #'(lambda () (interactive) (setq-local lisp-indent-function #'+modded/lisp-indent-function))))
+#+END_SRC
+