Skip to content

mcorbin/emacs-config

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

97 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mathieu Corbin Emacs config

.-----.--------.---.-.----.-----.
|  -__|        |  _  |  __|__ --|
|_____|__|__|__|___._|____|_____|

General Configuration

Appearance

General

nyan-mode is fun and pretty

(setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3")
(use-package nyan-mode
  :ensure t
  :config
  (progn
    (nyan-mode)
    (nyan-start-animation)))

Removing toolbar/menu/scrollbar…

(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
(blink-cursor-mode -1)
(setq inhibit-splash-screen t)
(setq mac-option-modifier nil
      mac-command-modifier 'meta
      x-select-enable-clipboard t)

   (line-number-mode 1)
   (column-number-mode 1)
   (global-hl-line-mode 1)

Limit font-lock-mode

(setq font-lock-maximum-decoration 3)

Fringe

Customize fringe

indicate-buffer-boundaries put arrows at the beginning/end of a buffer indate-empty-lines indicate in the fringe the lines at the end of a buffer.

(setq-default indicate-buffer-boundaries 'left)
(setq-default indicate-empty-lines +1)

Whitespaces

I want to detect trailing whitespace quickly

(setq-default show-trailing-whitespace t)

Fonts

I use Monospace font.

       ;; (set-frame-font "DejaVu Sans Mono")
(if (string= system-type "darwin")
  (set-face-attribute 'default nil :height 140)
  (set-frame-font "DejaVu Sans Mono"))

Themes

I load some custom themes and i display my theme only in graphic mode

 (add-to-list 'custom-theme-load-path "~/.emacs.d/themes")

(if (display-graphic-p)
     (load-theme 'spolsky t))

General

Answer y or n and not yes/no

(fset 'yes-or-no-p 'y-or-n-p)
(add-hook 'text-mode-hook 'visual-line-mode)
(add-hook 'text-mode-hook 'rainbow-delimiters-mode)

Encoding

utf-8 by default

(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-language-environment "UTF-8")
(prefer-coding-system 'utf-8)

Buffers

Non unique buffers name ? uniquify adds the parent path to the buffer name

(use-package uniquify)
(setq uniquify-buffer-name-style 'forward)

Override default kill buffer function (no ask)

(defun kill-default-buffer ()
  "Kill the currently active buffer"
  (interactive)
  (let (kill-buffer-query-functions) (kill-buffer)))

(global-set-key (kbd "C-x k") 'kill-default-buffer)

Backup files

Files suffixed with ~ in the current directory are ugly. We are still going to use backup files, as it can saves some time in case of trouble, but we’ll move them somewhere else : /tmp/emacs-1001 (for a user with the uid = 1001).

Note the we store them in /tmp so in case of a reboot, we loose them.

(defconst emacs-tmp-dir (format "%s/%s%s/" temporary-file-directory "emacs" (user-uid)))
(setq backup-directory-alist
      `((".*" . ,emacs-tmp-dir))
      auto-save-file-name-transforms
      `((".*" ,emacs-tmp-dir t))
      auto-save-list-file-prefix emacs-tmp-dir)

Now that all the temporary files are out of the way, we can keep more of them.

(setq delete-old-versions t
      kept-new-versions 6
      kept-old-versions 2
      version-control t)

Formatting

space instead of tabs

(setq-default indent-tabs-mode nil)
(defcustom indent-sensitive-modes
  '(coffee-mode python-mode haml-mode yaml-mode)
  "Modes for which auto-indenting is suppressed."
  :type 'list)
(defun smarter-move-beginning-of-line (arg)
  "Move point back to indentation of beginning of line.

Move point to the first non-whitespace character on this line.
If point is already there, move to the beginning of the line.
Effectively toggle between the first non-whitespace character and
the beginning of the line.

If ARG is not nil or 1, move forward ARG - 1 lines first.  If
point reaches the beginning or end of the buffer, stop there."
  (interactive "^p")
  (setq arg (or arg 1))

  ;; Move lines first
  (when (/= arg 1)
    (let ((line-move-visual nil))
      (forward-line (1- arg))))

  (let ((orig-point (point)))
    (back-to-indentation)
    (when (= orig-point (point))
      (move-beginning-of-line 1))))

;; remap C-a to `smarter-move-beginning-of-line'
(global-set-key [remap move-beginning-of-line]
                'smarter-move-beginning-of-line)

Async

async.el is a module for doing asynchronous processing in Emacs. Let’s load it as it’s gonna be useful. Let’s also load dired-async for the copy & co to be run asynchroniously (very useful with TRAMP).

(use-package async
  :ensure t)
(use-package dired-async
  :init
  (dired-async-mode 1))

Dired

(use-package dired-x)
(use-package dired-aux)

(when (string= system-type "darwin")
  (setq dired-use-ls-dired nil))

(setq dired-listing-switches "-laGh1v")

selection

expand-region

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

Zoom

(global-set-key (kbd "C-+") 'text-scale-increase)
(global-set-key (kbd "C--") 'text-scale-decrease)

scrolling

ensure that M-v always undoes C-v, so you can go back exactly.

(setq scroll-preserve-screen-position 'always)

Windows

Use shift + control + arrows to change the size of windows.

(global-set-key (kbd "S-C-<right>") 'shrink-window-horizontally)
(global-set-key (kbd "S-C-<left>") 'enlarge-window-horizontally)
(global-set-key (kbd "S-C-<down>") 'enlarge-window)
(global-set-key (kbd "S-C-<up>") 'shrink-window)

Popwin

popwin is a popup window manager for Emacs which makes you free from the hell of annoying buffers such like Help, Completions, compilation, and etc.

That says it all, it’s kind of a must.

(use-package popwin
  :ensure t
  :config
  (progn
    (add-to-list 'popwin:special-display-config `("*Swoop*" :height 0.5 :position bottom))
    (add-to-list 'popwin:special-display-config `("*Warnings*" :height 0.5 :noselect t))
    (add-to-list 'popwin:special-display-config `("*Procces List*" :height 0.5))
    (add-to-list 'popwin:special-display-config `("*Messages*" :height 0.5 :noselect t))
    (add-to-list 'popwin:special-display-config `("*Backtrace*" :height 0.5))
    (add-to-list 'popwin:special-display-config `("*Compile-Log*" :height 0.5 :noselect t))
    (add-to-list 'popwin:special-display-config `("*Remember*" :height 0.5))
    (add-to-list 'popwin:special-display-config `("*All*" :height 0.5))
    (add-to-list 'popwin:special-display-config `(flycheck-error-list-mode :height 0.5 :regexp t :position bottom))
    (popwin-mode 1)
    (global-set-key (kbd "C-z") popwin:keymap)))

Ace Jump

Jump to char with ace jump

(use-package ace-jump-mode
  :ensure t
  :commands ace-jump-mode
  :bind ("C-x j" . ace-jump-mode))

Flycheck

(use-package flycheck
  :ensure t
  :config (global-flycheck-mode))

Server mode

Start a server in not already running. I usually start emacs as a daemon when at the start of the computer, but you never know ;-).

I have an error about unsafe directory for /tmp/emacs100, that’s why the advice is there, to ignore the error (from stackoverflow).

(defadvice server-ensure-safe-dir (around
                                   my-around-server-ensure-safe-dir
                                   activate)
  "Ignores any errors raised from server-ensure-safe-dir"
  (ignore-errors ad-do-it))
(unless (string= (user-login-name) "root")
  (require 'server)
  (when (or (not server-process)
           (not (eq (process-status server-process)
                  'listen)))
    (unless (server-running-p server-name)
      (server-start))))

Other Mode

Discover my major

Discover key bindings and their meaning for the current Emacs major mode.

The command is inspired by discover.el and also uses the makey library. I thought, “Hey! Why not parse the information about the major mode bindings somehow and display that like discover.el does…”

(use-package discover-my-major
  :ensure t
  :bind ("C-h C-m" . discover-my-major))

Manage my minor

Let’s also use manage-my-minor to be able to enable/disable minor-modes.

(use-package manage-minor-mode
  :ensure t
  :bind ("C-c x n" . manage-minor-mode))

selectrum and contuls

 (use-package selectrum-prescient
   :config
   (prescient-persist-mode +1))

(use-package selectrum
  :preface (declare-function selectrum-insert-or-submit-current-candidate nil)
  :init
  (defun selectrum-insert-or-submit-current-candidate ()
    "Insert current candidate depending, or forward to
`selectrum-select-current-candidate' if input text hasn't changed since
last completion
Similar to ivy's `ivy-partial-or-done'."
    (interactive)
    (progn
      (let ((prev-input (selectrum-get-current-input)))
        (when (> (length (selectrum-get-current-candidates)) 0)
          (selectrum-insert-current-candidate))
        (when (string= prev-input (selectrum-get-current-input))
          (selectrum-select-current-candidate)))))
  :config
  (selectrum-mode +1)
  ;; to make sorting and filtering more intelligent
  (selectrum-prescient-mode +1)
  ;; to save your command history on disk, so the sorting gets more
  ;; intelligent over time
  ;; (prescient-persist-mode +1)
  (setq selectrum-count-style 'current/matches)
  (setq selectrum-num-candidates-displayed 21)
  :bind ((:map selectrum-minibuffer-map
               ("TAB" . selectrum-insert-or-submit-current-candidate)
               ("C-c C-o" . embark-export))))

(use-package consult
  :after erc
  :config
  ;; Optionally configure a function which returns the project root directory
  (autoload 'projectile-project-root "projectile")
  (setq consult-project-root-function #'projectile-project-root)

  :bind (("C-t" . consult-line)
         ("M-g M-g" . consult-goto-line)
         ("C-x C-SPC" . consult-global-mark)
         ("C-c C-SPC" . consult-mark)
         ("C-x C-g" . consult-grep)))

(use-package consult-flycheck
  :after consult
  :config
  (setq flycheck-display-errors-delay 0.5)
  :bind (("C-x C-l" . consult-flycheck)
         ("C-x l" . consult-flycheck)))

(use-package embark
  :config
  (defun refresh-selectrum ()
    (setq selectrum--previous-input-string nil))
  (add-hook 'embark-pre-action-hook #'refresh-selectrum)
  (add-hook 'embark-post-action-hook #'embark-collect--update-linked)
  (add-hook 'embark-collect-post-revert-hook
            (defun resize-embark-collect-window (&rest _)
              (when (memq embark-collect--kind '(:live :completions))
                (fit-window-to-buffer (get-buffer-window)
                                      (floor (frame-height) 2) 1)))))

(use-package embark-consult
  :ensure t
  :after (embark consult)
  :demand t ; only necessary if you have the hook below
  ;; if you want to have consult previews as you move around an
  ;; auto-updating embark collect buffer
  :hook
  (embark-collect-mode . embark-consult-preview-minor-mode))

(use-package marginalia
  :after consult
  :init
  (marginalia-mode)
  (setq marginalia-annotators '(marginalia-annotators-heavy)))

Company mode

company mode

(use-package company
    :ensure t)
(require 'company)
(global-company-mode)
(global-set-key (kbd "TAB") #'company-indent-or-complete-common)

Version control integration

Git

magit

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

git-timemachine

I recently discovered an extremely cool package called git-timemachine that allows you to step though the git history of the file you’re currently editing in Emacs.

(use-package git-timemachine
  :ensure t)

move-text

Allows to move the current line or region up/down. The source code is on the Wiki: http://www.emacswiki.org/emacs/move-text.el

(use-package move-text
  :ensure t
  :config (move-text-default-bindings))

Diff

The diff-mode of Emacs is pretty cool, but let’s show important whitespace when in this mode.

(add-hook 'diff-mode-hook (lambda ()
                            (setq-local whitespace-style
                                        '(face
                                          tabs
                                          tab-mark
                                          spaces
                                          space-mark
                                          trailing
                                          indentation::space
                                          indentation::tab
                                          newline
                                          newline-mark))
                            (whitespace-mode 1)))

multiple-cursors

Multiple cursors for Emacs, this is a pretty badass functionnality.

(use-package multiple-cursors
  :ensure t
  :bind (("C-S-c C-S-c" . mc/edit-lines)
         ("C->" . mc/mark-next-like-this)
         ("C-<" . mc/mark-previous-like-this)
         ("C-c C-<" . mc/mark-all-like-this)))

Projectile

Projectile is a project interaction library for Emacs. Its goal is to provide a nice set of features operating on a project level without introducing external dependencies(when feasible). For instance - finding project files has a portable implementation written in pure Emacs Lisp without the use of GNU find (but for performance sake an indexing mechanism backed by external commands exists as well).

(use-package projectile
  :ensure t
  :init (setq projectile-keymap-prefix (kbd "C-c p"))
  :config
  (progn
    (setq projectile-completion-system 'default)
    (setq projectile-enable-caching nil)
    (defun refresh-selectrum ()
      (setq selectrum--previous-input-string nil))
    (add-hook 'embark-pre-action-hook #'refresh-selectrum)
    (define-key projectile-mode-map (kbd "s-p") 'projectile-command-map)
    (define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)
    (projectile-global-mode)))

guru mode

(use-package guru-mode
  :ensure t)

lsp mode

(use-package lsp-mode
  :ensure t
  :config
  (define-key lsp-mode-map (kbd "C-c l") lsp-command-map))

(use-package lsp-ui
  :ensure t)

Languages

Lua

(use-package lua-mode
  :ensure t)

Lisp(s)

General

I cannot write lisp without rainbow-delimiters

(use-package rainbow-delimiters
  :ensure t
  :config
  (progn
    (add-hook 'prog-mode-hook 'rainbow-delimiters-mode)
    (add-hook 'cider-repl-mode-hook 'rainbow-delimiters-mode)))

Let’s install some LISP common useful modes.

(use-package paredit
  :ensure t)
(use-package highlight-parentheses
  :ensure t)

And define a comme lisp hook for all LISP-related prog-modes, mostly about parentheses.

(defun my/lisps-mode-hook ()
  (paredit-mode t)
  (rainbow-delimiters-mode t)
  (highlight-parentheses-mode t))

Emacs lisp

(add-hook 'emacs-lisp-mode-hook
          (lambda ()
            (my/lisps-mode-hook)
            (eldoc-mode 1)))

Clojure

Install flycheck-clj-kondo

(use-package flycheck-clj-kondo
  :ensure t)

Clojure mode

(use-package clojure-mode
 :ensure
  t
  :config
  (progn
    (require 'flycheck-clj-kondo)
    (add-hook 'clojure-mode-hook 'my/lisps-mode-hook)))

cider

Cider package with config

(use-package cider
  :ensure t
  :config (put-clojure-indent 'match 1))

(setq cider-repl-display-help-banner nil)
(add-hook 'cider-repl-mode-hook
       (lambda () (setq show-trailing-whitespace nil)))
(add-hook 'cider-repl-mode-hook 'my/lisps-mode-hook)

S1QL

By default, Emacs does not automatically truncate long lines in SQL(i) mode, let’s change that.

(add-hook 'sql-interactive-mode-hook
          (lambda ()
            (toggle-truncate-lines t)))

Adoc

(use-package adoc-mode
  :ensure t)

Markdown, Yaml & Toml

(use-package markdown-mode
  :ensure t)
(use-package yaml-mode
  :ensure t)
(use-package toml-mode
  :ensure t)

Docker

(use-package dockerfile-mode
  :ensure t)

Vagrant

Let’s add support for vagrant.

(use-package vagrant
  :ensure t
  :defer t)

And let’s also add a TRAMP add-on for Vagrant. The idea is to be able to do something like /vagrant:mybox/etc/hostname

(use-package vagrant-tramp
  :ensure t
  :defer t)

Python

(use-package elpy
  :ensure t
  :init
  (progn
    (setq elpy-rpc-python-command "python3")
    (elpy-enable)))

(use-package jedi-core
  :ensure t)


(use-package company-jedi
  :ensure t)

(defun my/python-mode-hook ()
  (add-to-list 'company-backends 'company-jedi))

(add-hook 'python-mode-hook 'my/python-mode-hook)

Rust

(use-package rust-mode
  :ensure t)

(use-package racer
  :ensure t)

(use-package cargo
  :ensure t)

(use-package flycheck-rust
  :ensure t)

(setq racer-cmd "~/.cargo/bin/racer")

(add-hook 'rust-mode-hook #'racer-mode)
(add-hook 'racer-mode-hook #'eldoc-mode)

(add-hook 'racer-mode-hook #'company-mode)
(add-hook 'rust-mode-hook 'cargo-minor-mode)

(add-hook 'rust-mode-hook
        (lambda ()
          (local-set-key (kbd "C-c <tab>") #'rust-format-buffer)))

(add-hook 'flycheck-mode-hook #'flycheck-rust-setup)
(setenv "PATH" (concat (getenv "PATH") ":~/.cargo/bin"))
(setq exec-path (append exec-path '("~/.cargo/bin")))

Go

Add go-mode

(if (string= system-type "darwin")
  (progn
      (setenv "GOPATH" "/Users/mathieucorbin/go")
      (setenv "PATH" (concat (getenv "PATH") ":/Users/mathieucorbin/go/bin:/usr/local/go/bin"))
      (setenv "PATH" (concat (getenv "PATH") ":/usr/local/bin"))
      (setq exec-path (append exec-path '("/Users/mathieucorbin/go/bin"))))
  (progn
    (setenv "GOPATH" "/home/mcorbin/prog/go")
    (setenv "PATH" (concat (getenv "PATH") ":/home/mcorbin/prog/go/bin:/usr/local/go/bin"))
    (setq exec-path (append exec-path '("/home/mcorbin/prog/go/bin")))))

(setq exec-path (append exec-path '("/usr/local/go/bin")))
(setq exec-path (append exec-path '("/usr/local/bin")))

  (use-package go-mode
    :ensure t)

And some extra packages

(use-package gotest
  :ensure t
  :init
  (bind-key "C-c r" 'go-run go-mode-map)
  (bind-key "C-c t C-g a" 'go-test-current-project go-mode-map)
  (bind-key "C-c t m" 'go-test-current-file go-mode-map)
  (bind-key "C-c t ." 'go-test-current-test go-mode-map)
  (bind-key "C-c t c" 'go-test-current-coverage go-mode-map)
  (bind-key "C-c t b" 'go-test-current-benchmark go-mode-map)
  (bind-key "C-c t C-g b" 'go-test-current-project-benchmarks go-mode-map))

  (use-package flycheck-golangci-lint
  :ensure t)

Setup the go-mode hooks

(defvar-local flycheck-local-checkers nil)
  (defun +flycheck-checker-get(fn checker property)
    (or (alist-get property (alist-get checker flycheck-local-checkers))
        (funcall fn checker property)))
  (advice-add 'flycheck-checker-get :around '+flycheck-checker-get)

(defun my-go-mode-hook ()
  (setq gofmt-command "gofmt")
  (flycheck-golangci-lint-setup)
  (setq flycheck-local-checkers '((lsp . ((next-checkers . (golangci-lint))))))
  (add-hook 'before-save-hook 'gofmt-before-save)
  (if (not (string-match "go" compile-command))
      (set (make-local-variable 'compile-command)
           "go build -v && go test -v && go vet")))

(defun lsp-go-install-save-hooks ()
  (add-hook 'before-save-hook #'lsp-format-buffer t t)
  (add-hook 'before-save-hook #'lsp-organize-imports t t))


(add-hook 'go-mode-hook #'lsp-go-install-save-hooks)
(add-hook 'go-mode-hook 'my-go-mode-hook)
(add-hook 'go-mode-hook #'lsp-deferred)

groovy

(use-package groovy-mode
  :ensure t)

(add-hook 'groovy-mode-hook
  (lambda ()
  (setq c-basic-offset 2
        tab-width 2
        groovy-indent-offset 2
        indent-tabs-mode nil)))

Terraform

(use-package terraform-mode
  :ensure t)

Puppet

(use-package puppet-mode
  :ensure t)

About

emacs config

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published