;;; init.el --- My configurations for GNU Emacs -*- lexical-binding: t; -*- ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;;; Commentary: ;; ;;; Code: ;; Garbage collection threshold maneuvre (setq gc-cons-threshold (* 512 1024 1024)) ;;; Tell me the start time at start-up ;;;###autoload (defun message-start-time () "Tell me the start time at start-up." (interactive) (message "%s" (emacs-init-time))) (add-hook 'emacs-startup-hook #'message-start-time) ;;; Macro to conveniently load files ;;;###autoload (defvar load-file-directory (cond ((stringp load-file-name) (file-name-directory load-file-name)) (t default-directory)) "The directory to load files.") ;; If this is a `defmacro', then the start time will be very long... ;;;###autoload (defsubst load-config (file-name) "Conviently load configuration file FILE-NAME in the same \ directory as `load-file-directory'." (load-file (expand-file-name file-name load-file-directory))) ;;;###autoload (defun load-config-later (file-name seconds) "Load FILE-NAME SECONDS later." (run-with-idle-timer seconds nil (lambda () (load-config file-name)))) ;;;###autoload (defmacro prepare-in-hook-once (entry-name hook file) "Define a function called ENTRY-NAME to load FILE in HOOK once." `(progn (defun ,entry-name () (interactive) (remove-hook ',hook ',entry-name) (load-config ,file)) (add-hook ',hook ',entry-name))) ;;;###autoload (defmacro load-after-function (function-name file-path doc redefine-p &rest def) "Load FILE-PATH after FUNCTION-NAME. After loading, execute DEF. Finally if REDEFINE-P is non-nil, then FUNCTION-NAME will be defined as DEF after loading. If FUNCTION-NAME is already a valid function, this advices the function instead of redefining the function, and REDEFINE-P has no effect." (declare (indent 2)) (cond ((fboundp function-name) `(let ((advice-symbol (intern (format "%s-advice" (symbol-name ',function-name))))) (defalias advice-symbol (lambda (&rest _args) ,(format "Advice for %s.\nThis is generated by `load-after-function'." function-name) (advice-remove ',function-name advice-symbol) (load-file (expand-file-name ,file-path load-file-directory)) ,@def)) (advice-add ',function-name :after advice-symbol))) (`(defun ,function-name () ,doc (interactive) (load-file (expand-file-name ,file-path load-file-directory)) ,@def ,(cond (redefine-p `(defun ,function-name () ,doc (interactive) ,@def))))))) (load-config "common.el") (load-config "basic.el") (load-config "backup-conf.el") (load-config "recentf-conf.el") (load-config "dashboard.el") (load-config "theme.el") (load-config "modeline.el") ;;; Prepare for ELisp (add-hook 'emacs-lisp-mode-hook (lambda () (set 'mode-name "ELisp"))) (prepare-in-hook-once prepare-elisp emacs-lisp-mode-hook "elisp.el") (prepare-in-hook-once prepare-skeleton emacs-lisp-mode-hook "skeleton-conf.el") ;;; Prepare for C (prepare-in-hook-once prepare-c c-mode-hook "c-conf.el") ;;; Prepare for Org (prepare-in-hook-once prepare-org org-mode-hook "org-conf.el") (add-hook 'org-mode-hook #'prepare-org) (define-key global-map (vector 3 97) #'prepare-org) (define-key global-map (vector 3 99) #'prepare-org) (define-key global-map (vector 3 ?l) #'prepare-org) ;;; Prepare for PDF (add-to-list 'auto-mode-alist (cons "pdf$" #'pdf-view-mode)) (load-after-function pdf-view-mode "pdf.el" "Fake mode that loads the pacakge." nil (pdf-view-mode)) ;;; Prepare for ABNF (add-to-list 'auto-mode-alist (cons (rx-to-string '(and ".abnf" string-end)) #'abnf-mode)) (load-after-function abnf-mode "abnf.el" "Fake mode that loads the ABNF configuration." nil (abnf-mode)) ;;; Prepare for skeletons (load-after-function prepare-skeletons "skeleton-conf.el" "Load skeletons." nil) ;;; Prepare for GLSL ;;;###autoload (load-after-function glsl-mode "glsl-conf.el" "Fake mode that loads the package." nil (glsl-mode)) (add-to-list 'auto-mode-alist (cons "\\.frag$" #'glsl-mode)) (add-to-list 'auto-mode-alist (cons "\\.vert$" #'glsl-mode)) (add-to-list 'auto-mode-alist (cons "\\.fs$" #'glsl-mode)) (add-to-list 'auto-mode-alist (cons "\\.vs$" #'glsl-mode)) ;;; rainbow-mode (use-package "rainbow-mode" 'rainbow-mode) ;;; LIN Is Noticeable ;; This is a package by Protesilaos. (use-package "protesilaos/lin" 'lin (let ((list-of-hooks '(git-rebase-mode-hook ibuffer-mode-hook magit-log-mode-hook notmuch-search-mode-hook notmuch-tree-mode-hook org-agenda-mode-hook tabulated-list-mode-hook dired-mode-hook blist-mode-hook))) (mapc (lambda (hook) (cond ;; don't do anything if the variable is not bounded. ((boundp hook) (add-hook hook #'lin-mode)))) list-of-hooks))) ;;; outline (load-after-function durand-maybe-enable-outline "outline-conf.el" "Load my outline configurations" nil) ;;; bongo ;;;###autoload (load-after-function bongo "durand-bongo.el" "Listen to music in Emacs." nil (bongo)) ;;; My PDF facilities (use-package "durand-chercher-pdf" 'durand-chercher-pdf (define-key durand-pdf-mode-map (vector ?q) 'quit-window) (define-key durand-pdf-mode-map (vector ?x) #'durand-chercher-pdf-exit) (define-key durand-pdf-mode-map (vector ?N) 'forward-line) (define-key durand-pdf-mode-map (vector ?n) 'durand-pdf-next-pdf-line) (define-key durand-pdf-mode-map (vector ?P) (lambda () (interactive) (forward-line -1))) (define-key durand-pdf-mode-map (vector ?p) 'durand-pdf-previous-pdf-line) (define-key durand-pdf-mode-map (vector 'return) 'durand-pdf-open-pdf) (define-key durand-pdf-mode-map (vector 32) 'durand-pdf-open-or-scroll-up) (define-key durand-pdf-mode-map (vector 'backspace) 'durand-pdf-open-or-scroll-down) (define-key durand-pdf-mode-map (vector ?o) 'kill-other-buffer-window) (define-key durand-pdf-mode-map (vector ?k) 'kill-current-buffer) (cond ((assoc durand-chercher-pdf-buffer-name display-buffer-alist #'string-match) (setcdr (assoc durand-chercher-pdf-buffer-name display-buffer-alist #'string-match) '((display-buffer-in-tab durand-display-in-one-window) (tab-name . "chercher pdf")))) (t (add-to-list 'display-buffer-alist `(,(rx-to-string `(seq bos ,durand-chercher-pdf-buffer-name eos)) (display-buffer-in-tab durand-display-in-one-window) (tab-name . "chercher pdf")))))) ;;; gnus (load-after-function gnus "gnus-conf.el" "Fake function to load gnus." nil (gnus)) (define-key global-map (vector 3 ?g) #'gnus) (define-key global-map (vector ?\H-g) #'gnus) ;;; Completion framework configurations (load-config "completion-conf.el") ;;; dired configurations (prepare-in-hook-once prepare-dired dired-mode-hook "dired-conf.el") (add-hook 'dired-mode-hook 'dired-hide-details-mode) ;;; Registers (use-package "rlist" 'rlist (define-key global-map (vector ?\C-x ?r ?L) #'rlist-list-registers) (setq rlist-expert t) (setq rlist-verbose t)) ;;; ibuffer (load-config "ibuffer.el") ;;; Olivetti mode (use-package "olivetti" 'olivetti (durand-hide-minor-mode olivetti-mode olivetti " Oli") (setq-default olivetti-body-width 80) (setq-default olivetti-style 'fancy)) ;; (load-config "center-buffer.el") ;;; Eshell (load-after-function eshell "eshell-conf.el" "Load Eshell and launch it." nil (eshell) (eshell-start-track-command-time)) ;;; tab configurations (load-config "tab-conf.el") ;;; Save sessions (load-config "desktop-conf.el") ;;; Text Configurations (prepare-in-hook-once prepare-text text-mode-hook "text-conf.el") ;;; TeX configurations (prepare-in-hook-once prepare-tex latex-mode-hook "tex-conf.el") ;;; elfeed (load-after-function elfeed "elfeed-conf.el" "Load elfeed and launch it." nil (elfeed)) (define-key global-map (vector 3 101) #'elfeed) ;;; rime configuration to input Chinese. ;; NOTE: I do not use rime now. ;; (load-after-function prepare-rime "rime-conf.el" ;; "Load rime and launch it." nil (durand-set-input-method)) ;;; Input method configuration (load-after-function toggle-input-method "input-conf.el" "Load my configurations of input methods." nil) ;; The effect of super is to apply bitwise or to the key with ;; (ash 1 23). The codes are as follows. ;; ;; Alt Super Hyper Shift Control Meta ;; 22 23 24 25 26 27 ;; However, for letters a-z, A-Z, [, ], \, ^, _, the effect of control ;; is to subtract the upcased character by 64; for letters a-z, A-Z, ;; the effect of shift is to apply `upcase' to it. (define-key global-map (vector (logior (ash 1 23) ?i)) #'prepare-rime) ;;; magit (load-after-function magit "magit-conf.el" "Load magit and launch it." nil (defalias 'magit 'magit-status) (magit)) (define-key global-map (vector ?\C-x ?g) 'magit) ;;; eww (load-after-function eww "eww-conf.el" "Load eww and launch it." nil) (define-key global-map (vector 3 ?v ?w) #'eww) (define-key global-map (vector ?\s-w) #'eww) ;;; Viewing things (load-config "view-conf.el") ;;; Prepare battery (load-after-function durand-battery "battery-conf.el" "Display battery information." nil (display-battery-mode 1)) (define-key durand-view-map (vector ?b) #'durand-battery) ;;;###autoload (load-after-function durand-time "time-conf.el" "Display time information." nil (display-time-mode 1)) (define-key durand-view-map (vector ?T) #'durand-time) ;;; flymake (prepare-in-hook-once prepare-flymake prog-mode-hook "flymake-conf.el") (define-key global-map (vector ?\s-m) #'prepare-flymake) ;;; Don't let s-q quit as I oft press that by accident. (define-key global-map (vector ?\s-q) #'window-toggle-side-windows) ;;; My simple utilities (use-package "durand-simple" 'durand-simple (define-key global-map (vector ?\C-\M-\s) #'durand-simple-mark-dwim) (define-key global-map (vector ?\C-o) #'durand-simple-open-line) (define-key global-map (vector ?\C-') #'durand-simple-pair-dwim) (define-key process-menu-mode-map (vector ?c) #'durand-simple-clear-processes)) ;;; Searches (load-config "search-conf.el") ;;; Transpose frame (use-package "transpose-frame" 'transpose-frame (define-key global-map (vector ?\C-\s-r) #'rotate-frame-clockwise) (define-key global-map (vector ?\C-\s-t) #'transpose-frame)) ;;; Go-mode (load-after-function go-mode "go-conf.el" "Load Go-mode configurations and lauch it." nil (go-mode)) (cond ((assoc "\\.go$" auto-mode-alist #'string=) (setcdr (assoc "\\.go$" auto-mode-alist #'string=) #'go-mode)) ((add-to-list 'auto-mode-alist (cons "\\.go$" #'go-mode)))) ;;; Graphviz-Dot-Mode (use-package "graphviz-dot-mode" 'graphviz-dot-mode) ;;; Rust (load-after-function rustic-mode "rust-conf.el" "Load Rust configurations." nil (rustic-mode)) (cond ((assoc "\\.rs$" auto-mode-alist #'string=) (setcdr (assoc "\\.rs$" auto-mode-alist #'string=) #'rustic-mode)) ((add-to-list 'auto-mode-alist (cons "\\.rs$" #'rustic-mode)))) ;;; Rust Music Mode (rumu) (load-after-function rumu-mode "rumu.el" "Load Rust music configurations" nil (rumu-mode)) (cond ((assoc "\\.rumu$" auto-mode-alist #'string=) (setcdr (assoc "\\.rumu$" auto-mode-alist #'string=) #'rumu-mode)) ((add-to-list 'auto-mode-alist (cons "\\.rumu$" #'rumu-mode)))) ;;; imenu settings (load-config "imenu-conf.el") ;;; Cat and mouse (cond ((display-mouse-p) (mouse-avoidance-mode 'none))) ;;; Bookmark conf (load-after-function blist "bookmark-conf.el" "Load my configurations for bookmarks and list bookmarks." nil (blist)) (define-key ctl-x-r-map (vector ?l) #'blist) ;;; Wifi and Bluetooth stuff (load-after-function durand-prepare-wifi-bluetooth "wifi-bluetooth-conf.el" "Load my configurations to manipulate Wifi and Bluetooth status." nil) (define-key global-map (vector 3 ?w ?w) #'durand-prepare-wifi-bluetooth) (define-key global-map (vector 3 ?w ?b) #'durand-prepare-wifi-bluetooth) (define-key global-map (vector 3 ?w ?l) #'durand-prepare-wifi-bluetooth) (define-key global-map (vector 3 ?w ?j) #'durand-prepare-wifi-bluetooth) ;;; server ;; (cond ;; ((bound-and-true-p server-process)) ;; ((server-start))) ;;; Reset the garbage collection threshold (setq gc-cons-threshold (* 2 1024 1024)) (provide 'init) ;;; init.el ends here