* General settings ** Garbage Collector #+begin_src emacs-lisp (defvar last-file-name-handler-alist file-name-handler-alist) (setq gc-cons-threshold (* 64 1024 1024) gc-cons-percentage 0.6 file-name-handler-alist nil) ;; after startup, it is important you reset this to some reasonable default. A large ;; gc-cons-threshold will cause freezing and stuttering during long-term ;; interactive use. (add-hook 'emacs-startup-hook (lambda () (setq gc-cons-threshold 16777216 gc-cons-percentage 0.1 file-name-handler-alist last-file-name-handler-alist))) #+end_src ** Appearance Set emacs theme. #+begin_src emacs-lisp (use-package doom-themes :ensure t :config ;; Global settings (defaults) (setq doom-themes-enable-bold t ; if nil, bold is universally disabled doom-themes-enable-italic t) ; if nil, italics is universally disabled (load-theme 'doom-one t) ;; Enable flashing mode-line on errors (doom-themes-visual-bell-config) (doom-themes-treemacs-config) ;; Corrects (and improves) org-mode's native fontification. (doom-themes-org-config)) #+end_src Colorize compilation windows #+begin_src emacs-lisp (use-package ansi-color :config (defun my-colorize-compilation-buffer () (when (eq major-mode 'compilation-mode) (ansi-color-apply-on-region compilation-filter-start (point-max)))) :hook (compilation-filter . my-colorize-compilation-buffer)) #+end_src Disabling menu/tool/scroll bars #+begin_src emacs-lisp (menu-bar-mode -1) (tool-bar-mode -1) (scroll-bar-mode -1) (setq-default indent-tabs-mode nil) (setq read-file-name-completion-ignore-case t) (setq org-src-window-setup 'current-window) #+end_src #+begin_src emacs-lisp (use-package all-the-icons :defer t :ensure t) #+end_src Show line numbers #+begin_src emacs-lisp (global-display-line-numbers-mode) #+end_src Show columns #+begin_src emacs-lisp (column-number-mode 1) #+end_src #+begin_src emacs-lisp (when (display-graphic-p) (defvar emacs-english-font "DejaVu Sans Mono" "The font name of English.") (defvar emacs-cjk-font "Noto Sans JP" "The font name for CJK.") (defvar emacs-font-size-pair '(15 . 18) "Default font size pair for (english . cjk)") (defvar emacs-font-size-pair-list '(( 5 . 6) ( 9 . 10) (10 . 12) (12 . 14) (13 . 16) (15 . 18) (17 . 20) (19 . 22) (20 . 24) (21 . 26) (24 . 28) (26 . 32) (28 . 34) (30 . 36) (34 . 40) (36 . 44)) "This list is used to store matching (english . cjk) font-size.") (defun font-exist-p (fontname) "Test if this font is exist or not." (if (or (not fontname) (string= fontname "")) nil (if (not (x-list-fonts fontname)) nil t))) (defun set-font (english chinese size-pair) "Setup Emacs English and CJK font on X window-system." (if (font-exist-p english) (set-frame-font (format "%s:pixelsize=%d" english (car size-pair)) t)) (if (font-exist-p chinese) (dolist (charset '(kana han symbol cjk-misc bopomofo)) (set-fontset-font (frame-parameter nil 'font) charset (font-spec :family chinese :size (cdr size-pair)))))) ;; Setup font size based on emacs-font-size-pair (set-font emacs-english-font emacs-cjk-font emacs-font-size-pair) (defun emacs-step-font-size (step) "Increase/Decrease emacs's font size." (let ((scale-steps emacs-font-size-pair-list)) (if (< step 0) (setq scale-steps (reverse scale-steps))) (setq emacs-font-size-pair (or (cadr (member emacs-font-size-pair scale-steps)) emacs-font-size-pair)) (when emacs-font-size-pair (message "emacs font size set to %.1f" (car emacs-font-size-pair)) (set-font emacs-english-font emacs-cjk-font emacs-font-size-pair)))) (defun increase-emacs-font-size () "Decrease emacs's font-size acording emacs-font-size-pair-list." (interactive) (emacs-step-font-size 1)) (defun decrease-emacs-font-size () "Increase emacs's font-size acording emacs-font-size-pair-list." (interactive) (emacs-step-font-size -1)) (global-set-key (kbd "C-=") 'increase-emacs-font-size) (global-set-key (kbd "C--") 'decrease-emacs-font-size)) #+end_src ** Basics Set default encoding #+begin_src emacs-lisp (prefer-coding-system 'utf-8) (set-default-coding-systems 'utf-8) (set-language-environment 'utf-8) (set-selection-coding-system 'utf-8) #+end_src Subword #+begin_src emacs-lisp (global-subword-mode 1) #+end_src Electric #+begin_src emacs-lisp (setq-default electric-pair-pairs '((?\( . ?\)) (?\[ . ?\]))) (electric-pair-mode t) #+end_src Show trailing white space #+begin_src emacs-lisp (setq-default show-trailing-whitespace t) #+end_src Config editing/reloading #+begin_src emacs-lisp (defun lys/config-visit () (interactive) (find-file "~/.emacs.d/config.org")) (defun lys/config-reload () (interactive) (org-babel-load-file (expand-file-name "~/.emacs.d/config.org"))) #+end_src Move backup files in a specific folder #+begin_src emacs-lisp (setq backup-directory-alist '(("" . "~/.emacs.d/backup"))) #+end_src Disabling emacs auto-saves #+begin_src emacs-lisp (setq auto-save-default nil) #+end_src #+begin_src emacs-lisp (use-package vterm :defer t :ensure t) #+end_src #+begin_src emacs-lisp (use-package treemacs :ensure t) #+end_src ** Evil #+begin_src emacs-lisp (fset 'lys/ctl-x-map ctl-x-map) (fset 'lys/help-map help-map) (defvar lys/evil-leader-command-map (let ((map (make-sparse-keymap))) ;; modeline-map (define-prefix-command 'lys/modeline-map) (define-key lys/modeline-map (kbd "c") '("cycle separators" . lys/telephone-line-separator-cycle)) ;; config-map (define-prefix-command 'lys/config-map) (define-key lys/config-map (kbd "o") '("open config" . lys/config-visit)) (define-key lys/config-map (kbd "r") '("reload config" . lys/config-reload)) ;; file-map (define-prefix-command 'lys/file-map) (define-key lys/file-map (kbd "f") '("open file" . counsel-find-file)) ;; buffer-map (define-prefix-command 'lys/buffer-map) (define-key lys/buffer-map (kbd "b") '("switch buffer" . counsel-ibuffer)) ;; leader-map (define-key map (kbd ";") '("eval" . eval-expression)) (define-key map (kbd ":") '("command" . counsel-M-x)) (define-key map (kbd "f") '("file" . lys/file-map)) (define-key map (kbd "b") '("buffer" . lys/buffer-map)) (define-key map (kbd "m") '("modeline" . lys/modeline-map)) (define-key map (kbd "p") '("projectile" . projectile-command-map)) (define-key map (kbd "w") '("windows" . evil-window-map)) ;; (define-key map (kbd "TAB") '("persp" . persp-key-map)) (define-key map (kbd "c") '("config" . lys/config-map)) (define-key map (kbd "x") '("commands" . lys/ctl-x-map)) (define-key map (kbd "h") '("help" . lys/help-map)) map) "Keymap for .") (fset 'lys/evil-leader-command-map lys/evil-leader-command-map) (defun lys/local-map-with-leader () "Set `current-local-map' to include C-c bindings under `lys/evil-leader-command-map'." (when (current-local-map) (let ((prefix (lookup-key (current-local-map) (kbd "C-c")))) (when (keymapp prefix) (let ((map (make-sparse-keymap))) (set-keymap-parent map (current-local-map)) (define-key lys/evil-leader-command-map (kbd ",") (make-composed-keymap nil prefix)) map))))) (add-hook 'after-change-major-mode-hook #'lys/local-map-with-leader) #+end_src #+begin_src emacs-lisp (use-package evil :ensure t :after (undo-tree) :hook (evil-local-mode . turn-on-undo-tree-mode) :init ;; This is optional since it's already set to t by default. (setq evil-want-integration t) (setq evil-want-keybinding nil) (setq evil-undo-system 'undo-tree) :config (setq evil-move-beyond-eol t) (evil-mode 1) (evil-set-leader '(normal visual) (kbd "SPC")) (evil-define-key '(normal visual) 'global (kbd "") 'lys/evil-leader-command-map) ;; (evil-define-key 'normal 'org-mode-map "]]" 'lys/org-next-heading) (global-undo-tree-mode 1)) (use-package evil-collection :after (evil) :ensure t :config (evil-collection-init)) (use-package evil-surround :after (evil evil-collection) :ensure t :config (global-evil-surround-mode 1)) #+end_src Undo #+begin_src emacs-lisp (use-package undo-tree :ensure t) #+end_src ** Projects Let's also add projectile #+begin_src emacs-lisp (use-package projectile :defer t :ensure t :bind (:map projectile-mode-map ("C-c p" . projectile-command-map)) :init (projectile-mode +1)) #+end_src ** Spelling Let's also add syntax checking #+begin_src emacs-lisp (use-package flycheck :ensure t :init (global-flycheck-mode)) #+end_src And add inline messages for flycheck #+begin_src emacs-lisp (use-package flycheck-inline :ensure t :after flycheck (add-hook 'flycheck-mode-hook #'flycheck-inline-mode)) #+end_src #+begin_src emacs-lisp (use-package flyspell-correct :ensure t :bind (("C-c s" . ace-flyspell-jump-word) ("C-M-;" . flyspell-correct-wrapper)) :hook '((text-mode . flyspell-mode) (prog-mode . flyspell-prog-mode))) (use-package ace-flyspell :ensure t :after flyspell-correct) (use-package flyspell-correct-ivy :init (setq flyspell-correct-interface #'flyspell-correct-ivy) :after flyspell-correct) #+end_src ** Perspectives #+begin_src emacs-lisp ;; (use-package persp-mode ;; :ensure t ;; :init ;; (persp-mode)) #+end_src ** Snippets Let's install yasnippet #+begin_src emacs-lisp (use-package yasnippet :defer t :ensure t :init (yas-global-mode 1)) #+end_src Now we can add snippets ! #+begin_src emacs-lisp (use-package yasnippet-snippets :defer t :after (yasnippet) :ensure t) #+end_src ** Git Let's install magit for git support #+begin_src emacs-lisp (use-package magit :defer t :ensure t) #+end_src ** Org mode #+begin_src emacs-lisp (defun disable-flycheck-in-org-src-block () (setq-local flycheck-disabled-checkers '(emacs-lisp-checkdoc))) (use-package org-bullets :ensure t :after org) (use-package org-tempo :after org) (use-package org :defer t :init (setq org-startup-folded t) (setq org-directory "~/.org/") (setq org-agenda-files '("~/.org/agenda/"))) (setq org-hide-emphasis-markers t) (font-lock-add-keywords 'org-mode '(("^ +\\([-*]\\) " (0 (prog1 () (compose-region (match-beginning 1) (match-end 1) "•")))))) (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1) (electric-pair-local-mode -1) (electric-indent-local-mode -1))) (add-hook 'org-src-mode-hook 'disable-flycheck-in-org-src-block) #+end_src ** Ledger mode #+begin_src emacs-lisp (use-package ledger-mode :defer t :ensure t) #+end_src ** Which-key #+begin_src emacs-lisp (use-package which-key :ensure t :init (which-key-mode)) #+end_src ** Rainbow #+begin_src emacs-lisp (use-package rainbow-mode :ensure t) (use-package rainbow-delimiters :ensure t) ;; todo: rewrite as a loop (set-face-attribute 'rainbow-delimiters-depth-1-face nil :foreground "dark orange") (set-face-attribute 'rainbow-delimiters-depth-2-face nil :foreground "deep pink") (set-face-attribute 'rainbow-delimiters-depth-3-face nil :foreground "chartreuse") (set-face-attribute 'rainbow-delimiters-depth-4-face nil :foreground "deep sky blue") (set-face-attribute 'rainbow-delimiters-depth-5-face nil :foreground "yellow") (set-face-attribute 'rainbow-delimiters-depth-6-face nil :foreground "orchid") (set-face-attribute 'rainbow-delimiters-depth-7-face nil :foreground "spring green") (set-face-attribute 'rainbow-delimiters-depth-8-face nil :foreground "sienna1") #+end_src ** Visual fill columns #+begin_src emacs-lisp (use-package visual-fill-column :ensure t) #+end_src ** Windows #+begin_src emacs-lisp (use-package ace-window :ensure t :bind (:map evil-window-map ("C-w" . ace-window) ("w" . ace-window)) :config (setq-default aw-scope 'frame) :after (evil)) #+end_src Get special buffers go straight #+begin_src emacs-lisp (use-package shackle :ensure t :config (setq shackle-default-rule '(:select t)) :init (shackle-mode 1)) #+end_src ** Auto completion #+begin_src emacs-lisp (use-package company :ensure t :init (add-hook 'after-init-hook 'global-company-mode)) #+end_src ** ivy #+begin_src emacs-lisp (use-package ivy :bind (("C-s" . swiper) :map ivy-minibuffer-map ("TAB" . ivy-alt-done) ("C-f" . 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)) (use-package counsel :demand t :bind (("M-x" . counsel-M-x) ("C-x b" . counsel-ibuffer) ("C-x C-f" . counsel-find-file) ;; ("C-M-j" . counsel-switch-buffer) ("C-M-l" . counsel-imenu) :map minibuffer-local-map ("C-r" . 'counsel-minibuffer-history))) (use-package counsel-projectile :ensure t :config (counsel-projectile-mode) :after (projectile)) (use-package ivy-rich :ensure t :after counsel :config (ivy-rich-mode 1)) #+end_src ** Others *** y-or-n-p Uses y-or-n-p instead of 'yes-or-no-p #+begin_src emacs-lisp (defalias 'yes-or-no-p 'y-or-n-p) #+end_src *** Scroll conservatively #+begin_src emacs-lisp (setq scroll-conservatively 100) #+end_src *** Ring bell #+begin_src emacs-lisp (setq ring-bell-function 'ignore) #+end_src *** Line highlighting #+begin_src emacs-lisp (when window-system (global-hl-line-mode t)) #+end_src *** Symbols prettifying #+begin_src emacs-lisp (when window-system (global-prettify-symbols-mode t)) #+end_src *** Backups, autosaves #+begin_src emacs-lisp (setq make-backup-file nil) (setq auto-save-default nil) #+end_src *** Startup Profiling #+begin_src emacs-lisp ;; Package `esup' allows you to run a child Emacs process with special ;; profiling functionality, and to collect timing results for each ;; form in your init-file. (use-package esup :config ;; Work around a bug where esup tries to step into the byte-compiled ;; version of `cl-lib', and fails horribly. (setq esup-depth 0)) #+end_src ** Dashboard Disable the startup messages and replace it by a nice dashboard which lists the 5 most recent visited files, recent bookmarks, projects and appointments. #+begin_src emacs-lisp (use-package dashboard :ensure t :config (setq inhibit-startup-message t inhibit-startup-screen t initial-buffer-choice (lambda () (get-buffer "*dashboard*")) dashboard-show-shortcuts nil dashboard-set-heading-icons t dashboard-set-file-icons t dashboard-agenda-time-string-format "%Y-%m-%d %H:%M" dashboard-filter-agenda-entry 'dashboard-no-filter-agenda dashboard-items '((recents . 5) (bookmarks . 5) (projects . 5) (agenda . 5))) (dashboard-setup-startup-hook)) #+end_src ** Mode-line #+begin_src emacs-lisp (defvar *lys/telephone-line-current-separator* 'halfsin "Telephone line's current separator.") (defun lys/telephone-line-symbols (symbol) "Generate all the list of variant's of symbol." (mapcar (lambda (suf) (intern (concat "telephone-line-" (symbol-name symbol) "-" suf))) '("left" "hollow-left" "right" "hollow-right"))) (defvar *lys/telephone-line-separators* `(,@(mapcar (lambda (sym) `(,sym . ,(lys/telephone-line-symbols sym))) '(cubed sin cos tan halfsin halfcos))) "Association list between a theme and the left/right separators of the theme.") (defun lys/telephone-set-separator () (let ((seps (alist-get *lys/telephone-line-current-separator* ,*lys/telephone-line-separators*))) (setq telephone-line-primary-left-separator (nth 0 seps) telephone-line-secondary-left-separator (nth 1 seps) telephone-line-primary-right-separator (nth 2 seps) telephone-line-secondary-right-separator (nth 3 seps)))) (defun lys/telephone-line-update () (setq mode-line-format (telephone-line--generate-mode-line))) (defun lys/telephone-line-separator-cycle () (interactive) (let* ((n (length *lys/telephone-line-separators*)) (seps (mapcar 'car *lys/telephone-line-separators*)) (next-sep-pos (mod (+ 1 (cl-position *lys/telephone-line-current-separator* seps)) n ))) (setq *lys/telephone-line-current-separator* (nth next-sep-pos seps)) (lys/telephone-set-separator) (lys/telephone-line-update))) (use-package telephone-line :ensure t :init (setq telephone-line-lhs '((evil . (telephone-line-evil-tag-segment)) (accent . (telephone-line-vc-segment telephone-line-erc-modified-channels-segment telephone-line-process-segment)) (nil . (telephone-line-buffer-segment)))) (setq telephone-line-rhs '((nil . (telephone-line-misc-info-segment)) (accent . (telephone-line-major-mode-segment)) (evil . (telephone-line-airline-position-segment)))) (setq telephone-line-height 20 telephone-line-evil-use-short-tag t) (lys/telephone-set-separator) (telephone-line-mode t)) #+end_src * Languages ** Language Server Protocol Installing LSP mode #+begin_src emacs-lisp (use-package lsp-mode :ensure t :commands lsp :init (setq lsp-keymap-prefix "C-c l") :hook ((rust-mode . lsp) (lsp-mode . lsp-enable-which-key-integration))) (use-package lsp-mode :ensure :commands lsp :custom ;; what to use when checking on-save. "check" is default, I prefer clippy (lsp-rust-analyzer-cargo-watch-command "clippy") (lsp-idle-delay 0.6) (lsp-rust-analyzer-server-display-inlay-hints t) :config (add-hook 'lsp-mode-hook 'lsp-ui-mode)) #+end_src Installing lsp-ui #+begin_src emacs-lisp (use-package lsp-ui :defer t :ensure t) #+end_src #+begin_src emacs-lisp (use-package lsp-treemacs :ensure t) #+end_src ** C++ #+begin_src emacs-lisp (use-package c++-mode :mode ("\\.cpp\\'" "\\.tpp\\'")) #+end_src #+begin_src emacs-lisp ;; (use-package flycheck-clang-tidy ;; :ensure t ;; :after c++-mode ;; :config ;; (add-hook 'flycheck-mode-hook #'flycheck-rust-setup)) (use-package flycheck-clang-analyzer :ensure t :after c++-mode :config (add-hook 'flycheck-mode-hook #'flycheck-clang-analyzer-setup)) #+end_src ** Objective Caml #+begin_src emacs-lisp (use-package tuareg :defer t :ensure t) #+end_src ** Rust Let's install rust-mode ! #+begin_src emacs-lisp (use-package rust-mode :ensure t :config (add-hook 'rust-mode-hook 'lsp)) ;;; Add some formatting setup (add-hook 'rust-mode-hook (lambda () (setq indent-tabs-mode nil))) (setq rust-format-on-save t) ;;; Add flycheck support (use-package flycheck-rust :ensure t :after rust-mode :config (add-hook 'flycheck-mode-hook #'flycheck-rust-setup)) ;;; Add cargo support (use-package cargo :ensure t :defer t :after rust-mode :config (add-hook 'rust-mode-hook 'cargo-minor-mode)) #+end_src ** Java #+begin_src emacs-lisp (use-package lsp-java :ensure t :config (add-hook 'java-mode-hook 'lsp)) (use-package dap-mode :ensure t :after lsp-mode :config (dap-auto-configure-mode)) (use-package dap-java) #+end_src ** Lisp #+begin_src emacs-lisp (use-package lispy :ensure t :hook (common-lisp-mode . lispy-mode) (emacs-lisp-mode . lispy-mode) (scheme-mode . lispy-mode) (racket-mode . lispy-mode) ;; (hy-mode . lispy-mode) ;; (lfe-mode . lispy-mode) ;; (dune-mode . lispy-mode) ;; (clojure-mode . lispy-mode) (lisp-mode . lispy-mode) :config (setq lispy-close-quotes-at-end-p t)) ;; (add-hook 'lispy-mode-hook #'turn-off-smartparens-mode)) (use-package lispyville :ensure t :after lispy :after evil) (add-hook 'lispy-mode-hook #'lispyville-mode) (add-hook 'emacs-lisp-mode-hook (lambda () (lispy-mode 1) (rainbow-delimiters-mode 1))) #+end_src #+begin_src emacs-lisp (use-package sly :ensure t :defer t) #+end_src ** Racket #+begin_src emacs-lisp (use-package racket-mode :ensure t :defer t) #+end_src ** Latex #+begin_src emacs-lisp (setq font-latex-fontify-sectioning 'color) (setq font-latex-fontify-script nil) #+end_src * Utilities ** PDF-tools #+begin_src emacs-lisp (use-package pdf-tools :mode ("\\.pdf\\'" . pdf-view-mode) :ensure t ;; :hook (pdf-view-mode . pdf-view-midnight-minor-mode) :hook (pdf-view-mode . (lambda () (display-line-numbers-mode 0))) :config (setq pdf-view-midnight-colors '("#ABB2BF" . "#282C35"))) #+end_src ** Not much mail #+begin_src emacs-lisp (use-package notmuch :defer t :ensure t) #+end_src