From 28da4f06348caf62822b7966b5f266c775a17e2a Mon Sep 17 00:00:00 2001 From: Aryadev Chavali Date: Thu, 6 Aug 2020 15:15:21 +0100 Subject: +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 --- Emacs/.config/emacs/config.org | 1391 ++++++++++++++++++++++------------------ 1 file changed, 778 insertions(+), 613 deletions(-) (limited to 'Emacs/.config') 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 - ("" . 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 , the weird little menu interaction button on some keyboards. - #+BEGIN_SRC emacs-lisp - (bind-keys - :prefix "" - :prefix-map dx:menu-map - ("" . 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 (" ," . 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 "" #'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 "" #'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 - ("" . 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 + ("" . 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 + -- cgit v1.2.3-13-gbd6f