Skip to content
This repository has been archived by the owner on Mar 21, 2023. It is now read-only.

Latest commit

 

History

History
609 lines (545 loc) · 16 KB

main.org

File metadata and controls

609 lines (545 loc) · 16 KB

Emacs config

Inspired by https://gist.github.com/saulius/b9f8b784dd3350be3a04c0d932f6087e

Package management

Uses Emacs straight.el in combination with use-package.

Bootstrap straight.el

(require 'scroll-bar)
(setq package-archives
        '(("gnu"              . "http://elpa.gnu.org/packages/")
          ("melpa-stable"     . "http://stable.melpa.org/packages/")
          ("melpa"            . "http://melpa.org/packages/")))
(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))

Integrate straight with use-package.

(straight-use-package 'use-package)

;; Always ensure and defer
(setq use-package-always-ensure t)
(setq use-package-always-defer t)

(use-package no-littering
  :straight t
  :demand t)

Setup basic path related config variables.

(defvar config-dir user-emacs-directory
  "The dir where config lives.")
(defvar config-cache-dir (expand-file-name ".cache" config-dir)
  "The dir to keep temporary cache files.")
(defvar config-custom-package-dir (expand-file-name "packages" config-dir)
  "The dir to download packages not available in melpa.")

(when (not (file-directory-p config-custom-package-dir))
  (make-directory config-custom-package-dir))

Core modules

Functions

Open this file

(defun open-config-file ()
    "Open main config file"
  (interactive)
  (find-file (concat config-dir "main.org")))

System

UTF-8 all the things.

(set-language-environment "UTF-8")
(prefer-coding-system 'utf-8-unix)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-buffer-file-coding-system 'utf-8)
(set-default-coding-systems 'utf-8)

Store all backup and autosave files in the tmp dir.

(setq backup-directory-alist
      `((".*" . ,temporary-file-directory)))
(setq auto-save-file-name-transforms
      `((".*" ,temporary-file-directory t)))

Do not create symbolic lock files.

(setq create-lockfiles nil)

Make backups of files, even when they’re in version control.

(setq vc-make-backup-files t)

Do not really want to type yes or no each time, so: yes/no => y/n.

(defalias 'yes-or-no-p 'y-or-n-p)

No vc backends. I only use git with magit.

(setq vc-handled-backends nil)

No bell rings.

(setq ring-bell-function 'ignore)

Don’t ask to create a buffer.

(setq confirm-nonexistent-file-or-buffer nil)

UI

Remove noise.

(scroll-bar-mode 0)
(menu-bar-mode -1)

Use a nice looking theme.

(use-package zenburn-theme
  :straight t
  :init
  (load-theme 'zenburn t))

Borrow Spacemacs modeline.

(use-package spaceline
  :straight t
  :init
  (require 'spaceline-config)
  (spaceline-toggle-minor-modes-off)
  (spaceline-toggle-workspace-number-off)
  (spaceline-toggle-window-number-off)
  (spaceline-toggle-anzu-off)
  (spaceline-toggle-purpose-off)
  (spaceline-toggle-buffer-position-off)
  (spaceline-toggle-hud-off)
  (spaceline-spacemacs-theme))

Interactively highlight which buffer is active by dimming the others.

(use-package dimmer
  :straight t
  :init
  (setq dimmer-percent 0.1)
  (dimmer-activate))

Key mapping setup

(use-package which-key
  :straight t
  :demand t
  :config
  (setq which-key-idle-delay 0.5)

  (require 'which-key)

  (which-key-mode)
  (which-key-setup-side-window-bottom))

;; macros
(defvar jj-leader "SPC"
  "Leader key")
(defvar jj-mode ","
  "Leader key for mode specific bindings")

(use-package general
  :straight t
  :init
  (general-evil-setup t)
  (general-define-key
   :prefix jj-leader
   :states 'normal
   "fed" 'open-config-file
   "qq" 'save-buffers-kill-terminal
   "fs" 'save-buffer
   "ff" 'find-file
   "bd" 'kill-this-buffer
   "TAB" 'previous-buffer
   "bn" 'next-buffer
   "bb" 'ivy-switch-buffer
   "bp" 'previous-buffer
   "hdb" 'describe-bindings
   "hdc" 'describe-char
   "hdf" 'describe-function
   "hdk" 'describe-key
   "hdp" 'describe-package
   "ws" 'split-window-vertically
   "wv" 'split-window-horizontally
   "wl" 'evil-window-right
   "wk" 'evil-window-up
   "wj" 'evil-window-down
   "wh" 'evil-window-left
   "wd" 'delete-window))

Evil

(use-package evil
  :straight t
  :demand t
  :bind (:map evil-normal-state-map ("M-." . nil))
  :init
  (setq evil-intercept-esc 'always
        evil-toggle-key "C-\\"
        evil-normal-state-tag " N "
        evil-insert-state-tag " I "
        evil-emacs-state-tag  " E "
        evil-visual-state-tag " V "
        evil-want-C-i-jump nil ;; make TAB work in console
        evil-want-fine-undo t)

  :config
  (evil-mode))

(use-package evil-surround
  :straight t
  :after evil
  :diminish global-evil-surround-mode
  :config
  (global-evil-surround-mode))

(use-package evil-collection
  :after evil
  :straight (evil-collection
              :type git
              :host github
              :repo "jojojames/evil-collection")
  :config
  (evil-collection-init))

(use-package evil-matchit
  :straight t
  :after evil
  :config
  (global-evil-matchit-mode 1))

Evil multi-cursor

(use-package evil-mc
  :straight t
  :after evil
  :config
  (global-evil-mc-mode  1))

Editor

Do not convert spaces to tabs

(setq-default indent-tabs-mode nil)

Turn off wordwrap

(setq-default truncate-lines 1)

Auto add newline at the end of file.

(setq require-final-newline t)

Increase history sizes.

(setq
 history-length 250                     ;default is 30
 kill-ring-max 5000                     ;truncate kill ring after 5000 entries
 mark-ring-max 5000)                    ;truncate mark ring after 5000 entries

Use TAB for completion.

(setq tab-always-indent 'complete)

Indentation Relative to Previous Lines. Indents the current line like the previous nonblank line

(setq indent-line-function 'indent-relative-maybe)

Make clipboard work for Mac

(use-package pbcopy
  :straight t
  :if (and (eq system-type 'darwin) (not (display-graphic-p)))
  :init (turn-on-pbcopy))

Visualize blanks (TAB, (HARD) SPACE and NEWLINE).

(use-package whitespace
  :straight t
  :demand t
  :diminish global-whitespace-mode
  :hook (prog-mode . whitespace-mode)
  :init
  (nmap :prefix jj-leader
    "t w" 'whitespace-mode)
  :config
  (setq whitespace-style '(face empty tabs lines-tail trailing))
  (setq whitespace-line-column 80))
(use-package ws-butler
  :straight t
  :demand t
  :diminish ws-butler-mode
  :config
  (add-hook 'prog-mode-hook 'ws-butler-mode))
(use-package smex
  :straight t
  :demand t
  :bind (("M-x" . 'smex))
  :config
  (smex-initialize))
(use-package expand-region
  :straight t
  :init
  (nmap :prefix jj-leader
    "v" '(expand-region :which-key "expand region"))
  (vmap
    "v" 'er/expand-region)
  :config
  (setq expand-region-contract-fast-key "v"
        expand-region-reset-fast-key "r"))
(use-package rainbow-delimiters
  :straight t
  :hook (prog-mode . rainbow-delimiters-mode))

(use-package evil-nerd-commenter
  :straight t
  :init
  (vmap
    "g c" 'evilnc-comment-or-uncomment-lines)

  (nmap
    "g c" '(evilnc-comment-or-uncomment-lines :which-key "Comment/uncomment lines")))
(use-package dumb-jump
  :straight t
  :general
  (:keymaps 'normal
   :prefix jj-leader
   "j" '(:ignore t :wk "jump around")
   "jg" 'dumb-jump-go
   "jo" 'dumb-jump-go-other-window
   "ji" 'dumb-jump-go-prompt
   "jb" 'dumb-jump-back)
  :custom
  (dumb-jump-selector 'ivy))
(use-package avy
  :straight t
  :init
  (vmap :prefix jj-leader
    "SPC" 'avy-goto-char)
  (nmap :prefix jj-leader
    "SPC" 'avy-goto-char))

Autocompletion

(use-package yasnippet
  :straight t
  :init
  (yas-global-mode 1))

(use-package company
  :straight t
  :demand t
  :diminish company-mode
  :hook (after-init . global-company-mode)
  :config
  (setq company-tooltip-align-annotations t) ; aligns annotation to the right
  (setq company-idle-delay 0.5)
  (setq company-tooltip-limit 10)
  (setq company-minimum-prefix-length 2)
  ;; invert the navigation direction if the the completion popup-isearch-match
  ;; is displayed on top (happens near the bottom of windows)
  (setq company-tooltip-flip-when-above t))

Syntax checkers and linters

(use-package flycheck
  :straight t
  :demand t
  :commands (flycheck-mode flycheck-list-errors flycheck-buffer)
  :hook (prog-mode . global-flycheck-mode)
  :init
  (nmap
    "] e" 'flycheck-next-error
    "[ e" 'flycheck-previous-error)
  (nmap :prefix jj-leader
    "e" '(:ignore t :which-key "lint errors")
    "e l" '(flycheck-list-errors :which-key "list errors")
    "e b" '(flycheck-buffer :which-key "check buffer")
    "e v" '(flycheck-verify-setup :which-key "verify linter setup")
    "e l" '(flycheck-list-errors :which-key "list-errors"))
  :config
  (setq flycheck-highlighting-mode 'lines))

Ivy

(use-package ivy
  :straight t
  :diminish ivy-mode
  :hook (after-init . ivy-mode)
  :config
  (setq ivy-use-virtual-buffers t
        ivy-count-format "(%d/%d) "
        ivy-wrap t
        ivy-virtual-abbreviate 'full
        ivy-initial-inputs-alist nil
        ivy-use-selectable-prompt t))

(use-package counsel
  :straight t
  :diminish counsel-mode
  :commands counsel-describe-face
  :hook (ivy-mode . counsel-mode)
  :general
  ([remap apropos]                  'counsel-apropos)
  ([remap bookmark-jump]            'counsel-bookmark)
  ([remap describe-face]            'counsel-describe-face)
  ([remap describe-function]        'counsel-describe-function)
  ([remap describe-variable]        'counsel-describe-variable)
  ([remap execute-extended-command] 'counsel-M-x)
  ([remap find-file]                'counsel-find-file)
  ([remap find-library]             'counsel-find-library)

  ([remap info-lookup-symbol]       'counsel-info-lookup-symbol)
  ([remap imenu]                    'counsel-imenu)
  ([remap recentf-open-files]       'counsel-recentf)
  ([remap org-capture]              'counsel-org-capture)
  ([remap swiper]                   'counsel-grep-or-swiper))

(use-package swiper
  :straight t
  :after ivy
  :bind ("C-s" . swiper)
  :config
  (setq swiper-action-recenter t))

(use-package ivy-hydra
  :straight t
  :after ivy
  :commands (ivy-dispatching-done-hydra ivy--matcher-desc))

(use-package ivy-rich
  :straight t
  :after ivy
  :init (ivy-rich-mode 1)
  :hook (ivy-rich-mode . (lambda ()
                           (setq ivy-virtual-abbreviate
                                 (or (and ivy-rich-mode 'abbreviate) 'name)))))

Project management

(use-package projectile
  :straight t
  :diminish projectile-mode
  :init
  (nmap :prefix jj-leader
    "p" '(:ignore t :which-key "project")
    "p s" '(counsel-projectile-rg :which-key "search in project")
    "p r" '(projectile-replace :which-key "replace in project")
    "p R" '(projectile-replace-regexp :which-key "replace regexp in project")
    "p d" '(counsel-projectile-find-dir :which-key "jump to dir")
    "p f" '(counsel-projectile :which-key "jump to file")
    "p g" '(counsel-git-grep :which-key "git grep")
    "p i" '(projectile-invalidate-cache :which-key "invalidate cache")
        "p p" '(counsel-projectile-switch-project :which-key "other project")
        "p b" '(counsel-projectile-switch-to-buffer :which-key "buffer"))
  :config
  (setq projectile-enable-caching nil
        projectile-completion-system 'ivy
        projectile-sort-order 'recentf)

  (projectile-global-mode))

(use-package counsel-projectile
  :straight t
  :config
  (counsel-projectile-mode))

Git

(use-package magit
  :straight t
  :init
  (nmap :prefix jj-leader
    "g" '(:ignore t :which-key "git")
    "g b" '(magit-blame :which-key "git blame")
    "g l" '(magit-log-current :which-key "git log")
    "g s" '(magit-status :which-key "git status"))

  :config
  (setq magit-display-buffer-function #'magit-display-buffer-fullframe-status-v1)
  (setq magit-push-arguments (quote ("--force-with-lease")))

  (with-eval-after-load 'magit-status
    (define-key magit-status-mode-map "p" 'magit-push-popup)))

(use-package evil-magit
  :straight t
  :after magit)

(use-package git-timemachine
  :straight t
  :init
  (nmap :prefix jj-leader
    "g t" '(git-timemachine :which-key "git timemachine"))

  (defadvice git-timemachine-mode (after toggle-evil activate)
     "Turn off `evil-local-mode' when enabling
     `git-timemachine-mode', and turn it back on when disabling
     `git-timemachine-mode'."
     (evil-local-mode (if git-timemachine-mode -1 1))))

Org

(use-package org
  :bind (("C-c c" . org-capture)
         ("C-c a" . org-agenda))
  :config
  (setq org-table-number-regexp "$a"))

Languages

LSP

(use-package lsp-mode
  :straight t
  :commands lsp)
(use-package py-isort
  :straight t
  :commands py-isort)
(use-package ccls
  :straight t
  :config
  (setq ccls-executable "ccls")
  (setq lsp-prefer-flymake nil)
  :hook ((c-mode c++-mode objc-mode) .
         (lambda () (require 'ccls) (lsp))))

Markdown

(use-package vmd-mode
  :straight t)

Python

(use-package elpy
  :straight t
  :init
  (elpy-enable)
  :config
  (setq python-shell-interpreter "ipython"
        python-shell-interpreter-args "-i --simple-prompt")
  )
(use-package py-isort
  :straight t
  :commands py-isort)

Dockerfile

(use-package dockerfile-mode
  :straight t
  :mode ("Dockerfile\\'" . dockerfile-mode))

YAML

(use-package yaml-mode
  :straight t
  :mode ("\\.yml$" . yaml-mode))

Terraform

(use-package terraform-mode
  :straight t
  :mode ("\\.tf$" . terraform-mode))

JSON

(use-package json-navigator
  :straight t)