Skip to content

Latest commit

 

History

History
801 lines (753 loc) · 24.5 KB

config.org

File metadata and controls

801 lines (753 loc) · 24.5 KB

Emacs Configuration

Emacs initialization

Package sources

(setq package-archives '(("gnu" . "http://elpa.gnu.org/packages/")
                         ("melpa" . "http://melpa.org/packages/")
                         ("org" . "http://orgmode.org/elpa/")))

use-package

(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

Configuration

Basic

Better defaults

(setq-default
 ad-redefinition-action 'accept                   ; Silence warnings for redefinition
 cursor-in-non-selected-windows t                 ; Hide the cursor in inactive windows
 display-time-default-load-average nil            ; Don't display load average
 fill-column 80                                   ; Set width for automatic line breaks
 help-window-select t                             ; Focus new help windows when opened
 indent-tabs-mode nil                             ; Prefers spaces over tabs
 inhibit-startup-screen t                         ; Disable start-up screen
 initial-scratch-message ""                       ; Empty the initial *scratch* buffer
 kill-ring-max 128                                ; Maximum length of kill ring
 load-prefer-newer t                              ; Prefers the newest version of a file
 mark-ring-max 128                                ; Maximum length of mark ring
 read-process-output-max (* 1024 1024)            ; Increase the amount of data reads from the process
 scroll-conservatively most-positive-fixnum       ; Always scroll by one line
 select-enable-clipboard t                        ; Merge system's and Emacs' clipboard
 tab-width 4                                      ; Set width for tabs
 use-package-always-ensure t                      ; Avoid the :ensure keyword for each package
 user-full-name "greensponge"                     ; Set the full name of the current user
 user-mail-address "[email protected]"        ; Set the email address of the current user
 vc-follow-symlinks t                             ; Always follow the symlinks
 view-read-only t)                                ; Always open read-only buffers in view-mode
(cd "~/")                                         ; Move to the user directory
(display-time-mode 1)                             ; Enable time in the mode-line
(fset 'yes-or-no-p 'y-or-n-p)                     ; Replace yes/no prompts with y/n
(set-default-coding-systems 'utf-8)               ; Default to utf-8 encoding
(show-paren-mode 1)                               ; Show the parent
(blink-cursor-mode 0)                             ; Stops cursor blinking

Don’t show startup message

(setq inhibit-startup-message t)

Don’t show menubar

(menu-bar-mode -1)

Don’t show toolbar

(tool-bar-mode -1)

Don’t show scrollbar

(scroll-bar-mode -1)

Highlight line

(global-hl-line-mode +1)

Delete selection

(delete-selection-mode 1)

Split horizontally by default

(setq split-height-threshold nil)
(setq split-width-threshold 0)

Different backup directory

(setq backup-directory-alist '(("." . "~/.saves")))

Display line numbers in programming files

(add-hook 'prog-mode-hook 'display-line-numbers-mode)

Bookmarks

Set bookmarks file

(setq bookmark-default-file "~/.emacs.d/bookmarks")

Save bookmarks when modified

(setq bookmark-save-flag 1)

Disable wrapping for long lines in display

(setq-default truncate-lines t)

Disable locking files

(setq create-lockfiles nil)

Move-text

(use-package move-text
  :bind (("M-<up>" . move-text-up)
         ("M-<down>" . move-text-down))
  :config (move-text-default-bindings))

Auto-reload files when they have been updated

(global-auto-revert-mode t)

Open shell

(use-package shell-pop
  :ensure t
  :config
  (global-set-key (kbd "C-f") 'shell-pop) ; I never use the forward char shortcut anyway.
  (setq shell-pop-term-shell "/bin/bash")
  (setq shell-pop-window-position "bottom")
  (setq shell-pop-autocd-to-working-dir t)
  (push (cons "\\*shell\\*" display-buffer--same-window-action) display-buffer-alist))

Advanced

Expand-region

(use-package expand-region 
  :ensure t
  :bind 
  ("C-+" . er/expand-region)
  ("C--" . er/contract-region))

Auto-completion

Run `M-x company-tabnine-install-binary` to install the TabNine binary for your system.

(use-package company
  :ensure t
  :init
  (add-hook 'after-init-hook 'global-company-mode)
  (setq company-idle-delay 0
        company-minimum-prefix-length 3
        company-selection-wrap-around 1
        company-tooltip-align-annotations t
        company-show-numbers t)
  (company-tng-configure-default))

(use-package company-lsp
  :commands company-lsp
  :ensure t
  :after (company lsp)
  :config
  (setq company-transformers nil
        company-lsp-async t
        company-lsp-cache-candidates nil)
  (push 'company-lsp company-backends))

Buffers

(use-package ibuffer
  :ensure t
  :bind ("C-x C-b" . ibuffer))

(use-package ibuffer-projectile
  :after ibuffer
  :preface
  (defun my/ibuffer-projectile ()
    (ibuffer-projectile-set-filter-groups)
    (unless (eq ibuffer-sorting-mode 'alphabetic)
      (ibuffer-do-sort-by-alphabetic)))
  :hook (ibuffer . my/ibuffer-projectile))

(defvar *protected-buffers* '("*scratch*" "*Messages*")
  "Buffers that cannot be killed.")

(defun my/protected-buffers ()
  "Protects some buffers from being killed."
  (dolist (buffer *protected-buffers*)
    (with-current-buffer buffer
      (emacs-lock-mode 'kill))))

(add-hook 'after-init-hook #'my/protected-buffers)

Toggle maximize on selected buffer

(defun toggle-maximize-buffer () "Maximize buffer"
  (interactive)
  (if (= 1 (length (window-list)))
      (jump-to-register '_) 
    (progn
      (window-configuration-to-register '_)
      (delete-other-windows))))

(define-key global-map (kbd "C-c f") 'toggle-maximize-buffer)

Undo and Redo

(use-package undo-tree
  :ensure t
  :diminish undo-tree-mode
  :init
  (global-undo-tree-mode 1)
  :config
  (defalias 'redo 'undo-tree-redo)
  :bind (("C-z" . undo)
         ("C-S-z" . redo)))

Windows

Don’t prompt before killing buffer

(global-set-key [remap kill-buffer] #'kill-this-buffer)

Give focus to new buffer on creation

(use-package window
  :ensure nil
  :bind (("C-x 3" . hsplit-last-buffer)
         ("C-x 2" . vsplit-last-buffer))
  :preface
  (defun hsplit-last-buffer ()
    "Gives the focus to the last created horizontal window."
    (interactive)
    (split-window-horizontally)
    (other-window 1))

  (defun vsplit-last-buffer ()
    "Gives the focus to the last created vertical window."
    (interactive)
    (split-window-vertically)
    (other-window 1)))

switch-window

(use-package switch-window
  :bind (("C-x o" . switch-window)
         ("C-x w" . switch-window-then-swap-buffer)))

windmove

(use-package windmove
  :bind (("C-c <left>" . windmove-left)
         ("C-c <down>" . windmove-down)
         ("C-c <up>" . windmove-up)
         ("C-c <right>" . windmove-right)))

Automatically tangle org file on save

Tangle after-save-hook, only on org-files

(defun dw/org-babel-tangle-dont-ask ()
  (let ((org-confirm-babel-evaluate nil))
    (org-babel-tangle)))

(add-hook 'org-mode-hook (lambda () (add-hook 'after-save-hook #'dw/org-babel-tangle-dont-ask
                                              'run-at-end 'only-in-org-mode)))

Registers

(set-register ?b '(file . "~/.bashrc"))
(set-register ?c '(file . "~/.emacs.d/.config.org"))

UI

Theme

(use-package doom-themes
  :ensure t
  :config
  (load-theme 'doom-gruvbox 'no-confirm))

Modeline

(use-package doom-modeline
  :ensure t
  :hook (after-init . doom-modeline-mode))

Icons

(use-package all-the-icons
  :ensure t)

Fonts

(set-face-attribute 'default nil :font "Source Code Pro Medium")
(set-fontset-font t 'latin "Noto Sans")

Modes

Ido-mode

(setq ido-everywhere t)
(setq ido-enable-flex-matching t)
(ido-mode t)

Org-mode

Org-babel-do-load-languages

(org-babel-do-load-languages
 'org-babel-load-languages
 '((emacs-lisp . t)
   (shell . t)))

;; stop asking for confirmation
(setq org-confirm-babel-evaluate nil)

Org-bullets-mode

(use-package org-bullets
  :ensure t
  :config
    (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1))))

Shift select

(setq org-support-shift-select t)

Useful global keys

(global-set-key (kbd "C-c l") 'org-store-link)
(global-set-key (kbd "C-c a") 'org-agenda)
(global-set-key (kbd "C-c c") 'org-capture)

Personal org-files

(global-set-key (kbd "C-c m c") (lambda() (interactive)(find-file "~/.emacs.d/config.org")))
(global-set-key (kbd "C-c m n") (lambda() (interactive)(find-file "~/.emacs.d/org-mode/org/notes.org")))
(global-set-key (kbd "C-c m r") (lambda() (interactive)(find-file "~/.emacs.d/org-mode/org/reports.org")))
(global-set-key (kbd "C-c m j") (lambda() (interactive)(find-file "~/.emacs.d/org-mode/org/journal.org")))

Getting things done

(setq org-tags-column 0)

(global-set-key (kbd "<f5>") (lambda() (interactive)(find-file "~/.emacs.d/org-mode/org/gtd.org")))
(global-set-key (kbd "<f6>") (lambda() (interactive)(find-file "~/.emacs.d/org-mode/org/inbox.org")))
(global-set-key (kbd "<f7>") (lambda() (interactive)(find-file "~/.emacs.d/org-mode/org/tickler.org")))
(global-set-key (kbd "<f8>") (lambda() (interactive)(find-file "~/.emacs.d/org-mode/org/someday.org")))

(setq org-agenda-start-on-weekday 1)
(setq org-agenda-files '("~/.emacs.d/org-mode/org"))

(setq org-refile-targets '(("~/.emacs.d/org-mode/org/gtd.org" :maxlevel . 3)
                           ("~/.emacs.d/org-mode/org/someday.org" :maxlevel . 1)
                           ("~/.emacs.d/org-mode/org/tickler.org" :maxlevel . 2)))

(setq org-capture-templates '(("t" "Todo [inbox]" entry
                               (file+headline "~/.emacs.d/org-mode/org/inbox.org" "Tasks")
                               "* TODO %i%?")
                              ("T" "Tickler" entry
                               (file+headline "~/.emacs.d/org-mode/org/tickler.org" "Tickler")
                               "* %i%? \n %U")
                              ("j" "Journal entry" entry
                               (file+datetree "~/.emacs.d/org-mode/org/journal.org")
                              "**** %U %^{Title}\n     %?")))

(setq org-todo-keywords '((sequence "TODO(t)" "WAITING(w)" "|" "DONE(d)" "CANCELLED(c)")))

Tags

;; Documentation:  https://orgmode.org/org.html#Tags
(setq org-tag-alist '((:startgroup . nil)
                      ("@work" . ?w) ("@home" . ?h)
                      (:endgroup . nil)))

Markdown-mode

You need to install pandoc separately on your system for preview to work.

(use-package markdown-mode
  :ensure t
  :commands (markdown-mode gfm-mode)
  :mode (("README\\.md\\'" . gfm-mode)
         ("\\.md\\'" . markdown-mode)
         ("\\.markdown\\'" . markdown-mode))
  :init (setq markdown-command "/usr/bin/pandoc"))

Lsp-mode

(use-package lsp-mode
  :ensure t
  :hook ((clojure-mode . lsp)
         (css-mode . lsp)
         (lsp-mode . lsp-enable-which-key-integration))
  :commands lsp
  :custom ((lsp-clojure-server-command '("java" "-jar" "/home/greensponge/clj-kondo/clj-kondo-lsp-server.jar")))
  :config
  (dolist (m '(clojure-mode
             clojurescript-mode))
  (add-to-list 'lsp-language-id-configuration `(,m . "clojure")))
  (setq lsp-file-watch-ignored
        '("[/\\\\]\\.git$"
          "[/\\\\]_build$"
          "[/\\\\]assets$"
          "[/\\\\]cover$"
          "[/\\\\]node_modules$"
          "[/\\\\]submodules$")))

(use-package lsp-ui
  :ensure t
  :after (lsp-mode))

Dap-mode

(use-package dap-mode :after lsp-mode :config (dap-auto-configure-mode))

General packages

Which key

(use-package which-key
	     :ensure t
	     :config(which-key-mode))

Projectile

(use-package projectile
  :ensure t
  :config
  (define-key projectile-mode-map (kbd "C-x p") 'projectile-command-map)
  (projectile-mode +1))

Dashboard

(use-package dashboard
  :ensure t
  :init
  (progn
    (setq dashboard-items '((recents . 5)
			    (agenda . 10)
			    (projects . 5)
			    (bookmarks .5)))
    (setq dashboard-center-content nil)
    (setq dashboard-banner-logo-title "Wherever you go, there you are.")
    (setq dashboard-set-file-icons t)
    (setq dashboard-set-heading-icons t)
    (setq dashboard-startup-banner "~/.emacs.d/assets/images/emacs-logo.png")
    (setq show-week-agenda-p t)
    (setq dashboard-set-navigator t)
    (setq dashboard-navigator-buttons
	  `(
	    ((,nil
	      "config file"
	      "Open config file"
	      (lambda (&rest _) (find-file "~/.emacs.d/config.org"))
	      ))))
    )
    :config
    (dashboard-setup-startup-hook))

Treemacs

(use-package treemacs
  :ensure t
  :config
  (setq treemacs-show-hidden-files t)
  (setq treemacs-git-mode 'extended)
  (setq treemacs-follow-mode t)
  (setq treemacs-project-follow-cleanup t))
(global-set-key (kbd "C-b") 'treemacs) ; I never use the backward char shortcut anyway.

(use-package treemacs-projectile
  :after (treemacs projectile)
  :ensure t)

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

Magit

(use-package magit
  :ensure t
  :bind ("C-x g" . magit-status))

Flycheck

(use-package flycheck
  :ensure t)

Swiper

(use-package swiper
  :ensure t)

Ivy

(use-package ivy
  :diminish
  :bind (("C-s" . swiper)
         :map ivy-minibuffer-map
         ("TAB" . ivy-alt-done)
         ("C-l" . ivy-alt-done)
         ("C-j" . ivy-next-line)
         ("C-k" . ivy-previous-line)
         :map ivy-switch-buffer-map
         ("C-k" . ivy-previous-line)
         ("C-l" . ivy-done)
         ("C-d" . ivy-switch-buffer-kill)
         :map ivy-reverse-i-search-map
         ("C-k" . ivy-previous-line)
         ("C-d" . ivy-reverse-i-search-kill))
  :init
  (ivy-mode 1)
  :config
  (setq ivy-use-virtual-buffers t)
  (setq ivy-wrap t)
  (setq ivy-count-format "(%d/%d) ")
  (setq enable-recursive-minibuffers t)

  ;; Use different regex strategies per completion command
  (push '(completion-at-point . ivy--regex-fuzzy) ivy-re-builders-alist) ;; This doesn't seem to work...
  (push '(swiper . ivy--regex-ignore-order) ivy-re-builders-alist)
  (push '(counsel-M-x . ivy--regex-ignore-order) ivy-re-builders-alist)

  ;; Set minibuffer height for different commands
  (setf (alist-get 'counsel-projectile-ag ivy-height-alist) 15)
  (setf (alist-get 'counsel-projectile-rg ivy-height-alist) 15)
  (setf (alist-get 'swiper ivy-height-alist) 15)
  (setf (alist-get 'counsel-switch-buffer ivy-height-alist) 7))

(use-package ivy-rich
  :init
  (ivy-rich-mode 1))

Counsel

(use-package counsel
  :bind (("M-x" . counsel-M-x)
         ("C-x b" . counsel-ibuffer)
         ("C-x C-f" . counsel-find-file)
         :map minibuffer-local-map
         ("C-r" . 'counsel-minibuffer-history))
  :config
  (setq ivy-initial-inputs-alist nil)) ;; Don't start searches with ^

Flx

(use-package flx  ;; Improves sorting for fuzzy-matched results
  :defer t
  :init
  (setq ivy-flx-limit 10000))

Smex

(use-package smex ;; Adds M-x recent command sorting for counsel-M-x
  :defer 1
  :after counsel)

Helpful

(use-package helpful
  :ensure t
  :custom
  (counsel-describe-function-function #'helpful-callable)
  (counsel-describe-variable-function #'helpful-variable)
  :bind
  ([remap describe-function] . counsel-describe-function)
  ([remap describe-command] . helpful-command)
  ([remap describe-variable] . counsel-describe-variable)
  ([remap describe-key] . helpful-key))

Calfw (With Org calendar)

 (use-package calfw
   :ensure t)

 (use-package calfw-org
   :ensure t)

 (setq calendar-week-start-day 1)

(global-set-key (kbd "C-c m a") 'cfw:open-org-calendar)

Hl-todo

Highlights TODOs throughout all programming modes, add custom keywords as needed.

(use-package hl-todo
  :hook (prog-mode . hl-todo-mode)
  :config
  (setq hl-todo-highlight-punctuation ":"
        hl-todo-keyword-faces
        `(("TODO"       warning bold)
          ("FIXME"      error bold)
          ("HACK"       font-lock-constant-face bold)
          ("REVIEW"     font-lock-keyword-face bold)
          ("NOTE"       success bold)
          ("DEPRECATED" font-lock-doc-face bold))))

Multiple cursors

(use-package multiple-cursors
  :ensure t
  :bind (("C->" . mc/mark-next-like-this)
         ("C-<" . mc/unmark-next-like-this)
         ("C-c C-<" . mc/mark-all-like-this)
         ("C-S-<mouse-1>" . mc/add-cursor-on-click)))

Centaur-tabs

(use-package centaur-tabs
  :demand
  :config
  (centaur-tabs-mode t)
  :bind
  ("C-<prior>" . centaur-tabs-backward)
  ("C-<next>" . centaur-tabs-forward))

Programming

C#

(use-package csharp-mode
  :hook
  ((csharp-mode . lsp-deferred)))

Docker

(use-package dockerfile-mode
  :ensure t)

EditorConfig

(use-package editorconfig
  :ensure t
  :config
  (editorconfig-mode 1))

HTML

(use-package emmet-mode
  :hook (css-mode sgml-mode web-mode))

Java

Lsp-java

Press [TAB] and [RET] if language server prompts you when opening a .Java file. Source: lsp-java

(use-package lsp-java :config (add-hook 'java-mode-hook 'lsp))

Dap-java

(use-package dap-java :ensure nil)

JavaScript

JSON

(use-package json-mode
  :mode "\\.json\\'"
  :hook (before-save . my/json-mode-before-save-hook)
  :preface
  (defun my/json-mode-before-save-hook ()
    (when (eq major-mode 'json-mode)
      (json-pretty-print-buffer)))

  (defun my/json-array-of-numbers-on-one-line (encode array)
    "Prints the arrays of numbers in one line."
    (let* ((json-encoding-pretty-print
            (and json-encoding-pretty-print
                 (not (loop for x across array always (numberp x)))))
           (json-encoding-separator (if json-encoding-pretty-print "," ", ")))
      (funcall encode array)))
  :config (advice-add 'json-encode-array :around #'my/json-array-of-numbers-on-one-line))

Common Lisp

SBCL & Quicklisp setup

Install the needed packages to use slime-helper by following these steps:

1. Install SBCL
2. Fetch quicklisp
3. Load quicklisp into SBCL context

```sh
sudo apt-get install sbcl
curl -O http://beta.quicklisp.org/quicklisp.lisp
sbcl --load quicklisp.lisp
```

Step into SBCL context by typing `sbcl` in your terminal and setup quick-lisp:

```sh
(quicklisp-quickstart:install)
(ql:quickload "quicklisp-slime-helper")
```

Load slime-helper

(load (expand-file-name "~/quicklisp/slime-helper.el"))
(setq inferior-lisp-program "/usr/bin/sbcl")
You can run the Common Lisp REPL like this: `M-x slime`

Clojure

Aggressive-indent

(use-package aggressive-indent
  :hook ((css-mode . aggressive-indent-mode)
         (emacs-lisp-mode . aggressive-indent-mode)
         (clojure-mode . aggressive-indent-mode)
         (lisp-mode . aggressive-indent-mode))
  :custom (aggressive-indent-comments-too))

Rainbow-delimiters

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

Smartparens

(use-package smartparens
  :ensure t
  :config (smartparens-global-mode 1)
  :bind (("C-M-a"     . sp-beginning-of-sexp)
         ("C-M-e"     . sp-end-of-sexp)
         ("C-<down>"  . sp-down-sexp)
         ("C-<up>"    . sp-up-sexp)
         ("M-<down>"  . sp-backward-down-sexp)
         ("M-<up>"    . sp-backward-up-sexp)
         ("C-M-f"     . sp-forward-sexp)
         ("C-M-b"     . sp-backward-sexp)
         ("C-M-n"     . sp-next-sexp)
         ("C-M-p"     . sp-previous-sexp)
         ("C-S-b"     . sp-backward-symbol)
         ("C-S-f"     . sp-forward-symbol)
         ("C-S-M->"   . sp-backward-unwrap)
         ("C-M-<"     . sp-unwrap-sexp)
         ("C-<right>" . sp-forward-slurp-sexp)
         ("M-<right>" . sp-forward-barf-sexp)
         ("C-<left>"  . sp-backward-slurp-sexp)
         ("M-<left>"  . sp-backward-barf-sexp)
         ("C-M-t"     . sp-transpose-sexp)
         ("C-M-k"     . sp-kill-sexp)
         ("C-k"       . sp-kill-hybrid-sexp)
         ("M-k"       . sp-backward-kill-sexp)))

(add-hook 'prog-mode-hook 'turn-on-smartparens-strict-mode)

Clojure-mode

(use-package clojure-mode
  :ensure t
  :mode (("\\.clj\\'" . clojure-mode)
         ("\\.edn\\'" . clojure-mode))
  :init
  (add-hook 'clojure-mode-hook #'eldoc-mode))

Cider

(use-package cider
  :ensure t
  :config
  (setq cider-font-lock-dynamically '(macro core function var)))

TypeScript

Setup-tide-mode

Note you need to have tslint installed globally for it to be enabled. Installing TypeScript globally might also be a good idea at this point.

  `npm install -g tslint`
  `npm install -g typescript`

You can execute `C-c ! v` to check what syntax checkers are running to confirm that everything works.
(defun setup-tide-mode ()
  (interactive)
  (tide-setup)
  (flycheck-mode +1)
  (setq flycheck-check-syntax-automatically '(save mode-enabled))
  (eldoc-mode +1)
  (tide-hl-identifier-mode +1)
  (company-mode +1))

;; aligns annotation to the right hand side
(setq company-tooltip-align-annotations t)

;; formats the buffer before saving
(add-hook 'before-save-hook 'tide-format-before-save)

(add-hook 'typescript-mode-hook #'setup-tide-mode)

Tide package setup

(use-package tide
  :after typescript-mode
  :ensure t)

Typescript-mode

(use-package typescript-mode
  :ensure t)