#+title: Emacs Configuration * Basic Configuration Emacs Configuration for emacs 29.50 ** Early Init #+begin_src emacs-lisp :tangle ~/.config/emacs/early-init.el ;;; early-init.el -*- lexical-binding: t; -*- ;; garbage collection (setq gc-cons-threshold (* 50 1024 1024)) ;; 50MB ;; prefers newest version of a file (customize-set-variable 'load-prefer-newer t) (setq package-enable-at-startup nil inhibit-startup-message t frame-resize-pixelwise t package-native-compile t) (scroll-bar-mode -1) (tool-bar-mode -1) (tooltip-mode -1) (set-fringe-mode 10) (menu-bar-mode -1) ;;(blink-cursor-mode 0) ;; initial load with blue theme (load-theme 'deeper-blue) (customize-set-variable 'initial-major-mode 'fundamental-mode) #+end_src ** Init *** Startup hook #+begin_src emacs-lisp :tangle ~/.config/emacs/init.el ;;; init.el -*- lexical-binding: t; -*- (add-hook 'emacs-startup-hook (lambda () (message "Crafted Emacs loaded in %s" (emacs-init-time)))) #+end_src *** Straight #+begin_src emacs-lisp :tangle ~/.config/emacs/init.el (require 'package) (add-to-list 'package-archives '("stable" . "https://stable.melpa.org/packages/")) (add-to-list 'package-archives '("melpa" . "https://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)) (setq straight-use-package-by-default t) (package-initialize) (unless package-archive-contents (package-refresh-contents)) #+end_src *** Add other modules #+begin_src emacs-lisp :tangle ~/.config/emacs/init.el (add-to-list 'load-path (expand-file-name "modules/" user-emacs-directory)) #+end_src *** Edit options **** Whitespace clean #+begin_src emacs-lisp :tangle ~/.config/emacs/init.el (add-hook 'before-save-hook #'whitespace-cleanup) #+end_src **** Tabs #+begin_src emacs-lisp :tangle ~/.config/emacs/init.el (setq-default indent-tabs-mode nil) (setq-default tab-width 4) #+end_src 협업에 있어서 코드에 tabs 크기를 명시하는 것도 방법일듯. ***** Modeline Indentation example - Emacs #+begin_src rust /* -*- Mode: rust; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ #+end_src - Vim #+begin_src shell # Embeded VIM Configurations # vim: filetype=sh noet sw=4 ts=4 fdm=marker #+end_src - Visual Studio Code install extension =modeline=. #+begin_src javascript // vim: set ft=js ts=4 sw=4 et: // vim: ts=4:sw=4:et:ft=js // -*- mode: js; indent-tabs-mode: nil; tab-width: 4 -*- // code: language=rust insertSpaces=false tabSize=4 #+end_src **** Line number #+begin_src emacs-lisp :tangle ~/.config/emacs/init.el (column-number-mode) (global-display-line-numbers-mode t) ;; Disable line numbers for some modes (dolist (mode '(org-mode-hook shell-mode-hook treemacs-mode-hook dired-mode-hook eshell-mode-hook)) (add-hook mode (lambda () (display-line-numbers-mode 0)))) #+end_src *** Backup options #+begin_src emacs-lisp :tangle ~/.config/emacs/init.el (setq backup-directory-alist `(("." . ,(expand-file-name "backups/" user-emacs-directory)))) (setq-default custom-file (expand-file-name ".custom.el" user-emacs-directory)) (when (file-exists-p custom-file) (load custom-file)) (setq delete-by-moving-to-trash t trash-directory "~/.local/share/Trash/files/") (setq undo-limit 100000000 auto-save-default t) (use-package no-littering) (setq auto-save-file-name-transforms `((".*" ,(no-littering-expand-var-file-name "auto-save/") t))) #+end_src *** Other options #+begin_src emacs-lisp :tangle ~/.config/emacs/init.el (set-default-coding-systems 'utf-8) (customize-set-variable 'large-file-warning-threshold 100000000) ;; 100MB (defconst ON-LINUX (eq system-type 'gnu/linux)) (defconst ON-MAC (eq system-type 'darwin)) (defconst ON-WINDOWS (memq system-type '(cygwin windows-nt ms-dos))) (setq gc-cons-threshold (* 2 1024 1024)) ; decreasing the threshold to 2MB (defvar my-config-file (expand-file-name "config.el" user-emacs-directory)) (when (file-exists-p my-config-file) (load my-config-file nil 'nomessage)) (setq use-short-answer t) (global-auto-revert-mode t) #+end_src * Modules Selection module #+begin_src emacs-lisp :tangle ~/.config/emacs/config.el ;;; config.el -*- lexical-binding: t; -*- (setq user-full-name "JaeYoo-Im" user-mail-address "cpu3792@gmail.com") ;;(add-to-list 'default-frame-alist `(font . "Fira Code Retina")) ;;(set-face-attribute 'default nil :font "Fira Code Retina" :height 12) ;;(set-face-attribute 'fixed-pitch nil :font "Fira Code Retina" :height 12) ;;(set-face-attribute 'variable-pitch nil :font "Fira Code Retina" :height 12 :weight 'regular) ;;(set-fontset-font t 'hangul (font-spec :family "NanumGothic" :height 12)) (add-hook 'emacs-startup-hook (lambda () (custom-set-faces `(default ((t (:font "Fira Code Retina 12")))) `(fixed-pitch ((t (:inherit (default))))) `(fixed-pitch-serif ((t (:inherit (default))))) `(variable-pitch ((t (:font "Ubuntu 12"))))))) (require 'custom-ui) (require 'custom-keybindings) (require 'custom-org) (require 'custom-completion) #+end_src ** Module Lists *** UI **** Doom themes #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-ui.el (use-package doom-themes) (if (display-graphic-p) (load-theme 'doom-palenight t) (load-theme 'doom-gruvbox t)) #+end_src **** Rainbow Delimiters #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-ui.el (use-package rainbow-delimiters :hook (prog-mode . rainbow-delimiters-mode)) #+end_src **** Setting Transparency #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-ui.el (setq visible-bell t) (set-frame-parameter nil 'alpha-background 0.9) (add-to-list 'default-frame-alist '(alpha-background . 0.9)) (defun toggle-transparency () "toggle transparency." (interactive) (let ((alpha-transparency 1.0)) (if (eq (frame-parameter nil 'alpha-background) alpha-transparency) (set-frame-parameter nil 'alpha-background 0.9) (set-frame-parameter nil 'alpha-background alpha-transparency)))) (defun my/transparency-round (val) "Round VAL to the nearest tenth of an integer." (/ (round (* 10 val)) 10.0)) (defun my/increase-frame-alpha-background () "Increase current frame’s alpha background." (interactive) (set-frame-parameter nil 'alpha-background (my/transparency-round (min 1.0 (+ (frame-parameter nil 'alpha-background) 0.1)))) (message "%s" (frame-parameter nil 'alpha-background))) (defun my/decrease-frame-alpha-background () "Decrease current frame’s alpha background." (interactive) (set-frame-parameter nil 'alpha-background (my/transparency-round (max 0.0 (- (frame-parameter nil 'alpha-background) 0.1)))) (message "%s" (frame-parameter nil 'alpha-background))) #+end_src **** Modeline #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-ui.el (use-package all-the-icons) (use-package doom-modeline :init (doom-modeline-mode 1) :config (setq doom-modeline-height 15 doom-modeline-env-version t doom-modeline-indent-info t)) #+end_src **** Whiteroom #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-ui.el (use-package writeroom-mode :disabled :defer t :straight (:build t) :init (global-writeroom-mode 1) :config (setq writeroom-width 100 writeroom-fullscreen-effect nil writeroom-maximize-window nil writeroom-mode-line t writeroom-major-modes '(text-mode org-mode markdown-mode nov-mode Info-mode))) #+end_src **** Visual Fill Column #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-ui.el (defun write-room-enable () (setq visual-fill-column-width 100 visual-fill-column-center-text t) (visual-fill-column-mode 1)) (use-package visual-fill-column :hook (org-mode . write-room-enable) (text-mode . write-room-enable) (markdown-mode . write-room-enable) (nov-mode . write-room-enable)) #+end_src **** Dashboard #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-ui.el (use-package page-break-lines) (use-package dashboard :init ;; tweak dashboard config before loading it (setq dashboard-projects-backend "project-el" dashboard-set-heading-icons t dashboard-set-file-icons t dashboard-center-content t ;; set to 't' for centered content dashboard-items '((recents . 10) (bookmarks . 5)) ;;(projects . 10))) dashboard-set-footer t dashboard-page-separator "\n\f\n" dashboard-startup-banner 'logo ;; use standard emacs logo as banner dashboard-set-navigator t) ;;(setq dashboard-startup-banner "~/.config/doom/doom-emacs-dash.png") ;; use custom image as banner ;; Format: "(icon title help action face prefix suffix)" (setq dashboard-navigator-buttons `(;; line1 ((,(all-the-icons-octicon "mark-github" :height 1.1 :v-adjust 0.0) "Github" "Browse my Github" (lambda (&rest _) (browse-url "https://github.com/JaeUs3792/"))) (,(all-the-icons-octicon "home" :height 1.1 :v-adjust 0.0) "Homepage" "Browse my Homepage" (lambda (&rest _) (browse-url "https://jaeus.net")))))) :config (dashboard-setup-startup-hook) (dashboard-modify-heading-icons '((recents . "file-text") (bookmarks . "book")))) (setq doom-fallback-buffer-name "*dashboard*") #+end_src **** Others #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-ui.el (defun self-screenshot (&optional type) "Save a screenshot of type TYPE of the current Emacs frame. As shown by the function `', type can weild the value `svg', `png', `pdf'. This function will output in /tmp a file beginning with \"Emacs\" and ending with the extension of the requested TYPE." (interactive) (let* ((type (if type type (intern (completing-read "Screenshot Type: " '(png svg pdf postscript))))) (extension (pcase type ('png ".png") ('svg ".svg") ('pdf ".pdf") ('postscript ".ps") (otherwise (error "Cannot export screenshot of type %s" otherwise)))) (filename (make-temp-file "Emacs-" nil extension)) (data (x-export-frames nil type))) (with-temp-file filename (insert data)) (kill-new filename) (rename-file filename (expand-file-name (file-name-nondirectory filename) "~")) (message filename))) #+end_src **** Provide Modules #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-ui.el (provide 'custom-ui) ;;; custom-ui.el ends here #+end_src *** Key Bindings **** Global Key #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-keybindings.el (global-set-key (kbd "C-c t") 'toggle-transparency) #+end_src **** Which keys When you begin a keybind, whichkey will show you all keybinds you can follow the first one with in order to form a full keywords. #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-keybindings.el (use-package which-key :defer t :init (which-key-mode) :diminish which-key-mode :config (setq which-key-idle-delay 0.5)) #+end_src **** General for managing keybindings. #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-keybindings.el (use-package general :init (general-auto-unbind-keys) :config (general-evil-setup t) (general-create-definer ju/leader-key-def :keymaps '(normal insert visual emacs) :prefix "SPC" :global-prefix "C-SPC")) (ju/leader-key-def "." 'find-file ;; Buffer "b" '(:ignore t :which-key "buffer handling") "b i" '(ibuffer :which-key "IBuffer") "b r" '(revert-buffer :which-key "Revert Buffer") "b k" '(kill-current-buffer :which-key "Kill current buffer") "b n" '(next-buffer :which-key "Next buffer") "b p" '(previous-buffer :which-key "Previous buffer") "b B" '(ibuffer-list-buffers :which-key "IBuffer List Buffers") "b K" '(kill-buffer :which-key "IBuffer Kill Buffers") ;; Eshell "e" '(:ignore t :which-key "eshell") "e h" '(counsel-esh-history :which "Kill history") "e s" '(eshell :which "run eshell") ;; Workspace ;; Counsel "f" '(:ignore t :which-key "file op.") "f r" '(consult-recent-file :which-key "Recent files") "t t" '(toggle-truncate-lines :which-key "Toggle truncate lines") ;; Shortcut "f o d" '((lambda () (interactive) (find-file (expand-file-name "~/.config/emacs/desktop.org"))) :which-key "open exwm config") "f o p" '((lambda () (interactive) (find-file (expand-file-name "~/org/example/emacs_my_previous.org"))) :which-key "open exwm config") "f o e" '((lambda () (interactive) (find-file (expand-file-name "~/org/example/emacs_another.org"))) :which-key "open exwm config") "f o c" '((lambda () (interactive) (find-file (expand-file-name "~/.config/emacs/emacs.org"))) :which-key "open emacs config") ;; Hydra "h" '(:ignore t :which-key "hydra") "h t" '(hydra-text-scale/body :which-key "scale text") "h w" '(hydra-writeroom-scale/body :which-key "scale whiteroom") "h a" '(hydra-modify-alpha/body :which-key "modify alpha background")) #+end_src **** Evil Mode #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-keybindings.el (use-package evil :after (general) :init (setq evil-want-integration t evil-want-keybinding nil evil-want-C-u-scroll t evil-want-C-i-jump nil) (require 'evil-vars) (evil-set-undo-system 'undo-tree) :config (evil-mode 1) (setq evil-want-fine-undo t) ; more granular undo with evil (evil-set-initial-state 'messages-buffer-mode 'normal) (evil-set-initial-state 'dashboard-mode 'normal)) (use-package evil-collection :after evil :ensure t :config (evil-collection-init)) (use-package undo-tree :init (global-undo-tree-mode) (setq undo-tree-visualizer-diff t undo-tree-visualizer-timestamps t) undo-tree-auto-save-history t undo-tree-enable-undo-in-region t undo-limit (* 800 1024) undo-strong-limit (* 12 1024 1024) undo-outer-limit (* 128 1024 1024)) #+end_src **** Hydra #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-keybindings.el (use-package hydra :defer t) (defhydra hydra-text-scale (:timeout 4) "scale text" ("t" text-scale-increase "in") ("s" text-scale-decrease "out") ("q" nil "finished" :exit t)) (defhydra hydra-writeroom-scale (:timeout 4) "scale whiteroom" ("t" writeroom-increase-width "enlarge") ("s" writeroom-decrease-width "shrink") ("r" writeroom-adjust-width "adjust") ("q" nil "finished" :exit t)) (defhydra hydra-modify-alpha () ("q" nil :exit t) ("s" my/decrease-frame-alpha-background) ("t" my/increase-frame-alpha-background)) #+end_src **** Provide Modules #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-keybindings.el (provide 'custom-keybindings) ;;; custom-keybindings.el ends here #+end_src *** Completion config from crafted-emacs https://github.com/SystemCrafter/crafted-emacs **** Vertico #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-completion.el (use-package vertico :ensure t :bind (:map vertico-map ("C-j" . vertico-next) ("C-k" . vertico-previous) ("M-h" . vertico-directory-up)) :custom (vertico-cycle t) :init (vertico-mode)) (use-package vertico-posframe :disabled :after vertico :ensure t :init (setq vertico-posframe-parameters `((left-fringe . 8) (right-fringe . 8) (alpha . 100))) (vertico-posframe-mode 1)) #+end_src **** Marginalia annotations placed at the margin of the minibuffer #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-completion.el (use-package marginalia :after vertico :ensure t :custom (marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light nil)) :init (marginalia-mode)) #+end_src **** Consult #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-completion.el ;;(defun my/get-project-root () ;; TODO after projectile ;; (when (fboundp 'projectile-project-root) ;; (projectile-project-root))) (use-package consult :demand t :bind (("C-s" . consult-line) :map minibuffer-local-map ("C-r" . consult-history)) :custom ;;(consult-project-root-function #'get-project-root) (completion-in-region-function #'consult-completion-in-region)) #+end_src **** Orderless orderless completion #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-completion.el (use-package orderless :ensure t :custom (completion-styles '(orderless basic)) (completion-category-overrides '((file (style basic partial-completion))))) #+end_src **** Embark Quick Action in minibuffer #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-completion.el (use-package embark :ensure t :bind (("C-." . embark-act) ("C-;" . embark-dwim) ("C-h B" . embark-bindings)) :init ;; Optionally replace the key help with a completing-read interface (setq prefix-help-command #'embark-prefix-help-command) :config ;; Hide the mode line of the Embark live/completions buffers (add-to-list 'display-buffer-alist '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*" nil (window-parameters (mode-line-format . none))))) (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 . consult-preview-at-point-mode)) #+end_src **** Corfu #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-completion.el (use-package corfu) (use-package popon :defer t :straight (popon :build t :type git :host nil :repo "https://codeberg.org/akib/emacs-popon.git")) (use-package confu-terminal :defer t :straight (confu-terminal :build t :type git :host nil :repo "https://codeberg.org/akib/emacs-corfu-terminal.git")) (add-to-list 'load-path (expand-file-name "straight/build/corfu/extensions" user-emacs-directory)) (require 'corfu-popupinfo) (require 'corfu) (unless (display-graphic-p) (require 'corfu-terminal) (corfu-terminal-mode +1)) (customize-set-variable 'corfu-cycle t) ;; Enable cycling for `corfu-next/previous' (customize-set-variable 'corfu-auto t) ;; Enable auto completion (customize-set-variable 'corfu-auto-prefix 2) (customize-set-variable 'corfu-auto-delay 0.0) ;; (customize-set-variable 'corfu-separator ?\s) ;; Orderless field separator ;; (customize-set-variable 'corfu-quit-at-boundary nil) ;; Never quit at completion boundary ;; (customize-set-variable 'corfu-quit-no-match nil) ;; Never quit, even if there is no match ;; (customize-set-variable 'corfu-preview-current nil) ;; Disable current candidate preview ;; (customize-set-variable 'corfu-preselect 'prompt) ;; Preselect the prompt ;; (customize-set-variable 'corfu-on-exact-match nil) ;; Configure handling of exact matches ;; (customize-set-variable 'corfu-scroll-margin 5) ;; Use scroll margin (customize-set-variable 'corfu-echo-documentation 0.25) (global-corfu-mode 1) (corfu-popupinfo-mode 1) (eldoc-add-command #'corfu-insert) (define-key corfu-map (kbd "M-p") #'corfu-popupinfo-scroll-down) (define-key corfu-map (kbd "M-n") #'corfu-popupinfo-scroll-up) (define-key corfu-map (kbd "M-d") #'corfu-popupinfo-toggle) #+end_src **** Cape #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-completion.el (use-package cape :init ;; Add `completion-at-point-functions', used by `completion-at-point'. (add-to-list 'completion-at-point-functions #'cape-dabbrev) (add-to-list 'completion-at-point-functions #'cape-file) ;;(add-to-list 'completion-at-point-functions #'cape-history) ;;(add-to-list 'completion-at-point-functions #'cape-keyword) ;;(add-to-list 'completion-at-point-functions #'cape-tex) ;;(add-to-list 'completion-at-point-functions #'cape-sgml) ;;(add-to-list 'completion-at-point-functions #'cape-rfc1345) ;;(add-to-list 'completion-at-point-functions #'cape-abbrev) ;;(add-to-list 'completion-at-point-functions #'cape-ispell) ;;(add-to-list 'completion-at-point-functions #'cape-dict) ;;(add-to-list 'completion-at-point-functions #'cape-symbol) ;;(add-to-list 'completion-at-point-functions #'cape-line) (advice-add 'pcomplete-completions-at-point :around #'cape-wrap-silent) ;; Silence the pcomplete capf, no errors or messages! ;; Important for corfu (advice-add 'pcomplete-completions-at-point :around #'cape-wrap-silent) ;; Ensure that pcomplete does not write to the buffer ;; and behaves as a pure `completion-at-point-function'. (advice-add 'pcomplete-completions-at-point :around #'cape-wrap-purify) ) (add-hook 'eshell-mode-hook (lambda () (setq-local corfu-quit-at-boundary t corfu-quit-no-match t corfu-auto nil) (corfu-mode))) #+end_src **** Provide Modules #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-completion.el (provide 'custom-completion) ;;; custom-completion.el ends here #+end_src *** Org Mode **** Valign | 12345678 | | |----------+---| | 일이삼사 | | #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-org.el (use-package valign :defer t :after (org markdown-mode) ;; :hook ((org-mode markdown-mode) . valign-mode) :custom ((valign-fancy-bar t))) #+end_src **** Provide Modules #+begin_src emacs-lisp :mkdirp yes :tangle ~/.config/emacs/modules/custom-org.el (provide 'custom-org) ;;; custom-org.el ends here #+end_src