.emacs.d

my Emacs config
git clone https://git.trogloxene.org/.emacs.d.git
Log | Files | Refs

commit 0741c6642d145f6e724c6344aa911642c8281f29
Author: Andsy10 <andsy1016@gmail.com>
Date:   Wed, 22 Jul 2026 08:14:08 +0800

Initial commit

Diffstat:
A.gitignore | 12++++++++++++
Aearly-init.el | 18++++++++++++++++++
Ainit.el | 43+++++++++++++++++++++++++++++++++++++++++++
Alisp/init-base.el | 268+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alisp/init-completion.el | 203+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alisp/init-const.el | 13+++++++++++++
Alisp/init-dashboard.el | 24++++++++++++++++++++++++
Alisp/init-dired.el | 143+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alisp/init-edit.el | 114+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alisp/init-elpa.el | 46++++++++++++++++++++++++++++++++++++++++++++++
Alisp/init-exwm.el | 159+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alisp/init-gptel.el | 186+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alisp/init-kbd-func.el | 339+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alisp/init-kbd.el | 418+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alisp/init-org.el | 284+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alisp/init-package.el | 228+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alisp/init-prog.el | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alisp/init-segmentation.el | 43+++++++++++++++++++++++++++++++++++++++++++
Alisp/init-startup.el | 103+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alisp/init-terminal-kbd.el | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alisp/init-terminal-package.el | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alisp/init-terminal-startup.el | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alisp/init-terminal-ui.el | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alisp/init-ui.el | 113+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alisp/init-window.el | 135+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alisp/my-dark-theme.el | 148+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alisp/my-light-theme.el | 148+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alisp/my-palette.el | 33+++++++++++++++++++++++++++++++++
28 files changed, 3655 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1,12 @@ +* + +!init.el +!early-init.el +!lisp/ +!lisp/**/ +!lisp/**/*.el + +!.gitignore + +/lisp/init-proxy.el +/lisp/init-local.el diff --git a/early-init.el b/early-init.el @@ -0,0 +1,18 @@ +;;; early-init.el --- early-init.el -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +(setq package-enable-at-startup nil) + +(setq inhibit-startup-screen t) +(when (fboundp 'tool-bar-mode) + (tool-bar-mode -1) + (scroll-bar-mode -1)) +(menu-bar-mode -1) + +(prefer-coding-system 'utf-8) + +(setq frame-background-mode 'dark) +;;; early-init.el ends here diff --git a/init.el b/init.el @@ -0,0 +1,43 @@ +;;; init.el --- init.el -*- lexical-binding: t -*- + +;;; Commentary: +;; trogloxene's Emacs + +;;; Code: + +(add-to-list 'load-path + (expand-file-name (concat user-emacs-directory "lisp"))) + +(setq custom-file (expand-file-name "custom.el" user-emacs-directory)) +(load custom-file t) + +(require 'init-const) + +(if (or (display-graphic-p) *is-android*) + (progn + (require 'init-proxy nil t) + (require 'init-startup) + (require 'init-elpa) + (require 'init-base) + (require 'init-edit) + (require 'init-completion) + (require 'init-package) + (require 'init-org) + (require 'init-prog) + (require 'init-window) + (require 'init-exwm) + (require 'init-dired) + (require 'init-gptel) + (require 'init-ui) + (require 'init-kbd-func) + (require 'init-kbd) + (require 'init-segmentation) + (require 'init-local nil t)) + (progn + (require 'init-terminal-startup) + (require 'init-proxy nil t) + (require 'init-elpa) + (require 'init-terminal-package) + (require 'init-terminal-ui) + (require 'init-terminal-kbd))) +;;; init.el ends here diff --git a/lisp/init-base.el b/lisp/init-base.el @@ -0,0 +1,268 @@ +;;; init-base.el --- base config -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +;; keybindings +(use-package general) + +;; mode names in mode line +(use-package delight + :config + (delight + `((eldoc-mode nil eldoc) + (org-indent-mode nil org-indent) + (desktop-environment-mode nil desktop-environment) + (hs-minor-mode nil hideshow) + (rainbow-delimiters-mode ,(propertize " Rdelimiters" 'face 'rainbow-delimiters-depth-1-face) rainbow-delimiters)))) + +;; garbage collection +(use-package gcmh + :delight + :init + (setq gcmh-idle-delay 'auto + gcmh-auto-idle-delay-factor 10 + gcmh-high-cons-threshold #x4000000) + (gcmh-mode)) + +;; benchmark +(use-package benchmark-init + :init + (benchmark-init/activate) + :hook + (after-init . benchmark-init/deactivate)) + +;; server-mode +(use-package server + :demand t + :hook + (emacs-startup . (lambda () + (unless (server-running-p) + (server-mode 1))))) + +;; recently opened files +(if (or (display-graphic-p) *is-android*) + (use-package recentf + :hook + (after-init . recentf-mode) + :init + (setq recentf-max-saved-items 30) + :config + (if *is-android* + (add-to-list 'recentf-exclude "~/storage/shared/my-org-note/journal/.*\\.org\\'") + (add-to-list 'recentf-exclude "~/org/my-org-note/journal/.*\\.org\\'") + (add-to-list 'recentf-exclude "~/org/my-org-note/20260509T232442==agenda--all-my-todos__org\\.org")) + (add-to-list 'recentf-exclude "~/.emacs.d/emms/history") + (add-to-list 'recentf-exclude "~/.emacs.d/bookmarks"))) + +;; save minibuffer history +(use-package savehist + :hook + (after-init . savehist-mode) + :init + (setq enable-recursive-minibuffers t + history-length 50 + savehist-additional-variables '(mark-ring + global-mark-ring + search-ring + regexp-search-ring + extended-command-history) + savehist-autosave-interval 300)) + +;; save cursor place +(use-package saveplace + :hook + (after-init . save-place-mode)) + +;; restart emacs +(use-package restart-emacs) + +;; async +(unless *is-android* + (use-package async + :hook + (after-init . dired-async-mode) + (after-init . async-bytecomp-package-mode))) + +;; autorevert buffer +(use-package autorevert + :delight + :hook + (after-init . global-auto-revert-mode)) + +;; display keybindings +(use-package which-key + :straight nil + :delight + :hook + (after-init . which-key-mode)) + +;; save window changes +(use-package winner + :hook + (after-init . winner-mode)) + +;; ibuffer +(use-package ibuffer + :config + (setq ibuffer-saved-filter-groups + '(("Main" + ("App" (mode . exwm-mode)) + ("Scratch" (or + (name . "^*scratch"))) + ("Tramp"(or + (name . "^\\*tramp"))) + ("eww" (or + (mode . eww-mode) + (mode . eww-bookmark-mode) + (mode . eww-buffers-mode) + (mode . eww-history-mode))) + ("AI" (or + (name . "^\\*OpenCode") + (name . "\\*opencode-serve\\*") + (name . "^\\*gptel"))) + ("Calc" (or + (mode . calc-mode) + (mode . calc-trail-mode))) + ("Text" (or + (mode . org-mode) + (mode . markdown-mode) + (name . "^\\*\\[D\\] FILE backlinks for"))) + ("Shell" (or + (mode . eshell-mode) + (mode . eat-mode) + (mode . vterm-mode))) + ("Scripts" (or + (mode . shell-script-mode) + (mode . shell-mode) + (mode . sh-mode) + (mode . lua-mode) + (mode . bat-mode))) + ("Config" (or + (mode . conf-mode) + (mode . conf-desktop-mode) + (mode . conf-toml-mode) + (mode . conf-xdefaults-mode) + (mode . conf-javaprop-mode) + (mode . conf-unix-mode) + (mode . toml-ts-mode) + (mode . yaml-ts-mode) + (mode . json-ts-mode))) + ("Elisp" (mode . emacs-lisp-mode)) + ("Scheme" (or + (mode . scheme-mode))) + ("Geiser" (or + (name . "^Geiser") + (mode . geiser-repl-mode) + (mode . geiser-debug-mode) + (mode . geiser-messages-mode) + (mode . geiser-debug-mode) + (mode . geiser-doc-mode) + (mode . geiser-autodoc-mode))) + ("Common-lisp" (or + (mode . common-lisp-mode) + (mode . lisp-mode))) + ("Sly" (or + (mode . lisp-data-mode) + (mode . sly-db-mode) + (mode . sly-mrepl-mode) + (name . "\\*sly-compilation\\*") + (name . "^\\*img-cache\\*"))) + ("Help" (or + (mode . help-mode) + (mode . helpful-mode))) + ("Info" (or + (name . "^\\*info"))) + ("Magit" (or + (mode . magit-blame-mode) + (mode . magit-cherry-mode) + (mode . magit-diff-mode) + (mode . magit-log-mode) + (mode . magit-process-mode) + (mode . magit-status-mode) + (mode . magit-revision-mode) + (mode . magit-refs-mode))) + ("Directories" (or + (mode . dired-mode) + (name . "^*dirvish") + (mode . trashed-mode))) + ("Grep" (or + (mode . grep-mode) + (mode . rg-mode) + (mode . xref--xref-buffer-mode) + (mode . xref-edit-mode) + (mode . occur-mode) + (mode . occur-edit-mode))) + ("Diff" (or + (name . "^*Diff") + (mode . ediff-mode) + (mode . vundo-diff-mode))) + ("Emacs" (or + (name . "^\\*Help\\*$") + (name . "^\\*Custom.*") + (name . "^\\*EMMS Playlist\\*") + (name . "^\\*Messages\\*$") + (name . "*Chinese-word-segmentation*") + (name . "^*Buffer List*") + (name . "\\*discomfort\\*") + (mode . calendar-mode) + (mode . grep-mode) + (mode . proced-mode) + (mode . syncthing-mode)))))) + + (add-hook 'ibuffer-hook + (lambda () (ibuffer-switch-to-saved-filter-groups "Main") + (unless (eq ibuffer-sorting-mode 'alphabetic) + (ibuffer-do-sort-by-alphabetic)))) + + (setq ibuffer-show-empty-filter-groups nil + ibuffer-use-other-window t + ibuffer-default-sorting-mode 'filename)) + +(use-package simple + :straight nil + :hook + (after-init . size-indication-mode) + (after-init . column-number-mode) + :config + (setq kill-whole-line t + set-mark-command-repeat-pop t)) ;easier to pop marks + +;; scroll +(unless *is-mac* + (use-package pixel-scroll + :straight nil + :hook + (after-init . pixel-scroll-precision-mode) + :init + (setq scroll-preserve-screen-position t + scroll-conservatively 101) + :config + (advice-add 'pixel-scroll-precision :around + (lambda (orig event) + (cl-letf (((symbol-function 'device-class) + (lambda (&rest _) 'mouse))) + (funcall orig event)))))) + +;; eww +(use-package eww + :config + (setq eww-auto-rename-buffer t)) + +;; tramp +(use-package tramp + :config + (setq tramp-default-method 'ssh + tramp-auto-save-directory "~/.emacs.d/tramp-auto-save") + (add-to-list 'tramp-remote-path 'tramp-own-remote-path) + (connection-local-set-profile-variables + 'remote-dirvish-fix + '((insert-directory-program . "ls") + (tramp-direct-async-process . t))) + (connection-local-set-profiles + '(:application tramp :protocol "ssh") + 'remote-dirvish-fix)) + +(provide 'init-base) +;;; init-base.el ends here diff --git a/lisp/init-completion.el b/lisp/init-completion.el @@ -0,0 +1,203 @@ +;;; init-completion.el --- completion config -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +;; minibuffer completion +(use-package vertico + :hook + (after-init . vertico-mode)) + +;; orderless completion +(use-package orderless + :custom + (completion-styles '(orderless basic))) + +;; marginalia in minibuffer +(use-package marginalia + :hook + (after-init . marginalia-mode)) + +;; search and navigation +(use-package consult + :config + ;; set locate arguments + (cond + (*is-windows* + (setq consult-locate-args (encode-coding-string "es.exe -i -p -r" 'gbk) + consult-ripgrep-args (encode-coding-string + "rg --null --line-buffered --color=never --max-columns=1000 --path-separator / --smart-case --no-heading --line-number" + 'gbk)) + (add-to-list 'process-coding-system-alist '("es" gbk . gbk))) + (*is-mac* + (setq consult-locate-args "mdfind -name")) + (*is-linux* + (setq consult-locate-args "plocate --basename --ignore-case"))) + + ;; help + (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help) + (setq consult-narrow-key "<") + + ;; xref + (setq xref-show-definitions-function #'consult-xref) + (setq xref-show-xrefs-function #'consult-xref) + + ;; set some buffer filter + (setq consult-buffer-filter + (cl-union consult-buffer-filter + '("^\\*dirvish" + "^PREVIEW" + "^\\*helpful" + "^\\*Help" + "Diff" + "straight" + "\\*Messages\\*" + "\\*Chinese-word-segmentation\\*" + "\\*gptel-reasoning\\*" + "\\*gptel-log\\*") + :test 'equal))) + +;; right-click +(use-package embark + :commands + embark-prefix-help-command + :init + (setq prefix-help-command 'embark-prefix-help-command) + :config + (defun my-embark-preview () + "Previews candidate in vertico buffer, unless it's a consult command." + (interactive) + (unless (bound-and-true-p consult--preview-function) + (save-selected-window + (let ((embark-quit-after-action nil)) + (embark-dwim))))) + + (add-to-list 'display-buffer-alist + '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*" + nil + (window-parameters (mode-line-format . none)))) + + (with-no-warnings + (with-eval-after-load 'which-key + (defun embark-which-key-indicator () + "An embark indicator that displays keymaps using which-key. +The which-key help message will show the type and value of the +current target followed by an ellipsis if there are further +targets." + (lambda (&optional keymap targets prefix) + (if (null keymap) + (which-key--hide-popup-ignore-command) + (which-key--show-keymap + (if (eq (plist-get (car targets) :type) 'embark-become) + "Become" + (format "Act on %s '%s'%s" + (plist-get (car targets) :type) + (embark--truncate-target (plist-get (car targets) :target)) + (if (cdr targets) "…" ""))) + (if prefix + (pcase (lookup-key keymap prefix 'accept-default) + ((and (pred keymapp) km) km) + (_ (key-binding prefix 'accept-default))) + keymap) + nil nil t (lambda (binding) + (not (string-suffix-p "-argument" (cdr binding)))))))) + + (setq embark-indicators + '(embark-which-key-indicator + embark-highlight-indicator + embark-isearch-highlight-indicator)) + + (defun embark-hide-which-key-indicator (fn &rest args) + "Hide the which-key indicator immediately when using the completing-read prompter." + (which-key--hide-popup-ignore-command) + (let ((embark-indicators + (remq #'embark-which-key-indicator embark-indicators))) + (apply fn args))) + + (advice-add #'embark-completing-read-prompter + :around #'embark-hide-which-key-indicator)))) + +;; embark-consult +(use-package embark-consult) + +;; eglot +(use-package eglot + :config + (setq eglot-send-changes-idle-time 0.25)) + +;; corfu +(use-package corfu + :autoload + (corfu-quit consult-completion-in-region) + :bind + (:map corfu-map + ("M-d" . corfu-popupinfo-documentation)) + :custom + (corfu-auto t) + (corfu-auto-prefix 2) + (corfu-count 12) + (corfu-preview-current nil) + (corfu-on-exact-match nil) + (corfu-auto-delay 0.2) + (corfu-popupinfo-delay '(0.4 . 0.2)) + (global-corfu-modes '((not erc-mode + circe-mode + help-mode + gud-mode + vterm-mode) + t)) + :hook + (after-init . global-corfu-mode) + (after-init . corfu-popupinfo-mode) + (after-init . corfu-history-mode) + :config + ;;Quit completion before saving + (add-hook 'before-save-hook #'corfu-quit) + (add-hook 'eshell-mode-hook + (lambda () + (setq-local corfu-auto nil) + (local-set-key (kbd "TAB") 'completion-at-point))) + :bind + (:map corfu-map + ("RET" . nil))) + +(if (not (and (display-graphic-p) + (>= emacs-major-version 31))) + (use-package corfu-terminal + :hook + (after-init . corfu-terminal-mode))) + +(use-package emacs + :custom + (tab-always-indent 'complete) + + ;; Emacs 30 and newer: Disable Ispell completion function. + ;; Try `cape-dict' as an alternative. + (text-mode-ispell-word-completion nil) + + ;; Hide commands in M-x which do not apply to the current mode. Corfu + ;; commands are hidden, since they are not used via M-x. This setting is + ;; useful beyond Corfu. + (read-extended-command-predicate #'command-completion-default-include-p)) + +;; cape +(use-package cape + :commands (cape-file cape-elisp-block cape-keyword) + :autoload (cape-wrap-noninterruptible cape-wrap-nonexclusive cape-wrap-buster) + :autoload (cape-wrap-silent) + :init + ;; (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-elisp-block) + (add-to-list 'completion-at-point-functions #'cape-keyword) + ;; (add-to-list 'completion-at-point-functions #'cape-abbrev) + + ;; Make these capfs composable. + (advice-add 'comint-completion-at-point :around #'cape-wrap-nonexclusive) + (advice-add 'eglot-completion-at-point :around #'cape-wrap-buster) + (advice-add 'eglot-completion-at-point :around #'cape-wrap-nonexclusive) + (advice-add 'pcomplete-completions-at-point :around #'cape-wrap-nonexclusive)) + +(provide 'init-completion) +;;; init-completion.el ends here diff --git a/lisp/init-const.el b/lisp/init-const.el @@ -0,0 +1,13 @@ +;;; init-const.el --- constant and system stuff -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +(defconst *is-mac* (eq system-type 'darwin)) +(defconst *is-linux* (eq system-type 'gnu/linux)) +(defconst *is-windows* (or (eq system-type 'ms-dos) (eq system-type 'windows-nt))) +(defconst *is-android* (if (getenv "TERMUX_VERSION") t nil)) + +(provide 'init-const) +;;; init-const.el ends here diff --git a/lisp/init-dashboard.el b/lisp/init-dashboard.el @@ -0,0 +1,24 @@ +;;; init-dashboard.el --- dashboard -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +(use-package dashboard + :autoload dashboard-setup-startup-hook + :hook after-init + :config + (setq dashboard-banner-logo-title (format "%s" emacs-version) + dashboard-banner-ascii " ##### # # # # ####### # # # ##### ##### \n# # ## # # # # ## ## # # # # # # \n# # # # # # # # # # # # # # # \n# #### # # # # # ##### # # # # # # ##### \n# # # # # # # # # # ####### # # \n# # # ## # # # # # # # # # # # \n ##### # # ##### ####### # # # # ##### ##### " + dashboard-startup-banner 'ascii + dashboard-footer-messages '("hello") + dashboard-center-content t + dashboard-navigation-cycle t + dashboard-items '((recents . 8) + (bookmarks . 5) + (projects . 5)) + dashboard-item-shortcuts '((recents . "r") (bookmarks . "b") (projects . "p") (agenda . "a") (registers . "e"))) + (dashboard-setup-startup-hook)) + +(provide 'init-dashboard) +;;; init-dashboard.el ends here diff --git a/lisp/init-dired.el b/lisp/init-dired.el @@ -0,0 +1,143 @@ +;;; init-dired.el --- dired & dirvish -*-lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +(use-package dired + :straight nil + :config + (when *is-mac* + (setq insert-directory-program "gls" + dired-use-ls-dired t)) + (setq dired-dwim-target t + dired-listing-switches + "-l --almost-all --human-readable --group-directories-first --no-group" + dired-recursive-deletes 'always + dired-recursive-copies 'always + dired-mouse-drag-files t + mouse-drag-and-drop-region-cross-program t + dired-compress-file-default-suffix ".zip" + dired-kill-when-opening-new-dired-buffer nil + dired-auto-revert-buffer t + dired-create-destination-dirs 'ask + dired-create-destination-dirs-on-trailing-dirsep t + remote-file-name-inhibit-delete-by-moving-to-trash t) + (put 'dired-find-alternate-file 'disabled nil)) + +;; dirvish +(use-package dirvish + :straight + (dirvish :fork (:host github :repo "latiagertrutis/dirvish")) + :init + (dirvish-override-dired-mode) + :config + (require 'vc) + + (if (or *is-mac* *is-android*) + (setq dirvish-hide-details t) + (setq dirvish-hide-details '(dirvish-side))) + + (if *is-android* + (setq dirvish-default-layout nil + dirvish-layout-recipes '((1 0.6))) + (setq dirvish-default-layout nil + dirvish-layout-recipes '((1 0.15 0.45)))) + + (setq dirvish-use-mode-line t + dirvish-mode-line-format '(:left (sort omit symlink) :right (free-space index)) + dirvish-attributes '(file-time file-size) + dirvish-yank-sources 'session + dirvish-hide-cursor nil) + + :custom + (dirvish-quick-access-entries + (cond + (*is-windows* + '(("h" "~/" "Home") + ("e" "~/.emacs.d/" "Emacs config") + ("p" "c:/Users/gaozh/Pictures/Screenshots/" "Pictures") + ("d" "f:/下载25-2-10/" "Download") + ("v" "f:/luping26-1-11/" "Videos") + ("n" "h:/emacs/my-org-note/" "Notes"))) + + (*is-mac* + '(("h" "~/" "Home") + ("e" "~/.emacs.d/" "Emacs config") + ("p" "~/Pictures/" "Pictures") + ("d" "~/Downloads/" "Download") + ("v" "~/Movies/" "Videos") + ("n" "~/org/my-org-note/" "Notes") + ("g" "~/gptel/" "gptel sessions"))) + + (*is-linux* + '(("h" "~/" "Home") + ("e" "~/.emacs.d/" "Emacs config") + ("s" "~/.config/guix/" "System config") + ("p" "~/Pictures/" "Pictures") + ("d" "~/downloads/" "Downloads") + ("v" "~/视频/" "Videos") + ("n" "~/org/my-org-note/" "Notes") + ("g" "~/gptel/" "gptel sessions"))) + + (*is-android* + '(("h" "~/" "Home") + ("e" "~/.emacs.d" "Emacs") + ("n" "~/storage/shared/my-org-note/" "Notes") + ("g" "~/gptel/" "gptel sessions"))) + (t nil)))) + +;; gitignore +(use-package dired-gitignore + :after + (dirvish dirvish-vc transient) + :demand t + :config + (transient-define-suffix dirvish-toggle-gitignore () + "Toggle `dired-gitignore-mode' in current Dirvish buffer." + :description + (lambda () + (format "Gitignore filter (%s)" + (if dired-gitignore-mode + (propertize "+" 'face 'transient-value) + (propertize "-" 'face 'transient-inactive-value)))) + :transient t + (interactive) + (dired-gitignore-mode 'toggle)) + + (transient-append-suffix 'dirvish-vc-menu "v" + '("i" dirvish-toggle-gitignore))) + +;; trashed +(unless *is-mac* + (use-package trashed + :commands + (trashed) + :config + (setq trashed-action-confirmer 'y-or-n-p + trashed-use-header-line t + trashed-sort-key '("Date deleted" . t) + trashed-date-format "%Y-%m-%d %H:%M:%S"))) + +;; dired-async +(use-package dired-rsync + :config + (setq dired-rsync-options "-az -e ssh")) + +;; mount disk +(when *is-linux* + (use-package debase + :straight + (debase :type git + :host codeberg + :repo "emacs-weirdware/debase")) + + (use-package discomfort + :commands discomfort + :straight + (discomfort :type git + :host codeberg + :repo "emacs-weirdware/discomfort"))) + +(provide 'init-dired) +;;; init-dired.el ends here diff --git a/lisp/init-edit.el b/lisp/init-edit.el @@ -0,0 +1,114 @@ +;;; init-edit.el --- edit and navigate -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +;; delete select +(use-package delsel + :hook + (after-init . delete-selection-mode)) + +;; insert paris +(use-package elec-pair + :config + (setq electric-pair-inhibit-predicate 'electric-pair-conservative-inhibit + electric-pair-pairs (append '((?\= . ?\=)) electric-pair-pairs))) + +;; multiple cursors +(use-package multiple-cursors + :custom + (mc/insert-numbers-default 1) + (mc/always-run-for-all t) + :init + (setq mc/cmds-to-run-once + '(god-mode-all + hydra-multiple-cursors/body + hydra-multiple-cursors/mc/edit-lines + hydra-multiple-cursors/mc/insert-numbers + hydra-multiple-cursors/mc/mark-all-dwim + hydra-multiple-cursors/mc/mark-next-like-this + hydra-multiple-cursors/mc/mark-next-like-this-symbol + hydra-multiple-cursors/mc/mark-next-like-this-word + hydra-multiple-cursors/mc/mark-previous-like-this + hydra-multiple-cursors/mc/mark-previous-like-this-symbol + hydra-multiple-cursors/mc/mark-previous-like-this-word + hydra-multiple-cursors/mc/unmark-next-like-this + hydra-multiple-cursors/mc/unmark-previous-like-this + hydra-multiple-cursors/nil))) + +;; useful commands +(use-package crux) + +;; hungry-delete +(use-package hungry-delete) + +;; drag-stuff +(use-package drag-stuff) + +;; better undo/redo +(use-package undo-fu + :config + (setq undo-in-region t + undo-fu-allow-undo-in-region t)) + +;; save undo history across sessions +(use-package undo-fu-session + :hook + (after-init . undo-fu-session-global-mode)) + +;; undo tree +(use-package vundo + :init + (setq undo-limit 800000 + undo-strong-limit 1200000 + undo-outer-limit 12000000)) + +;; expand-region +(use-package expand-region + :commands + (er/mark-symbol er/mark-word) + :config + (setq expand-region-smart-cursor t)) + +;; Chinese support for avy +(use-package ace-pinyin + :delight + :hook + (after-init . ace-pinyin-global-mode)) + +;; avy-zap +(use-package avy-zap + :bind + (("M-z" . avy-zap-to-char-dwim) + ("M-Z" . avy-zap-up-to-char-dwim))) + +;; modal editing +(use-package god-mode + :init + (if *is-android* (add-hook 'after-init-hook 'god-mode-all)) + :config + (unless (or *is-android* (not use-package-always-defer)) (which-key-enable-god-mode-support)) + (setq god-mode-enable-function-key-translation nil + god-exempt-major-modes + (cl-union '(diff-mode exwm-mode) god-exempt-major-modes :test 'equal) + god-mode-lighter-string "THANK-GOD-MODE") + + (defun my-sync-god-mode-lighter-face (&rest _) + (set-face-attribute 'god-mode-lighter nil + :inherit 'isearch-fail + :background (face-attribute 'mode-line :background nil t) + :weight 'bold)) + (my-sync-god-mode-lighter-face) + (add-hook 'enable-theme-functions #'my-sync-god-mode-lighter-face) + + (defun my-sync-line-numbers-with-god-mode () + (let ((desired (if (bound-and-true-p god-local-mode) + 'relative + t))) + (unless (or (eq display-line-numbers desired) (bound-and-true-p olivetti-mode)) + (setq display-line-numbers desired)))) + (add-hook 'post-command-hook #'my-sync-line-numbers-with-god-mode)) + +(provide 'init-edit) +;;; init-edit.el ends here diff --git a/lisp/init-elpa.el b/lisp/init-elpa.el @@ -0,0 +1,46 @@ +;;; init-elpa.el --- package manager -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +;; straight.el + +(defvar bootstrap-version) +(let ((bootstrap-file + (expand-file-name + "straight/repos/straight.el/bootstrap.el" + (or (bound-and-true-p straight-base-dir) + user-emacs-directory))) + (bootstrap-version 7)) + (unless (file-exists-p bootstrap-file) + (with-current-buffer + (url-retrieve-synchronously + "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el" + 'silent 'inhibit-cookies) + (goto-char (point-max)) + (eval-print-last-sexp))) + (load bootstrap-file nil 'nomessage)) + +(setq straight-repository-branch t) + +;; el-patch +(use-package el-patch + :straight t) + +;; install use-package +(if (< emacs-major-version 29) + (straight-use-package 'use-package)) + +;; configure use-package +(setq use-package-always-defer (if *is-windows* nil t) + use-package-expand-minimally t + use-package-verbose t + straight-use-package-version t + straight-use-package-by-default t) + +;; imenu +(setopt use-package-enable-imenu-support t) + +(provide 'init-elpa) +;;; init-elpa.el ends here diff --git a/lisp/init-exwm.el b/lisp/init-exwm.el @@ -0,0 +1,159 @@ +;;; init-exwm.el --- exwm config -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +(when *is-linux* + (use-package exwm + :hook + (exwm-init . restart-fcitx5) + (exwm-init . my-desktop-init) + :config + (setq pop-up-windows nil) + (setq exwm-workspace-number 1) + (exwm-input-set-key (kbd "s-&") + (lambda (command) + (interactive (list (read-shell-command "$ "))) + (let ((display-buffer-alist + '((".*" . (display-buffer-no-window . nil))))) + (async-shell-command command)))) + + (defun my--exwm-switch-to-workspace (delta) + (let ((target + (mod (+ exwm-workspace-current-index delta) + (length exwm-workspace--list)))) + (exwm-workspace-switch target))) + + (defun my-exwm-next-workspace () + "Switch to next exwm workspace." + (interactive) + (my--exwm-switch-to-workspace 1) + (if (= 1 (length exwm-workspace--list)) + (message "No next workspace"))) + + (defun my-exwm-previous-workspace () + "Switch to previous exwm workspace." + (interactive) + (my--exwm-switch-to-workspace -1) + (if (= 1 (length exwm-workspace--list)) + (message "No previous workspace"))) + + (global-set-key (kbd "s-]") 'my-exwm-next-workspace) + (global-set-key (kbd "s-[") 'my-exwm-previous-workspace) + + (add-to-list 'global-mode-string + '(:eval (propertize (format " WS:%d " exwm-workspace-current-index) + 'face 'mode-line-emphasis)) + t) + + (setq exwm-input-prefix-keys + '(?\C-x + ?\C-u + ?\C-c + ?\C-h + ?\M-x + ?\M-o + ?\M-[ + ?\M-] + ?\s-[ + ?\s-] + ?\s- + XF86AudioLowerVolume + XF86AudioRaiseVolume + XF86AudioMute + )) + (define-key exwm-mode-map [?\C-q] 'exwm-input-send-next-key) + + (setq exwm-input-global-keys + `(([?\s-r] . exwm-reset) + ([?\s-b] . windmove-left) + ([?\s-f] . windmove-right) + ([?\s-p] . windmove-up) + ([?\s-n] . windmove-down) + ([?\s-S] . desktop-environment-screenshot) + ([?\s-s] . desktop-environment-screenshot-part) + ([?\s-w] . exwm-workspace-switch) + ([?\s-o] . other-window) + ([?\s-m] . exwm-layout-toggle-mode-line) + ([?\s-`] . (lambda () (interactive) (exwm-workspace-switch-create 0))) + ,@(mapcar (lambda (i) + `(,(kbd(format "s-%d" i)) . + (lambda () + (interactive) + (exwm-workspace-switch-create ,i)))) + (number-sequence 0 9)))) + + (setq exwm-input-simulation-keys + `((,(kbd "C-f") . [right]) + (,(kbd "C-b") . [left]) + (,(kbd "C-p") . [up]) + (,(kbd "C-n") . [down]) + (,(kbd "C-a") . [home]) + (,(kbd "C-e") . [end]) + (,(kbd "M-f") . [C-right]) + (,(kbd "A-f") . [C-right]) + (,(kbd "M-b") . [C-left]) + (,(kbd "A-b") . [C-left]) + (,(kbd "C-d") . [delete]) + (,(kbd "C-k") . [S-end delete]) + (,(kbd "M-<backspace>") . ,(kbd "C-<backspace>")) + (,(kbd "M-d") . ,(kbd "C-<delete>")) + (,(kbd "M-w") . [?\C-c]) + (,(kbd "C-y") . [?\C-v]) + (,(kbd "C-w") . [?\C-x]) + (,(kbd "C-/") . [?\C-z]) + (,(kbd "C-?") . ,(kbd "C-S-z")))) + + (defun my-exwm-update-class () + (exwm-workspace-rename-buffer exwm-class-name)) + (add-hook 'exwm-update-class-hook #'my-exwm-update-class) + + (require 'exwm-xim) + (exwm-xim-mode) + (exwm-wm-mode)) + + (use-package desktop-environment + :after exwm + :demand t + :init + (add-hook 'exwm-wm-mode-hook 'desktop-environment-mode) + :config + (advice-add 'desktop-environment-screenshot :after + (lambda (&rest _) (message "Saved fullscreen screenshot."))) + (advice-add 'desktop-environment-screenshot-part :after + (lambda (&rest _) (message "Saved partial screenshot."))) + :custom + (desktop-environment-screenshot-command + "import -window root ~/Pictures/screenshot-$(date +%Y%m%d-%H%M%S).png") + (desktop-environment-screenshot-partial-command + "import ~/Pictures/screenshot-$(date +%Y%m%d-%H%M%S).png")) + + (use-package xdg-launcher + :demand t + :after exwm + :straight + (xdg-launcher :type git + :host github + :repo "emacs-exwm/xdg-launcher") + :bind + (("s-SPC" . xdg-launcher-run-app)) + :init + (with-eval-after-load 'consult + (unless (memq 'xdg-launcher-consult-source consult-buffer-sources) + (setq consult-buffer-sources + (append consult-buffer-sources '(xdg-launcher-consult-source))))))) + +(when *is-mac* + ;; launcher + (use-package launcher + :straight + (launcher + :type git + :host github + :repo "xiaoxinghu/launcher.el") + :bind + ("s-SPC" . launcher))) + +(provide 'init-exwm) +;;; init-exwm.el ends here diff --git a/lisp/init-gptel.el b/lisp/init-gptel.el @@ -0,0 +1,186 @@ +;;; init-gptel.el --- ai -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +(use-package gptel + :config + (setq gptel-log-level t + gptel-default-mode 'org-mode + gptel-include-reasoning "*gptel-reasoning*") + (add-hook 'gptel-post-response-functions 'gptel-end-of-response) + (add-hook 'gptel-post-stream-hook 'gptel-auto-scroll) + (setq gptel-prompt-prefix-alist '((markdown-mode . "## User: ") (org-mode . "** User: ") (text-mode . "## User: "))) + + (gptel-make-tool + :name "read_buffer" ; javascript-style snake_case name + :function (lambda (buffer) ; the function that will run + (unless (buffer-live-p (get-buffer buffer)) + (error "error: buffer %s is not live." buffer)) + (with-current-buffer buffer + (buffer-substring-no-properties (point-min) (point-max)))) + :description "return the contents of an emacs buffer" + :args (list '(:name "buffer" + :type string ; :type value must be a symbol + :description "the name of the buffer whose contents are to be retrieved")) + :category "emacs") ; An arbitrary label for grouping + + (gptel-make-openai "gptel-Kimi-Code" + :host "api.kimi.com" + :endpoint "/coding/v1/chat/completions" + :protocol "https" + :key (lambda () + (auth-source-pick-first-password :host "api.kimi.com" :user "apikey")) + :stream t + :models '(kimi-k3) + :header (lambda (_) + (when-let* ((key (gptel--get-api-key))) + `(("User-Agent" . "RooCode/3.30.3") + ("HTTP-Referer" . "https://github.com/RooVetGit/Roo-Cline") + ("X-Title" . "Roo Code") + ("Authorization" . ,(concat "Bearer " key)))))) + + (setq gptel-model 'kimi-k3 + gptel-backend (gptel-get-backend "gptel-Kimi-Code")) + + (defun my-gptel--sanitize-filename (name) + "Clean NAME into a safe kebab-case filename string." + (let ((clean (downcase name))) + (setq clean (replace-regexp-in-string "[^a-z0-9_-]" "-" clean)) + (setq clean (replace-regexp-in-string "^-+\\|[-]+$" "" clean)) + (setq clean (replace-regexp-in-string "-[-]+" "-" clean)) + (string-trim clean))) + + (defun my-gptel-save-session () + "Save current gptel session to ~/gptel/sessions/ with AI-generated +filename. +The filename is prefixed with a YYYYMMDD-HHmmss timestamp and generated +from the last 1500 characters of the buffer." + (interactive) + (unless gptel-mode + (user-error "Not a gptel session buffer")) + (let* ((buf (current-buffer)) + (content (with-current-buffer buf + (buffer-substring-no-properties (point-min) (point-max)))) + (tail (substring content (max 0 (- (length content) 1500)))) + (prompt-text (format "Based on the following conversation, generate a short kebab-case +filename (3 to 5 lowercase English words, hyphen-separated, no file +extension). Output ONLY the filename, nothing else.\n\n%s" + tail))) + (message "Generating filename with AI...") + (let ((fsm (gptel-request prompt-text + :system "You are a filename generator. Output ONLY a short kebab-case +filename (3-5 lowercase English words separated by hyphens). No +explanations, no quotes, no punctuation, no file extension." + :stream nil + :callback + (lambda (response info) + (condition-case err + (cond + ((null response) + (message "Failed to generate filename: %s" + (or (plist-get info :status) "unknown error"))) + ((not (stringp response)) + (message "Unexpected response type: %S" response)) + (t + (let* ((generated (my-gptel--sanitize-filename (string-trim response))) + (generated (if (string-empty-p generated) + "gptel-session" + generated)) + (timestamp (format-time-string "%Y%m%d-%H%M%S")) + (dir (expand-file-name "~/gptel/sessions/")) + (base (concat timestamp "-" generated)) + (file (expand-file-name (concat base ".org") dir))) + ;; handle name collision + (when (file-exists-p file) + (setq base (concat timestamp "-" generated "-" (format-time-string "%S"))) + (setq file (expand-file-name (concat base ".org") dir))) + (unless (file-directory-p dir) + (make-directory dir t)) + ;; write-file triggers gptel--save-state to preserve metadata + (with-current-buffer buf + (write-file file)) + (if (file-exists-p file) + (progn + (pop-to-buffer (find-file-noselect file)) + (message "Saved gptel session to %s" file)) + (message "ERROR: File was not created: %s" file))))) + (error (message "gptel save-session error: %S" err))))))) + (unless (plist-get (gptel-fsm-info fsm) :callback) + (message "WARNING: gptel-request did not register callback!"))))) + + (with-eval-after-load 'gptel + (define-key gptel-mode-map (kbd "C-c C-s") #'my-gptel-save-session))) + +(use-package gptel-agent + :after gptel + :demand t + :config + (add-to-list 'gptel-agent-dirs "~/.emacs.d/lisp/" t) + (gptel-agent-update)) + +(use-package gptel-magit + :straight + (gptel-magit :fork (:host github :repo "ArthurHeymans/gptel-magit")) + :hook + (magit-mode . gptel-magit-install) + :init + (with-eval-after-load 'gptel + (gptel-make-openai "gptel-Kimi-Code-magit" + :host "api.kimi.com" + :endpoint "/coding/v1/chat/completions" + :protocol "https" + :key (lambda () + (auth-source-pick-first-password :host "api.kimi.com" :user "apikey")) + :stream t + :models '((kimi-for-coding)) + :request-params '(:temperature 0.6 :thinking (:type "disabled")) + :header (lambda (_) + (when-let* ((key (gptel--get-api-key))) + `(("User-Agent" . "RooCode/3.30.3") + ("HTTP-Referer" . "https://github.com/RooVetGit/Roo-Cline") + ("X-Title" . "Roo Code") + ("Authorization" . ,(concat "Bearer " key)))))) + + (setq gptel-magit-model 'kimi-for-coding + gptel-magit-backend (gptel-get-backend "gptel-Kimi-Code-magit")))) + +;; opencode +(use-package plz + :straight + (plz :type git + :host github + :repo "alphapapa/plz.el" + :ref "v0.9.1")) + +(use-package plz-media-type + :straight + (plz-media-type :type git + :host github + :repo "r0man/plz-media-type" + :ref "v0.2.4")) + +(use-package plz-event-source + :straight + (plz-event-source :type git + :host github + :repo "r0man/plz-event-source" + :ref "v0.1.3")) + +(use-package opencode + :straight + (opencode :type git + :host codeberg + :repo "sczi/opencode.el") + :hook + (opencode-session-control-mode . disable-truncate-lines)) + +(use-package eval-elisp-mcp + :straight + (eval-elisp-mcp :type git + :host codeberg + :repo "sczi/eval-elisp-mcp")) + +(provide 'init-gptel) +;;; init-gptel.el ends here diff --git a/lisp/init-kbd-func.el b/lisp/init-kbd-func.el @@ -0,0 +1,339 @@ +;;; init-kbd-func.el --- functions for keybindings -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +(defun open-init-file() + "Open user's init.el file in ~/.emacs.d ." + (interactive) + (find-file "~/.emacs.d/init.el")) + +(when *is-windows* + (defun restart-emacs () + "Restart emacs (for Windows)" + (interactive) + (save-some-buffers) + (w32-shell-execute "open" "runemacs.exe") + (kill-emacs))) + +(defun disable-truncate-lines () + (toggle-truncate-lines 1)) + +(defun my-jinx-smart-toggle () + "Toggle jinx-mode smartly. +Disable jinx-mode if it's enable and global-jinx-mode is disable , +otherwise toggle global-jinx-mode." + (interactive) + (unless (featurep 'jinx) + (require 'jinx)) + (let ((local-on (bound-and-true-p jinx-mode)) + (global-on (bound-and-true-p global-jinx-mode))) + (cond + ((and local-on (not global-on)) + (message "disable jinx-mode in current buffer") + (jinx-mode -1)) + (t + (if global-on + (progn + (message "disable global-jinx-mode") + (global-jinx-mode -1)) + (progn + (message "enable global-jinx-mode") + (global-jinx-mode 1))))))) + +(defun popper-toggle-type-delete-other-window() + "Toggle type of popper window and delete other window." + (interactive) + (popper-toggle-type) + (delete-other-windows)) + +(defun consult-directory-externally (file) + "Open FILE externally using the default application of the system." + (interactive "fOpen externally: ") + (if (and (eq system-type 'windows-nt) + (fboundp 'w32-shell-execute)) + (shell-command-to-string + (encode-coding-string + (replace-regexp-in-string "/" "\\\\" + (format "explorer.exe %s" + (file-name-directory + (expand-file-name file)))) + 'gbk)) + (call-process (pcase system-type + ('darwin "open") + ('cygwin "cygstart") + (_ "xdg-open")) + nil 0 nil + (file-name-directory (expand-file-name file))))) + +(defun my-open-current-directory () + "Open current directory in default file explorer." + (interactive) + (consult-directory-externally default-directory)) + +(defun consult-fd-home () + "Search for all files in home folder use fd." + (interactive) + (let ((consult-fd-args "fd -H -I -i -c never --full-path") + (default-directory "~/")) + (consult-fd))) + +(defun org-cycle-parent-subtree() + "Cycle parent org subtree." + (interactive) + (if (org-at-heading-p) + (progn + (org-up-heading 1) + (org-cycle)) + (org-back-to-heading) + (org-cycle))) + +(defun my-denote-journal-path-to-existing-entry (&optional date interval) + "Return the path of current denote journal if it exists, otherwise return nil." + (require 'denote-journal) + (let* ((internal-date + (denote-journal--date-in-interval-p (or date (current-time)) interval)) + (files (denote-journal--get-entry internal-date interval))) + (if files + (denote-journal-select-file-prompt files)))) + +(defun my-denote-journal-open-entry () + "Open current denote-journal entry." + (interactive) + (if (my-denote-journal-path-to-existing-entry) + (find-file (my-denote-journal-path-to-existing-entry)) + (message "No journal for today yet"))) + +(defun my-denote-open-metanote () + "Open denote metanote in +`~/org/my-org-note/20260508T220745==metanote--all-my-metanotes__org.org'" + (interactive) + (find-file + (concat org-directory "/20260508T220745==metanote--all-my-metanotes__org.org"))) + +(defun my-denote-find-file () + "Find file use denote-file-prompt." + (interactive) + (let ((denote-excluded-files-regexp "=journal\\|=archive")) + (find-file (denote-file-prompt)))) + +(defun my-denote-find-backlink-with-location () + "Like `denote-find-backlink-with-location' but with consult preview." + (interactive) + (when-let* ((current-file buffer-file-name) + (id (or (denote-retrieve-filename-identifier current-file) + (user-error "The current file does not have a Denote identifier"))) + (files (denote-directory-files nil :omit-current :text-only)) + (fetcher (lambda () (xref-matches-in-files id files)))) + (consult-xref fetcher nil))) + +(defun my-denote-org-find-backlink-for-heading-with-location () + "Like `denote-org-backlinks-for-heading' but with consult preview." + (interactive) + (unless (featurep 'denote-org) + (require 'denote-org)) + (when-let* ((heading-id (or (denote-org--get-file-id-and-heading-id-or-context) + (user-error "The current file does not have a denote identifier"))) + (files (denote-directory-files nil :omit-current :text-only)) + (fetcher (lambda () (xref-matches-in-files heading-id files)))) + (consult-xref fetcher nil))) + +(defun my-org-table-align-all () + "Ajust all table in current buffer." + (interactive) + (save-excursion + (goto-char (point-min)) + (org-table-map-tables 'org-table-align t))) + +(defun org-align-description-list () + "Ajust all `::' in active region. " + (interactive) + (align-regexp (region-beginning) (region-end) "\\(\\s-*\\)::" 1 1 nil)) + +(defun my-blog-publish (&optional directory) + "Publish blog , git add/commit/push , generate commit message." + (interactive) + (let* ((blog-dir (or directory + (if *is-windows* + "h:/emacs/hugo/this-is-my-blog/" + "~/org/hugo/this-is-my-blog/"))) + (timestamp (format-time-string "%Y-%m-%d %H:%M:%S")) + (default-directory blog-dir)) + (message "Adding files...") + (eshell-command "git add .") + (message "Committing: %s" timestamp) + (eshell-command (format "git commit -m \"Update: %s\"" timestamp)) + (message "Pushing to remote...") + (let ((exit-code (eshell-command "git push"))) + (if (eq exit-code t) + (message "Push may have failed or nothing to push, check *Messages* buffer for details") + (message "Push successfully %s" timestamp))))) + +(defun my-blog-preview () + "Save and preview blog." + (interactive) + (save-buffer) + (let ((default-directory (if *is-windows* + "h:/emacs/hugo/this-is-my-blog/" + "~/org/hugo/this-is-my-blog/"))) + (start-process "hugo-server" "*hugo-server*" + "hugo" "server" "-D" "--bind" "0.0.0.0" "--port" "1313") + (sleep-for 2) + (browse-url "http://localhost:1313"))) + +(defun my-note-push () + "Git add/commit/push notes in `~/org/my-org-note/', generate commit message." + (interactive) + (my-blog-publish "~/org/my-org-note/")) + +(defun my-org-tree-slide-start () + "Start `org-tree-slide'." + (interactive) + (when (eq major-mode 'org-mode) + (setq-local header-line-format nil + mode-line-format nil + cursor-type 'hbar + olivetti-body-width 100) + (blink-cursor-mode -1) + (cnfonts-increase-fontsize 3) + (hl-line-mode 'toggle) + (read-only-mode 1) + (jinx-mode -1) + (org-tree-slide-mode 1))) + +(defun my-org-tree-slide-stop () + "Stop `org-tree-slide'." + (interactive) + (when (and (eq major-mode 'org-mode) (memq 'org-tree-slide-mode local-minor-modes)) + (org-mode-restart) + (blink-cursor-mode 1) + (cnfonts-decrease-fontsize 3) + (hl-line-mode 1) + (read-only-mode -1) + (jinx-mode 1) + (org-tree-slide-mode -1))) + +(defun my-dired-next-line() + "Move to forward line in dired buffer" + (interactive) + (forward-line 1) + (dired-move-to-filename)) + +(defun my-dirvish-layout-toggle () + "Toggle layout using first recipe in `dirvish-layout-recipes' instead of +fallback." + (interactive) + (let ((dv (dirvish-curr))) + (unless dv (user-error "Not a dirvish buffer")) + (unless (dv-curr-layout dv) + (setf (dv-ff-layout dv) (car dirvish-layout-recipes))) + (dirvish-layout-toggle))) + +(defun my-magit-toggle-parent-section () + "Toggle parent magit section." + (interactive) + (magit-section-up) + (magit-section-toggle (magit-section-at))) + +(defun my-persp-remove-marked-ibuffers () + "Remove marked buffers from perspective." + (interactive) + (let ((buffers (ibuffer-get-marked-buffers))) + (dolist (buf buffers) + (persp-remove-buffer buf)))) + +(defun my-persp-add-marked-ibuffers (persp-name) + "Add marked buffers to perspective." + (interactive + (list (completing-read "Perspective: " + (persp-names) + nil nil))) + (let ((buffers (ibuffer-get-marked-buffers))) + (persp-switch persp-name) + (dolist (buf buffers) + (persp-add-buffer buf)))) + +(defun my-persp-set-marked-ibuffers (persp-name) + "Set marked buffers to perspective." + (interactive + (list (completing-read "Perspective: " + (persp-names) + nil nil))) + (let ((buffers (ibuffer-get-marked-buffers))) + (persp-switch persp-name) + (dolist (buf buffers) + (persp-set-buffer buf)))) + +(defun my-gptel-agent-project () + "Run `gptel-agent' in current project's root (by run it with prefix +argument)." + (interactive) + (let ((current-prefix-arg '-)) + (call-interactively 'gptel-agent))) + +(defun my-opencode () + "Run `opencode' in project root." + (interactive) + (let ((default-directory (project-root (project-current t)))) + (opencode))) + +(defun my-consult-grep-project () + "Run `consult-grep' in current project's root." + (interactive) + (when-let* ((proj (project-current t))) + (consult-grep (project-root proj)))) + +(defun consult-colors-emacs (color) + "Show a list of all supported colors for a particular frame. + +You can insert the name (default), or insert or kill the hexadecimal or RGB +value of the selected COLOR." + (interactive + (list (consult--read (list-colors-duplicates (defined-colors)) + :prompt "Emacs color: " + :require-match t + :category 'color + :history '(:input consult-colors-history)))) + (insert color)) + +(defun fix-theme-colors () + "Fix invalid color name in theme files." + (interactive) + (load-file (expand-file-name "~/.emacs.d/lisp/fix-theme-colors.el"))) + +(when *is-linux* + (defun reboot () + "Execute loginctl reboot command." + (interactive) + (eshell-command "loginctl reboot")) + + (defun poweroff () + "Execute loginctl poweroff command" + (interactive) + (eshell-command "loginctl poweroff")) + + (defun suspend () + "Execute loginctl suspend command" + (interactive) + (eshell-command "loginctl suspend")) + + (defun my-desktop-init () + "Launch something for linux desktop." + (interactive) + (unless (zerop (shell-command "pgrep -x mihomo")) + (start-process-shell-command "mihomo" nil "mihomo -d ~/.config/mihomo/")) + (start-process-shell-command "xrandr-refresh" nil "xrandr --output DP-4 --mode 2560x1440 --rate 165.00") + (start-process-shell-command "xinput" nil "xinput set-prop 12 'libinput Accel Speed' -0.45")) + + (defun restart-fcitx5 () + "Kill and restart fcitx5, to fix random issues in exwm." + (interactive) + (if (zerop (shell-command "pgrep fcitx5")) + (progn + (eshell-command "pkill fcitx5") + (eshell-command "fcitx5 -d")) + (eshell-command "fcitx5 -d")))) + +(provide 'init-kbd-func) +;;; init-kbd-func.el ends here diff --git a/lisp/init-kbd.el b/lisp/init-kbd.el @@ -0,0 +1,418 @@ +;;; init-kbd.el --- keybindings -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +;; god-mode +(general-def god-local-mode-map + "i" 'god-mode-all + "[" 'backward-paragraph + "]" 'forward-paragraph + "." 'repeat + "y" 'yank + "C-c C-<f12>" 'scratch-buffer + "z" 'avy-goto-char + "'" 'avy-goto-word-1 + "<f2>" 'open-init-file) + +;; g for gptel +(general-def + :prefix "C-c g" + "g" 'gptel + "m" 'gptel-menu + "s" 'gptel-send + "a" 'gptel-agent + "t" 'gptel-tools + "o" 'opencode + "p" 'opencode-select-project + "l" 'opencode-select-session + "n" 'opencode-new-session) + +(general-def gptel-mode-map + "C-c C-s" 'my-gptel-save-session + "C-c C-k" 'gptel-abort) + +;; opencode +(general-def opencode-session-mode-map + "C-c C-p" 'comint-previous-prompt + "C-c M-p" 'opencode-respond-permission + "C-c x" nil + "C-c C-k" 'opencode-abort-session + "C-c C-c" 'nil + "C-c n" 'nil + "C-c N" 'opencode-new-session) + +(general-def opencode-session-control-mode-map + "n" 'next-line + "p" 'previous-line + "N" 'opencode-new-session) + +;; u for ui +(general-def + :prefix "C-c u" + "l" 'global-tab-line-mode + "d" 'disable-theme + "R" 'rainbow-mode + "b" 'indent-bars-mode + "t" 'consult-theme + "c" 'consult-colors-emacs + "f" 'describe-face + "r" 'rainbow-delimiters-mode + "k" 'keycast-header-line-mode + "w" 'global-whitespace-mode) + +;; f for find and consult command +(general-def + :prefix "C-c f" + "r" 'consult-recent-file + "f" 'consult-find + "g" 'consult-grep + "e" 'consult-flycheck + "l" 'consult-locate + "h" 'consult-fd-home + "m" 'consult-man + "d" 'my-open-current-directory + "j" 'consult-jinx + "k" 'consult-kmacro + "o" 'consult-outline + "i" 'consult-info + "s" 'consult-focus-lines) + +;; p for project +(general-def + :prefix "C-x p" + "b" 'consult-project-buffer + "E" 'eat-project + "r" 'my-consult-grep-project + "R" 'project-query-replace-regexp + "v" 'magit-project-status + "V" 'project-vc-dir + "a" 'my-opencode + "i" 'project-ibuffer) + +;; v for version control +(general-def + :prefix "C-x v" + "=" 'magit-diff-buffer-file + "c" 'magit-clone + "i" 'magit-init + "l" 'magit-log-buffer-file + "h" 'magit-log-buffer-file) + +;; t for modes toggle +(general-def + :prefix "C-c t" + "f" 'flycheck-mode + "j" 'my-jinx-smart-toggle + "g" 'gptel-mode + "h" 'global-diff-hl-mode) + +;; o for org-mode +(general-def + :prefix "C-c o" + "f" 'my-denote-find-file + "g" 'consult-denote-grep + "s" 'consult-org-agenda + "C" 'calendar + "c" 'org-capture + "d" 'denote + "r" 'denote-rename-file-date + "R" 'denote-rename-file + "m" 'my-denote-open-metanote + "q" 'org-ql-search) + +;; j for journal +(general-def + :prefix "C-c j" + "o" 'my-denote-journal-open-entry + "n" 'denote-journal-new-or-existing-entry) + +;; m for media +(general-def + :prefix "C-c m" + "n" 'emms-next + "p" 'emms-previous + "b" 'emms-browser + "s" 'emms-start + "q" 'emms-stop + "P" 'emms-pause + "S" 'emms-toggle-single-track + "l" 'emms-playlist-mode-switch-buffer + "d" 'emms-play-directory) + +;; d for dired +(general-def + :prefix "C-c d" + "a" 'dirvish-quick-access + "s" 'dirvish-side + "h" 'dirvish-history-menu + "f" 'dirvish-fd + "F" 'dirvish-fd-switches-menu + "t" 'trashed + "d" 'discomfort) + +;; x for some other command +(general-def + :prefix "C-c x" + "e" 'eshell + "E" 'eat + "p" 'proced + "b" 'benchmark-init/show-durations-tree + "B" 'benchmark-init/show-durations-tabulated + "s" 'syncthing) + +;; scratch buffer +(if *is-mac* + (general-def "C-c <f12>" 'scratch-buffer) + (general-def "C-c <delete>" 'scratch-buffer)) + +;; dired +(general-def (dired-mode-map dirvish-mode-map) + "s" 'dirvish-quicksort + "h" 'dirvish-history-menu + "M-," 'scroll-other-window-down + "M-." 'scroll-other-window + "<mouse-2>" 'emms-play-dired + "C-c m a" 'emms-add-dired + "<down>" 'my-dired-next-line + "C-n" 'my-dired-next-line + "n" 'my-dired-next-line + "b" 'dired-up-directory + "C-b" 'backward-char + "C-f" 'forward-char + "<right>" 'dired-find-file + "<left>" 'dired-up-directory + "C-/" 'dired-undo + "<SPC>" 'my-dirvish-layout-toggle + "C-c C-r" 'dired-rsync) + +(general-def (dired-mode-map dirvish-mode-map) + :prefix "C-c d" + "u" 'dirvish-setup-menu + "r" 'dirvish-renaming-menu + "v" 'dirvish-vc-menu + "m" 'dirvish-mark-menu + "i" 'dirvish-file-info-menu + "y" 'dirvish-yank-menu) + +;; magit +(general-def (magit-mode-map tokei-mode-map) + "C-<tab>" 'my-magit-toggle-parent-section) + +;; sly +(general-def (sly-mode-map sly-editing-mode-map) + "M-p" 'backward-paragraph + "M-n" 'forward-paragraph) + +(general-def sly-prefix-map + "M-p" 'sly-pprint-eval-last-expression + "C-p" 'sly-previous-note + "C-n" 'sly-next-note) + +;; vterm +(general-def vterm-mode-map + "M-]" nil + "C-q" 'vterm-send-next-key) + +;; eat +(general-def (eat-semi-char-mode-map + eat-line-mode-map + eat-char-mode-map + eat-eshell-semi-char-mode-map + eat-eshell-char-mode-map) + "M-[" nil + "M-]" nil) + +;; embark +(general-def embark-file-map + "d" 'consult-directory-externally + "p" 'emms-play-dired) + +(general-def minibuffer-local-map + "C-c C-e" 'embark-export) + +;; completion +(general-def completion-list-mode-map + "M-n" 'minibuffer-next-completion + "M-p" 'minibuffer-previous-completion) + +;; markdown +(general-def markdown-mode-map + "M-p" nil + "M-n" nil) + +;; org-mode +(general-def org-mode-map + "C-<tab>" 'org-cycle-parent-subtree + "M-g i" 'consult-outline + "M-g M-i" 'consult-outline + "C-c t l" 'org-toggle-link-display + "M-{" 'backward-paragraph + "M-}" 'forward-paragraph + "C-," 'crux-duplicate-current-line-or-region + "C-c o l" 'denote-link + "C-c o L" 'denote-org-link-to-heading + "C-c o b" 'my-denote-find-backlink-with-location + "C-c o B" 'my-denote-org-find-backlink-for-heading-with-location + "C-c o t" 'my-org-tree-slide-start) + +;; org-tree-slide-mode +(general-def org-tree-slide-mode-map + "<left>" 'org-tree-slide-move-previous-tree + "<right>" 'org-tree-slide-move-next-tree + "C-c o t" 'my-org-tree-slide-stop + "ESC" 'my-org-tree-slide-stop + "q" 'my-org-tree-slide-stop) + +;; hs-hide-mode +(general-def hs-minor-mode-map + "C-c h" 'hs-toggle-hiding + "C-c H" 'hs-hide-all + "C-c S" 'hs-show-all) + +;; calendar +(general-def calendar-mode-map + "RET" 'denote-journal-calendar-find-file) + +;; ibuffer +(general-def ibuffer-mode-map + "h k" 'my-persp-remove-marked-ibuffers + "h A" 'my-persp-set-marked-ibuffers + "h a" 'my-persp-add-marked-ibuffers) + +;; multiple-cursor +(general-def mc/keymap + "<return>" 'newline) + +;; emms +(general-def emms-playlist-mode-map + "<prior>" 'emms-previous + "<next>" 'emms-next + "C-c C-s" 'emms-history-save) + +;; perspective +(general-def persp-mode-map + "C-c p c" nil + "C-c p d" 'persp-kill + "C-x M-b" 'persp-ibuffer) + +;; info +(general-def Info-mode-map + "M-n" 'forward-paragraph) + +;; diff +(general-def diff-mode-map + "M-o" 'other-window) + +;; discomfort +(general-def discomfort-mode-map + "p" 'previous-line + "P" 'discomfort-poweroff) + +;; eww +(general-def eww-mode-map + "M-n" 'forward-paragraph + "M-p" 'backward-paragraph) + +;; global map with C-c prefix +(general-def + :prefix "C-c" + "c" 'hydra-multiple-cursors/body + "r" 'restart-emacs + "e" 'er/expand-region + "s" 'consult-line + "a" 'org-agenda + "l" 'org-store-link + "k" 'comment-line + "K" 'comment-kill) + +;; global map +(general-def + + ;; god-mode + "M-i" 'god-mode-all + + ;; buffer, file, and window + "<f2>" 'open-init-file + "<mouse-4>" 'previous-buffer + "<mouse-5>" 'next-buffer + "M-[" 'previous-buffer + "M-]" 'next-buffer + "C-x C-b" 'ibuffer-other-window + "C-x K" 'crux-kill-other-buffers + "C-x b" 'consult-buffer + "C-x C-1" 'delete-other-windows + "C-x C-2" 'split-window-below + "C-x C-3" 'split-window-right + "C-x C-0" 'delete-window + + ;; edit + "M-c" 'capitalize-dwim + "M-u" 'upcase-dwim + "M-l" 'downcase-dwim + "C-," 'crux-duplicate-current-line-or-region + "C-<backspace>" 'crux-kill-line-backwards + "M-y" 'consult-yank-from-kill-ring + "C-c <backspace>" 'hungry-delete-backward + "C-c C-<backspace>" 'hungry-delete-forward + "M-P" 'drag-stuff-up + "M-N" 'drag-stuff-down + "M-F" 'drag-stuff-right + "M-B" 'drag-stuff-left + "C-M-SPC" 'er/mark-symbol + "M-@" 'er/mark-word + "C-S-<mouse-1>" 'mc/add-cursor-on-click + + ;; undo + "C-/" 'undo-fu-only-undo + "C-?" 'undo-fu-only-redo + "C-x u" 'vundo + + ;; navigate + "M-p" 'backward-paragraph + "M-n" 'forward-paragraph + "<mouse-2>" 'xref-find-definitions-at-mouse + "C-M-;" 'avy-goto-char + "C-M-'" 'avy-goto-word-1 + "M-g g" 'avy-goto-line + "M-g M-g" 'consult-goto-line + "M-g i" 'consult-imenu + "M-g I" 'consult-imenu-multi + "M-g M-i" 'consult-imenu + + ;; window + "C-M-<left>" 'shrink-window-horizontally + "C-M-<right>" 'enlarge-window-horizontally + "C-M-<down>" 'shrink-window + "C-M-<up>" 'enlarge-window + "M-`" 'popper-toggle + "C-M-=" 'popper-toggle-type-delete-other-window + "M-o" 'other-window + "<f10>" 'esw/swap-two-windows + + ;; other + "C-x r b" 'consult-bookmark + "C-;" 'embark-act) + +(cond + (*is-android* + (general-def + "C-M-w" 'popper-toggle-type-delete-other-window)) + (*is-linux* + (general-def + "M-S-SPC" 'xdg-launcher-run-app)) + (t nil)) + +;; expand region +(setq expand-region-reset-fast-key "r") +(setq expand-region-contract-fast-key "c") + +;; diff changes when saving buffers +(add-to-list 'save-some-buffers-action-alist + (list "d" + (lambda (buffer) (diff-buffer-with-file (buffer-file-name buffer))) + "show diff between the buffer and its file")) + +(provide 'init-kbd) +;;; init-kbd.el ends here diff --git a/lisp/init-org.el b/lisp/init-org.el @@ -0,0 +1,284 @@ +;;; init-org.el --- org-mode config -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +(use-package org + :hook + (org-mode . org-indent-mode) + (org-mode . visual-line-mode) + (org-mode . my-org-electric-pair-fix) + (org-mode . electric-pair-local-mode) + + :init + (setq org-directory + (cond + (*is-windows* "h:/emacs/my-org-note") + (*is-mac* "~/org/my-org-note") + (*is-linux* "~/org/my-org-note") + (*is-android* "~/storage/shared/my-org-note"))) + + :config + (defvar org-hide-space-keywords + '(("\\cc\\( \\)[*/_=~+]\\cc.*?[*/_=~+]" + (0 (prog1 () (add-text-properties (match-beginning 1) (match-end 1) '(invisible t))))) + ("[*/_=~+].*?\\cc[*/_=~+]\\( \\)\\cc" + (0 (prog1 () (add-text-properties (match-beginning 1) (match-end 1) '(invisible t))))))) + (font-lock-add-keywords 'org-mode org-hide-space-keywords 'append) + + (add-to-list 'org-src-lang-modes '("yaml" . yaml-ts)) + (add-to-list 'org-src-lang-modes '("json" . json-ts)) + (add-to-list 'org-src-lang-modes '("toml" . toml-ts)) + + (if *is-windows* + (add-hook 'org-mode-hook 'font-lock-update)) + + (unless *is-windows* + (add-hook 'org-mode 'jinx-mode)) + + (defun my-org-electric-pair-fix () + (setq-local electric-pair-inhibit-predicate + (lambda (char) + (or (eq char ?<) + (electric-pair-default-inhibit char))))) + + ;; log in drawer + (setq org-log-done t + org-log-into-drawer t) + + ;; dont set bookmark + (setq org-bookmark-names-plist nil) + + ;; todo keywords + (setq org-todo-keywords + (quote ((sequence "TODO(t)" "SOMEDAY(S)" "STARTED(s)" "WAITING(w)" "|" "DONE(d!/!)" "CANCELLED(c@/!)") + (sequence "IDKY(i)" "|" "KNOWN(k)" "CANCELLED(c@/!)")))) + + ;; agenda + (setq org-agenda-files `(,(concat org-directory "/20260509T232442==agenda--all-my-todos__org.org"))) + + (setq org-agenda-span 'day) + (setq org-agenda-skip-function-global + '(org-agenda-skip-entry-if 'todo '("COMMENT")))) + +;; optimize line wrapping in tables +(use-package phscroll + :hook + (org-mode . org-phscroll-activate) + :init + (setq org-startup-truncated nil)) + +;; org-babel scheme +(use-package ob-scheme + :demand t + :after org + :straight nil + :config + (add-to-list 'org-babel-load-languages '(scheme . t)) + (org-babel-do-load-languages + 'org-babel-load-languages + org-babel-load-languages)) + +;; denote +(use-package denote + :hook + (after-init . denote-rename-buffer-mode) + (dired-mode . denote-dired-mode) + :init + (setq denote-directory org-directory) + (setq denote-org-store-link-to-heading 'context + denote-prompts '(title signature keywords)) + (setq denote-title-history nil + denote-signature-history + '("note" "project" "fun" "wisdom" "article" "data" "metanote" "agenda" "journal" "archive") + denote-known-keywords + '("emacs") + denote-title-history nil)) + +;; denote-org +(use-package denote-org) + +;; denote-lint +(use-package denote-lint + :straight + (denote-lint :type git + :host github + :repo "Andsy10/denote-lint" + :protocol ssh) + :config + (setq org-link-elisp-confirm-function nil)) + +;; denote-journal +(use-package denote-journal + :hook + (calendar-mode . denote-journal-calendar-mode) + :config + (setq denote-journal-directory (expand-file-name "journal" denote-directory)) + (setq denote-journal-keyword nil) + (setq denote-journal-signature "journal") + (setq denote-journal-keyword "daily")) + +;; denote-explore +(use-package denote-explore) + +;; consult-denote +(use-package consult-denote + :hook + (after-init . consult-denote-mode)) + +;; org-download +(use-package org-download + :after org + :demand t + :hook + (org-mode . org-link-preview-region) + :config + (setq-default org-download-image-dir "./images/" + org-download-heading-lvl nil) + (setq org-download-dragndrop t + org-download-method 'directory + org-image-actual-width nil + org-download-image-html-width 600 + org-return-follows-link t)) + +;; org-ql +(use-package org-ql) + +;; org-super-agenda 配置 +(use-package org-super-agenda + :config + (org-super-agenda-mode)) + +;; agenda +(use-package org-agenda + :straight nil + :hook + (org-agenda-finalize . disable-truncate-lines) + :config + (setq org-agenda-prefix-format '((agenda . " %?-12t% s") + (todo . " ") + (tags . " ") + (search . " "))) + + (setq org-agenda-sorting-strategy + '((agenda time-up scheduled-up deadline-up priority-down category-keep) + (todo priority-down category-keep) + (tags priority-down category-keep) + (search category-keep))) + + (setq org-agenda-custom-commands + '(("qd" "TODO entries sort by closed time" + ((org-ql-block '(closed) + ((org-ql-block-header "Closed TODOs") + (org-super-agenda-groups + '((:auto-ts t))))))) + ("qS" "SOMEDAYs" + ((org-ql-block '(todo "SOMEDAY") + ((org-ql-block-header "SOMEDAYs") + (org-super-agenda-groups + '((:auto-ts t))))))) + ("qs" "STARTEDs" + ((org-ql-block '(todo "STARTED") + ((org-ql-block-header "STARTEDs") + (org-super-agenda-groups + '((:auto-ts t))))))) + ("qt" "TODOs sort by start time" + ((org-ql-block '(todo) + ((org-ql-block-header "TODOs") + (org-super-agenda-groups + '((:auto-ts t))))))) + ("qa" "all TODO entries" + ((org-ql-block '(and (not (done)) (todo)) + ((org-ql-block-header "all TODOs") + (org-super-agenda-groups + '((:name "started" :todo "STARTED") + (:name "waiting" :todo "WAITING") + (:name "priority = A" :priority "A") + (:name "priority = B" :priority "B") + (:name "priority = C" :priority "C") + (:name "other priority" :priority< "C") + (:name "someday" :todo "SOMEDAY") + (:name "I dont know yet" :todo "IDKY")))))))))) + +;; capture +(use-package org-capture + :straight nil + :config + (setq my-org-capture-file (concat org-directory "/20260509T232442==agenda--all-my-todos__org.org")) + (setq org-capture-templates + `(("t" "TODO" entry + (file+headline ,my-org-capture-file "Something to do") + "* TODO %<%m-%d> %?\n%T" :empty-lines 1) + ("s" "STARTED" entry + (file+headline ,my-org-capture-file "Something to do") + "* STARTED %<%m-%d> %?\n%T" :empty-lines 1) + ("S" "SOMEDAY" entry + (file+headline ,my-org-capture-file "Something to do") + "* SOMEDAY %<%m-%d> %?\n%T" :empty-lines 1) + ("i" "IDKY" entry + (file+headline ,my-org-capture-file "Something to know") + "* IDKY %<%m-%d> %?\n%T" :empty-lines 1)))) + +;; hugo +(use-package ox-hugo + :init + (with-eval-after-load 'org-capture + (defun org-hugo-new-subtree-post-capture-template () + "Returns `org-capture' template string for new Hugo post. +See `org-capture-templates' for more information." + (let* ((title (read-from-minibuffer "Post Title: ")) ;Prompt to enter the post title + (fname (org-hugo-slug title))) + (mapconcat #'identity + `( + ,(concat "* TODO " title) + ":PROPERTIES:" + ,(concat ":EXPORT_FILE_NAME: " fname) + ":END:" + "\n\n") ;Place the cursor here finally + "\n"))) + (add-to-list 'org-capture-templates + `("h" ;`org-capture' binding + h + "Hugo post" + entry + ;; It is assumed that below file is present in `org-directory' + ;; and that it has a "Blog Ideas" heading. It can even be a + ;; symlink pointing to the actual location of all-posts.org! + (file+headline ,(if *is-windows* + "h:/emacs/hugo/this-is-my-blog/all-blog.org" + "~/org/hugo/this-is-my-blog/all-blog.org") + "Blog Ideas") + (function org-hugo-new-subtree-post-capture-template))))) + +;; presentation +(use-package org-tree-slide) + +;; Chinese calendar +(use-package cal-china-x + :after calendar + :autoload cal-china-x-setup + :init + (cal-china-x-setup) + :config + (setq calendar-mark-holidays-flag t + cal-china-x-important-holidays cal-china-x-chinese-holidays + cal-china-x-general-holidays '((holiday-lunar 1 15 "元宵节") + (holiday-lunar 7 7 "七夕节") + (holiday-fixed 3 8 "妇女节") + (holiday-fixed 3 12 "植树节") + (holiday-fixed 5 4 "青年节") + (holiday-fixed 6 1 "儿童节") + (holiday-fixed 9 10 "教师节")) + holiday-other-holidays '((holiday-fixed 2 14 "情人节") + (holiday-fixed 4 1 "愚人节") + (holiday-fixed 12 25 "圣诞节") + (holiday-fixed 6 7 "高考") + (holiday-float 5 0 2 "母亲节") + (holiday-float 6 0 3 "父亲节") + (holiday-float 11 4 4 "感恩节")) + calendar-holidays (append cal-china-x-important-holidays + cal-china-x-general-holidays + holiday-other-holidays))) + +(provide 'init-org) +;;; init-org.el ends here diff --git a/lisp/init-package.el b/lisp/init-package.el @@ -0,0 +1,228 @@ +;;; init-package.el --- some other packages -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +;; keycast +(if use-package-always-defer + (use-package keycast)) + +;; display match count for isearch +(use-package anzu + :delight + :hook + (after-init . global-anzu-mode)) + +;; writable grep +(use-package wgrep) + +;; ripgrep +(use-package rg) + +;; hydra +(use-package hydra + :config + ;; multiple-cursors hydra + (defhydra hydra-multiple-cursors () + " + ^Mark^ ^Unmark^ ^Other^ +------------------------------------------------------------------ +_p_ : prev line _P_ : previous _c_ : edit lines +_n_ : next line _N_ : next _._ : pop +_b_ : prev word _q_ : quit +_f_ : next word _i_ : insert numbers +_B_ : prev symbol +_F_ : next symbol +_s_ : in region +_a_ : all dwim +" + ("p" mc/mark-previous-like-this) + ("n" mc/mark-next-like-this) + ("b" mc/mark-previous-like-this-word) + ("f" mc/mark-next-like-this-word) + ("B" mc/mark-previous-like-this-symbol) + ("F" mc/mark-next-like-this-symbol) + ("P" mc/unmark-previous-like-this) + ("N" mc/unmark-next-like-this) + ("a" mc/mark-all-dwim) + ("s" mc/mark-all-in-region) + ("c" mc/edit-lines) + ("i" mc/insert-numbers) + ("." mc/mark-pop) + ("q" nil))) + +;; spell checker +(unless *is-windows* + (use-package jinx + :delight + (jinx-mode " Jinx" jinx) + :bind + ([remap ispell-word] . jinx-correct) + :config + (setq jinx-languages "en_US") + (add-to-list 'jinx-exclude-regexps '(t "\\cc")) + (with-eval-after-load 'jinx + (dolist (range '((#x4E00 . #x9FFF) + (#x3400 . #x4DBF) + (#x3000 . #x303F) + (#xFF00 . #xFFEF) + (#x20000 . #x2A6DF))) + (let ((start (car range)) + (end (cdr range))) + (dotimes (i (- end start)) + (modify-syntax-entry (+ start i) "_" jinx--syntax-table)))))) + + (use-package consult-jinx + :straight + (consult-jinx + :type git + :host github + :repo "Andsy10/consult-jinx" + :protocol ssh))) + +;; terminal emulator +(unless *is-windows* + (use-package eat + :straight + (eat :type git + :host codeberg + :repo "akib/emacs-eat" + :files ("*.el" + ("term" "term/*.el") + "*.texi" + "*.ti" + ("terminfo/e" "terminfo/e/*") + ("terminfo/65" "terminfo/65/*") + ("integration" "integration/*") + (:exclude ".dir-locals.el" "*-tests.el"))) + :hook + (eshell-load . eat-eshell-mode) + (eshell-load . eat-eshell-visual-command-mode) + (eat-mode . toggle-truncate-lines) + :config + (setq eat-term-terminfo-directory eat--terminfo-path))) + +;; wordspace +(use-package perspective + :bind + ("C-x M-b" . persp-list-buffers) + :custom + (persp-mode-prefix-key (kbd "C-c p")) + :hook + (after-init . persp-mode) + :config + (setq persp-switch-to-buffer-behavior 'switch) + (with-eval-after-load 'consult + (consult-customize consult-source-buffer :hidden t :default nil) + (add-to-list 'consult-buffer-sources persp-consult-source)) + (setq switch-to-prev-buffer-skip + (lambda (win buff bury-or-kill) + (or (not (persp-is-current-buffer buff)) + (cl-some (lambda (re) (string-match-p re (buffer-name buff))) + consult-buffer-filter)))) + (setq persp-initial-frame-name "main")) + +;; magit +(use-package magit + :config + (setq magit-bind-magit-project-status nil) + (unless *is-windows* + (setq magit-diff-refine-hunk 'all))) + +;; git-timemachine +(use-package git-timemachine) + +;; ediff +(use-package ediff + :config + (setq ediff-window-setup-function 'ediff-setup-windows-plain + ediff-split-window-function 'split-window-horizontally)) + +;; diff-hl +(use-package diff-hl + :hook + (diff-hl-mode . diff-hl-margin-mode) + (diff-hl-mode . global-diff-hl-show-hunk-mouse-mode) + (diff-hl-mode . diff-hl-flydiff-mode)) + +;; project +(use-package project + :config + (setq project-switch-commands (assq-delete-all 'project-vc-dir project-switch-commands)) + (setq project-switch-commands + (seq-uniq (append project-switch-commands + '((magit-project-status "Magit" ?v) + (eat-project "Eat" ?E) + (project-query-replace-regexp "Query Replace" ?R) + (consult-grep "Grep" ?r) + (consult-project-buffer "Buffers" ?b) + (project-ibuffer "Ibuffer" ?i) + (opencode "OpenCode" ?a)))))) + +(use-package project-ibuffer + :straight + (project-ibuffer :type git + :host github + :repo "Andsy10/project-ibuffer" + :protocol ssh)) + +;; emms +(use-package emms + :commands + (emms-playlist-mode-switch-buffer) + :config + (emms-all) + (setq emms-player-list '(emms-player-vlc) + emms-info-functions '(emms-info-native)) + (emms-history-load)) + +;; tokei +(use-package tokei) + +;; helpful +(use-package helpful + :bind + (([remap describe-function] . helpful-callable) + ([remap describe-command] . helpful-command) + ([remap describe-variable] . helpful-variable) + ([remap describe-key] . helpful-key) + ([remap describe-symbol] . helpful-symbol) + :map emacs-lisp-mode-map + ("C-c C-d C-d" . helpful-at-point) + :map lisp-interaction-mode-map + ("C-c C-d C-d" . helpful-at-point) + :map helpful-mode-map + ("C-x K" . helpful-kill-buffers) + ("r" . remove-hook-at-point))) + +;; typing game +(use-package typit) + +;; guix +(if *is-linux* + (use-package guix)) + +;; process manager +(use-package proced + :straight nil + :custom + (proced-auto-update-flag t) + (proced-goal-attribute nil) + (proced-show-remote-processes t) + (proced-enable-color-flag t) + (proced-format 'custom) + :config + (add-to-list + 'proced-format-alist + '(custom user pid ppid sess tree pcpu pmem rss start time state (args comm))) + (setq proced-low-memory-usage-threshold 0.025 + proced-medium-memory-usage-threshold 0.125)) + +;; syncthing +(use-package syncthing + :hook + (syncthing-mode . disable-truncate-lines)) + +(provide 'init-package) +;;; init-package.el ends here diff --git a/lisp/init-prog.el b/lisp/init-prog.el @@ -0,0 +1,88 @@ +;;; init-prog.el --- programming -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +;; hideshow +(use-package hideshow + :hook + (prog-mode . hs-minor-mode)) + +;; xref +(use-package xref + :autoload xref-show-definitions-completing-read + :init + (when (executable-find "rg") + (setq xref-search-program 'ripgrep)) + + (setq xref-show-definitions-function #'xref-show-definitions-completing-read + xref-show-xrefs-function #'xref-show-definitions-completing-read)) + +;; syntax checking +(use-package flycheck) + +(use-package flycheck-guile + :hook + (scheme-mode . (lambda () + (require 'flycheck-guile)))) + +(use-package consult-flycheck) + +;; tree-sitter +(use-package treesit-auto + :hook + (after-init . global-treesit-auto-mode) + :config + (setq treesit-auto-install 'prompt) + (setq treesit-font-lock-level 4)) + +;; scheme +(use-package geiser + :config + (with-eval-after-load 'geiser + (setq geiser-default-implementation 'guile))) + +(use-package geiser-guile) + +;; common-lisp +(use-package sly + :config + (setq sly-lisp-implementations nil)) + +(use-package lisp-extra-font-lock + :hook + (lisp-mode . lisp-extra-font-lock-mode)) + +;; markdown +(use-package markdown-mode + :bind + (:map markdown-mode-map + ("C-c C-e" . markdown-do)) + :hook + (markdown-mode . visual-line-mode) + :init + (setq markdown-command "multimarkdown" + markdown-fontify-code-blocks-natively t)) + +(use-package edit-indirect) + +;; html +(use-package shr + :config + (setq shr-inhibit-images nil + shr-use-fonts nil)) + +(use-package htmlize) + +;; caddy +(use-package caddyfile-mode + :mode + (("Caddyfile\\'" . caddyfile-mode) + ("caddy\\.conf\\'" . caddyfile-mode))) + +;; some modes +(add-to-list 'auto-mode-alist '("\\.service\\'" . conf-unix-mode)) + +(provide 'init-prog) +;;; init-prog.el ends here diff --git a/lisp/init-segmentation.el b/lisp/init-segmentation.el @@ -0,0 +1,43 @@ +;;; init-segmentation.el --- Chinese word segmentation -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +;; emacs-chinese-word-segmentation +(use-package cns + :straight nil + :hook + (after-init . require-cns) + (after-init . global-cns-mode) + :init + (cond + (*is-windows* + (add-to-list 'load-path "h:/emacs/emacs-chinese-word-segmentation/") + (setq cns-process-type 'shell) + (setq cns-prog "h:/emacs/emacs-chinese-word-segmentation/cnws.exe") + (setq cns-dict-directory "h:/emacs/emacs-chinese-word-segmentation/cppjieba/dict") + (setq cns-process-shell-command + (format "%s %s %s %s %s %s" + cns-prog + (concat (file-name-as-directory cns-dict-directory) "jieba.dict.utf8") + (concat (file-name-as-directory cns-dict-directory) "hmm_model.utf8") + (concat (file-name-as-directory cns-dict-directory) "user.dict.utf8") + (concat (file-name-as-directory cns-dict-directory) "idf.utf8") + (concat (file-name-as-directory cns-dict-directory) "stop_words.utf8")))) + + (t + (add-to-list 'load-path "~/emacs-stuff/emacs-chinese-word-segmentation/") + (setq cns-process-type 'shell) + (setq cns-prog "~/emacs-stuff/emacs-chinese-word-segmentation/cnws") + (setq cns-dict-directory "~/emacs-stuff/emacs-chinese-word-segmentation/cppjieba/dict/"))) + + :config + (defun require-cns () + (require 'cns nil t)) + + (setq cns-recent-segmentation-limit 40) + (define-key cns-mode-map (kbd "C-<backspace>") nil)) + +(provide 'init-segmentation) +;;; init-segmentation.el ends here diff --git a/lisp/init-startup.el b/lisp/init-startup.el @@ -0,0 +1,103 @@ +;;; init-startup.el --- startup settings -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +;; coding system +(set-selection-coding-system 'utf-8) +(when (fboundp 'set-charset-priority) + (set-charset-priority 'unicode)) +(set-default-coding-systems 'utf-8) +(set-buffer-file-coding-system 'utf-8) +(set-clipboard-coding-system 'utf-8) +(set-file-name-coding-system 'utf-8) +(set-keyboard-coding-system 'utf-8) +(set-next-selection-coding-system 'utf-8) +(set-selection-coding-system 'utf-8) +(set-terminal-coding-system 'utf-8) +(setq locale-coding-system 'utf-8) +(setq system-time-locale "C") + +;; fullscreen +(cond + (*is-mac* + (set-frame-parameter nil 'fullscreen 'fullscreen) + (toggle-frame-fullscreen) + (global-unset-key (kbd "<f12>")) + (global-set-key (kbd "<f12>") 'toggle-frame-fullscreen)) + (*is-windows* + (toggle-frame-maximized)) + (t nil)) + +;; backup and autosave +(setq backup-directory-alist + `((".*" . ,(expand-file-name "backup/" user-emacs-directory))) + backup-by-copying t + delete-old-versions t + kept-new-versions 6 + kept-old-versions 2 + version-control t) +(setq auto-save-file-name-transforms + `((".*" ,(expand-file-name "auto-save-list/" user-emacs-directory) t))) + +;; horizontal scroll +(put 'scroll-left 'disabled nil) + +;; disable lockfiles +(setq create-lockfiles nil) + +;; disable ring bell +(setq ring-bell-function 'ignore) + +;; package manager load path +(cond + (*is-windows* + (add-to-list 'exec-path (expand-file-name "H/appppppppppp/scoop/apps/")) + (setenv "PATH" (concat (expand-file-name "H/appppppppppp/scoop/apps/") ";" (getenv "PATH")))) + (*is-mac* + (add-to-list 'exec-path (expand-file-name "/opt/homebrew/bin/")) + (setenv "PATH" (concat (expand-file-name "/opt/homebrew/bin/") ":" (getenv "PATH")))) + (*is-linux* + (add-to-list 'exec-path (expand-file-name "~/.guix-home/profile/bin/")) + (setenv "PATH" (concat (expand-file-name "~/.guix-home/profile/bin/") ":" (getenv "PATH"))))) + +;; scratch buffer +(setq initial-scratch-message + "") + +(defun my-scratch-set-mode (&rest _) + (when (eq major-mode 'fundamental-mode) + (funcall initial-major-mode))) + +(advice-add 'scratch-buffer :after #'my-scratch-set-mode) + +;; frame title +(setq-default frame-title-format '("%b - Emacs")) + +;; native compile warning +(setq native-comp-async-warnings-errors-kind 'silent) + +;; short answer +(if (boundp 'use-short-answers) + (setq use-short-answers t) + (fset 'yes-or-no-p 'y-or-n-p)) + +;; trash +(setq delete-by-moving-to-trash t) + +;; optimize word wrapping +(setq word-wrap-by-category t) + +;; don't insert tabs +(setq-default indent-tabs-mode nil) + +;; modifier keys on mac +(when *is-mac* + (setq mac-command-modifier 'meta) + (setq mac-option-modifier 'super) + (setq mac-pass-control-to-system nil) + (setq mac-pass-command-to-system nil)) + +(provide 'init-startup) +;;; init-startup.el ends here diff --git a/lisp/init-terminal-kbd.el b/lisp/init-terminal-kbd.el @@ -0,0 +1,82 @@ +;;; init-terminal-kbd.el --- keybindings -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +;; general +(use-package general) + +(defun open-init-file() + "Open user's init.el file in ~/.emacs.d ." + (interactive) + (find-file "~/.emacs.d/init.el")) + +;; scratch buffer +(if *is-mac* + (general-def "C-c <f12>" 'scratch-buffer) + (general-def "C-c <delete>" 'scratch-buffer) + (general-def "C-c <deletechar>" 'scratch-buffer)) + +;; diff +(general-def diff-mode-map + "M-o" 'other-window) + +;; dired +(general-def dired-mode-map + "b" 'dired-up-directory) + +;; global map with C-c prefix +(general-def + :prefix "C-c" + "e" 'er/expand-region + "k" 'comment-line + "f r" 'recentf + "i" 'imenu) + +;; global map +(general-def + + ;; buffer, file, and window + "<f2>" 'open-init-file + "C-x C-b" 'ibuffer-other-window + "C-x K" 'crux-kill-other-buffers + + ;; edit + "M-c" 'capitalize-dwim + "M-u" 'upcase-dwim + "M-l" 'downcase-dwim + "C-," 'crux-duplicate-current-line-or-region + "C-k" 'crux-smart-kill-line + "C-<backspace>" 'crux-kill-line-backwards + "M-y" 'yank-from-kill-ring + "C-c DEL" 'hungry-delete-backward + "C-c C-DEL" 'hungry-delete-forward + "M-P" 'drag-stuff-up + "M-N" 'drag-stuff-down + "C-M-@" 'er/mark-symbol + "M-@" 'er/mark-word + "C-M-h" 'backward-kill-sexp + + ;; undo + "C-/" 'undo + "C-M-_" 'undo-redo + + ;; navigate + "M-p" 'backward-paragraph + "M-n" 'forward-paragraph + + ;; window + "M-<left>" 'shrink-window-horizontally + "M-<right>" 'enlarge-window-horizontally + "M-<down>" 'shrink-window + "M-<up>" 'enlarge-window + "M-o" 'other-window) + +(add-to-list 'save-some-buffers-action-alist + (list "d" + (lambda (buffer) (diff-buffer-with-file (buffer-file-name buffer))) + "show diff between the buffer and its file")) + +(provide 'init-terminal-kbd) +;;; init-terminal-kbd.el ends here diff --git a/lisp/init-terminal-package.el b/lisp/init-terminal-package.el @@ -0,0 +1,93 @@ +;;; init-terminal-package.el --- major packages -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +(use-package gcmh + :delight + :hook + (emacs-startup . gcmh-mode) + :init + (setq gcmh-idle-delay 'auto + gcmh-auto-idle-delay-factor 10 + gcmh-high-cons-threshold #x4000000)) + +(use-package benchmark-init + :init + (benchmark-init/activate) + :hook + (after-init . benchmark-init/deactivate)) + +(use-package recentf + :hook + (after-init . recentf-mode) + :init + (setq recentf-max-saved-items 30) + :config + (if *is-android* + (add-to-list 'recentf-exclude "~/storage/shared/my-org-note/journal/.*\\.org\\'") + (add-to-list 'recentf-exclude "~/org/my-org-note/journal/.*\\.org\\'") + (add-to-list 'recentf-exclude "~/org/my-org-note/20260509T232442==agenda--all-my-todos__org\\.org"))) + +(use-package savehist + :hook + (after-init . savehist-mode) + :init + (setq enable-recursive-minibuffers t + history-length 50 + savehist-additional-variables '(mark-ring + global-mark-ring + search-ring + regexp-search-ring + extended-command-history) + savehist-autosave-interval 300)) + +(use-package saveplace + :hook + (after-init . save-place-mode)) + +(use-package restart-emacs) + +(use-package autorevert + :delight + :hook + (after-init . global-auto-revert-mode)) + +(use-package crux) + +(use-package hungry-delete) + +(use-package drag-stuff) + +(use-package expand-region + :commands + (er/mark-symbol er/mark-word) + :config + (setq expand-region-smart-cursor t)) + +(use-package savehist + :init + (setq enable-recursive-minibuffers t + history-length 50 + savehist-additional-variables '(mark-ring + global-mark-ring + search-ring + regexp-search-ring + extended-command-history) + savehist-autosave-interval 300) + (savehist-mode)) + +(use-package saveplace + :init + (save-place-mode)) + +(use-package icomplete + :init + (fido-mode) + :config + (keymap-unset minibuffer-local-completion-map "TAB") + (keymap-set minibuffer-local-completion-map "TAB" 'icomplete-force-complete)) + +(provide 'init-terminal-package) +;;; init-terminal-package.el ends here diff --git a/lisp/init-terminal-startup.el b/lisp/init-terminal-startup.el @@ -0,0 +1,89 @@ +;;; init-const.el --- constant and system stuff -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +(global-display-line-numbers-mode 1) + +(defconst *is-mac* (eq system-type 'darwin)) +(defconst *is-linux* (eq system-type 'gnu/linux)) +(defconst *is-windows* (or (eq system-type 'ms-dos) (eq system-type 'windows-nt))) +(defconst *is-android* (if (getenv "TERMUX_VERSION") t nil)) + +(set-selection-coding-system 'utf-8) +(when (fboundp 'set-charset-priority) + (set-charset-priority 'unicode)) +(set-default-coding-systems 'utf-8) +(set-buffer-file-coding-system 'utf-8) +(set-clipboard-coding-system 'utf-8) +(set-file-name-coding-system 'utf-8) +(set-keyboard-coding-system 'utf-8) +(set-next-selection-coding-system 'utf-8) +(set-selection-coding-system 'utf-8) +(set-terminal-coding-system 'utf-8) +(setq locale-coding-system 'utf-8) +(setq system-time-locale "C") + +(setq backup-directory-alist + `((".*" . ,(expand-file-name "backup/" user-emacs-directory))) + backup-by-copying t + delete-old-versions t + kept-new-versions 6 + kept-old-versions 2 + version-control t) + +(setq auto-save-file-name-transforms + `((".*" ,(expand-file-name "auto-save-list/" user-emacs-directory) t))) + +(put 'scroll-left 'disabled nil) + +(setq create-lockfiles nil) + +(setq ring-bell-function 'ignore) + +(cond + (*is-windows* + (add-to-list 'exec-path (expand-file-name "H/appppppppppp/scoop/apps/")) + (setenv "PATH" (concat (expand-file-name "H/appppppppppp/scoop/apps/") ";" (getenv "PATH")))) + (*is-mac* + (add-to-list 'exec-path (expand-file-name "/opt/homebrew/bin/")) + (setenv "PATH" (concat (expand-file-name "/opt/homebrew/bin/") ":" (getenv "PATH")))) + (*is-linux* + (add-to-list 'exec-path (expand-file-name "~/.guix-home/profile/bin/")) + (setenv "PATH" (concat (expand-file-name "~/.guix-home/profile/bin/") ":" (getenv "PATH"))))) + +(global-auto-revert-mode 1) + +(when (display-graphic-p) + (recentf-mode) + (setq recentf-max-saved-items 30)) + +(delete-selection-mode) + +(setq initial-scratch-message + "") + +(setq native-comp-async-warnings-errors-kind 'silent) + +(if (boundp 'use-short-answers) + (setq use-short-answers t) + (fset 'yes-or-no-p 'y-or-n-p)) + +(setq delete-by-moving-to-trash t) + +(setq xref-search-program + (cond + ((or (executable-find "ripgrep") + (executable-find "rg")) + 'ripgrep) + (t 'grep))) + +(setq word-wrap-by-category t) + +(setq-default indent-tabs-mode nil) + +(setq kill-whole-line t) + +(provide 'init-terminal-startup) +;;; init-terminal-statup.el ends here diff --git a/lisp/init-terminal-ui.el b/lisp/init-terminal-ui.el @@ -0,0 +1,82 @@ +;;; init-terminal-ui.el --- ui and other style customization cofig -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +;; display file size in mode line +(size-indication-mode t) + +;; display column number in mode line +(column-number-mode t) + +;; highlight current line +(global-hl-line-mode t) + +;; theme +(if (>= (display-color-cells) 16777216) + (progn + (defvar base03 "#062624") + (defvar base02 "#0c2b29") + (defvar base01 "#4d6967") + (defvar base00 "#728e8c") + (defvar base1 "#7f9b99") + (defvar cyan "#01928d") + (defvar blue "#2570cd") + (defvar green "#3a9c36") + (defvar magenta "#d33682") + (defvar yellow "#a87c04") + (defvar orange "#c24713") + (defvar red "#ce2825") + + (custom-set-faces + `(default ((t (:foreground ,base00 :background ,base03)))) + `(cursor ((t (:inverse t)))) + `(region ((t (:exdend t :foreground ,base03 :background ,base00)))) + `(shadow ((t (:foreground ,base01)))) + `(error ((t (:foreground ,orange)))) + `(warning ((t (:foreground ,yellow)))) + `(font-lock-builtin-face ((t (:foreground ,base00 :weight bold :slant normal)))) + `(font-lock-comment-face ((t (:foreground ,base01)))) + `(font-lock-keyword-face ((t (:foreground ,cyan :weight bold)))) + `(font-lock-variable-name-face ((t (:foreground ,blue)))) + `(font-lock-constant-face ((t (:foreground ,blue :weight bold)))) + `(font-lock-string-face ((t (:foreground ,green)))) + `(font-lock-type-face ((t (:foreground ,yellow)))) + `(font-lock-function-name-face ((t (:foreground ,blue)))) + `(hl-line ((t (:background ,base02 :extend t)))) + `(show-paren-match ((t (:foreground ,magenta :weight bold)))) + `(show-paren-mismatch ((t (:foreground ,base03 :background ,red)))) + `(icomplete-first-match ((t (:foreground ,yellow :weight bold)))) + `(completions-common-part ((t (:foreground ,blue)))) + `(minibuffer-prompt ((t (:foreground ,base01 :weight bold)))) + `(line-number ((t (:foreground ,base01 :weight extra-light)))) + `(button ((t (:foreground ,base00 :underline t)))) + `(mode-line ((t (:background ,base00 :foreground ,base03)))) + `(mode-line-inactive ((t (:background ,base02 :foreground ,base00)))) + `(dired-header ((t (:foreground ,green)))) + `(dired-directory ((t (:foreground ,blue)))) + `(dired-ignored ((t (:foreground ,base01)))) + `(isearch ((t (:background ,magenta :foreground ,base03)))) + `(lazy-highlight ((t (:background ,yellow :foreground ,base03)))) + `(isearch-fail ((t (:foreground ,red)))) + `(org-block ((t (:inhert default)))) + `(org-document-title ((t (:inhert default :weight bold)))) + `(org-document-info ((t (:inhert org-document-title)))) + `(eshell-prompt ((t (:foreground ,yellow :weight bold)))) + `(diff-header ((t (:foreground ,base00 :background ,base02)))) + `(diff-file-header ((t (:inherit: diff-header :weight bold)))) + `(diff-hunk-header ((t (:foreground "#c1a059" :background "#253224")))) + `(diff-added ((t (:foreground "#73b971" :background "#103628")))) + `(diff-refine-added ((t (:foreground "#8cc78d" :background "#1d522e")))) + `(diff-removed ((t (:foreground "#e17360" :background "#2d2c25")))) + `(diff-refine-removed ((t (:foreground "#e7917f" :background "#5c3225")))) + `(xref-file-header ((t (:foreground ,base01)))) + `(xref-line-number ((t (:foreground ,green)))) + `(match ((t (:foreground ,base1 :background ,base02 :weight bold)))))) + + (progn + (global-hl-line-mode nil))) + +(provide 'init-terminal-ui) +;;; init-terminal-ui.el ends here diff --git a/lisp/init-ui.el b/lisp/init-ui.el @@ -0,0 +1,113 @@ +;;; init-ui.el --- ui and other style customization cofig -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +;; custom-theme-load-path +(add-to-list 'custom-theme-load-path "~/.emacs.d/lisp/") + +;; trust all themes +(setq custom-safe-themes t) + +;; solarized +(use-package solarized-theme + :straight + (solarized-emacs + :fork + (:type git :host github :repo "Andsy10/solarized-emacs" :protocol ssh)) + :init + (if (and (daemonp) (not *is-android*)) + (add-hook 'after-make-frame-functions + (lambda (frame) + (with-selected-frame frame + (load-theme 'my-dark t)))) + (if *is-android* + (load-theme 'my-light t) + (load-theme 'my-dark t)))) + +;; line numbers +(use-package display-line-numbers + :hook + (after-init . global-display-line-numbers-mode) + :config + (setq display-line-numbers-type '2 + display-line-numbers-grow-only t + display-line-numbers-width-start 4)) + +;; resize margins +(use-package olivetti + :delight + :hook + (org-mode . olivetti-mode) + (olivetti-mode . (lambda () (display-line-numbers-mode -1))) + :init + (setq olivetti-body-width 85)) + +;; rainbow mode +(use-package rainbow-mode) + +;; rainbow-delimiters +(use-package rainbow-delimiters) + +;; some themes +(use-package naysayer-theme) +(use-package ef-themes) + +(if *is-android* + (use-package simple-modeline + :hook + (after-init . simple-modeline-mode))) + +;; eshell-syntax-highlighting +(use-package eshell-syntax-highlighting + :hook + (eshell-mode . eshell-syntax-highlighting-global-mode)) + +;; indent-bars +(use-package indent-bars + :custom + (indent-bars-color '(font-lock-comment-face :face-bg nil :blend 0.4)) + (indent-bars-highlight-current-depth '(:face default :blend 0.4)) + (indent-bars-pattern ".") + (indent-bars-width-frac 0.1) + (indent-bars-pad-frac 0.1) + (indent-bars-color-by-depth nil) + (indent-bars-no-descend-string t) + (indent-bars-prefer-character t)) + +;; highlight current line +(use-package hl-line + :hook + (after-init . global-hl-line-mode)) + +;; display time in mode line +(unless *is-android* + (use-package time + :hook + (persp-mode . display-time-mode) + :config + (setq display-time-default-load-average nil + display-time-string-forms + '((propertize + (concat + (propertize (format-time-string " %I:%M") 'face 'display-time-date-and-time) + (propertize (format-time-string "-%p") 'face 'font-lock-comment-face)) + 'help-echo (format-time-string "%A, %B %d, %Y")))))) + +;; easier to setup fonts +(use-package cnfonts + :hook + (after-init . cnfonts-mode) + :init + (setq cnfonts-personal-fontnames + '(("Sarasa Fixed TC") ;English + ("Sarasa Fixed TC") ;Chinese + nil ;ext-B + nil ;symbol + nil)) ;what's this + :config + (cnfonts--select-profile "profile1")) + +(provide 'init-ui) +;;; init-ui.el ends here diff --git a/lisp/init-window.el b/lisp/init-window.el @@ -0,0 +1,135 @@ +;;; init-window.el --- windows manage packages -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +(use-package window + :straight nil + :config + (setq switch-to-buffer-obey-display-actions t)) + +(use-package popper + :defines + popper-echo-dispatch-actions + :commands + popper-group-by-directory + :hook + (after-init . popper-mode) + + :init + (setq popper-reference-buffers + '("\\*Messages\\*" + "Output\\*$" "\\*Pp Eval Output\\*$" + "\\*Compile-Log\\*" + "\\*Completions\\*" + "\\*Warnings\\*" + "\\*Flymake diagnostics.*\\*" + "\\*Async Shell Command\\*" + "\\*Apropos\\*" + "\\*Backtrace\\*" + "\\*prodigy\\*" + "\\*Calendar\\*" + "\\*Holidays\\*" + "\\*Embark Actions\\*" + "\\*Finder\\*" + "\\*Kill Ring\\*" + "\\*Embark Export:.*\\*" + "\\*Edit Annotation.*\\*" + "\\*Flutter\\*" + "\\*Ibuffer\\*" + "^\\*Finder-" + "Buffers\\*$" + "^\\*Geiser" + "\\*gptel-Kimi-Code\\*" + "\\*gptel-agent:.*\\*" + "^\\*OpenCode Sessions" + "^\\*sly" + "^magit" + "\\*discomfort\\*" + "\\*eww bookmarks\\*" + "\\*eww history\\*" + "\\*Proced\\*" + bookmark-bmenu-mode + lsp-bridge-ref-mode + comint-mode + compilation-mode + help-mode helpful-mode + tabulated-list-mode + Buffer-menu-mode + occur-mode + gnus-article-mode devdocs-mode + grep-mode occur-mode rg-mode deadgrep-mode ag-mode pt-mode + ivy-occur-mode ivy-occur-grep-mode + process-menu-mode list-environment-mode cargo-process-mode + youdao-dictionary-mode osx-dictionary-mode fanyi-mode + gptel-mode + ibuffer-mode + + "^\\*eshell.*\\*.*$" eshell-mode + ".*eshell\\*$" + "^\\*shell.*\\*.*$" shell-mode + "^\\*terminal.*\\*.*$" term-mode + "^\\*vterm.*\\*.*$" vterm-mode + "^\\*eat.*\\*.*$" eat-mode + + "\\*DAP Templates\\*$" dap-server-log-mode + "\\*ELP Profiling Restuls\\*" profiler-report-mode + "\\*Flycheck errors\\*$" " \\*Flycheck checker\\*$" + "\\*Paradox Report\\*$" "\\*package update results\\*$" "\\*Package-Lint\\*$" + "\\*[Wo]*Man.*\\*$" + "\\*ert\\*$" overseer-buffer-mode + "\\*gud-debug\\*$" + "\\*lsp-help\\*$" "\\*lsp session\\*$" + "\\*quickrun\\*$" + "\\*tldr\\*$" + "\\*vc-.*\\*$" + "\\*eldoc\\*" + "^\\*elfeed-entry\\*$" + "^\\*macro expansion\\**" + + "\\*Agenda Commands\\*" "\\*Org Select\\*" "\\*Capture\\*" "^CAPTURE-.*\\.org*" "^CAPTURE-" "\\*Org Note\\*" + "\\*Gofmt Errors\\*$" "\\*Go Test\\*$" godoc-mode + "\\*docker-containers\\*" "\\*docker-images\\*" "\\*docker-networks\\*" "\\*docker-volumes\\*" + "\\*prolog\\*" inferior-python-mode inf-ruby-mode swift-repl-mode + "\\*rustfmt\\*$" rustic-compilation-mode rustic-cargo-clippy-mode + rustic-cargo-outdated-mode rustic-cargo-test-mode + + "^\\*\\[D\\] FILE backlinks for" "^\\*Denote HEADING backlinks for")) + + (when (display-grayscale-p) + (setq popper-mode-line + '("[POP]"))) + (setq popper-echo-dispatch-actions t) + (setq popper-group-function nil) + + :config + (popper-echo-mode 1) + + (with-no-warnings + (defun my-popper-fit-window-height (win) + "Determine the height of popup window WIN by fitting it to the buffer's content." + (fit-window-to-buffer + win + (floor (frame-height) 3) + (floor (frame-height) 3))) + (setq popper-window-height #'my-popper-fit-window-height) + + (defun popper-close-window-hack (&rest _) + "Close popper window via `C-g'." + ;; `C-g' can deactivate region + (when (and (called-interactively-p 'interactive) + (not (region-active-p)) + popper-open-popup-alist) + (let ((window (caar popper-open-popup-alist))) + (when (window-live-p window) + (delete-window window))))) + (advice-add #'keyboard-quit :before #'popper-close-window-hack))) + +;; windmove +(use-package windmove + :hook + (after-init . windmove-swap-states-default-keybindings)) + +(provide 'init-window) +;;; init-window.el ends here diff --git a/lisp/my-dark-theme.el b/lisp/my-dark-theme.el @@ -0,0 +1,148 @@ +;;; my-dark-theme.el --- Dark Theme -*- lexical-binding: t -*- + +;;; Commentary: +;; A green dark theme base on solarized-theme + +;;; Code: + +(require 'solarized) +(require 'my-palette) +(eval-when-compile + (require 'solarized-palettes)) + +(deftheme my-dark "A dark theme using Solarized framework.") + +(solarized-with-color-variables-with-palette + 'dark + 'my-dark + my-dark-core-palette + '((custom-theme-set-faces + theme-name + + `(font-lock-keyword-face ((,class (:foreground ,cyan :weight bold)))) + `(font-lock-doc-face ((,class (:foreground ,green :slant normal)))) + `(font-lock-string-face ((,class (:foreground ,green)))) + + `(italic ((,class (:slant italic)))) + `(line-number ((,class (:foreground ,base01 :weight light)))) + `(button ((,class (:foreground ,yellow :underline t)))) + + `(mode-line ((,class (:foreground ,base0 :background ,base02)))) + `(mode-line-inactive ((,class (:foreground ,base01 :background ,base03)))) + `(display-time-date-and-time ((,class (:foreground ,base1 :bold t)))) + + `(org-level-1 ((,class (:foreground ,orange :height 1.0 :weight normal)))) + `(org-level-2 ((,class (:foreground ,blue :height 1.0 :weight normal)))) + `(org-level-3 ((,class (:foreground ,green :height 1.0 :weight normal)))) + `(org-level-4 ((,class (:foreground ,yellow :height 1.0 :weight normal)))) + `(org-level-5 ((,class (:foreground ,cyan :height 1.0 :weight normal)))) + `(org-level-6 ((,class (:foreground ,green :height 1.0 :weight normal)))) + `(org-level-7 ((,class (:foreground ,orange :height 1.0 :weight normal)))) + `(org-level-8 ((,class (:foreground ,blue :height 1.0 :weight normal)))) + `(org-document-title ((,class (:foreground ,base0 :height 1.0 :weight bold)))) + `(org-done ((,class (:foreground ,green :weight bold)))) + `(org-headline-done ((,class (:foreground ,green)))) + `(org-block-begin-line ((,class (:foreground ,base01 :slant italic)))) + `(org-block-end-line ((,class (:foreground ,base01 :slant italic)))) + `(org-priority ((,class (:foreground ,green :weight bold)))) + `(org-checkbox ((,class (:foreground ,base0 :weight bold)))) + `(org-dispatcher-highlight ((,class (:inherit diff-hunk-header :weight bold)))) + + `(calendar-month-header ((,class (:foreground ,base0 :weight bold)))) + `(holiday ((,class (:underline (:style line :color ,yellow))))) + `(cal-china-x-important-holiday-face ((,class (:underline (:style line :color ,red))))) + `(cal-china-x-general-holiday-face ((,class (:underline (:style line :color ,yellow))))) + + `(denote-journal-calendar ((,class (:foreground ,cyan :slant italic)))) + `(denote-faces-keywords ((,class (:foreground ,cyan)))) + + `(markdown-header-face-1 ((,class (:foreground ,orange :height 1.0 :weight normal)))) + `(markdown-header-face-2 ((,class (:foreground ,blue :height 1.0 :weight normal)))) + `(markdown-header-face-3 ((,class (:foreground ,green :height 1.0 :weight normal)))) + `(markdown-header-face-4 ((,class (:foreground ,yellow :height 1.0 :weight normal)))) + `(markdown-header-face-5 ((,class (:foreground ,cyan :height 1.0 :weight normal)))) + `(markdown-header-face-6 ((,class (:foreground ,green :height 1.0 :weight normal)))) + `(markdown-code-face ((,class (:foreground ,base0)))) + `(markdown-table-face ((,class (:foreground ,green)))) + + `(dashboard-footer-face ((,class (:foreground ,blue)))) + `(dashboard-text-banner ((,class (:foreground ,green)))) + `(dashboard-heading ((,class (:foreground ,green :weight bold)))) + + `(dired-broken-symlink ((,class (:inherit dired-symlink :foreground ,orange)))) + `(dired-header ((,class (:foreground ,green)))) + `(dirvish-file-time ((,class (:foreground ,base01)))) + `(dirvish-free-space ((,class (:foreground ,green)))) + `(dired-async-mode-message ((,class (:foreground ,red)))) + `(dired-async-message ((,class (:foreground ,yellow)))) + + `(diff-hunk-header ((,class (:foreground ,yellow-1fg :background ,yellow-1bg)))) + + `(consult-file ((,class (:foreground ,green)))) + `(consult-notes-name ((,class (:foreground ,base01)))) + `(consult-notes-time ((,class (:foreground ,base01)))) + `(consult-notes-size ((,class (:foreground ,base01)))) + + `(vertico-current ((,class (:background ,base02 :extend t :underline nil)))) + + `(transient-key-stay ((,class (:foreground ,cyan :inherit transient-key)))) + `(transient-key-return ((,class (:foreground ,violet :inherit transient-key)))) + `(transient-key-exit ((,class (:foreground ,blue :inherit transient-key)))) + `(transient-key-stack ((,class (:foreground ,magenta :inherit transient-key)))) + `(transient-key-recurse ((,class (:foreground ,blue :inherit transient-key)))) + `(transient-key-noop ((,class (:foreground ,base01 :inherit transient-key)))) + + `(geiser-font-lock-repl-output ((,class (:foreground ,green)))) + `(geiser-font-lock-doc-link ((,class (:foreground ,blue :underline t)))) + `(geiser-font-lock-error-link ((,class (:foreground ,orange :underline t)))) + + `(lisp-extra-font-lock-backquote ((,class (:inherit font-lock-type-face)))) + + `(vundo-saved ((,class (:foreground ,green)))) + `(vundo-last-saved ((,class (:foreground ,green :weight bold)))) + `(vundo-highlight ((,class (:foreground ,cyan :weight bold)))) + `(vundo-node ((,class (:foreground ,base01)))) + `(vundo-stem ((,class (:foreground ,base01)))) + + `(jinx-misspelled ((,class (:underline (:style line :color ,yellow))))) + + `(keycast-key ((,class (:foreground ,green :weight bold)))) + + `(emms-playlist-track-face ((,class (:foreground ,cyan)))) + `(emms-playlist-selected-face ((,class (:foreground ,blue :weight bold)))) + + `(proced-pid ((,class (:foreground ,violet)))) + `(proced-session-leader-pid ((,class (:inherit proced-pid :underline t)))) + `(proced-ppid ((,class (:foreground ,blue)))) + `(proced-sess ((,class (:inherit proced-ppid)))) + `(proced-emacs-pid ((,class (:foreground ,magenta)))) + `(proced-memory-low-usage ((,class (:foreground ,green)))) + `(proced-memory-medium-usage ((,class (:foreground ,yellow)))) + `(proced-memory-high-usage ((,class (:foreground ,red)))) + `(proced-executable ((,class (:foreground ,cyan)))) + `(proced-run-status-code ((,class (:foreground ,green)))) + `(proced-interruptible-sleep-status-code ((,class (:foreground ,base01)))) + `(proced-uninterruptible-sleep-status-code ((,class (:foreground ,red)))) + `(proced-time-colon ((,class (:foreground ,base01)))) + `(proced-cpu ((,class (:foreground ,base0)))) + `(proced-mem ((,class (:foreground ,base0)))) + + `(syncthing-bold ((,class (:inherit bold)))) + `(syncthing-italic ((,class (:inherit italic)))) + `(syncthing-my-id ((,class (:foreground ,blue :weight bold)))) + `(syncthing-rate-upload ((,class (:foreground ,green)))) + `(syncthing-rate-download ((,class (:foreground ,blue :weight bold)))) + `(syncthing-uptime ((,class (:foreground ,magenta :wegiht bold)))) + `(syncthing-count-discovery ((,class (:foreground ,blue :weight bold)))) + `(syncthing-count-listeners ((,class (:foreground ,green :weight bold)))) + `(syncthing-count-local-bytes ((,class (:foreground ,cyan :weight bold)))) + `(syncthing-count-local-files ((,class (:inherit default :weight bold)))) + `(syncthing-count-local-folders ((,class (:foreground ,yellow :weight bold)))) + `(syncthing-progress-100 ((,class (:foreground ,green)))) + `(syncthing-progress-75 ((,class (:foreground ,cyan)))) + `(syncthing-progress-50 ((,class (:foreground ,yellow)))) + `(syncthing-progress-25 ((,class (:foreground ,orange)))) + `(syncthing-progress-0 ((,class (:foreground ,red))))))) + +(provide-theme 'my-dark) +;;; my-dark-theme.el ends here diff --git a/lisp/my-light-theme.el b/lisp/my-light-theme.el @@ -0,0 +1,148 @@ +;;; my-light-theme.el --- Light Theme -*- lexical-binding: t -*- + +;;; Commentary: +;; A green light theme base on solarized-theme + +;;; Code: + +(require 'solarized) +(require 'my-palette) +(eval-when-compile + (require 'solarized-palettes)) + +(deftheme my-light "A light theme using Solarized framework.") + +(solarized-with-color-variables-with-palette + 'light + 'my-light + my-light-core-palette + '((custom-theme-set-faces + theme-name + + `(font-lock-keyword-face ((,class (:foreground ,cyan :weight bold)))) + `(font-lock-doc-face ((,class (:foreground ,green :slant normal)))) + `(font-lock-string-face ((,class (:foreground ,green)))) + + `(italic ((,class (:slant italic)))) + `(line-number ((,class (:foreground ,base01 :weight light)))) + `(button ((,class (:foreground ,yellow :underline t)))) + + `(mode-line ((,class (:foreground ,base0 :background ,base02)))) + `(mode-line-inactive ((,class (:foreground ,base01 :background ,base03)))) + `(display-time-date-and-time ((,class (:foreground ,base1 :bold t)))) + + `(org-level-1 ((,class (:foreground ,orange :height 1.0 :weight normal)))) + `(org-level-2 ((,class (:foreground ,blue :height 1.0 :weight normal)))) + `(org-level-3 ((,class (:foreground ,green :height 1.0 :weight normal)))) + `(org-level-4 ((,class (:foreground ,yellow :height 1.0 :weight normal)))) + `(org-level-5 ((,class (:foreground ,cyan :height 1.0 :weight normal)))) + `(org-level-6 ((,class (:foreground ,green :height 1.0 :weight normal)))) + `(org-level-7 ((,class (:foreground ,orange :height 1.0 :weight normal)))) + `(org-level-8 ((,class (:foreground ,blue :height 1.0 :weight normal)))) + `(org-document-title ((,class (:foreground ,base0 :height 1.0 :weight bold)))) + `(org-done ((,class (:foreground ,green :weight bold)))) + `(org-headline-done ((,class (:foreground ,green)))) + `(org-block-begin-line ((,class (:foreground ,base01 :slant italic)))) + `(org-block-end-line ((,class (:foreground ,base01 :slant italic)))) + `(org-priority ((,class (:foreground ,green :weight bold)))) + `(org-checkbox ((,class (:foreground ,base0 :weight bold)))) + `(org-dispatcher-highlight ((,class (:inherit diff-hunk-header :weight bold)))) + + `(calendar-month-header ((,class (:foreground ,base0 :weight bold)))) + `(holiday ((,class (:underline (:style line :color ,yellow))))) + `(cal-china-x-important-holiday-face ((,class (:underline (:style line :color ,red))))) + `(cal-china-x-general-holiday-face ((,class (:underline (:style line :color ,yellow))))) + + `(denote-journal-calendar ((,class (:foreground ,cyan :slant italic)))) + `(denote-faces-keywords ((,class (:foreground ,cyan)))) + + `(markdown-header-face-1 ((,class (:foreground ,orange :height 1.0 :weight normal)))) + `(markdown-header-face-2 ((,class (:foreground ,blue :height 1.0 :weight normal)))) + `(markdown-header-face-3 ((,class (:foreground ,green :height 1.0 :weight normal)))) + `(markdown-header-face-4 ((,class (:foreground ,yellow :height 1.0 :weight normal)))) + `(markdown-header-face-5 ((,class (:foreground ,cyan :height 1.0 :weight normal)))) + `(markdown-header-face-6 ((,class (:foreground ,green :height 1.0 :weight normal)))) + `(markdown-code-face ((,class (:foreground ,base0)))) + `(markdown-table-face ((,class (:foreground ,green)))) + + `(dashboard-footer-face ((,class (:foreground ,blue)))) + `(dashboard-text-banner ((,class (:foreground ,green)))) + `(dashboard-heading ((,class (:foreground ,green :weight bold)))) + + `(dired-broken-symlink ((,class (:inherit dired-symlink :foreground ,orange)))) + `(dired-header ((,class (:foreground ,green)))) + `(dirvish-file-time ((,class (:foreground ,base01)))) + `(dirvish-free-space ((,class (:foreground ,green)))) + `(dired-async-mode-message ((,class (:foreground ,red)))) + `(dired-async-message ((,class (:foreground ,yellow)))) + + `(diff-hunk-header ((,class (:foreground ,yellow-1fg :background ,yellow-1bg)))) + + `(consult-file ((,class (:foreground ,green)))) + `(consult-notes-name ((,class (:foreground ,base01)))) + `(consult-notes-time ((,class (:foreground ,base01)))) + `(consult-notes-size ((,class (:foreground ,base01)))) + + `(vertico-current ((,class (:background ,base02 :extend t :underline nil)))) + + `(transient-key-stay ((,class (:foreground ,cyan :inherit transient-key)))) + `(transient-key-return ((,class (:foreground ,violet :inherit transient-key)))) + `(transient-key-exit ((,class (:foreground ,blue :inherit transient-key)))) + `(transient-key-stack ((,class (:foreground ,magenta :inherit transient-key)))) + `(transient-key-recurse ((,class (:foreground ,blue :inherit transient-key)))) + `(transient-key-noop ((,class (:foreground ,base01 :inherit transient-key)))) + + `(geiser-font-lock-repl-output ((,class (:foreground ,green)))) + `(geiser-font-lock-doc-link ((,class (:foreground ,blue :underline t)))) + `(geiser-font-lock-error-link ((,class (:foreground ,orange :underline t)))) + + `(lisp-extra-font-lock-backquote ((,class (:inherit font-lock-type-face)))) + + `(vundo-saved ((,class (:foreground ,green)))) + `(vundo-last-saved ((,class (:foreground ,green :weight bold)))) + `(vundo-highlight ((,class (:foreground ,cyan :weight bold)))) + `(vundo-node ((,class (:foreground ,base01)))) + `(vundo-stem ((,class (:foreground ,base01)))) + + `(jinx-misspelled ((,class (:underline (:style line :color ,yellow))))) + + `(keycast-key ((,class (:foreground ,green :weight bold)))) + + `(emms-playlist-track-face ((,class (:foreground ,cyan)))) + `(emms-playlist-selected-face ((,class (:foreground ,blue :weight bold)))) + + `(proced-pid ((,class (:foreground ,violet)))) + `(proced-session-leader-pid ((,class (:inherit proced-pid :underline t)))) + `(proced-ppid ((,class (:foreground ,blue)))) + `(proced-sess ((,class (:inherit proced-ppid)))) + `(proced-emacs-pid ((,class (:foreground ,magenta)))) + `(proced-memory-low-usage ((,class (:foreground ,green)))) + `(proced-memory-medium-usage ((,class (:foreground ,yellow)))) + `(proced-memory-high-usage ((,class (:foreground ,red)))) + `(proced-executable ((,class (:foreground ,cyan)))) + `(proced-run-status-code ((,class (:foreground ,green)))) + `(proced-interruptible-sleep-status-code ((,class (:foreground ,base01)))) + `(proced-uninterruptible-sleep-status-code ((,class (:foreground ,red)))) + `(proced-time-colon ((,class (:foreground ,base01)))) + `(proced-cpu ((,class (:foreground ,base0)))) + `(proced-mem ((,class (:foreground ,base0)))) + + `(syncthing-bold ((,class (:inherit bold)))) + `(syncthing-italic ((,class (:inherit italic)))) + `(syncthing-my-id ((,class (:foreground ,blue :weight bold)))) + `(syncthing-rate-upload ((,class (:foreground ,green)))) + `(syncthing-rate-download ((,class (:foreground ,blue :weight bold)))) + `(syncthing-uptime ((,class (:foreground ,magenta :wegiht bold)))) + `(syncthing-count-discovery ((,class (:foreground ,blue :weight bold)))) + `(syncthing-count-listeners ((,class (:foreground ,green :weight bold)))) + `(syncthing-count-local-bytes ((,class (:foreground ,cyan :weight bold)))) + `(syncthing-count-local-files ((,class (:inherit default :weight bold)))) + `(syncthing-count-local-folders ((,class (:foreground ,yellow :weight bold)))) + `(syncthing-progress-100 ((,class (:foreground ,green)))) + `(syncthing-progress-75 ((,class (:foreground ,cyan)))) + `(syncthing-progress-50 ((,class (:foreground ,yellow)))) + `(syncthing-progress-25 ((,class (:foreground ,orange)))) + `(syncthing-progress-0 ((,class (:foreground ,red))))))) + +(provide-theme 'my-light) +;;; my-light-theme.el ends here diff --git a/lisp/my-palette.el b/lisp/my-palette.el @@ -0,0 +1,33 @@ +;;; my-palette.el --- Color palette for solarized -*- lexical-binding: t -*- + +;;; Commentary: +;; Palette of my-theme . + +;;; Code: + +(defvar my-dark-core-palette + '("#062624" ; darkest-base + "#E3FCFB" ; brightest-base + "#A87C04" ; yellow + "#C24713" ; orange + "#CE2825" ; red + "#d33682" ; magenta + "#6c71c4" ; violet + "#2570CD" ; blue + "#01928D" ; cyan + "#3A9C36")) ; green + +(defvar my-light-core-palette + '("#051E23" ; darkest-base + "#FCFFDE" ; brightest-base + "#A87C04" ; yellow + "#C24713" ; orange + "#CE2825" ; red + "#d33682" ; magenta + "#6c71c4" ; violet + "#2570CD" ; blue + "#01928D" ; cyan + "#3A9C36")) ; green + +(provide 'my-palette) +;;; my-palette.el ends here