dotfiles/.config/emacs/emacs.org

36 KiB
Executable File
Raw Blame History

Emacs Configuration

Basic Configuration

Emacs Configuration for emacs 29.50

Early Init

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

Init

Startup hook

;;; init.el -*- lexical-binding: t; -*-
(add-hook 'emacs-startup-hook
          (lambda ()
            (message "Crafted Emacs loaded in %s"
                     (emacs-init-time))))

Straight

(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))
(straight-use-package '(use-package :build t))
(setq use-package-always-ensure t)

Add other modules

(add-to-list 'load-path (expand-file-name "modules/" user-emacs-directory))

Edit options

Whitespace clean
(add-hook 'before-save-hook #'whitespace-cleanup)
Tabs
(setq-default indent-tabs-mode nil)
(setq-default tab-width 4)

협업에 있어서 코드에 tabs 크기를 명시하는 것도 방법일듯.

Modeline Indentation example
  • Emacs

    /* -*- Mode: rust; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
  • Vim

    # Embeded VIM Configurations
    # vim: filetype=sh noet sw=4 ts=4 fdm=marker
  • Visual Studio Code install extension modeline.

    // 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
    
Line number
  (column-number-mode)
  (global-display-line-numbers-mode t)
  ;; Disable line numbers for some modes
  (dolist (mode '(org-mode-hook
                  nov-mode-hook
                  shell-mode-hook
                  treemacs-mode-hook
                  dired-mode-hook
                  eshell-mode-hook))
    (add-hook mode (lambda () (display-line-numbers-mode 0))))

Backup options

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

Other options

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

Modules Selection module

  ;;; config.el -*- lexical-binding: t; -*-
  (setq user-full-name "JaeYoo-Im"
        user-mail-address "cpu3792@gmail.com")

  (setq default-input-method "korean-hangul")

  (add-hook 'emacs-startup-hook
            (lambda ()
              (custom-set-faces
               `(default ((t (:font "Fira Code 10"))))
               `(fixed-pitch ((t (:inherit (default)))))
               `(fixed-pitch-serif ((t (:inherit (default)))))
               `(variable-pitch ((t (:font "Ubuntu 10")))))))

  (require 'custom-ui)
  (require 'custom-keybindings)
  (require 'custom-default)
  (require 'custom-org)
  (require 'custom-completion)
  (require 'custom-projects)
  ;;(require 'custom-workspaces)
  (require 'custom-latex)
  (require 'custom-extra)

Module Lists

Default

emacs built-in package config

Eshell
(use-package eshell
  :defer t
  :straight (:type built-in :build t)
  :config
  (setq eshell-prompt-function
        (lambda ()
          (concat (abbreviate-file-name (eshell/pwd))
                  (if (= (user-uid) 0) " # " " λ ")))
        eshell-prompt-regexp "^[^#λ\n]* [#λ] "))
Dired
  (use-package dired
    :straight (:type built-in)
    :ensure nil
    :commands (dired dired-jump)
    :bind (("C-x C-j" . dired-jump))
    :custom ((dired-listing-switches "-agho --group-directories-first"))
    :config
    (evil-collection-define-key 'normal 'dired-mode-map
      "h" 'dired-single-up-directory
      "l" 'dired-single-buffer))
  (autoload 'dired-omit-mode "dired-x")
  (add-hook 'dired-load-hook
            (lambda ()
              (interactive)
              (dired-hide-dotfiles--hide)))
  ;;;; to use h,l key
  (use-package dired-single
    :commands (dired dired-jump))
  ;;;; colorful dired
  (use-package diredfl
    :hook (dired-mode . diredfl-mode))
  ;;;; from doom emacs
  (defun +dired-enable-git-info-h ()
    "Enable `dired-git-info-mode' in git repos."
    (and (not (file-remote-p default-directory))
         (locate-dominating-file "." ".git")
         (dired-git-info-mode 1)))
  (use-package dired-git-info)
  (use-package diff-hl
    :hook (dired-mode . diff-hl-dired-mode-unless-remote)
    :hook (magit-post-refresh . diff-hl-magit-post-refresh)
    :config
    ;; use margin instead of fringe
    (diff-hl-margin-mode))
  (use-package dired-rsync
    :config
    (bind-key "C-c C-r" 'dired-rsync dired-mode-map))
  (use-package all-the-icons-dired
    :hook (dired-mode . all-the-icons-dired-mode)
    :config
    ;; HACK Fixes #1929: icons break file renaming in Emacs 27+, because the icon
    ;;      is considered part of the filename, so we disable icons while we're in
    ;;      wdired-mode.
    ;;(when EMACS27+
    (defvar +wdired-icons-enabled -1))
  (use-package dired-hide-dotfiles
    :hook (dired-mode . dired-hide-dotfiles-mode)
    :config
    (evil-collection-define-key 'normal 'dired-mode-map
      "H" 'dired-hide-dotfiles-mode))

  ;; TODO check emacs29 updates
  ;;(csetq dired-mouse-drag-files                   t
  ;;       mouse-drag-and-drop-region-cross-program t)
Provide Modules
  (provide 'custom-default)
  ;;; custom-default.el ends here

UI

Doom themes
  (use-package doom-themes)
  (if (display-graphic-p)
      (load-theme 'doom-palenight t)
    (load-theme 'doom-gruvbox t))
Rainbow Delimiters
  (use-package rainbow-delimiters
    :hook (prog-mode . rainbow-delimiters-mode))
Setting Transparency
  (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 frames 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 frames 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)))
Modeline
  (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-persp-name t
          doom-modeline-persp-icon t
          doom-modeline-display-default-persp-name t
          doom-modeline-indent-info t))
Whiteroom
  ;;(use-package writeroom-mode
  ;;  :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)))
Visual Fill Column
  (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))
Dashboard
  (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-set-navigator t)

    (setq dashboard-startup-banner 'logo)
    ;;(setq dashboard-startup-banner "~/.dotfiles/.config/emacs/logo3d.png")
    ;; 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*")
Others
(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)))
Provide Modules
(provide 'custom-ui)
;;; custom-ui.el ends here

Key Bindings

Global Key
  (global-set-key (kbd "C-c t") 'toggle-transparency)
  (global-set-key (kbd "C-M-j") 'consult-buffer)

  ;; Make ESC quit prompts
  (global-set-key (kbd "<escape>") 'keyboard-escape-quit)
  ;; this annoying binding.
  (global-unset-key (kbd "C-j"))
  (global-unset-key (kbd "C-k"))
  (global-unset-key (kbd "S-SPC"))    ;; use only S-\
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.

(use-package which-key
  :defer t
  :init (which-key-mode)
  :diminish which-key-mode
  :config
  (setq which-key-idle-delay 0.5))
General

for managing keybindings.

  (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")
    ;; Magit
    "g" '(:ignore t :which-key "magit")
    "g g" '(magit :which-key "magit")
    ;; Project-el
    "p" '(:ignore t :which-key "project")
    "p ." '(project-switch-project :which-key "switch project")
    "p p" '(project-switch-project :which-key "switch project")
    "p c" '(project-compile :which-key "compile")
    "p f" '(project-find-file :which-key "find-file")
    "p k" '(project-kill-buffers :which-key "kill buffers")
    "p s" '(project-shell :which-key "shell")
    "p e" '(project-eshell :which-key "eshell")
    "p d" '(project-dired :which-key "dired")
    "p g" '(project-find-regexp :which-key "find-regexp"))
Evil Mode
  (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 evil-nerd-commenter
    :after evil
    :config
    (define-key evil-normal-state-map (kbd "g c") 'evilnc-comment-or-uncomment-lines)
    (define-key evil-visual-state-map (kbd "g c") 'evilnc-comment-or-uncomment-lines))
  (use-package evil-numbers
    :after evil
    :config
    ;; unfortunately C-x is emacs common key binding.
    (define-key evil-normal-state-map (kbd "g =") 'evil-numbers/inc-at-pt)
    (define-key evil-normal-state-map (kbd "g -") 'evil-numbers/dec-at-pt)
    (define-key evil-visual-state-map (kbd "g =") 'evil-numbers/inc-at-pt)
    (define-key evil-visual-state-map (kbd "g -") 'evil-numbers/dec-at-pt))

  (modify-syntax-entry ?_ "w")
Undo Tree
  (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))
Hydra
  (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 ()
    ("s" my/decrease-frame-alpha-background "decrease alpha")
    ("t" my/increase-frame-alpha-background "increase alpha")
    ("q" nil "finished" :exit t))
Provide Modules
(provide 'custom-keybindings)
;;; custom-keybindings.el ends here

Completion

config from crafted-emacs https://github.com/SystemCrafter/crafted-emacs

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

annotations placed at the margin of the minibuffer

  (use-package marginalia
    :after vertico
    :ensure t
    :custom
    (marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light nil))
    :init
    (marginalia-mode))
Consult
    (use-package consult
      :demand t
      :bind (("C-s" . consult-line)
             :map minibuffer-local-map
             ("C-r" . consult-history))
      :custom
      (completion-in-region-function #'consult-completion-in-region))
Orderless

orderless completion

  (use-package orderless
    :ensure t
    :custom
    (completion-styles '(orderless basic))
    (completion-category-overrides '((file (style basic partial-completion)))))
Embark

Quick Action in minibuffer

  (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))
Corfu
  (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)
Cape
  (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)))
Provide Modules
(provide 'custom-completion)
;;; custom-completion.el ends here

Org Mode

Valign
12345678
일이삼사
(use-package valign
  :defer t
  :after (org markdown-mode)
  ;; :hook ((org-mode markdown-mode) . valign-mode)
  :custom ((valign-fancy-bar t)))
Org PDF tools

get link from pdf,

  (use-package org-pdftools
    :hook (org-mode . org-pdftools-setup-link))
Provide Modules
  (provide 'custom-org)
  ;;; custom-org.el ends here

Projects

MAGIT
  (use-package magit
    :commands (magit-status magit-get-current-branch)
    :custom
    (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1))
  (use-package magit-todos
    :after (magit todo)
    :config
    (setq magit-todos-ignore-case t))
  (use-package forge
    :after magit)
Highlight TODOs
TODO test
  (use-package hl-todo
    :hook (prog-mode . hl-todo-mode)
    :config
    (setq hl-todo-highlight-punctuation ":"
          hl-todo-keyword-faces
          `(;; For things that need to be done, just not today.
            ("TODO" warning bold)
            ;; For problems that will become bigger problems later if not
            ;; fixed ASAP.
            ("FIXME" error bold)
            ;; For tidbits that are unconventional and not intended uses of the
            ;; constituent parts, and may break in a future update.
            ("HACK" font-lock-constant-face bold)
            ;; For things that were done hastily and/or hasn't been thoroughly
            ;; tested. It may not even be necessary!
            ("REVIEW" font-lock-keyword-face bold)
            ;; For especially important gotchas with a given implementation,
            ;; directed at another user other than the author.
            ("NOTE" success bold)
            ;; For things that just gotta go and will soon be gone.
            ("DEPRECATED" font-lock-doc-face bold)
            ;; For a known bug that needs a workaround
            ("BUG" error bold)
            ;; For warning about a problematic or misguiding code
            ("XXX" font-lock-constant-face bold))))
Provide Modules
  (provide 'custom-projects)
  ;;; custom-projects.el ends here

Workspaces

Tabspace
  ;;(use-package tabspaces
  ;;  :disabled
  ;;  ;; use this next line only if you also use straight, otherwise ignore it.
  ;;  :straight (:type git :host github :repo "mclear-tools/tabspaces")
  ;;  :hook (after-init . tabspaces-mode) ;; use this only if you want the minor-mode loaded at startup.
  ;;  :commands (tabspaces-switch-or-create-workspace
  ;;             tabspaces-open-or-create-project-and-workspace)
  ;;  :custom
  ;;  (tabspaces-use-filtered-buffers-as-default t)
  ;;  (tabspaces-default-tab "Default")
  ;;  (tabspaces-remove-to-default t)
  ;;  (tabspaces-include-buffers '("*scratch*"))
  ;;  ;; sessions
  ;;  (tabspaces-session t)
  ;;  (tabspaces-session-auto-restore t)
  ;;  :config
  ;;  (ju/leader-key-def
  ;;    "TAB" '(tabspaces-command-map :which-key "tabspaces-command-map")))
Perspective
  ;;(use-package perspective
  ;;  :disabled
  ;;  :demand t
  ;;  :bind (("C-M-j" . consult-buffer)
  ;;         ("C-M-k" . persp-switch)
  ;;         ("C-M-n" . persp-next)
  ;;         ("C-x k" . persp-kill-buffer*))
  ;;  :custom
  ;;  (persp-initial-frame-name "Main")
  ;;  (persp-mode-prefix-key (kbd "C-c p"))
  ;;  :config
  ;;  (ju/leader-key-def
  ;;    "TAB" '(perspective-map :which-key "perspective"))
  ;;  ;; Running `persp-mode' multiple times resets the perspective list...
  ;;  (unless (equal persp-mode t)
  ;;    (persp-mode)))
  ;;(provide 'custom-workspaces)
    ;;; custom-workspaces.el ends here

Latex

AUCTEX

writing and formatting tex file in Emacs.

  (use-package auctex
    :defer t
    :init
    (setq TeX-command-default   (if (executable-find "latexmk") "LatexMk" "LaTeX")
          TeX-engine            (if (executable-find "xetex")   'xetex    'default)
          TeX-auto-save                     t
          TeX-parse-self                    t
          TeX-syntactic-comment             t
          TeX-auto-local                    ".auctex-auto"
          TeX-style-local                   ".auctex-style"
          TeX-source-correlate-mode         t
          TeX-source-correlate-method       'synctex
          TeX-source-correlate-start-server nil
          TeX-electric-sub-and-superscript  t
          TeX-fill-break-at-separators      nil
          TeX-save-query                    t)
    :config
    (setq TeX-master t)
    (setcar (cdr (assoc "Check" TeX-command-list)) "chktex -v6 -H %s")
    (add-hook 'TeX-mode-hook (lambda ()
                               (setq ispell-parser          'tex
                                     fill-nobreak-predicate (cons #'texmathp fill-nobreak-predicate))))
    (add-hook 'TeX-mode-hook #'visual-line-mode)
    (add-hook 'TeX-update-style-hook #'rainbow-delimiters-mode))
Cdlatex

speed-up insertion of environments and math templates.

(use-package cdlatex
  :defer t
  :after auctex
  :hook (LaTeX-mode . cdlatex-mode)
  :hook (org-mode   . org-cdlatex-mode)
  :config
  (setq cdlatex-use-dollar-to-ensure-math nil)
  :general
  (phundrak/major-leader-key
    :packages 'cdlatex
    :keymaps 'cdlatex-mode-map
    "$" nil
    "(" nil
    "{" nil
    "[" nil
    "|" nil
    "<" nil
    "^" nil
    "_" nil
    [(control return)] nil))
Preview pane
  (use-package latex-preview-pane)

TODO gddg

Provide Modules
  (provide 'custom-latex)
  ;;; custom-latex.el ends here

Extra

Helpful
  (use-package helpful
    :commands (helpful-callable helpful-variable helpful-command helpful-key)
    :custom
    (counsel-describe-function-function #'helpful-callable)
    (counsel-describe-variable-function #'helpful-variable)
    :bind
    ([remap describe-function] . describe-function)
    ([remap describe-command] . helpful-command)
    ([remap describe-variable] . describe-variable)
    ([remap describe-key] . helpful-key))
PDF Tool

enhanced PDF viewer on emacs

  (use-package pdf-tools)
PDF view restore
  (use-package pdf-view-restore
    :after pdf-tools
    :defer t
    :hook (pdf-view-mode . pdf-view-restore-mode)
    :config
    (setq pdf-view-restore-filename (expand-file-name ".tmp/pdf-view-restore"
                                                      user-emacs-directory)))
Nov
  (use-package nov
    :mode ("\\.epub\\'" . nov-mode))
Provide Modules
  (provide 'custom-extra)
  ;;; custom-extra.el ends here