An open API service indexing awesome lists of open source software.

https://github.com/mcorbin/emacs-config

emacs config
https://github.com/mcorbin/emacs-config

Last synced: 3 months ago
JSON representation

emacs config

Awesome Lists containing this project

README

        

#+TITLE: Mathieu Corbin Emacs config
#+AUTHOR: Mathieu Corbin

#+begin_src

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

#+end_src

* General Configuration
** Appearance
*** General

nyan-mode is fun and pretty

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

Removing toolbar/menu/scrollbar...
#+begin_src emacs-lisp
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
(blink-cursor-mode -1)
(setq inhibit-splash-screen t)
#+end_src

#+BEGIN_SRC emacs-lisp

(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)
#+END_SRC

Limit font-lock-mode
#+BEGIN_SRC emacs-lisp
(setq font-lock-maximum-decoration 3)
#+END_SRC

*** 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.
#+BEGIN_SRC emacs-lisp
(setq-default indicate-buffer-boundaries 'left)
(setq-default indicate-empty-lines +1)
#+END_SRC

*** Whitespaces

I want to detect trailing whitespace quickly
#+BEGIN_SRC emacs-lisp
(setq-default show-trailing-whitespace t)

#+END_SRC

*** Fonts

I use Monospace font.
#+begin_src emacs-lisp
;; (set-frame-font "DejaVu Sans Mono")
(if (string= system-type "darwin")
(set-face-attribute 'default nil :height 140)
(set-frame-font "DejaVu Sans Mono"))
#+end_src

*** Themes

I load some custom themes and i display my theme only in graphic mode
#+begin_src emacs-lisp
(add-to-list 'custom-theme-load-path "~/.emacs.d/themes")

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

** General

Answer y or n and not yes/no
#+BEGIN_SRC emacs-lisp
(fset 'yes-or-no-p 'y-or-n-p)
#+END_SRC

#+BEGIN_SRC emacs-lisp
(add-hook 'text-mode-hook 'visual-line-mode)
(add-hook 'text-mode-hook 'rainbow-delimiters-mode)
#+END_SRC

*** Encoding

utf-8 by default

#+begin_src emacs-lisp
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-language-environment "UTF-8")
(prefer-coding-system 'utf-8)
#+end_src

*** Buffers

Non unique buffers name ? uniquify adds the parent path to the buffer name
#+begin_src emacs-lisp
(use-package uniquify)
(setq uniquify-buffer-name-style 'forward)
#+end_src

Override default kill buffer function (no ask)
#+BEGIN_SRC emacs-lisp
(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)
#+END_SRC

*** 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.

#+begin_src emacs-lisp
(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)
#+end_src

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

#+begin_src emacs-lisp
(setq delete-old-versions t
kept-new-versions 6
kept-old-versions 2
version-control t)
#+end_src
*** Formatting

space instead of tabs
#+begin_src emacs-lisp
(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)
#+end_src

#+BEGIN_SRC emacs-lisp
(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)
#+END_SRC
*** 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).

#+BEGIN_SRC emacs-lisp
(use-package async
:ensure t)
(use-package dired-async
:init
(dired-async-mode 1))
#+END_SRC

*** Dired

#+BEGIN_SRC emacs-lisp

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

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

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

#+END_SRC

*** selection

expand-region

#+BEGIN_SRC emacs-lisp
(use-package expand-region
:ensure t
:bind ("C-=" . er/expand-region))
#+END_SRC

*** Zoom
#+BEGIN_SRC emacs-lisp
(global-set-key (kbd "C-+") 'text-scale-increase)
(global-set-key (kbd "C--") 'text-scale-decrease)
#+END_SRC

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

#+BEGIN_SRC emacs-lisp
(setq scroll-preserve-screen-position 'always)
#+END_SRC

*** Windows

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

#+BEGIN_SRC emacs-lisp
(global-set-key (kbd "S-C-") 'shrink-window-horizontally)
(global-set-key (kbd "S-C-") 'enlarge-window-horizontally)
(global-set-key (kbd "S-C-") 'enlarge-window)
(global-set-key (kbd "S-C-") 'shrink-window)
#+END_SRC

*** Popwin

#+BEGIN_QUOTE
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.
#+END_QUOTE

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

#+BEGIN_SRC emacs-lisp
(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)))
#+END_SRC

*** Ace Jump

Jump to char with ace jump
#+BEGIN_SRC emacs-lisp
(use-package ace-jump-mode
:ensure t
:commands ace-jump-mode
:bind ("C-x j" . ace-jump-mode))
#+END_SRC

*** Flycheck
#+BEGIN_SRC emacs-lisp
(use-package flycheck
:ensure t
:config (global-flycheck-mode))
#+END_SRC

** 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 [[http://stackoverflow.com/a/17069276/89249][stackoverflow]]).

#+BEGIN_SRC emacs-lisp
(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))))
#+END_SRC

* Other Mode
** Discover my major

#+BEGIN_QUOTE
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…”
#+END_QUOTE

#+BEGIN_SRC emacs-lisp
(use-package discover-my-major
:ensure t
:bind ("C-h C-m" . discover-my-major))
#+END_SRC

** Manage my minor

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

#+BEGIN_SRC emacs-lisp
(use-package manage-minor-mode
:ensure t
:bind ("C-c x n" . manage-minor-mode))
#+END_SRC

** selectrum and contuls
#+BEGIN_SRC emacs-lisp
(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)))
#+END_SRC
** Company mode
#+BEGIN_QUOTE
company mode
#+END_QUOTE

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

#+END_SRC
** Version control integration
*** Git

**** magit

#+begin_src emacs-lisp
(use-package magit
:ensure t
:bind ("C-c g" . magit-status))
#+end_src

**** 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.

#+BEGIN_SRC emacs-lisp
(use-package git-timemachine
:ensure t)
#+END_SRC

** 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

#+BEGIN_SRC emacs-lisp
(use-package move-text
:ensure t
:config (move-text-default-bindings))
#+END_SRC

** Diff

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

#+BEGIN_SRC emacs-lisp
(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)))

#+END_SRC

** multiple-cursors

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

#+BEGIN_SRC emacs-lisp
(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)))
#+END_SRC

** Projectile

#+BEGIN_QUOTE
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).
#+END_QUOTE

#+BEGIN_SRC emacs-lisp
(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)))
#+END_SRC

#+BEGIN_SRC emacs-lisp

#+END_SRC

** guru mode

#+BEGIN_SRC emacs-lisp
(use-package guru-mode
:ensure t)
#+END_SRC

** lsp mode

#+BEGIN_SRC emacs-lisp
(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)
#+END_SRC

* Languages
** Lua

#+BEGIN_SRC emacs-lisp
(use-package lua-mode
:ensure t)
#+END_SRC

** Lisp(s)
*** General

I cannot write lisp without rainbow-delimiters

#+BEGIN_SRC emacs-lisp
(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)))

#+END_SRC

Let's install some LISP common useful modes.

#+BEGIN_SRC emacs-lisp
(use-package paredit
:ensure t)
(use-package highlight-parentheses
:ensure t)
#+END_SRC

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

#+BEGIN_SRC emacs-lisp
(defun my/lisps-mode-hook ()
(paredit-mode t)
(rainbow-delimiters-mode t)
(highlight-parentheses-mode t))
#+END_SRC

*** Emacs lisp

#+BEGIN_SRC emacs-lisp
(add-hook 'emacs-lisp-mode-hook
(lambda ()
(my/lisps-mode-hook)
(eldoc-mode 1)))
#+END_SRC

*** Clojure

Install flycheck-clj-kondo

#+BEGIN_SRC emacs-lisp
(use-package flycheck-clj-kondo
:ensure t)
#+END_SRC

Clojure mode
#+BEGIN_SRC emacs-lisp
(use-package clojure-mode
:ensure
t
:config
(progn
(require 'flycheck-clj-kondo)
(add-hook 'clojure-mode-hook 'my/lisps-mode-hook)))
#+END_SRC

**** cider

Cider package with config
#+BEGIN_SRC emacs-lisp
(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)
#+END_SRC
** S1QL

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

#+BEGIN_SRC emacs-lisp
(add-hook 'sql-interactive-mode-hook
(lambda ()
(toggle-truncate-lines t)))
#+END_SRC

** Adoc

#+BEGIN_SRC emacs-lisp
(use-package adoc-mode
:ensure t)
#+END_SRC
** Markdown, Yaml & Toml

#+BEGIN_SRC emacs-lisp
(use-package markdown-mode
:ensure t)
#+END_SRC

#+BEGIN_SRC emacs-lisp
(use-package yaml-mode
:ensure t)
#+END_SRC

#+BEGIN_SRC emacs-lisp
(use-package toml-mode
:ensure t)
#+END_SRC

** Docker

#+BEGIN_SRC emacs-lisp
(use-package dockerfile-mode
:ensure t)
#+END_SRC
** Vagrant

Let's add support for vagrant.

#+BEGIN_SRC emacs-lisp
(use-package vagrant
:ensure t
:defer t)
#+END_SRC

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=

#+BEGIN_SRC emacs-lisp
(use-package vagrant-tramp
:ensure t
:defer t)
#+END_SRC

** Python
#+BEGIN_SRC emacs-lisp

(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)

#+END_SRC

** Rust
#+BEGIN_SRC emacs-lisp

(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 ") #'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")))
#+END_SRC

** Go

Add go-mode
#+BEGIN_SRC emacs-lisp

(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)

#+END_SRC

And some extra packages

#+BEGIN_SRC emacs-lisp

(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)

#+END_SRC

Setup the go-mode hooks

#+BEGIN_SRC emacs-lisp

(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)

#+END_SRC

** groovy
#+BEGIN_SRC emacs-lisp

(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)))
#+END_SRC
** Terraform
#+BEGIN_SRC emacs-lisp
(use-package terraform-mode
:ensure t)
#+END_SRC
** Puppet

#+BEGIN_SRC emacs-lisp

(use-package puppet-mode
:ensure t)

#+END_SRC