* Initialization ** Garbage Collection Improvement #+BEGIN_SRC emacs-lisp (defun my-minibuffer-setup-hook () (setq gc-cons-threshold most-positive-fixnum)) (defun my-minibuffer-exit-hook () (setq gc-cons-threshold 800000000)) (add-hook 'minibuffer-setup-hook #'my-minibuffer-setup-hook) (add-hook 'minibuffer-exit-hook #'my-minibuffer-exit-hook) (defun gc-idle-timer () "Trigger garbage collection when Emacs is idle for 0.5 seconds." (run-with-idle-timer 1.2 t 'garbage-collect)) (gc-idle-timer) #+END_SRC ** List of packages to install #+BEGIN_SRC emacs-lisp (setq my-package-list '( use-package no-littering rainbow-delimiters ansi-color expand-region mwim delsel multiple-cursors evil-nerd-commenter dired-subtree dracula-theme nerd-icons nerd-icons-dired nerd-icons-completion nerd-icons-corfu vertico marginalia orderless consult magit lsp-mode lsp-ui corfu yasnippet yasnippet-snippets cmake-mode cmake-font-lock glsl-mode indent-bars evil evil-collection projectile)) #+END_SRC ** Packages #+BEGIN_SRC emacs-lisp (require 'package) ;; Emacs builtin ;; set package.el repositories (setq package-archives '( ("org" . "https://orgmode.org/elpa/") ("gnu" . "https://elpa.gnu.org/packages/") ("melpa" . "https://melpa.org/packages/") )) ;; initialize built-in package management (package-initialize) ;; update packages list if we are on a new install (unless package-archive-contents (package-refresh-contents)) ;; programmatically install/ensure installed ;; pkgs in your personal list (dolist (package my-package-list) (unless (package-installed-p package) (package-install package))) #+END_SRC ** Customize in different file #+BEGIN_SRC emacs-lisp (setq custom-file (expand-file-name "customs.el" user-emacs-directory)) (load custom-file :no-error-if-file-is-missing) #+END_SRC * Basic changes ** Behaviour #+BEGIN_SRC emacs-lisp (use-package no-littering) (setq make-backup-files nil create-lockfiles nil erc-join-buffer 'window confirm-kill-processes nil) (setq backup-directory-alist `((".*" . ,temporary-file-directory))) (setq auto-save-file-name-transforms `((".*" ,temporary-file-directory t))) (setq inhibit-startup-message t backup-inhibited t) (setq vc-follow-symlinks t) (use-package saveplace :init (save-place-mode)) (add-hook 'prog-mode-hook (lambda () (setq-local lsp-enable-indentation nil))) #+END_SRC ** Org Mode #+BEGIN_SRC emacs-lisp (setq org-startup-folded t org-src-preserve-indentation t org-src-tab-acts-natively t org-edit-src-content-indentation t) #+END_SRC ** UI #+BEGIN_SRC emacs-lisp (scroll-bar-mode -1) (tool-bar-mode -1) (tooltip-mode -1) (menu-bar-mode -1) (column-number-mode +1) (setq-default fill-column 80) (global-display-line-numbers-mode t) (setq display-line-numbers-width-start t display-line-numbers-type t) (use-package rainbow-delimiters :hook (prog-mode . rainbow-delimiters-mode)) (use-package ansi-color :hook (compilation-filter . ansi-color-compilation-filter)) #+END_SRC ** Text Editing #+BEGIN_SRC emacs-lisp ;; tab width (setq-default tab-width 4) (setq backward-delete-char-untabify-method "hungry") ;; scrolling (setq scroll-up-aggressively nil scroll-down-aggressively nil scroll-conservatively 101) (setq scroll-step 1) (setq scroll-margin 8) ;; electric pair (electric-pair-mode +1) ;; improved C-g dwim (defun prot/keyboard-quit-dwim () (interactive) (cond ((region-active-p) (keyboard-quit)) ((derived-mode-p 'completion-list-mode) (delete-completion-window)) ((> (minibuffer-depth) 0) (abort-recursive-edit)) (t (keyboard-quit)))) (define-key global-map (kbd "C-g") #'prot/keyboard-quit-dwim) ;; expand keybind (use-package expand-region :bind("C-=" . er/expand-region)) ;; better move beginning and end (use-package mwim :bind (("C-a" . mwim-beginning) ("C-e" . mwim-end-of-line))) ;; selected marked text when typing start (use-package delsel :ensure nil ; no need to install it as it is built-in :hook (after-init . delete-selection-mode)) (use-package multiple-cursors :bind (:map global-map ("C->" . 'mc/mark-next-like-this) ("C-<" . 'mc/mark-previous-like-this) ("C-c C->" . 'mc/mark-all-like-this) :map mc/keymap ("" . nil))) ;; better commenting (use-package evil-nerd-commenter :bind ("M-;" . evilnc-comment-or-uncomment-lines)) #+END_SRC ** Dired #+BEGIN_SRC emacs-lisp (use-package dired :ensure nil :commands (dired) :hook ((dired-mode . dired-hide-details-mode) (dired-mode . hl-line-mode)) :config (setq dired-recursive-copies 'always) (setq dired-recursive-deletes 'always) (setq dired-dwim-target t) (setq dired-kill-when-opening-new-dired-buffer t) (setq dired-listing-switches "-alh --group-directories-first")) (use-package dired-subtree :after dired :bind ( :map dired-mode-map ("" . dired-subtree-toggle) ("TAB" . dired-subtree-toggle) ("" . dired-subtree-remove) ("S-TAB" . dired-subtree-remove)) :config (setq dired-subtree-use-backgrounds nil)) #+END_SRC * Evil Mode #+BEGIN_SRC emacs-lisp (setq evil-want-C-u-scroll t) (setq evil-want-keybinding nil) (setq evil-undo-system 'undo-redo) (use-package evil) (use-package evil-collection) ;; C-g to exit mode (defun evil-keyboard-quit () "Keyboard quit and force normal state." (interactive) (and evil-mode (evil-force-normal-state)) (keyboard-quit)) (define-key evil-normal-state-map (kbd "C-g") #'evil-keyboard-quit) (define-key evil-motion-state-map (kbd "C-g") #'evil-keyboard-quit) (define-key evil-insert-state-map (kbd "C-g") #'evil-keyboard-quit) (define-key evil-window-map (kbd "C-g") #'evil-keyboard-quit) (define-key evil-operator-state-map (kbd "C-g") #'evil-keyboard-quit) ;; tab to fold ;; (defun my/evil-fold-key () ;; (local-set-key (kbd "") #'evil-toggle-fold)) ;; (add-hook 'prog-mode-hook #'my/evil-fold-key) ;; (add-hook 'text-mode-hook #'my/evil-fold-key) ;; enable mode and collection keybinds (evil-mode) (evil-collection-init) (define-key evil-insert-state-map (kbd "C-d") #'evil-delete-char) #+END_SRC * Style #+BEGIN_SRC emacs-lisp (use-package dracula-theme) (load-theme 'dracula) (set-face-attribute 'show-paren-match nil :background "dark violet" :foreground "black") #+END_SRC ** Icons #+BEGIN_SRC emacs-lisp (use-package nerd-icons) (use-package nerd-icons-dired :ensure t :hook (dired-mode . nerd-icons-dired-mode)) (use-package nerd-icons-completion :ensure t :after marginalia :config (add-hook 'marginalia-mode-hook #'nerd-icons-completion-marginalia-setup)) (use-package nerd-icons-corfu :ensure t :after corfu :config (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter)) #+END_SRC * Minibuffer completion #+BEGIN_SRC emacs-lisp (use-package vertico :ensure nil :custom (vertico-count 15) :diminish vertico-mode :bind (:map vertico-map ("C-n" . vertico-next) ("C-p" . vertico-previous)) :init (vertico-mode t)) (use-package vertico-directory :after vertico :ensure nil ;; More convenient directory navigation commands :bind (:map vertico-map ("RET" . vertico-directory-enter) ("DEL" . vertico-directory-delete-char) ("M-DEL" . vertico-directory-delete-word))) (use-package marginalia :after vertico :custom (marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light nil)) :config (marginalia-mode)) (use-package orderless :config (setq completion-styles '(orderless partial-completion basic) completion-category-defaults nil completion-category-overrides '((file (styles . (partial-completion)))))) (use-package savehist :ensure nil ; it is built-in :hook (after-init . savehist-mode)) #+END_SRC * Development ** Magit #+BEGIN_SRC emacs-lisp (use-package transient) (use-package magit :bind (("C-x g" . magit-status)) :custom (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1)) #+END_SRC ** LSP *** lsp-mode #+BEGIN_SRC emacs-lisp (use-package lsp-mode :init (setq lsp-keymap-prefix "C-c l" lsp-headerline-breadcrumb-enable nil lsp-completion-enable-additional-text-edit nil lsp-enable-on-type-formatting nil lsp-completion-provider :none lsp-idle-delay 0.05) :hook (;; automatic lsp (c++-mode . lsp) (c-mode . lsp)) :commands lsp) ;; ui (use-package lsp-ui :commands lsp-ui-mode :hook (lsp-mode . lsp-ui-mode) :bind ( ("C-c r" . lsp-ui-peek-find-references) ("C-c d" . lsp-ui-peek-find-definitions) )) #+END_SRC *** lsp-mode performance #+BEGIN_SRC emacs-lisp (setq read-process-output-max (* 1024 1024)) ;; 1mb ;; lsp booster (defun lsp-booster--advice-json-parse (old-fn &rest args) "Try to parse bytecode instead of json." (or (when (equal (following-char) ?#) (let ((bytecode (read (current-buffer)))) (when (byte-code-function-p bytecode) (funcall bytecode)))) (apply old-fn args))) (advice-add (if (progn (require 'json) (fboundp 'json-parse-buffer)) 'json-parse-buffer 'json-read) :around #'lsp-booster--advice-json-parse) (defun lsp-booster--advice-final-command (old-fn cmd &optional test?) "Prepend emacs-lsp-booster command to lsp CMD." (let ((orig-result (funcall old-fn cmd test?))) (if (and (not test?) ;; for check lsp-server-present? (not (file-remote-p default-directory)) ;; see lsp-resolve-final-command, it would add extra shell wrapper lsp-use-plists (not (functionp 'json-rpc-connection)) ;; native json-rpc (executable-find "emacs-lsp-booster")) (progn (when-let ((command-from-exec-path (executable-find (car orig-result)))) ;; resolve command from exec-path (in case not found in $PATH) (setcar orig-result command-from-exec-path)) (message "Using emacs-lsp-booster for %s!" orig-result) (cons "emacs-lsp-booster" orig-result)) orig-result))) (advice-add 'lsp-resolve-final-command :around #'lsp-booster--advice-final-command) #+END_SRC ** Text Completion #+BEGIN_SRC emacs-lisp ;; corfu (fancy completion) (use-package corfu :bind (:map corfu-map ("C-g" . corfu-quit)) :init (global-corfu-mode) (corfu-history-mode)) ;; completion preview (ghost text) (global-completion-preview-mode) (global-set-key (kbd "M-n") 'completion-preview-next-candidate) (global-set-key (kbd "M-p") 'completion-preview-prev-candidate) #+END_SRC ** Snippets #+BEGIN_SRC emacs-lisp (use-package yasnippet :config (yas-global-mode t) :diminish yas-minor-mode) (global-set-key (kbd "") 'completion-preview-next-candidate) (define-key yas-keymap (kbd "TAB") nil) (define-key yas-keymap (kbd "S-TAB") nil) (define-key yas-minor-mode-map(kbd "TAB") nil) (define-key yas-minor-mode-map (kbd "S-TAB") nil) (define-key yas-keymap (kbd "M-n") 'yas-next-field) (define-key yas-keymap (kbd "M-p") 'yas-prev-field) (use-package yasnippet-snippets) #+END_SRC ** Projectile #+BEGIN_SRC emacs-lisp (use-package projectile) #+END_SRC ** C-like settings #+BEGIN_SRC emacs-lisp (defun my-c-mode-common-hook () ;; my customizations for all of c-mode, c++-mode, objc-mode, java-mode (setq c-default-style "k&r" c-basic-offset 4 indent-tabs-mode t) (c-set-offset 'arglist-intro '+) (add-to-list 'c-offsets-alist '(arglist-close . c-lineup-close-paren))) (add-hook 'c-mode-common-hook 'my-c-mode-common-hook) #+END_SRC ** CMake #+BEGIN_SRC emacs-lisp (use-package cmake-mode) (use-package cmake-font-lock) (setq cmake-tab-width 4) (defun my-cmake-mode-hook () ;; my customizations for all of c-mode, c++-mode, objc-mode, java-mode (setq indent-tabs-mode t)) (add-hook 'cmake-mode-hook 'my-cmake-mode-hook) #+END_SRC ** Shader Languages #+BEGIN_SRC emacs-lisp (use-package glsl-mode) #+END_SRC * Misc Binds #+BEGIN_SRC emacs-lisp ;; shortcuts (use-package consult :custom ;; Disable preview (consult-preview-key nil) :bind (("C-x b" . 'consult-buffer) ;; Switch buffer, including recentf and bookmarks ("M-l" . 'consult-git-grep) ;; Search inside a project ("M-y" . 'consult-yank-pop) ;; Paste by selecting the kill-ring ("M-s" . 'consult-line) ;; Search current buffer, like swiper ("C-c i" . 'consult-imenu) ;; Search the imenu )) (global-set-key (kbd "C-c f") 'ff-find-other-file) (global-set-key (kbd "C-c g") 'projectile-ripgrep) (global-set-key (kbd "C-c F") 'projectile-find-file) #+END_SRC