aboutsummaryrefslogtreecommitdiff
path: root/emacs/.emacs.d/init
diff options
context:
space:
mode:
authorYuchen Pei <id@ypei.org>2023-06-17 17:20:29 +1000
committerYuchen Pei <id@ypei.org>2023-06-17 17:20:29 +1000
commit093ffa5fbf7143f4668bb0a3dc9659a5cc836e12 (patch)
tree1ed4e14b2a43b8e338f4ad6a04d969b99b9239be /emacs/.emacs.d/init
parentabc686827ae38ee715d9eed1c5c29161c74127e6 (diff)
Moving things one level deeper
To ease gnu stow usage. Now we can do stow -t ~ emacs
Diffstat (limited to 'emacs/.emacs.d/init')
-rw-r--r--emacs/.emacs.d/init/ycp-basic.el60
-rw-r--r--emacs/.emacs.d/init/ycp-buffer.el239
-rw-r--r--emacs/.emacs.d/init/ycp-client.el104
-rw-r--r--emacs/.emacs.d/init/ycp-complete.el375
-rw-r--r--emacs/.emacs.d/init/ycp-dired.el118
-rw-r--r--emacs/.emacs.d/init/ycp-editing.el116
-rw-r--r--emacs/.emacs.d/init/ycp-emms.el99
-rw-r--r--emacs/.emacs.d/init/ycp-fun.el35
-rw-r--r--emacs/.emacs.d/init/ycp-gnus.el214
-rw-r--r--emacs/.emacs.d/init/ycp-grep.el125
-rw-r--r--emacs/.emacs.d/init/ycp-help.el114
-rw-r--r--emacs/.emacs.d/init/ycp-markup.el97
-rw-r--r--emacs/.emacs.d/init/ycp-org.el417
-rw-r--r--emacs/.emacs.d/init/ycp-package.el70
-rw-r--r--emacs/.emacs.d/init/ycp-pdf.el60
-rw-r--r--emacs/.emacs.d/init/ycp-prog.el373
-rw-r--r--emacs/.emacs.d/init/ycp-project.el45
-rw-r--r--emacs/.emacs.d/init/ycp-system.el85
-rw-r--r--emacs/.emacs.d/init/ycp-theme.el46
-rw-r--r--emacs/.emacs.d/init/ycp-time.el141
-rw-r--r--emacs/.emacs.d/init/ycp-vc.el89
-rw-r--r--emacs/.emacs.d/init/ycp-web.el165
22 files changed, 3187 insertions, 0 deletions
diff --git a/emacs/.emacs.d/init/ycp-basic.el b/emacs/.emacs.d/init/ycp-basic.el
new file mode 100644
index 0000000..07bb11f
--- /dev/null
+++ b/emacs/.emacs.d/init/ycp-basic.el
@@ -0,0 +1,60 @@
+;;; ycp-basic.el -- My config for basic stuff -*- lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation.
+
+;; Author: Yuchen Pei <id@ypei.org>
+;; Protesilaos Stavrou <info@protesilaos.com>
+;; Maintainer: Yuchen Pei <id@ypei.org>
+;; Package-Requires: ((emacs "28.2"))
+
+;; This file is part of dotfiles.
+
+;; dotfiles is free software: you can redistribute it and/or modify it
+;; under the terms of the GNU Affero General Public License as
+;; published by the Free Software Foundation, either version 3 of the
+;; License, or (at your option) any later version.
+
+;; dotfiles is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; Affero General Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public
+;; License along with dotfiles. If not, see
+;; <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; My config for basic stuff.
+
+;;; Code:
+
+
+(setq use-short-answers t)
+(prefer-coding-system 'utf-8)
+(set-default-coding-systems 'utf-8)
+(set-terminal-coding-system 'utf-8)
+(set-keyboard-coding-system 'utf-8)
+(set-language-environment 'utf-8)
+
+(my-configure
+ (my-keybind global-map
+ "C-x C-c" nil
+ "C-x C-c C-c" #'save-buffers-kill-emacs
+ "C-x C-z" nil
+ )
+ (setq auth-source-save-behavior nil)
+ )
+
+(my-configure
+ (:delay 5)
+ (require 'my-utils)
+ (my-keybind global-map
+ "C-c <f2>" #'my-rename-file-and-buffer
+ "C-c <delete>" #'my-delete-file-and-kill-buffer
+ "C-g" #'my-keyboard-quit-dwim
+ )
+)
+
+(provide 'ycp-basic)
+;;; ycp-basic.el ends here
diff --git a/emacs/.emacs.d/init/ycp-buffer.el b/emacs/.emacs.d/init/ycp-buffer.el
new file mode 100644
index 0000000..56bcf08
--- /dev/null
+++ b/emacs/.emacs.d/init/ycp-buffer.el
@@ -0,0 +1,239 @@
+;;; ycp-buffer.el -- My config for buffers, windows, frames etc. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation.
+
+;; Author: Yuchen Pei <id@ypei.org>
+;; Protesilaos Stavrou <info@protesilaos.com>
+;; Maintainer: Yuchen Pei <id@ypei.org>
+;; Package-Requires: ((emacs "28.2"))
+
+;; This file is part of dotfiles.
+
+;; dotfiles is free software: you can redistribute it and/or modify it under
+;; the terms of the GNU Affero General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; dotfiles is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+;; Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public
+;; License along with dotfiles. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; My config for buffers, windows, frames etc..
+
+;;; Code:
+
+
+(my-package my-buffer
+ (:delay 15)
+ (my-keybind global-map
+ "\M-c" #'my-copy-buffer-file-name
+ "<C-f2>" #'my-rename-file-and-buffer
+ "C-x k" #'my-kill-buffer
+ "M-s b" #'my-switch-to-buffer-matching-major-mode
+ "M-s v" #'my-buffers-vc-root
+ ;; F7: Cycle or create buffers with the same base buffer as the
+ ;; current buffer
+ "<f7>" #'my-create-or-switch-indirect-buffers
+ ;; F8: Cycle or create buffers with the same major mode as the
+ ;; current buffer
+ "<f8>" #'my-buffer-create-or-cycle-same-mode
+ ;; F9: Prompt for a mode, then switch to or create a buffer of
+ ;; that mode
+ "<f9>" #'my-buffer-switch-or-create-major-mode
+ )
+ )
+
+(my-configure
+ (:delay 15)
+ (my-keybind ctl-x-x-map
+ "f" #'follow-mode ; override `font-lock-update'
+ "r" #'rename-uniquely
+ "l" #'visual-line-mode)
+
+ ;; make ibuffer default
+ (advice-add 'list-buffers :override 'ibuffer-list-buffers)
+
+ ;; In Emacs 27+, use Control + mouse wheel to scale text.
+ (setq mouse-wheel-scroll-amount
+ '(1
+ ((shift) . 5)
+ ((meta) . 0.5)
+ ((control) . text-scale))
+ mouse-drag-copy-region nil
+ make-pointer-invisible t
+ mouse-wheel-progressive-speed t
+ mouse-wheel-follow-mouse t)
+
+ ;; Scrolling behaviour
+ (setq-default scroll-conservatively 1 ; affects `scroll-step'
+ scroll-margin 0
+ next-screen-context-lines 0)
+
+ (mouse-wheel-mode 1)
+ (define-key global-map (kbd "C-M-<mouse-3>") #'tear-off-window))
+
+;;; Repeatable key chords (repeat-mode)
+(my-package repeat
+ (:delay 30)
+ (setq repeat-on-final-keystroke t
+ repeat-exit-timeout 5
+ repeat-exit-key "<escape>"
+ repeat-keep-prefix nil
+ repeat-check-key t
+ repeat-echo-function 'ignore
+ ;; Technically, this is not in repeal.el, though it is the
+ ;; same idea.
+ set-mark-command-repeat-pop t)
+ (repeat-mode 1))
+
+;;;; Built-in bookmarking framework (bookmark.el)
+(my-package bookmark
+ (setq bookmark-use-annotations nil)
+ (setq bookmark-automatically-show-annotations t)
+ (add-hook 'bookmark-bmenu-mode-hook #'hl-line-mode))
+
+(my-package follow
+ (:delay 15)
+ ;; TODO: update this to adapt to number of windows
+ (my-keybind follow-mode-map
+ "C-v" #'follow-scroll-up
+ "M-v" #'follow-scroll-down
+ "<next>" #'follow-scroll-up
+ "<prior>" #'follow-scroll-down)
+ )
+
+(my-package view
+ (:delay 10)
+ (my-keybind view-mode-map
+ "n" #'next-line
+ "p" #'previous-line
+ "f" #'forward-char
+ "b" #'backward-char
+ "e" #'move-end-of-line
+ "a" #'move-beginning-of-line
+ "v" #'scroll-up-command
+ "V" #'scroll-down-command
+ "l" #'previous-buffer
+ "r" #'next-buffer
+ "d" nil
+ "u" nil
+ "w" #'kill-ring-save
+ "i" #'view-mode)
+ (my-keybind global-map "C-`" #'view-mode))
+
+;; move windows
+(my-package windmove
+ (:delay 5)
+ (windmove-default-keybindings 'control)
+ ;; swap windows
+ (windmove-swap-states-default-keybindings '(control shift))
+ (setq windmove-wrap-around t))
+
+(my-package winner
+ (:delay 5)
+ (winner-mode t))
+
+;;;; `window', `display-buffer-alist', and related
+(my-package window
+ (require 'time)
+ (require 'my-buffer)
+ (setq display-buffer-alist
+ `(;; no window
+ ("\\`\\*Async Shell Command\\*\\'"
+ (display-buffer-no-window)
+ (dedicated . t))
+ ;; bottom side window
+ ("\\*Org Select\\*" ; the `org-capture' key selection
+ (display-buffer-in-side-window)
+ (dedicated . t)
+ (side . bottom)
+ (slot . 0)
+ (window-parameters . ((mode-line-format . none))))
+ ;; bottom buffer (NOT side window)
+ ((or . (,(my-buffer-make-display-matcher
+ '(flymake-diagnostics-buffer-mode
+ flymake-project-diagnostics-mode
+ messages-buffer-mode backtrace-mode))
+ "\\*\\(Warnings\\|Compile-Log\\|Org Links\\)\\*"
+ ,world-clock-buffer-name))
+ (display-buffer-reuse-mode-window display-buffer-at-bottom)
+ (window-height . 0.3)
+ (dedicated . t)
+ (preserve-size . (t . t)))
+ ("\\*\\(Output\\|Register Preview\\).*"
+ (display-buffer-reuse-mode-window display-buffer-at-bottom))
+ ;; below current window
+ ((derived-mode . help-mode) ; See the hooks for `visual-line-mode'
+ (display-buffer-reuse-mode-window display-buffer-below-selected))
+ ("\\*\\vc-\\(incoming\\|outgoing\\|git : \\).*"
+ (display-buffer-reuse-mode-window display-buffer-below-selected)
+ (window-height . 0.1)
+ (dedicated . t)
+ (preserve-size . (t . t)))
+ ((derived-mode . log-view-mode)
+ (display-buffer-reuse-mode-window display-buffer-below-selected)
+ (window-height . 0.3)
+ (dedicated . t)
+ (preserve-size . (t . t)))
+ ((derived-mode . reb-mode) ; M-x re-builder
+ (display-buffer-reuse-mode-window display-buffer-below-selected)
+ (window-height . 4) ; note this is literal lines, not relative
+ (dedicated . t)
+ (preserve-size . (t . t)))
+ ("\\*\\(Calendar\\|Bookmark Annotation\\).*"
+ (display-buffer-reuse-mode-window display-buffer-below-selected)
+ (dedicated . t)
+ (window-height . fit-window-to-buffer))
+ ("\\*ispell-top-choices\\*.*"
+ (display-buffer-reuse-mode-window display-buffer-below-selected)
+ (window-height . fit-window-to-buffer))
+ ;; same window
+
+ ;; NOTE 2023-02-17: `man' does not fully obey the
+ ;; `display-buffer-alist'. It works for new frames and for
+ ;; `display-buffer-below-selected', but otherwise is
+ ;; unpredictable. See `Man-notify-method'.
+ ((or . ((derived-mode . Man-mode)
+ (derived-mode . woman-mode)
+ "\\*\\(Man\\|woman\\).*"
+ "\\*shell\\*.*"))
+ (display-buffer-same-window))
+))
+
+ (setq switch-to-buffer-in-dedicated-window 'pop)
+ (setq window-combination-resize t)
+ (my-keybind resize-window-repeat-map
+ ">" #'enlarge-window-horizontally
+ "<" #'shrink-window-horizontally)
+ )
+
+(my-keybind global-map
+ "C-x C-n" #'next-buffer ; override `set-goal-column'
+ "C-x C-p" #'previous-buffer ; override `mark-page'
+ "C-x !" #'delete-other-windows-vertically
+ "C-x _" #'balance-windows ; underscore
+ "C-x -" #'fit-window-to-buffer ; hyphen
+ "C-x +" #'balance-windows-area
+ "C-x }" #'enlarge-window
+ "C-x {" #'shrink-window
+ "C-x >" #'enlarge-window-horizontally ; override `scroll-right'
+ "C-x <" #'shrink-window-horizontally) ; override `scroll-left'
+
+(my-package my-buffer
+ (:delay 10)
+ (my-keybind global-map
+ "<f1>" #'my-focus-write
+ "<insert>" #'my-cycle-windows
+ "C-M-<mouse-4>" #'my-increase-default-face-height
+ "C-M-<mouse-5>" #'my-decrease-default-face-height)
+ )
+
+(setq large-file-warning-threshold 15000000)
+
+(provide 'ycp-buffer)
diff --git a/emacs/.emacs.d/init/ycp-client.el b/emacs/.emacs.d/init/ycp-client.el
new file mode 100644
index 0000000..def2351
--- /dev/null
+++ b/emacs/.emacs.d/init/ycp-client.el
@@ -0,0 +1,104 @@
+;;; ycp-client.el -- My config for non-http clients -*- lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation.
+
+;; Author: Yuchen Pei <id@ypei.org>
+;; Package-Requires: ((emacs "28.2"))
+
+;; This file is part of dotfiles.
+
+;; dotfiles is free software: you can redistribute it and/or modify it under
+;; the terms of the GNU Affero General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; dotfiles is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+;; Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public
+;; License along with dotfiles. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; My config for non-http clients. like wget, ytdl, sql, irc, etc
+
+
+;;; Code:
+
+;;; Note: erc is only allowed when `my-profile' is erc, as assigned in early-init.el
+(my-package erc
+ (setq erc-lurker-hide-list '("JOIN" "PART" "QUIT"))
+ (setq erc-disable-ctcp-replies t)
+ (setq erc-modules
+ '(button completion irccontrols list match menu move-to-prompt
+ netsplit networks noncommands notifications readonly
+ ring stamp track))
+ (my-setq-from-local erc-track-exclude erc-server erc-nick erc-port)
+ ;; use auth-source for authentication
+ (setq erc-prompt-for-password nil)
+ (setq erc-paranoid t)
+ (setq erc-fill-mode t)
+ (require 'erc-match)
+ (set-face-attribute 'erc-fool-face nil :foreground "white")
+ (setq erc-fool-highlight-type 'all)
+ (my-setq-from-local erc-fools)
+ (erc-tls))
+
+(my-package dictionary
+ (:delay 15)
+ (autoload 'dictionary-search "dictionary"
+ "Ask for a word and search it in all dictionaries" t)
+ (autoload 'dictionary-match-words "dictionary"
+ "Ask for a word and search all matching words in the dictionaries" t)
+ (autoload 'dictionary-lookup-definition "dictionary"
+ "Unconditionally lookup the word at point." t)
+ (autoload 'dictionary "dictionary"
+ "Create a new dictionary buffer" t)
+ (autoload 'dictionary-mouse-popup-matching-words "dictionary"
+ "Display entries matching the word at the cursor" t)
+ (autoload 'dictionary-popup-matching-words "dictionary"
+ "Display entries matching the word at the point" t)
+ (autoload 'dictionary-tooltip-mode "dictionary"
+ "Display tooltips for the current word" t)
+ (autoload 'global-dictionary-tooltip-mode "dictionary"
+ "Enable/disable dictionary-tooltip-mode for all buffers" t)
+ (my-keybind global-map
+ "C-c dd" #'dictionary-search
+ "C-c dm" #'dictionary-match-words)
+ (setq dictionary-server "dict.org"
+ dictionary-default-popup-strategy "lev" ; read doc string
+ dictionary-create-buttons nil
+ dictionary-use-single-buffer t))
+
+(my-package wget
+ (:delay 60)
+ (setq wget-download-directory "~/Downloads")
+ (setq my-wget-size-threshold (* 20 1024 1024))
+ (require 'my-wget)
+ (my-setq-from-local my-wget-video-archive-directory)
+ (my-keybind eww-mode-map "s" #'my-eww-wget-save-page)
+)
+
+(my-package my-ytdl
+ (:delay 60)
+ (my-setq-from-local my-ytdl-audio-download-dir my-ytdl-video-download-dir))
+
+(my-package my-media-segment
+ (:delay 60))
+
+(my-package detached
+ (:install t)
+ (:delay 60)
+ (my-keybind detached-shell-mode-map
+ "C-<return>" nil
+ "C-S-<return>" #'detached-attach-session)
+ (require 'my-detached)
+ (my-keybind global-map "\M-z" #'my-execute-external-command)
+)
+
+(my-package pactl (:delay 60))
+
+(provide 'ycp-client)
+;;; ycp-client.el ends here
diff --git a/emacs/.emacs.d/init/ycp-complete.el b/emacs/.emacs.d/init/ycp-complete.el
new file mode 100644
index 0000000..aed7b3b
--- /dev/null
+++ b/emacs/.emacs.d/init/ycp-complete.el
@@ -0,0 +1,375 @@
+;;; ycp-complete.el -- My config for minibuffer and completions -*- lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation.
+
+;; Author: Yuchen Pei <id@ypei.org>
+;; Protesilaos Stavrou <info@protesilaos.com>
+;; Maintainer: Yuchen Pei <id@ypei.org>
+;; Package-Requires: ((emacs "28.2"))
+
+;; This file is part of dotfiles.
+
+;; dotfiles is free software: you can redistribute it and/or modify it under
+;; the terms of the GNU Affero General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; dotfiles is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+;; Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public
+;; License along with dotfiles. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; My config for minibuffer and completions.
+
+;;; Code:
+
+
+
+;; completion, minibuffer, corfu, tempel
+;; part adapted from prot-dotfiles
+(my-package minibuffer
+ (setq completion-styles '(basic partial-completion emacs22 orderless))
+ (setq completion-category-overrides
+ ;; NOTE 2021-10-25: I am adding `basic' because it works better as a
+ ;; default for some contexts. Read:
+ ;; <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=50387>.
+ ;;
+ ;; `partial-completion' is a killer app for files, because it
+ ;; can expand ~/.l/s/fo to ~/.local/share/fonts.
+ ;;
+ ;; If `basic' cannot match my current input, Emacs tries the
+ ;; next completion style in the given order. In other words,
+ ;; `orderless' kicks in as soon as I input a space or one of its
+ ;; style dispatcher characters.
+ '((file (styles . (basic partial-completion orderless)))
+ (project-file (styles . (basic substring partial-completion orderless)))
+ (imenu (styles . (emacs22 substring orderless)))
+ (kill-ring (styles . (emacs22 substring orderless)))
+ (consult-location (styles . (emacs22 substring orderless)))
+ (eglot (styles . (emacs22 substring orderless)))))
+ (setq completion-ignore-case t)
+ (setq read-buffer-completion-ignore-case t)
+ (setq read-file-name-completion-ignore-case t)
+ ;; disable space to run minibuffer-complete-word
+ (my-keybind minibuffer-mode-map
+ "SPC" nil
+ "?" nil)
+ (my-keybind minibuffer-local-completion-map
+ "SPC" nil
+ "?" nil)
+ (setq enable-recursive-minibuffers t)
+ (minibuffer-depth-indicate-mode 1)
+ (setq resize-mini-windows t)
+ (setq read-answer-short t)
+ (setq echo-keystrokes 0.25)
+ ;; Do not allow the cursor to move inside the minibuffer prompt. I
+ ;; got this from the documentation of Daniel Mendler's Vertico
+ ;; package: <https://github.com/minad/vertico>.
+ (setq minibuffer-prompt-properties
+ '(read-only t cursor-intangible t face minibuffer-prompt))
+ (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)
+ (minibuffer-electric-default-mode 1))
+
+;;;; `savehist' (minibuffer and related histories)
+(my-package savehist
+ (setq savehist-file (locate-user-emacs-file "savehist"))
+ (setq history-length 500)
+ (setq history-delete-duplicates t)
+ (setq savehist-save-minibuffer-history t)
+ (setq savehist-additional-variables '(register-alist kill-ring))
+ (savehist-mode 1))
+
+;;;; `dabbrev' (dynamic word completion (dynamic abbreviations))
+(my-package dabbrev
+ (setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_")
+ (setq dabbrev-abbrev-skip-leading-regexp "[$*/=~']")
+ (setq dabbrev-backward-only nil)
+ (setq dabbrev-case-distinction 'case-replace)
+ (setq dabbrev-case-fold-search nil)
+ (setq dabbrev-case-replace 'case-replace)
+ (setq dabbrev-check-other-buffers t)
+ (setq dabbrev-eliminate-newlines t)
+ (setq dabbrev-upcase-means-case-search t))
+
+;;; icomplete
+(my-package icomplete
+ (icomplete-vertical-mode t)
+ (setq icomplete-show-matches-on-no-input t)
+ (setq icomplete-prospects-height 4)
+ (setq icomplete-scroll t)
+ (setq icomplete-matches-format "[%s/%s] ")
+ (require 'my-complete)
+ (my-keybind icomplete-minibuffer-map
+ "<tab>" #'icomplete-force-complete
+ "M-<tab>" #'minibuffer-complete
+ "C-M-i" #'minibuffer-complete
+ "C-s" #'icomplete-forward-completions
+ "C-r" #'icomplete-backward-completions
+ "C-v" #'my-icomplete-vertical-forward-page
+ "M-v" #'my-icomplete-vertical-backward-page))
+
+(my-package recentf
+ (setq recentf-max-saved-items 1000)
+ (setq
+ recentf-exclude
+ '("~\\'" "\\`out\\'" "\\.log\\'" "^/[^/]*:" "\\.el\\.gz\\'" "~$" "/mnt/"
+ "^/tmp/"))
+ (recentf-mode 1)
+ ;; disable recentf-save-list on quit on non-emacs-client so that it does not
+ ;; overwrite the recentf file
+ (require 'my-utils)
+ (unless (my-server-p)
+ (setq kill-emacs-hook (delete 'recentf-save-list kill-emacs-hook)))
+ (require 'my-complete)
+ (my-server-timer recentf-timer nil 300 'my-recentf-save-list-silently)
+ )
+
+;;; corfu
+(my-package corfu
+ (:install t)
+ (:delay 5)
+ (global-corfu-mode 1)
+ (corfu-popupinfo-mode 1)
+ (setq corfu-auto t
+ corfu-cycle t
+ corfu-separator ?\s)
+ (define-key corfu-map [remap next-line] nil)
+ (define-key corfu-map [remap previous-line] nil)
+ (define-key corfu-map [remap beginning-of-buffer] nil)
+ (define-key corfu-map [remap end-of-buffer] nil)
+ (my-keybind corfu-map
+ "C-j" 'corfu-insert
+ "<RET>" 'nil
+ "C-s" #'corfu-next
+ "C-r" #'corfu-previous)
+ (require 'my-corfu)
+ (add-hook 'minibuffer-setup-hook #'my-corfu-enable-always-in-minibuffer 1)
+ )
+
+;;; cape
+(my-package cape
+ (:install t)
+ (:delay 15)
+ (setq cape-dabbrev-min-length 3)
+ (setq cape-symbol-wrapper
+ '((org-mode ?~ ?~)
+ (markdown-mode ?` ?`)
+ (log-edit-mode ?' ?')
+ (message-mode ?' ?')))
+ (dolist (backend '( cape-symbol cape-keyword cape-file cape-history cape-dabbrev))
+ (add-to-list 'completion-at-point-functions backend)))
+
+;;; consult
+(my-package consult
+ (:install t)
+ (:delay 10)
+ (setq consult-line-numbers-widen t)
+ ;; (setq completion-in-region-function #'consult-completion-in-region)
+ (setq consult-async-min-input 3)
+ (setq consult-async-input-debounce 0.5)
+ (setq consult-async-input-throttle 0.8)
+ (setq consult-narrow-key ">")
+ (setq register-preview-delay 0.8
+ register-preview-function #'consult-register-format)
+ (setq consult-find-args "find . -not ( -path */.git* -prune )")
+ (setq consult-preview-key 'any)
+ (add-to-list 'consult-mode-histories '(vc-git-log-edit-mode . log-edit-comment-ring))
+ (add-hook 'completion-list-mode-hook #'consult-preview-at-point-mode)
+ (require 'consult-imenu) ; the `imenu' extension is in its own file
+ (require 'my-consult)
+ (my-keybind global-map
+ "C-x b" #'consult-buffer
+ "C-z" #'consult-buffer
+ "C-x l" #'consult-locate
+ "M-g M-g" #'consult-goto-line
+ "M-K" #'consult-keep-lines ; M-S-k is similar to M-S-5 (M-%)
+ "M-F" #'consult-focus-lines ; same principle
+ "M-s M-b" #'consult-buffer
+ "M-s M-f" #'consult-find
+ "M-s M-G" #'consult-grep
+ "M-s M-g" #'my-consult-grep-default
+ "M-s M-h" #'consult-history
+ "M-s M-i" #'consult-imenu
+ "M-s M-l" #'consult-line
+ "M-s M-m" #'consult-mark
+ "M-y" #'consult-yank-pop
+ "M-s M-s" #'consult-outline)
+ (my-keybind consult-narrow-map "?" #'consult-narrow-help)
+ (my-keybind minibuffer-local-map "C-s" #'consult-history)
+ )
+
+;;; marginalia
+(my-package marginalia
+ (:install t)
+ (:delay 10)
+ (setq marginalia-max-relative-age 0)
+ (marginalia-mode 1))
+
+(setq tempel-path
+ (locate-user-emacs-file "*tempel-templates"))
+(my-package tempel
+ (:install t)
+ (:delay 15)
+ (require 'my-tempel)
+ (my-keybind global-map
+ "M-=" #'tempel-complete ; Alternative: `tempel-expand'
+ "M-*" #'tempel-insert)
+ (my-keybind tempel-map
+ "RET" #'tempel-done
+ "C-p" #'tempel-previous
+ "C-n" #'tempel-next
+ "<tab>" #'tempel-next
+ "<backtab>" #'tempel-previous
+ "C-S-<iso-lefttab>" #'tempel-previous)
+ (require 'my-tempel)
+ (dolist (hook '(prog-mode-hook text-mode-hook))
+ (add-hook hook 'my-tempel-setup-capf))
+ )
+
+;; consult-recoll
+(my-package consult-recoll
+ (:delay 30)
+ (:install t)
+ )
+
+(my-package hmm
+ (:delay 60)
+ (my-setq-from-local hmm-web-search-engines)
+ (require 'my-net)
+ (setq hmm-web-browsers
+ '((:name eww :command eww)
+ (:name luwak :command luwak-open)
+ (:name firefox :command browse-url-firefox)
+ (:name firefox-private :command my-browse-url-firefox-private)
+ (:name tor-browser :command my-browse-url-tor-browser)
+ (:name download-and-open :command my-fetch-url)))
+ (setq hmm-handlers
+ '(:query
+ ((:command servall-ytdl-search)
+ (:command servall-wikipedia-open)
+ (:command servall-wikipedia-search)
+ (:command hcel-global-ids)
+ (:command osm-search)
+ (:command my-org-recoll-mdn)
+ (:command consult-recoll)
+ (:command locate)
+ (:command project-or-external-find-regexp)
+ (:command dictionary-search)
+ (:command my-libgen-search)
+ (:command my-libgen-search-isbn)
+ (:command my-openlibrary-search)
+ ;; TODO: sx, grep-somewhere, grep-here, gnus news, gnus email
+ ;; rt-liber (some sort of smart search)
+ )
+
+ ;; URL handlers handle all schemes, including file:
+ ;; We want to add all file-handlers here with regex that filters
+ ;; file: in scheme
+ :url
+ ((:schemes ("http" "https")
+ :regex "^en.wikipedia.org/wiki/.*$"
+ :command servall-wikipedia-open)
+ (:schemes ("http" "https")
+ :regex
+ "^\\(?:.*\\.\\)?\\(?:stackexchange\\|stackoverflow\\|mathoverflow\\|askubuntu\\)\\.com/.*$"
+ :command sx-open-link)
+ (:schemes ("http" "https")
+ :regex
+ "^\\(?:.*\\.\\)?news.ycombinator.com/.*$"
+ :command hnreader-comment)
+ (:schemes ("http" "https")
+ :command my-org-grok)
+ (:schemes ("mailto") :command browse-url-mail)
+ (:schemes ("mailto") :command my-gnus-fastmail-mail-url)
+ (:schemes ("http" "https") :command my-ytdl-audio)
+ (:schemes ("http" "https") :command my-ytdl-video)
+ (:schemes ("http" "https") :command my-describe-package-from-url
+ :regex
+ "^\\(?:elpa.gnu.org/packages\\|elpa.gnu.org/devel\\|elpa.nongnu.org/nongnu\\)\\(?:/.*\\).html")
+ (:command emms-play-url
+ :schemes
+ ("ftp" "http" "https" "mms" "rtmp" "rtsp" "sftp" "smb" "srt")
+ ) ;;FIXME: buggy
+ ;; TODO: magit-clone-shallow, osm
+ )
+
+ :file
+ ;; by mimetypes / extensions etc, most can be handled by find-file?
+ ;; shell can be used for dir
+ ((:command find-file)
+ (:command dired :mimetypes ("inode/directory"))
+ (:command my-shell-with-directory :mimetypes ("inode/directory"))
+ (:command magit-status :mimetypes ("inode/directory"))
+ (:command byte-compile-file :mimetypes ("text/x-lisp"))
+ (:command hmm-file-mime-type))))
+ (setq hmm-external-handlers
+ '((:name mpv
+ :external-command "mpv %U"
+ :display-name "mpv player"
+ :description "Play url with mpv"
+ :schemes
+ ("ftp" "http" "https" "mms" "rtmp" "rtsp" "sftp" "smb" "srt")
+ :handling :url)
+ (:name wget
+ :external-command "wget %U"
+ :display-name "GNU Wget"
+ :description "The non-interactive network downloader"
+ :schemes
+ ("ftp" "http" "https")
+ :handling :url)
+ (:name qutebrowser
+ :external-command "qutebrowser %U"
+ :display-name "qutebrowser"
+ :description "A keyboard-driven, vim-like browser based on PyQt5"
+ :schemes
+ ("http" "https")
+ :handling :url)
+ (:name torsocks-mpv
+ :external-command "torsocks mpv %U"
+ :display-name "mpv player torsocks"
+ :description "Play url with mpv over torsocks"
+ :schemes
+ ("ftp" "http" "https" "mms" "rtmp" "rtsp" "sftp" "smb" "srt")
+ :handling :url)
+ (:name clean-elc-compile
+ :external-command "clean-elc-compile %f"
+ :description "Clean compile a directory of elisp files"
+ :display-buffer t
+ :mimetypes ("inode/directory")
+ :handling :file)
+ (:name mogrify-strip
+ :external-command "mogrify -strip %F"
+ :description "Strip images of all profiles and comments"
+ :display-buffer t
+ :handling :file)
+ (:name pacfind
+ :external-command "pacfind %f"
+ :description "Find the pacman package containing a command"
+ :display-buffer t
+ :handling :query)))
+ (setq hmm-matchers
+ '(((thing-at-point-url-at-point) . hmm-url)
+ ((thing-at-point-file-at-point) . hmm-file)
+ ((and (derived-mode-p 'dired-mode) (dired-get-filename nil t))
+ . hmm-file)
+ ((and (derived-mode-p 'dired-mode) (expand-file-name default-directory))
+ . hmm-file)
+ ((and (derived-mode-p 'org-mode) (my-org-link-at-point)) . hmm-url)
+ ((get-text-property (point) 'shr-url) . hmm-url)
+ ((and (derived-mode-p 'luwak-mode)
+ (get-text-property (point) 'url))
+ . hmm-url)
+ ((and (derived-mode-p 'luwak-mode)
+ (plist-get luwak-data :url))
+ . hmm-url)
+ ((thing-at-point 'symbol) . hmm-query)
+ ((buffer-file-name) . hmm-file)
+ ((expand-file-name default-directory) . hmm-file)))
+ (hmm-update))
+
+(provide 'ycp-complete)
diff --git a/emacs/.emacs.d/init/ycp-dired.el b/emacs/.emacs.d/init/ycp-dired.el
new file mode 100644
index 0000000..e8a10ae
--- /dev/null
+++ b/emacs/.emacs.d/init/ycp-dired.el
@@ -0,0 +1,118 @@
+;;; ycp-dired.el -- My config for dired and friends -*- lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation.
+
+;; Author: Yuchen Pei <id@ypei.org>
+;; Protesilaos Stavrou <info@protesilaos.com>
+;; Maintainer: Yuchen Pei <id@ypei.org>
+;; Package-Requires: ((emacs "28.2"))
+
+;; This file is part of dotfiles.
+
+;; dotfiles is free software: you can redistribute it and/or modify it under
+;; the terms of the GNU Affero General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; dotfiles is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+;; Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public
+;; License along with dotfiles. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; My config for dired and friends.
+
+;;; Code:
+
+
+(setq delete-by-moving-to-trash 'always)
+
+(my-package dired
+ (:delay 5)
+ (put 'dired-find-alternate-file 'disabled nil)
+ (setq dired-dwim-target t)
+ (setq dired-recursive-copies 'always)
+ (setq dired-recursive-deletes 'always)
+ (setq dired-listing-switches "-alh")
+ (add-hook 'dired-mode-hook (lambda () (interactive)
+ (auto-revert-mode t)))
+ (add-hook 'dired-mode-hook #'hl-line-mode)
+ (setq dired-listing-switches "-al --block-size='1")
+ (my-keybind dired-mode-map
+ "^" (lambda () (interactive) (find-alternate-file "..")))
+ (my-keybind global-map
+ "C-x C-j" #'dired-jump
+ ;; to open a dir in dired, find-file is more than sufficient
+ "C-x d" #'dired-jump)
+ )
+
+(my-package my-dired
+ (:delay 5)
+ (my-keybind dired-mode-map
+ "a" #'my-dired-find-or-alternate
+ "<return>" #'my-dired-find-or-alternate
+ "r" #'my-dired-do-rename-and-symlink-back
+ "s" #'my-dired-toggle-sorting)
+ )
+
+;;; dired-aux
+(my-package dired-aux
+ (:delay 5)
+ (setq dired-isearch-filenames 'dwim)
+ (setq dired-create-destination-dirs 'ask) ; Emacs 27
+ (setq dired-vc-rename-file t) ; Emacs 27
+ (setq dired-do-revert-buffer (lambda (dir) (not (file-remote-p dir))))
+ (my-keybind dired-mode-map
+ "C-+" #'dired-create-empty-file
+ ;; "M-s f" #'nil
+ "C-x v v" #'dired-vc-next-action)
+ ) ; Emacs 28
+
+
+;;; dired-x
+(my-package dired-x
+ (:delay 5)
+ (add-hook 'dired-mode-hook #'dired-omit-mode)
+ (setq dired-omit-files "\\`[.]?#")
+ (setq dired-clean-up-buffers-too t)
+ (setq dired-clean-confirm-killing-deleted-buffers t)
+ (setq dired-x-hands-off-my-keys t) ; easier to show the keys I use
+ (setq dired-bind-man nil)
+ (setq dired-bind-info nil)
+ (my-keybind dired-mode-map "I" #'dired-info))
+
+;;; required by dired-subtree
+(my-package dash
+ (:delay 5)
+ (:install t))
+
+(my-package dired-subtree
+ (:delay 5)
+ (setq dired-subtree-use-backgrounds nil)
+ (my-keybind dired-mode-map
+ "<tab>" #'dired-subtree-toggle
+ "<backtab>" #'dired-subtree-remove))
+
+;;; image-dired
+(my-package image-dired
+ (:delay 10)
+ (setq image-dired-thumbnail-storage 'standard)
+ (setq image-dired-external-viewer "xdg-open")
+ (setq image-dired-thumb-size 80)
+ (setq image-dired-thumb-margin 2)
+ (setq image-dired-thumb-relief 0)
+ (setq image-dired-thumbs-per-row 4)
+ (my-keybind image-dired-thumbnail-mode-map
+ "<return>" #'image-dired-thumbnail-display-external))
+
+
+;;; dired-du
+(my-package dired-du
+ (require 'dired-du)
+ (setq dired-du-size-format 'comma))
+
+(provide 'ycp-dired)
diff --git a/emacs/.emacs.d/init/ycp-editing.el b/emacs/.emacs.d/init/ycp-editing.el
new file mode 100644
index 0000000..e9c7e4c
--- /dev/null
+++ b/emacs/.emacs.d/init/ycp-editing.el
@@ -0,0 +1,116 @@
+;;; ycp-editing.el -- My config for editing -*- lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation.
+
+;; Author: Yuchen Pei <id@ypei.org>
+;; Protesilaos Stavrou <info@protesilaos.com>
+;; Maintainer: Yuchen Pei <id@ypei.org>
+;; Package-Requires: ((emacs "28.2"))
+
+;; This file is part of dotfiles.
+
+;; dotfiles is free software: you can redistribute it and/or modify it under
+;; the terms of the GNU Affero General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; dotfiles is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+;; Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public
+;; License along with dotfiles. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; My config for editing.
+
+;;; Code:
+
+
+;; line wrap at window edge
+(set-default 'truncate-lines nil)
+
+(setq kill-do-not-save-duplicates t)
+(setq bidi-inhibit-bpa t)
+(setq save-interprogram-paste-before-kill t)
+(setq kill-ring-max 200)
+
+(my-package my-editing
+ (:delay 5)
+ (my-keybind global-map
+ "M-k" #'my-kill-line-backward
+ "M-w" #'my-copy-line-or-region
+ "C-o" #'my-new-line-above-or-below
+ "C-<" #'my-escape-url-dwim
+ "M-'" #'my-insert-pair
+ "M-\\" #'my-delete-pair-dwim
+ "M-Z" #'my-zap-back-to-char
+ "C-x C-t" #'my-transpose-lines
+ "M-`" #'my-buffer-create-scratch
+ "C-M-;" #'my-comment-and-copy-selection
+ "M-Q" #'my-unfill-paragraph
+ "C-x M-s" #'my-save-without-formatting
+ "C-x w" #'my-copy-url-at-point
+ "C-<backspace>" #'my-backward-kill-path-component
+ "C-w" #'my-kill-region-if-active
+ "C-c r <SPC>" #'my-replace-leading-space
+ "C-c r <RET>" #'my-concat-lines
+ "C-M-y" #'my-yank-primary
+ "C-a" #'my-beginning-of-line-or-indentation
+ )
+ )
+
+(setq viper-mode nil)
+(my-package viper
+ (:delay 60))
+
+(define-key global-map [f2] 'revert-buffer)
+(define-key global-map (kbd "C-c r r") 'replace-regexp)
+(define-key global-map (kbd "C-c r s") 'replace-string)
+
+(my-keybind global-map
+ "M-o" #'delete-blank-lines ; alias for C-x C-o
+ "M-SPC" #'cycle-spacing
+ "M-z" #'zap-up-to-char ; NOT `zap-to-char'
+ "<C-M-backspace>" #'backward-kill-sexp
+ )
+
+(my-package pyim
+ (:delay 30)
+ (:install t))
+
+;;;; Auto revert mode
+(setq auto-revert-verbose t)
+(global-auto-revert-mode 1)
+
+;;;; Delete selection
+(delete-selection-mode 1)
+
+;;;; Tabs, indentation, and the TAB key
+(setq-default tab-always-indent 'complete
+ tab-first-completion 'word-or-paren-or-punct ; Emacs 27
+ tab-width 2
+ indent-tabs-mode nil)
+
+(define-key global-map [f12] 'display-line-numbers-mode)
+
+;; show column number
+(column-number-mode t)
+
+(define-key global-map (kbd "C-x F") 'my-sudo-find-file)
+
+;; find file
+(ffap-bindings)
+
+(put 'narrow-to-region 'disabled nil)
+
+(setq large-file-warning-threshold 15000000)
+
+(add-hook 'text-mode-hook #'turn-on-auto-fill)
+(add-to-list
+ 'auto-mode-alist
+ '("\\(README\\|CHANGELOG\\|COPYING\\|LICENSE\\)\\'" . text-mode))
+
+(provide 'ycp-editing)
diff --git a/emacs/.emacs.d/init/ycp-emms.el b/emacs/.emacs.d/init/ycp-emms.el
new file mode 100644
index 0000000..d83b53b
--- /dev/null
+++ b/emacs/.emacs.d/init/ycp-emms.el
@@ -0,0 +1,99 @@
+;;; ycp-emms.el -- My configs for multimedia -*- lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation.
+
+;; Author: Yuchen Pei <id@ypei.org>
+;; Package-Requires: ((emacs "28.2"))
+
+;; This file is part of dotfiles.
+
+;; dotfiles is free software: you can redistribute it and/or modify it under
+;; the terms of the GNU Affero General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; dotfiles is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+;; Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public
+;; License along with dotfiles. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; My configs for multimedia.
+
+;;; Code:
+
+;;; emms is only loaded when `my-profile' is emms, see early-init.el
+(my-package emms
+ (:install t)
+ (require 'emms-setup)
+ ;; FIXME: only enable what i use
+ (emms-all)
+ (setq emms-playing-time-resume-from-last-played t)
+ (add-to-list 'emms-info-functions 'emms-info-ytdl)
+ ;; emms-info-native is not very useful
+ (delete 'emms-info-native emms-info-functions)
+ (setq emms-source-file-default-directory (locate-user-emacs-file "emms"))
+ (setq emms-source-playlist-default-format 'native)
+ (setq emms-repeat-playlist t)
+ (my-keybind emms-playlist-mode-map "C-x C-f" #'emms-play-playlist)
+ (setq emms-player-list '(emms-player-mpv))
+ (setq emms-player-vlc-parameters '("--intf=qt" "--extraintf=rc"))
+ (setq emms-playlist-buffer-name "*EMMS Playlist*")
+ (setq emms-source-file-directory-tree-function
+ 'emms-source-file-directory-tree-find)
+ (setq emms-info-ytdl-using-torsocks t)
+ (add-hook 'emms-playlist-mode-hook #'hl-line-mode)
+ (add-hook 'emms-metaplaylist-mode-hook #'hl-line-mode)
+ )
+
+(my-package my-emms
+ (my-setq-from-local my-emms-playlist-alist)
+ (my-keybind global-map
+ "C-c s t" #'my-emms-mpv-toggle-torsocks
+ "C-c s SPC" #'my-emms-switch-to-playlist-buffer
+ "C-c s v" #'my-emms-mpv-toggle-video
+ "<XF86AudioPause>" #'emms-pause
+ "<XF86AudioPlay>" #'emms-pause
+ "<XF86AudioNext>" #'emms-next
+ "<XF86AudioPrev>" #'emms-seek-backward
+ "C-c s a" #'emms-add-all
+ "C-c s s" #'emms
+ "C-c s S" #'my-emms-save-all
+ "C-c s e" #'emms-metaplaylist-mode-go
+ "C-c s m" #'emms-mode-line-toggle
+ "C-c s n" #'emms-next
+ "C-c s r" #'emms-random
+ "C-c s p" #'my-emms-print-current-track-display-name
+ "C-c s f" #'my-emms-append-current-track-to-favourites
+ "C-c s F" #'emms-append-current-track-name-to-file
+ "C-c s P" #'emms-pause
+ "C-c s u" #'emms-add-url
+ "C-c s o" #'my-emms-add-url-region
+ "C-c s y" #'my-emms-add-ytdl-playlist
+ "C-c s w" #'my-emms-kill-current-track-name
+ )
+ (my-keybind emms-playlist-mode-map
+ "s" #'my-emms-playlist-save-current-buffer
+ "C-<return>" #'my-emms-playlist-mode-make-current
+ "w" #'my-emms-playlist-kill-track-name-at-point
+ "D" #'my-emms-playlist-delete-at-point
+ "R" #'my-emms-random-album
+ "N" #'my-emms-next-track-or-random-album
+ )
+ (add-hook 'emms-player-started-hook 'my-emms-maybe-seek-to-last-played)
+ (my-override emms-mode-line-enable)
+ (my-override emms-mode-line-disable)
+ (my-override emms-mode-line-toggle)
+ (add-hook 'emms-playlist-selection-changed-hook
+ 'my-emms-output-current-track-to-i3bar-file)
+ (setq emms-player-next-function 'my-emms-next-track-or-random-album)
+ (my-keybind dired-mode-map "e" #'my-dired-add-to-emms)
+ (my-override emms-track-simple-description)
+ (my-emms-add-all)
+ )
+
+(provide 'ycp-emms)
diff --git a/emacs/.emacs.d/init/ycp-fun.el b/emacs/.emacs.d/init/ycp-fun.el
new file mode 100644
index 0000000..41dd482
--- /dev/null
+++ b/emacs/.emacs.d/init/ycp-fun.el
@@ -0,0 +1,35 @@
+;;; ycp-fun.el -- My config for amusement -*- lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation.
+
+;; Author: Yuchen Pei <id@ypei.org>
+;; Package-Requires: ((emacs "28.2"))
+
+;; This file is part of dotfiles.
+
+;; dotfiles is free software: you can redistribute it and/or modify it under
+;; the terms of the GNU Affero General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; dotfiles is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+;; Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public
+;; License along with dotfiles. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; My config for amusement.
+
+;;; Code:
+
+
+
+(my-package meme (:delay 60))
+(my-package slime-volleyball (:delay 60))
+
+(provide 'ycp-fun)
+;;; ycp-fun.el ends here
diff --git a/emacs/.emacs.d/init/ycp-gnus.el b/emacs/.emacs.d/init/ycp-gnus.el
new file mode 100644
index 0000000..7a03703
--- /dev/null
+++ b/emacs/.emacs.d/init/ycp-gnus.el
@@ -0,0 +1,214 @@
+;;; ycp-gnus.el -- My config for email etc -*- lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation.
+
+;; Author: Yuchen Pei <id@ypei.org>
+;; Protesilaos Stavrou <info@protesilaos.com>
+;; Maintainer: Yuchen Pei <id@ypei.org>
+;; Package-Requires: ((emacs "28.2"))
+
+;; This file is part of dotfiles.
+
+;; dotfiles is free software: you can redistribute it and/or modify it under
+;; the terms of the GNU Affero General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; dotfiles is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+;; Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public
+;; License along with dotfiles. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; My config for email etc. Covers gnus, bbdb, message mode etc.
+
+;;; Code:
+
+
+(my-setq-from-local user-mail-address user-full-name)
+(setq mail-user-agent 'message-user-agent)
+(setq auth-sources '("~/.authinfo.gpg"))
+
+;;;; `mm-encode'
+(my-package mm-encode
+ (setq mm-encrypt-option nil ; use 'guided if you need more control
+ mm-sign-option nil)) ; same
+
+;;;; `mml-sec'
+(my-package mml-sec
+ (setq mml-secure-openpgp-encrypt-to-self t
+ mml-secure-openpgp-sign-with-sender t
+ mml-secure-smime-encrypt-to-self t
+ mml-secure-smime-sign-with-sender t))
+
+;;;; `message'
+(my-package message
+ (setq mail-user-agent 'message-user-agent
+ message-elide-ellipsis "\n> [... %l lines elided]\n"
+ compose-mail-user-agent-warnings nil
+ message-mail-user-agent t ; use `mail-user-agent'
+ message-citation-line-function #'message-insert-formatted-citation-line
+ message-ignored-cited-headers "" ; default is "." for all headers
+ message-confirm-send nil
+ message-kill-buffer-on-exit t
+ message-wide-reply-confirm-recipients t
+ message-citation-line-format
+ "On %a %Y-%m-%d %H:%M:%S %z, %N wrote:\n")
+ (add-hook 'message-setup-hook #'message-sort-headers)
+ )
+
+(my-package smtpmail
+ (my-setq-from-local smtpmail-default-smtp-server
+ smtpmail-smtp-server smtpmail-stream-type)
+ (setq smtpmail-smtp-service 587
+ smtpmail-queue-mail nil))
+
+;;;; `sendmail' (mail transfer agent)
+(setq send-mail-function 'smtpmail-send-it)
+
+;;; gnus
+(my-package gnus
+ (setq gnus-select-method '(nnnil ""))
+ (setq gnus-group-line-format "%M%S%p%P%5y:%B%(%G%)
+")
+ (setq gnus-secondary-select-methods
+ '(
+ ;; "fastdove" is just a name given to gnus
+ (nnimap "fastdove"
+ (nnimap-address "localhost")
+ (nnimap-stream plain)
+ (nnimap-server-port "imap"))
+ ))
+ (setq gnus-agent t)
+ (dolist (mode '(gnus-group-mode-hook
+ gnus-summary-mode-hook
+ gnus-browse-mode-hook))
+ (add-hook mode #'hl-line-mode))
+ (require 'my-gnus)
+ (my-setq-from-local my-gnus-inbox-group
+ my-gnus-group-alist)
+ (my-keybind global-map
+ "C-c n i" #'my-gnus-open-inbox
+ "C-c n n" #'my-gnus-start
+ "C-c n u" #'gnus-group-get-new-news)
+ (my-server-timer my-gnus-new-news-timer nil 300
+ 'my-gnus-group-get-new-news-quietly)
+ )
+
+(my-configure
+ (:delay 10)
+ (org-link-set-parameters "gnus" :follow #'my-org-open-gnus-link))
+
+(my-package gnus-dired
+ (add-hook 'dired-mode-hook #'turn-on-gnus-dired-mode))
+
+(my-package gnus-msg
+ (setq gnus-gcc-mark-as-read t)
+ (setq gnus-message-replysign t)
+ (my-setq-from-local gnus-posting-styles)
+ (my-override mm-display-external)
+ )
+
+;; checking sources
+(my-package gnus-start
+ (setq gnus-check-new-newsgroups 'ask-server)
+ (setq gnus-read-active-file 'some)
+ (setq gnus-use-dribble-file t)
+ (setq gnus-always-read-dribble-file t))
+
+(my-package gnus-search
+ (setq gnus-search-use-parsed-queries t))
+
+(my-package gnus-win
+ (setq gnus-use-full-window nil))
+
+(my-package gnus-topic
+ (require 'my-gnus)
+ (my-keybind gnus-topic-mode-map
+ "u" #'my-gnus-topic-up
+ "<RET>" #'my-gnus-topic-select-group)
+ )
+
+(my-package gnus-group
+ (require 'my-gnus)
+ (my-keybind gnus-group-mode-map
+ "n" #'next-line
+ "p" #'previous-line
+ "m" #'my-gnus-group-compose
+ "M-&" nil
+ "<RET>" #'my-gnus-topic-select-group)
+ (add-hook 'gnus-group-mode-hook 'gnus-topic-mode)
+ )
+
+(my-package gnus-sum
+ (require 'my-gnus)
+ (setq gnus-ignored-from-addresses user-full-name)
+ (my-keybind gnus-summary-mode-map
+ "n" #'my-gnus-summary-next-article-like-mu4e
+ "p" #'my-gnus-summary-prev-article-like-mu4e
+ "q" #'my-gnus-summary-exit-like-mu4e
+ "M-u" nil
+ "M-&" nil
+ "m" #'my-gnus-move-article-like-mu4e
+ "r" #'my-gnus-archive-article-like-mu4e
+ "d" #'my-gnus-trash-article-like-mu4e
+ "." #'gnus-summary-show-raw-article)
+ (setq gnus-sum-thread-tree-root ""
+ gnus-sum-thread-tree-single-leaf "└>"
+ gnus-sum-thread-tree-leaf-with-other "├>"
+ gnus-sum-thread-tree-indent " ")
+ (setq gnus-summary-line-format "%*%U%R%z %d %(%-20,20f%) %B%S
+")
+ (setq gnus-thread-sort-functions
+ '(gnus-thread-sort-by-most-recent-date))
+ )
+
+(my-package nnrss
+ (:delay 60)
+ (setq nnrss-use-local t))
+
+(my-package gnus-art
+ (setq gnus-inhibit-images t)
+ (setq gnus-treat-display-smileys nil)
+ (setq gnus-article-x-face-too-ugly ".*")) ; all images in headers are outright
+ ; annoying---disabled!
+;; gnus-desktop-notify
+(my-package gnus-desktop-notify
+ (:delay 30)
+ (gnus-desktop-notify-mode)
+ (setq gnus-desktop-notify-groups 'gnus-desktop-notify-explicit)
+ )
+
+(my-package gnus-demon
+ (gnus-demon-add-scanmail))
+
+;;; bbdb
+(my-package bbdb
+ (:delay 60)
+ (bbdb-initialize)
+ (setq bbdb-mail-user-agent 'gnus-user-agent)
+ (require 'my-bbdb)
+ (my-keybind bbdb-mode-map "C-c C-c" #'my-bbdb-done)
+ (setq bbdb-phone-style nil
+ bbdb-default-country nil)
+ (my-override bbdb-read-record)
+ (my-override bbdb-create)
+ (my-keybind global-map
+ "C-c b a" #'my-bbdb-all
+ "C-c b b" #'bbdb
+ "C-c b c" #'bbdb-create)
+ )
+
+(my-package bbdb-anniv (:delay 60))
+
+;; bbdb-vcard
+(my-package bbdb-vcard
+ (:delay 60)
+ (bbdb-vcard-default-keybindings)
+ (my-setq-from-local bbdb-vcard-default-dir))
+
+(provide 'ycp-gnus)
diff --git a/emacs/.emacs.d/init/ycp-grep.el b/emacs/.emacs.d/init/ycp-grep.el
new file mode 100644
index 0000000..715f643
--- /dev/null
+++ b/emacs/.emacs.d/init/ycp-grep.el
@@ -0,0 +1,125 @@
+;;; ycp-grep.el -- My config for search -*- lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation.
+
+;; Author: Yuchen Pei <id@ypei.org>
+;; Protesilaos Stavrou <info@protesilaos.com>
+;; Maintainer: Yuchen Pei <id@ypei.org>
+;; Package-Requires: ((emacs "28.2"))
+
+;; This file is part of dotfiles.
+
+;; dotfiles is free software: you can redistribute it and/or modify it under
+;; the terms of the GNU Affero General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; dotfiles is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+;; Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public
+;; License along with dotfiles. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; My config for search. Covers grep, search, isearch, occur, recoll
+;; etc.
+
+;;; Code:
+
+
+;;; `grep' package
+(my-package grep
+ (:delay 10)
+ (setq grep-command "grep -inRH --color -A1 -B1 -E ")
+ ;; in the form of (string . position), see docs of read-from-minibuffer
+ (setq grep-find-command
+ '("find . -type f -exec grep -inRH --color -A1 -B1 -E \\{\\} +" . 52))
+ (grep-apply-setting 'grep-find-template
+ "find -H <D> <X> -type f <F> -exec grep <C> -n --null -E -A1 -B1 <R> /dev/null \\{\\} +")
+ (setq grep-files-aliases
+ '(("all" . "* .*")
+ ("el" . "*.el")
+ ("ch" . "*.[ch]")
+ ("c" . "*.c")
+ ("cc" . "*.cc *.cxx *.cpp *.C *.CC *.c++")
+ ("cchh" . "*.cc *.[ch]xx *.[ch]pp *.[CHh] *.CC *.HH *.[ch]++")
+ ("hh" . "*.hxx *.hpp *.[Hh] *.HH *.h++")
+ ("h" . "*.h")
+ ("l" . "[Cc]hange[Ll]og*")
+ ("m" . "[Mm]akefile*")
+ ("tex" . "*.tex")
+ ("texi" . "*.texi")
+ ("asm" . "*.[sS]")
+ ("docs" . "*.md *.html *.rst *.org *.txt *.asciidoc *.adoc *.tex *.texi")))
+ (my-keybind global-map
+ "C-c r f" #'grep-find
+ "C-c r g" #'grep)
+)
+
+(my-package my-grep
+ (:delay 10)
+ ;; TODO: do we really need this?
+ (advice-add 'grep :filter-return #'my-grep-focus-buffer)
+)
+
+(my-package isearch
+ (:delay 5)
+ (setq search-whitespace-regexp ".*?" ; one `setq' here to make it obvious they are a bundle
+ isearch-lax-whitespace t
+ isearch-regexp-lax-whitespace nil)
+ (setq isearch-lazy-count t)
+ (setq lazy-count-prefix-format nil)
+ (setq lazy-count-suffix-format " (%s/%s)")
+ (setq isearch-yank-on-move 'shift)
+ (setq isearch-allow-scroll 'unlimited)
+ (setq isearch-repeat-on-direction-change t)
+ (define-key minibuffer-local-isearch-map (kbd "M-/") #'isearch-complete-edit)
+ (my-keybind isearch-mode-map
+ "C-g" #'isearch-cancel ; instead of `isearch-abort'
+ "M-/" #'isearch-complete
+ "C-o" #'isearch-occur)
+ (my-keybind global-map
+ "C-s" 'isearch-forward-regexp
+ "C-r" 'isearch-backward-regexp)
+ )
+
+(my-package replace
+ (:delay 5)
+ (add-hook 'occur-mode-hook #'hl-line-mode)
+ (my-keybind occur-mode-map "t" #'toggle-truncate-lines)
+ )
+
+
+;;; `xref' package
+(my-package xref
+ ;; All those have been changed for Emacs 28
+ (setq xref-show-definitions-function #'xref-show-definitions-completing-read) ; for M-.
+ (setq xref-show-xrefs-function #'xref-show-definitions-buffer)
+ )
+
+;;; wgrep (writable grep)
+(my-package wgrep
+ (:install t)
+ (:delay 15)
+ (setq wgrep-auto-save-buffer t)
+ (setq wgrep-change-readonly-file t)
+ (my-keybind grep-mode-map
+ "e" #'wgrep-change-to-wgrep-mode
+ "C-x C-q" #'wgrep-change-to-wgrep-mode
+ "C-c C-c" #'wgrep-finish-edit))
+
+;;; org-recoll
+(my-package org-recoll
+ (:delay 60)
+ (my-keybind org-recoll-mode-map
+ "n" #'org-next-visible-heading
+ "p" #'org-previous-visible-heading
+ "f" #'org-recoll-next-page
+ "b" #'org-recoll-previous-page
+ "<ret>" #'org-open-at-point
+ "q" #'quit-window))
+
+(provide 'ycp-grep)
diff --git a/emacs/.emacs.d/init/ycp-help.el b/emacs/.emacs.d/init/ycp-help.el
new file mode 100644
index 0000000..b699be9
--- /dev/null
+++ b/emacs/.emacs.d/init/ycp-help.el
@@ -0,0 +1,114 @@
+;;; ycp-help.el -- My configs for help -*- lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation.
+
+;; Author: Yuchen Pei <id@ypei.org>
+;; Protesilaos Stavrou <info@protesilaos.com>
+;; Maintainer: Yuchen Pei <id@ypei.org>
+;; Package-Requires: ((emacs "28.2"))
+
+;; This file is part of dotfiles.
+
+;; dotfiles is free software: you can redistribute it and/or modify it under
+;; the terms of the GNU Affero General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; dotfiles is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+;; Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public
+;; License along with dotfiles. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; My configs for help. Covers help, man, woman, eldoc, info etc.
+
+;;; Code:
+
+
+(my-package help-mode
+ (my-keybind help-mode-map
+ "x" #'describe-command
+ "v" #'describe-variable
+ "f" #'describe-function)
+ (setq help-window-select t)
+ (my-keybind global-map
+ "C-h h" nil
+ "C-h K" #'describe-keymap ; overrides `Info-goto-emacs-key-command-node'
+ "C-h c" #'describe-char ; overrides `describe-key-briefly'
+ "C-h D" #'shortdoc-display-group
+ )
+ )
+
+(my-package info
+ ;; TODO consider using `Info-additional-directory-list' instead
+ (add-to-list 'Info-directory-list (locate-user-emacs-file "info")))
+
+(my-keybind global-map
+ "C-h C-f" #'find-function
+ "C-h C-l" #'find-library
+ "C-h C-v" #'find-variable
+ "C-h C-p" #'list-packages)
+(my-setq-from-local find-function-C-source-directory)
+
+(my-package eldoc
+ (:delay 5)
+ (setq eldoc-echo-area-prefer-doc-buffer t)
+ )
+
+(my-package man
+ (:delay 10)
+ (setq Man-notify-method 'pushy)
+ (require 'my-buffer)
+ (add-to-list 'my-buffer-create-functions
+ '(Man-mode . man)))
+
+(my-package woman
+ (:delay 10)
+ (require 'my-buffer)
+ (add-to-list 'my-buffer-create-functions
+ '(woman-mode . woman)))
+
+(my-package help-at-pt
+ (setq help-at-pt-timer-delay .2)
+ (setq help-at-pt-display-when-idle t)
+ (help-at-pt-set-timer))
+
+(my-package my-help
+ (:delay 10)
+ (my-keybind global-map
+ "C-h M" #'my-woman-man
+ "C-h i" #'my-info-display-manual
+ "C-h ." #'my-describe-symbol-at-point
+ "\C-h!" #'my-external-command-open-source)
+ (my-keybind help-mode-map
+ "o" #'my-help-goto-symbol
+ "j" #'my-help-goto-symbol)
+ )
+
+(my-configure
+ (:delay 10)
+ (add-to-list 'my-buffer-create-functions '(Info-mode . 'my-info-display-manual)))
+
+;;;; Tooltips (tooltip-mode)
+(my-package tooltip
+ (:delay 15)
+ (setq tooltip-delay 0.5
+ tooltip-short-delay 0.5
+ x-gtk-use-system-tooltips nil
+ tooltip-frame-parameters
+ '((name . "tooltip")
+ (internal-border-width . 6)
+ (border-width . 0)
+ (no-special-glyphs . t)))
+ (autoload #'tooltip-mode "tooltip")
+ (tooltip-mode 1))
+
+(my-package my-utils
+ (:delay 15)
+ (my-setq-from-local my-docs-root-dir))
+
+(provide 'ycp-help)
diff --git a/emacs/.emacs.d/init/ycp-markup.el b/emacs/.emacs.d/init/ycp-markup.el
new file mode 100644
index 0000000..c001131
--- /dev/null
+++ b/emacs/.emacs.d/init/ycp-markup.el
@@ -0,0 +1,97 @@
+;;; ycp-markup.el -- My config for markup formats -*- lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation.
+
+;; Author: Yuchen Pei <id@ypei.org>
+;; Package-Requires: ((emacs "28.2"))
+
+;; This file is part of dotfiles.
+
+;; dotfiles is free software: you can redistribute it and/or modify it under
+;; the terms of the GNU Affero General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; dotfiles is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+;; Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public
+;; License along with dotfiles. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; My config for markup formats.
+
+;;; Code:
+
+
+
+;;; parsing and formatting markup and serialization languages: html, markdown,
+;;; xml, yaml, etc.
+;;; Some parts adapted from prot-dotfiles
+(my-package shr
+ (:delay 30)
+ (advice-add 'shr-heading :around #'my-shr-add-id-advice)
+ (setq shr-use-colors nil)
+ (setq shr-use-fonts nil)
+ (setq shr-max-image-proportion 0.6)
+ (setq shr-image-animate nil)
+ (setq shr-width fill-column)
+ (setq shr-max-width fill-column)
+ (setq shr-discard-aria-hidden t)
+ (setq shr-cookie-policy nil)
+ )
+
+(my-package tex-mode
+ (:delay 60)
+ (setq latex-run-command "pdflatex")
+ (setq tex-print-file-extension ".pdf"))
+
+(my-package texinfo
+ (:delay 60)
+ (my-keybind texinfo-mode-map "C-c C-c" #'makeinfo-buffer))
+
+(my-package yaml-mode
+ (:delay 60)
+ (:install t)
+ (add-to-list 'auto-mode-alist '("\\.yml\\'" . yaml-mode))
+ (add-hook 'yaml-mode-hook #'display-line-numbers-mode))
+
+;;; markdown
+(my-package markdown-mode
+ (:delay 60)
+ (my-keybind markdown-mode-map "C-c C-l" 'markdown-insert-link)
+ (setq markdown-hide-urls t)
+ (put 'markdown-translate-filename-function 'safe-local-variable 'functionp)
+ (require 'my-markdown)
+ (my-keybind markdown-mode-map "<ret>" 'my-markdown-maybe-follow-thing-at-point))
+
+;; mediawiki
+(my-package mediawiki (:delay 60))
+
+(my-package ledger-mode
+ (:install t)
+ (:delay 60)
+ (add-hook 'ledger-mode-hook
+ (lambda ()
+ (setq-local tab-always-indent 'complete)
+ (setq-local completion-cycle-threshold t)
+ (setq-local ledger-complete-in-steps t)
+ (setq-local company-mode nil)))
+ (setq ledger-binary-path "hledger"))
+
+;;; todo: open epub in emacs client with nov
+(my-package nov
+ (:delay 15)
+ (add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))
+ (setq nov-text-width fill-column)
+ (add-hook 'nov-mode-hook 'follow-mode)
+ (require 'my-nov)
+ (my-override nov-render-title)
+ (my-override nov-scroll-up)
+ )
+
+(provide 'ycp-markup)
+;;; ycp-markup.el ends here
diff --git a/emacs/.emacs.d/init/ycp-org.el b/emacs/.emacs.d/init/ycp-org.el
new file mode 100644
index 0000000..240cfcf
--- /dev/null
+++ b/emacs/.emacs.d/init/ycp-org.el
@@ -0,0 +1,417 @@
+;; -*- lexical-binding: t; -*-
+
+;;; the glorious org mode
+(my-package org
+ (my-keybind global-map
+ "M-u" #'org-store-link
+ "C-c a" #'org-agenda
+ "C-c c" #'org-capture
+ "<f6>" #'my-org-open-default-notes-file
+ )
+ (setq org-startup-folded 'overview)
+ (my-override org-next-link)
+ (my-override org-previous-link)
+ (my-override org--mouse-open-at-point)
+ (my-keybind org-mode-map
+ "M-l" #'org-insert-last-stored-link
+ "M-n" #'org-next-link
+ "M-p" #'org-previous-link
+ "C-c C-l" #'org-insert-link
+ "C-j" #'default-indent-new-line
+ )
+ (my-keybind minibuffer-mode-map "M-l" #'org-insert-last-stored-link)
+ (my-setq-from-local my-org-common-properties org-directory
+ my-org-doc-dir)
+ ;; disable auto-indent on RET
+ (add-hook 'org-mode-hook (lambda () (electric-indent-local-mode -1)))
+ ;; disable truncate lines
+ (add-hook 'org-mode-hook #'toggle-truncate-lines)
+ ;; disable yas-minor-mode for org
+ (add-hook 'org-mode-hook (lambda () (yas-minor-mode -1)))
+ (add-hook 'org-mode-hook (lambda () (setq-local tab-width 2)))
+
+ (setq org-adapt-indentation 'headline-data)
+ (setq org-special-ctrl-a/e t)
+ (setq org-special-ctrl-k t)
+ (setq org-M-RET-may-split-line '((default . nil)))
+ (setq org-catch-invisible-edits 'show)
+ (setq org-modules '(ol-bbdb ol-gnus ol-info))
+ (setq org-use-sub-superscripts '{})
+ (setq org-use-fast-todo-selection 'expert)
+ (setq org-fontify-quote-and-verse-blocks t)
+ (setq org-highlight-latex-and-related nil) ; other options affect elisp regexp
+ ; in src blocks
+ (setq org-log-done 'time)
+ (setq org-archive-location "%s_archive::")
+ (setq org-file-apps
+ '((auto-mode . emacs)
+ (directory . emacs)
+ ("\\.mm\\'" . default)
+ ("\\.x?html?\\'" . emacs)
+ ("\\.pdf\\'" . emacs)
+ ("\\.mp4\\'" . "xdg-open %s")))
+ (setq org-structure-template-alist
+ '(("a" . "export ascii")
+ ("c" . "center")
+ ("C" . "comment")
+ ("e" . "example")
+ ("E" . "export")
+ ("h" . "export html")
+ ("l" . "export latex")
+ ("m" . "src emacs-lisp")
+ ("q" . "quote")
+ ("s" . "src")
+ ("v" . "verse")))
+ (setq org-use-tag-inheritance nil)
+ (my-setq-from-local org-default-notes-file)
+ (setq org-export-backends '(ascii beamer html icalendar latex md odt org))
+ (setq org-image-actual-width '(400))
+ (setq org-log-into-drawer t)
+ (plist-put org-format-latex-options :scale 1.5)
+ (setq org-reverse-note-order t)
+ (add-hook 'before-save-hook #'my-org-update-updated)
+ )
+
+(my-package org-goto
+ (setq org-goto-interface 'outline-path-completion)
+ )
+
+(my-package org-element
+ ;; org-persist is buggy with encoding etc. let's disable it
+ (setq org-element-cache-persistent nil)
+ )
+
+;;; ox - org export
+(my-package ox
+ (:delay 60)
+ (setq org-export-headline-levels 8)
+ (require 'ox-html)
+ (setq org-html-prefer-user-labels t)
+ (setq org-html-self-link-headlines t)
+ (require 'ox-icalendar)
+ (setq org-icalendar-include-bbdb-anniversaries t)
+ (setq org-icalendar-include-todo t)
+ (setq org-icalendar-use-scheduled '(event-if-todo todo-start))
+ )
+
+(my-package org-id
+ (setq org-id-link-to-org-use-id 'create-if-interactive)
+ )
+
+;;; cite
+(my-package oc
+ (:delay 60)
+ (my-setq-from-local org-cite-global-bibliography)
+ )
+
+(my-package org-src
+ (:delay 10)
+ (setq org-edit-src-persistent-message nil)
+ (my-keybind org-src-mode-map "C-c C-c" #'org-edit-src-exit)
+ (setq org-src-window-setup 'current-window)
+ (setq org-src-preserve-indentation t) ;; useful for yaml and python
+ )
+
+(my-package org-agenda
+ (:delay 10)
+ (my-keybind global-map "C-c g" 'my-org-store-agenda-view-A)
+ (setq org-agenda-confirm-kill t)
+ (setq org-agenda-follow-indirect t)
+ (setq org-agenda-time-leading-zero t)
+ (setq org-agenda-todo-ignore-time-comparison-use-seconds t)
+ (setq org-agenda-todo-ignore-deadlines 'all)
+ (setq org-agenda-todo-ignore-scheduled 'all)
+ (setq org-agenda-todo-ignore-with-date 'all)
+ (setq org-agenda-todo-ignore-timestamp 'all)
+ (setq org-agenda-tags-todo-honor-ignore-options t)
+ (setq org-agenda-dim-blocked-tasks nil)
+ (setq org-agenda-sticky t)
+ (setq org-agenda-inhibit-startup t)
+ (my-setq-from-local org-agenda-files)
+ (setq org-agenda-skip-deadline-if-done nil)
+ (setq org-agenda-skip-scheduled-if-done nil)
+ (setq org-agenda-skip-timestamp-if-done t)
+ (setq org-agenda-start-on-weekday 6)
+ (setq org-agenda-custom-commands
+ `(("A" "Agenda and next"
+ ((agenda ""
+ ((org-agenda-span 'week)))
+ (tags-todo "PRIORITY=\"A\"" nil))
+ nil
+ ,(my-get-from-local my-org-agenda-and-next-export-files))
+ ("B" "Agenda and context"
+ ((agenda "" ((org-agenda-span 'week)))
+ (tags-todo "{^@.*}"))
+ nil)
+ ("@" "context todos"
+ ((tags-todo "{^@.*}"))
+ nil)))
+ (setq org-agenda-prefix-format
+ '((agenda . "%-5:c%?-12t% s")
+ (todo . "%-4:c")
+ (tags . "%-4:c")
+ (search . "%-4:c")))
+ (setq org-agenda-use-tag-inheritance nil)
+ (add-hook 'org-agenda-mode-hook #'hl-line-mode)
+ (add-hook 'org-agenda-after-show-hook 'my-org-agenda-after-show)
+ (org-defkey org-agenda-mode-map "d" #'org-agenda-deadline)
+ (org-defkey org-agenda-mode-map "s" #'org-agenda-schedule)
+ (setq org-agenda-window-setup 'other-window)
+ )
+
+(my-package ob-core
+ (setq org-babel-load-languages '((emacs-lisp . t) (shell . t)))
+ (setq org-confirm-babel-evaluate nil)
+ )
+
+(my-package org-capture
+ (setq org-capture-templates
+ `(("j" "Journal" entry
+ (file+olp+datetree ,(my-get-from-local my-org-journal-file))
+ "* %^{Title}
+:PROPERTIES:
+:CREATED: %U
+:END:
+
+%?")
+ ("t" "Todo" entry
+ (file+headline org-default-notes-file "Inbox")
+ "* TODO %a%?
+:PROPERTIES:
+:CREATED: %U
+:END:
+
+%i"
+ :prepend t)
+ ("ya" "Blank audio" entry
+ (file+headline org-default-notes-file "Audios")
+ nil
+ :prepend t)
+ ("book" "Blank books and papers" entry
+ (file+headline org-default-notes-file "Books and papers")
+ nil
+ :prepend t)
+ ("video" "Blank videos" entry
+ (file+headline org-default-notes-file "Videos")
+ nil
+ :prepend t)
+ ("entity" "Blank entities" entry
+ (file+headline org-default-notes-file "Entities")
+ nil
+ :prepend t)
+ ("videogame" "Blank video games" entry
+ (file+headline org-default-notes-file "Video games")
+ nil
+ :prepend t)
+ ("software" "Blank software" entry
+ (file+headline org-default-notes-file "Software")
+ nil
+ :prepend t)
+ ("organisation" "Blank organisation" entry
+ (file+headline org-default-notes-file "Organisations")
+ nil
+ :prepend t)
+ ("people" "Blank people" entry
+ (file+headline org-default-notes-file "People")
+ nil
+ :prepend t)
+ ("game" "Blank games" entry
+ (file+headline org-default-notes-file "Games")
+ nil
+ :prepend t)
+ ("location" "Blank location" entry
+ (file+headline org-default-notes-file "Locations")
+ nil
+ :prepend t))))
+
+(my-package org-clock
+ (setq org-clock-history-length 100)
+ (setq org-clock-in-switch-to-state "DOIN")
+ (setq org-clock-idle-time 10)
+ (setq org-clock-mode-line-total 'auto)
+ (setq org-clock-persist 'history)
+ (org-clock-persistence-insinuate))
+
+(my-package org-refile
+ (setq org-outline-path-complete-in-steps nil)
+ (setq org-refile-allow-creating-parent-nodes 'confirm)
+ (setq org-refile-targets '((org-agenda-files :maxlevel . 5)))
+ (setq org-refile-use-cache t)
+ (setq org-refile-use-outline-path t)
+ )
+
+;;; todo: some of these commands will take a while to be ready
+(my-package org-keys
+ (setq org-return-follows-link t)
+ (setq org-use-speed-commands t)
+ (setq org-speed-commands
+ '(("User commands")
+ ("m" . my-magit-clone-org-source)
+ ("c" . my-org-copy-property-value)
+ ("x" . my-org-osm-goto)
+ ("X" . my-osm-org-add-properties)
+ ("y" . my-grok-update-properties)
+ ("z" . my-org-orgzly-merge-link)
+ ("A" . org-attach)
+ ("P" . my-org-set-common-property)
+ ("N" . my-org-jump-to-last-visible-child)
+ ("d" . org-deadline)
+ ("s" . org-schedule)
+ ("S" . org-toggle-narrow-to-subtree)
+ (";" . org-timer-set-timer)
+ ("," . org-timer-pause-or-continue)
+ ("h" . my-org-entry-toggle-drawer-visibility)
+ ("Outline Navigation")
+ ("n" org-speed-move-safe 'org-next-visible-heading)
+ ("p" org-speed-move-safe 'org-previous-visible-heading)
+ ("f" org-speed-move-safe 'org-forward-heading-same-level)
+ ("b" org-speed-move-safe 'org-backward-heading-same-level)
+ ("F" . org-next-block)
+ ("B" . org-previous-block)
+ ("u" org-speed-move-safe 'outline-up-heading)
+ ("j" . org-goto)
+ ("g" org-refile
+ '(4))
+ ("Outline Visibility")
+ ("C" . org-shifttab)
+ (" " . org-display-outline-path)
+ ("s" . org-toggle-narrow-to-subtree)
+ ("k" . org-cut-subtree)
+ ("=" . org-columns)
+ ("Outline Structure Editing")
+ ("U" . org-metaup)
+ ("D" . org-metadown)
+ ("r" . org-metaright)
+ ("l" . org-metaleft)
+ ("R" . org-shiftmetaright)
+ ("L" . org-shiftmetaleft)
+ ("i" . my-org-append-subheading)
+ ("^" . org-sort)
+ ("w" . org-refile)
+ ("a" . org-archive-subtree-default-with-confirmation)
+ ("@" . org-mark-subtree)
+ ("#" . org-toggle-comment)
+ ("Clock Commands")
+ ("I" . org-clock-in)
+ ("O" . org-clock-out)
+ ("Meta Data Editing")
+ ("t" . org-todo)
+ ("," org-priority)
+ ("0" org-priority 32)
+ ("1" org-priority 65)
+ ("2" org-priority 66)
+ ("3" org-priority 67)
+ (":" . org-set-tags-command)
+ ("e" . org-set-effort)
+ ("E" . org-inc-effort)
+ ("W" lambda
+ (m)
+ (interactive "sMinutes before warning: ")
+ (org-entry-put
+ (point)
+ "APPT_WARNTIME" m))
+ ("Agenda Views etc")
+ ("v" . org-agenda)
+ ("/" . org-sparse-tree)
+ ("Misc")
+ ("o" . org-open-at-point)
+ ("?" . org-speed-command-help)
+ ("<" org-agenda-set-restriction-lock 'subtree)
+ (">" org-agenda-remove-restriction-lock)))
+ )
+
+;;;;
+;; org attach
+;;;;
+(my-package org-attach
+ (:delay 15)
+ (setq org-attach-store-link-p 'attached)
+ (require 'my-org)
+ (my-setq-from-local my-org-attach-copy-attached-targets)
+ (add-to-list 'org-attach-commands '((?k) my-org-attach-copy-attached-docs
+ "Copy attached docs."))
+ (require 'my-scihub)
+ (add-to-list 'org-attach-commands '((?p) my-org-attach-scihub
+ "Download document from scihub."))
+ (require 'my-calibre)
+ (add-to-list 'org-attach-commands '((?C) org-attach-calibre-book
+ "Attach from local calibre libray."))
+ (add-to-list 'org-attach-commands '((?V) my-org-attach-all-url-plaintext
+ "Fetch all urls to plaintext file"))
+ (my-override org-attach-url)
+ (add-to-list 'org-attach-commands '((?U) my-org-attach-url-plaintext
+ "Fetch url to plaintext file"))
+ (add-to-list 'org-attach-commands '((?A) my-org-attach-url-plaintext-all-media
+ "Fetch url to plaintext file, and all media
+ files therein."))
+ )
+
+;; org-protocol
+(my-package org-protocol
+ (:delay 30)
+ (require 'my-org)
+ (add-to-list 'org-protocol-protocol-alist
+ '("grok"
+ :protocol "grok"
+ :function my-org-protocol-grok)))
+
+;; org man links
+(my-package ol-man
+ (:delay 30)
+ (setq org-man-command 'woman))
+
+(my-package ol
+ (:delay 10)
+ (require 'my-buffer)
+ (add-to-list 'org-link-frame-setup
+ (cons 'file 'my-find-file-maybe-other-window)))
+
+(my-package my-org
+ (:delay 10)
+ (my-keybind org-mode-map
+ "C-c 1" #'my-org-insert-date-range
+ "C-c ns" #'my-org-substitute-gnus-link-after-archiving
+ "C-x w" #'my-org-copy-link-at-point
+ "C-'" #'my-org-store-link-and-return
+ "C-c M-w" #'my-org-copy-dwim
+ "C-c <f7>" #'my-org-open-shell-at-attach-dir
+ "C-M-n" #'my-org-next-block-or-results
+ "C-M-p" #'my-org-previous-block-or-results)
+ (add-hook 'org-follow-link-hook 'my-org-follow-link-after)
+ (my-override org-insert-all-links)
+ (my-override org-open-at-point-global)
+ (my-override org-refile-get-targets)
+ (my-override org-insert-last-stored-link)
+ (org-link-set-parameters "info" :follow #'my-org-info-open-new-window)
+ (org-link-set-parameters "rt" :follow #'my-org-rt-open-new-window)
+ (my-override org-src--make-source-overlay)
+ (my-server-timer my-org-clock-save-timer
+ nil 600 'my-org-clock-maybe-save)
+ (my-server-idle-timer my-org-refile-rebuild-cache-timer
+ 600 t 'my-org-refile-cache-rebuild)
+ (my-server-idle-timer my-org-agenda-redo-all-timer
+ 660 t 'my-org-agenda-redo-all)
+ (org-defkey org-agenda-mode-map "0" #'my-org-agenda-priority-0)
+ (org-defkey org-agenda-mode-map "1" #'my-org-agenda-priority-A)
+ (org-defkey org-agenda-mode-map "2" #'my-org-agenda-priority-B)
+ (org-defkey org-agenda-mode-map "3" #'my-org-agenda-priority-C)
+ (with-eval-after-load "org-capture"
+ (advice-add 'org-capture-place-template
+ :around 'my-org-capture-place-template-dont-delete-windows))
+ )
+
+(my-package my-org
+ (:delay 30)
+ (require 'my-web)
+ (org-link-set-parameters "http" :follow (lambda (url arg)
+ (my-browse-url
+ (concat "http:" url) arg)))
+ (org-link-set-parameters "https" :follow (lambda (url arg)
+ (my-browse-url
+ (concat "https:" url) arg)))
+ (require 'eww)
+ (define-key eww-mode-map (kbd "C-'") 'my-eww-org-protocol-grok)
+ )
+
+(provide 'ycp-org)
+;;; ycp-org.el ends here
diff --git a/emacs/.emacs.d/init/ycp-package.el b/emacs/.emacs.d/init/ycp-package.el
new file mode 100644
index 0000000..bdf24f7
--- /dev/null
+++ b/emacs/.emacs.d/init/ycp-package.el
@@ -0,0 +1,70 @@
+;;; ycp-package.el -- My configs for package -*- lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation.
+
+;; Author: Yuchen Pei <id@ypei.org>
+;; Package-Requires: ((emacs "28.2"))
+
+;; This file is part of dotfiles.
+
+;; dotfiles is free software: you can redistribute it and/or modify it under
+;; the terms of the GNU Affero General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; dotfiles is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+;; Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public
+;; License along with dotfiles. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; My configs for package. This should be the second require in the
+;; init file after my-package.
+
+;;; Code:
+
+
+
+;; TODO: The use of `my-allowed-package' may necessitate some refactoring to
+;; hide configs under an (my-package dummy)
+(cond
+ ((equal my-profile "emms")
+ (setq my-allowed-packages '(package windmove emms my-emms)))
+ ((equal my-profile "erc")
+ (setq my-allowed-packages '(package windmove icomplete modus-themes erc)))
+ (t
+ (setq my-omit-packages
+ '(typescript-mode tide web-mode flycheck ggtags crystal-mode
+ proof-general sml-mode emms my-emms erc))))
+
+(my-read-local-config)
+;; only start server on default profile
+(unless my-profile (server-start))
+
+;;; packages; customization
+(my-package package
+ (setq package-archives
+ '(("gnu" . "https://elpa.gnu.org/packages/")
+ ("elpa-devel" . "https://elpa.gnu.org/devel/")
+ ("nongnu" . "https://elpa.nongnu.org/nongnu/")))
+ (setq package-archive-priorities
+ '(("gnu" . 3)
+ ("nongnu" . 2)
+ ("elpa-deval" . 1)))
+ (setq package-pinned-packages
+ '((hcel . "elpa-devel")
+ (luwak . "elpa-devel")))
+ (add-hook 'package-menu-mode-hook #'hl-line-mode)
+)
+
+(my-package cus-edit
+ (my-keybind global-map
+ "C-c u u" #'customize
+ "C-c u g" #'customize-group
+ "C-c u o" #'customize-option))
+
+(provide 'ycp-package)
diff --git a/emacs/.emacs.d/init/ycp-pdf.el b/emacs/.emacs.d/init/ycp-pdf.el
new file mode 100644
index 0000000..d90a527
--- /dev/null
+++ b/emacs/.emacs.d/init/ycp-pdf.el
@@ -0,0 +1,60 @@
+;;; ycp-pdf.el -- My config for non-markup doc formats -*- lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation.
+
+;; Author: Yuchen Pei <id@ypei.org>
+;; Package-Requires: ((emacs "28.2"))
+
+;; This file is part of dotfiles.
+
+;; dotfiles is free software: you can redistribute it and/or modify it under
+;; the terms of the GNU Affero General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; dotfiles is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+;; Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public
+;; License along with dotfiles. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; My config for non-markup doc formats. Covers pdf, docx etc.
+
+;;; Code:
+
+
+
+(my-package pdf-tools
+ (:install t)
+ (:delay 15)
+ (pdf-loader-install))
+
+(my-package pdf-history
+ (:delay 15)
+ (my-keybind pdf-history-minor-mode-map
+ "l" #'pdf-history-backward
+ "r" #'pdf-history-forward
+ "N" nil
+ "P" nil)
+ )
+
+(my-package my-pdf-tools
+ (:delay 15)
+ (my-keybind pdf-view-mode-map
+ "i" #'my-pdf-outline-jump
+ "]" #'my-pdf-view-forward-node
+ "N" #'my-pdf-view-forward-node-same-depth
+ "[" #'my-pdf-view-backward-node
+ "P" #'my-pdf-view-backward-node-same-depth
+ "U" #'my-pdf-view-backward-node-lower-depth
+ "." #'my-pdf-view-enlarge-a-bit
+ "," #'my-pdf-view-shrink-a-bit)
+ )
+
+(provide 'ycp-pdf)
+;;; ycp-pdf.el ends here
+
diff --git a/emacs/.emacs.d/init/ycp-prog.el b/emacs/.emacs.d/init/ycp-prog.el
new file mode 100644
index 0000000..9ab868b
--- /dev/null
+++ b/emacs/.emacs.d/init/ycp-prog.el
@@ -0,0 +1,373 @@
+;;; ycp-prog.el -- My config for programming -*- lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation.
+
+;; Author: Yuchen Pei <id@ypei.org>
+;; Package-Requires: ((emacs "28.2"))
+
+;; This file is part of dotfiles.
+
+;; dotfiles is free software: you can redistribute it and/or modify it under
+;; the terms of the GNU Affero General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; dotfiles is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+;; Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public
+;; License along with dotfiles. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; My config for programming. Covers comint, shell, eshell, compile,
+;; xref, eglot, prog-mode etc.
+
+;;; Code:
+
+
+
+;;; comint, shell, eshell
+(my-package comint
+ (setq ansi-color-for-comint-mode t)
+ (setq-default comint-scroll-to-bottom-on-input t)
+ (setq-default comint-scroll-to-bottom-on-output nil)
+ (setq-default comint-input-autoexpand 'input)
+ (setq comint-prompt-read-only t)
+ (setq comint-buffer-maximum-size 9999)
+ (setq comint-completion-autolist t)
+ (define-key comint-mode-map (kbd "C-<up>") 'windmove-up)
+ (define-key comint-mode-map (kbd "C-<down>") 'windmove-down)
+ (setq comint-input-ring-size 5000)
+ (setq comint-input-ignoredups t)
+ (setq comint-terminfo-terminal "dumb")
+ (setq comint-password-prompt-regexp
+ (concat comint-password-prompt-regexp
+ "\\|^BECOME password:\\s *\\'"
+ "\\|^SSH password:\\s *\\'"))
+ )
+
+(my-package shell
+ (:delay 5)
+ (setq shell-command-prompt-show-cwd t)
+ (setq shell-input-autoexpand 'input)
+
+ (my-keybind shell-mode-map
+ "<up>" #'comint-previous-input
+ "<down>" #'comint-next-input
+ "C-c C-k" #'comint-clear-buffer
+ "C-c C-w" #'comint-write-output)
+ (setq shell-command-prompt-show-cwd t)
+ (add-hook 'shell-mode-hook
+ (lambda ()
+ (setq comint-input-ring-file-name "~/.bash_history")))
+ (add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)
+ )
+
+(my-package sh-script
+ (:delay 5)
+ (setq sh-basic-offset 2)
+ (add-to-list 'auto-mode-alist '("PKGBUILD" . sh-mode))
+)
+
+(my-package my-prog
+ (:delay 10)
+ ;; tab-width 8 for ls etc.
+ (add-hook 'shell-mode-hook 'my-set-tab-width-to-8)
+ (my-keybind comint-mode-map "C-<return>"
+ #'my-comint-send-input-and-return-prompt)
+ (add-to-list 'my-buffer-create-functions
+ '(shell-mode . my-shell-with-directory))
+ (my-keybind shell-mode-map "<f2>" #'my-restart-shell)
+ (add-hook 'shell-mode-hook 'my-shell-disable-company-if-remote)
+ )
+
+(my-package eshell
+ (:delay 60)
+ (setq eshell-modules-list
+ '(eshell-alias eshell-banner eshell-basic eshell-cmpl eshell-dirs eshell-glob eshell-hist eshell-ls eshell-pred eshell-prompt eshell-script eshell-term eshell-tramp eshell-unix))
+ )
+
+(my-package bash-completion
+ (:install t)
+ (:delay 15))
+
+;;; prog modes: c, c++, elisp, js, css, ts,
+(my-package prog-mode
+ (add-hook 'prog-mode-hook #'display-line-numbers-mode)
+ (add-hook 'prog-mode-hook (lambda () (setq-local tab-width 2))))
+
+;; cmake
+(my-package cmake-mode
+ (:delay 60))
+
+;;; eglot
+(my-package eglot
+ (:delay 10)
+ (add-to-list 'eglot-server-programs
+ '((php-mode phps-mode)
+ "phpactor" "language-server" "-vvv"))
+ (add-hook 'before-save-hook (lambda () (interactive)
+ (when (eglot-managed-p)
+ (unless (eq major-mode 'haskell-mode)
+ (eglot-format-buffer)))))
+ (setq-default eglot-workspace-configuration
+ '((:pylsp
+ (plugins
+ (pylint
+ (enabled . t)
+ (executable . "/usr/bin/pylint"))))
+ (:haskell-language-server
+ (haskell
+ (formattingProvider . :json-false)))))
+ (add-to-list 'eglot-server-programs
+ '(haskell-mode
+ "haskell-language-server-wrapper" "--lsp" "--debug"))
+
+ ;; I'm not sure why this is needed, but it throws an error if I remove it
+ (cl-defmethod project-root ((project (head eglot-project)))
+ (cdr project))
+
+ (defun my-project-try-tsconfig-json (dir)
+ (when-let* ((found (locate-dominating-file dir "tsconfig.json")))
+ (cons 'eglot-project found)))
+
+ (add-hook 'project-find-functions
+ 'my-project-try-tsconfig-json nil nil)
+
+ (add-to-list 'eglot-server-programs
+ '((typescript-mode) "typescript-language-server" "--stdio")))
+
+(my-package cc-mode
+ (:delay 5)
+ (define-key c-mode-map (kbd "C-c C-c") 'compile)
+ )
+
+(my-package my-prog
+ (:delay 10)
+ (add-hook 'c-mode-hook 'my-c-set-compile-command)
+ (my-keybind global-map "C-c 8" #'my-set-tab-width-to-8)
+ )
+
+;;; emacs-lisp mode
+(my-package elisp-mode
+ (my-keybind emacs-lisp-mode-map "C-c C-c" #'eval-buffer)
+ (add-hook 'emacs-lisp-mode-hook (lambda () (auto-fill-mode 1)))
+ (setq print-length 1000)
+ (my-keybind global-map
+ "<f5>" #'my-toggle-debug-on-error-quit
+ "C-c e e" (lambda () (interactive)
+ (find-file (locate-user-emacs-file "init.el")))
+ "C-c e d" (lambda () (interactive)
+ (find-file (locate-user-emacs-file "init")))
+ "C-c e m" (lambda () (interactive)
+ (find-file (locate-user-emacs-file "lisp/my")))
+ "C-c e b" (lambda () (interactive)
+ (my-switch-to-buffer-matching-major-mode
+ 'emacs-lisp-mode)))
+ ;; for deep recursion, e.g. in radix tree
+ (setq max-specpdl-size 32000)
+ )
+
+;;; paredit
+(my-package paredit
+ (:install t)
+ (add-hook 'emacs-lisp-mode-hook #'enable-paredit-mode)
+ (add-hook 'eval-expression-minibuffer-setup-hook #'enable-paredit-mode)
+ (add-hook 'ielm-mode-hook #'enable-paredit-mode)
+ (add-hook 'lisp-mode-hook #'enable-paredit-mode)
+ (add-hook 'lisp-data-mode-hook #'enable-paredit-mode)
+ (add-hook 'lisp-interaction-mode-hook #'enable-paredit-mode)
+ (add-hook 'scheme-mode-hook #'enable-paredit-mode)
+ (my-keybind paredit-mode-map
+ "M-<left>" #'paredit-forward-barf-sexp
+ "M-<right>" #'paredit-forward-slurp-sexp
+ "C-<left>" nil
+ "C-<right>" nil
+ "M-?" nil
+ "C-j" nil ;not ideal, we just want to unshadow it in lisp-interaction-mode
+ "<RET>" #'paredit-newline
+ "M-s" nil
+ "M-o" #'paredit-splice-sexp
+ "M-h" #'paredit-convolute-sexp)
+ )
+
+;;; flymake
+(my-package flymake
+ (:install t)
+ (:delay 15)
+ (my-keybind flymake-mode-map
+ "M-n" #'flymake-goto-next-error
+ "M-p" #'flymake-goto-prev-error))
+
+(my-package my-prog
+ (require 'xref)
+ (my-override xref-query-replace-in-results))
+
+(my-package js
+ (:delay 60)
+ (setq js-indent-level 2)
+ (add-hook 'js-mode-hook 'subword-mode)
+ (my-keybind js-mode-map "M-." #'xref-find-definitions)
+ )
+
+(my-package typescript-mode
+ (:delay 60)
+ (:install t)
+ (add-to-list 'auto-mode-alist '("\\.ts\\'" . typescript-mode))
+ (setq typescript-indent-level 2)
+ )
+
+(my-package tide
+ (:delay 60)
+ (require 'my-tide)
+ ;; aligns annotation to the right hand side
+ (setq company-tooltip-align-annotations t)
+
+ ;; formats the buffer before saving
+ (add-hook 'before-save-hook 'tide-format-before-save)
+
+ (add-hook 'typescript-mode-hook #'setup-tide-mode)
+ (add-hook 'typescript-mode-hook 'subword-mode)
+ )
+
+(my-package web-mode
+ (:delay 60)
+ (:install t)
+ (add-to-list 'auto-mode-alist '("\\.tsx\\'" . web-mode))
+ (add-to-list 'auto-mode-alist '("\\.jsx\\'" . web-mode))
+ (setq web-mode-content-types-alist '(("jsx" . "\\.js[x]?\\'")))
+ (setq web-mode-markup-indent-offset 2)
+ (setq web-mode-code-indent-offset 2)
+ (add-hook 'web-mode-hook
+ (lambda ()
+ (when (string-equal "tsx" (file-name-extension buffer-file-name))
+ (my-setup-tide-mode))))
+ )
+
+(my-package flycheck
+ (:delay 60)
+ (flycheck-add-mode 'typescript-tslint 'web-mode)
+ )
+
+(my-package css-mode
+ (setq css-indent-offset 2))
+
+(my-package haskell-mode
+ (:install t)
+ (:delay 60)
+ ;; do we need to require haskell-command?
+ (setq haskell-compile-command
+ "ghc -Wall -ferror-spans -fforce-recomp -dynamic -c %s")
+ (my-keybind haskell-mode-map "C-c C-c" #'haskell-compile)
+ (setq haskell-mode-stylish-haskell-path "brittany")
+ (setq haskell-stylish-on-save t)
+ (my-setq-from-local haskell-hoogle-url)
+ (add-hook 'haskell-mode-hook 'subword-mode)
+ (add-hook 'haskell-mode-hook 'interactive-haskell-mode)
+ (add-hook 'haskell-mode-hook
+ (lambda ()
+ (set (make-local-variable 'company-backends)
+ (append '((company-capf company-dabbrev-code))
+ company-backends))))
+ (setq haskell-interactive-popup-errors t)
+ (setq haskell-process-suggest-hoogle-imports t)
+ (setq haskell-process-log t)
+ (cl-pushnew '(haskell-process-use-ghci . t)
+ safe-local-variable-values :test #'equal)
+ (cl-pushnew '(haskell-indent-spaces . 4)
+ safe-local-variable-values :test #'equal)
+ (cl-pushnew '(haskell-tags-on-save . t)
+ safe-local-variable-values :test #'equal)
+ (cl-pushnew '(haskell-indentation-where-post-offset . 2)
+ safe-local-variable-values :test #'equal)
+ (cl-pushnew '(haskell-indentation-where-pre-offset . 2)
+ safe-local-variable-values :test #'equal)
+ (cl-pushnew '(haskell-indentation-ifte-offset . 4)
+ safe-local-variable-values :test #'equal)
+ (cl-pushnew '(haskell-indentation-left-offset . 4)
+ safe-local-variable-values :test #'equal)
+ (cl-pushnew '(haskell-indentation-starter-offset . 1)
+ safe-local-variable-values :test #'equal)
+ (cl-pushnew '(haskell-indentation-layout-offset . 4)
+ safe-local-variable-values :test #'equal))
+
+(my-package hcel
+ ;; fixme: credential
+ (:delay 60)
+ (:install t)
+ ;; The official one is https://haskell-code-explorer.mfix.io
+ (my-setq-from-local hcel-host)
+ (my-keybind global-map
+ "C-c hh" #'hcel
+ "C-c hi" #'hcel-global-ids
+ "C-c ho" #'hcel-help)
+ )
+
+(my-package hcel-haddorg
+ (:delay 60)
+ ;; fixme: credential
+ (my-setq-from-local hcel-haddorg-dir))
+
+(my-package ggtags
+ (:install t)
+ (:delay 60)
+ (my-keybind ggtags-navigation-map
+ ggtags-navigation-map "M-<" nil
+ ggtags-navigation-map "M->" nil))
+
+(my-package phps-mode
+ (:install t)
+ (:delay 60)
+ (add-to-list 'auto-mode-alist '("\\.\\(?:php[s345]?\\|phtml\\)\\'" . phps-mode))
+ (add-to-list 'auto-mode-alist '("\\.\\(?:php\\.inc\\|stub\\)\\'" . phps-mode))
+ (add-to-list 'auto-mode-alist '("/\\.php_cs\\(?:\\.dist\\)?\\'" . phps-mode))
+ (add-hook 'before-save-hook (lambda () (interactive)
+ (when (eq major-mode 'phps-mode)
+ (phps-mode-format-buffer)))))
+
+(my-package crystal-mode
+ (:delay 60)
+ (require 'flycheck-crystal))
+
+(my-package imenu
+ (:delay 5)
+ (my-keybind global-map "C-c i" #'imenu)
+)
+
+;;; proof-general
+(my-package proof-general
+ (:install t)
+ (:delay 60)
+ (setq coq-prog-name "/usr/bin/coqtop")
+ (setq coq-compiler "~/.opam/default/bin/coqc")
+ (setq coq-prog-env '("PATH=/usr/bin/:$HOME/.opam/default/bin/"))
+ (setq coq-diffs 'on)
+ (setq proof-three-window-enable nil))
+
+;;; tree-sitter
+(add-to-list 'load-path (locate-user-emacs-file "lisp/elisp-tree-sitter/core"))
+(add-to-list 'load-path (locate-user-emacs-file "lisp/elisp-tree-sitter/lisp"))
+(my-package tree-sitter
+ (:delay 15)
+ (require 'tree-sitter-hl)
+ (require 'tree-sitter-langs)
+ (require 'tree-sitter-debug)
+ (require 'tree-sitter-query)
+ (add-to-list 'tree-sitter-major-mode-language-alist
+ '(haskell-mode . haskell))
+ (add-to-list 'tree-sitter-major-mode-language-alist
+ '(phps-mode . php))
+ (global-tree-sitter-mode)
+ (add-hook 'tree-sitter-after-on-hook #'tree-sitter-hl-mode))
+
+;;; sml
+(my-package sml-mode
+ (:install t)
+ (:delay 60)
+ (setq sml-indent-level 2))
+
+(provide 'ycp-prog)
+;;; ycp-prog.el ends here
diff --git a/emacs/.emacs.d/init/ycp-project.el b/emacs/.emacs.d/init/ycp-project.el
new file mode 100644
index 0000000..d8c2628
--- /dev/null
+++ b/emacs/.emacs.d/init/ycp-project.el
@@ -0,0 +1,45 @@
+;;; ycp-project.el -- My config for project -*- lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation.
+
+;; Author: Yuchen Pei <id@ypei.org>
+;; Package-Requires: ((emacs "28.2"))
+
+;; This file is part of dotfiles.
+
+;; dotfiles is free software: you can redistribute it and/or modify it under
+;; the terms of the GNU Affero General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; dotfiles is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+;; Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public
+;; License along with dotfiles. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; My config for project-related functionalities.
+
+;;; Code:
+
+
+(my-package my-project
+ (:delay 15)
+ (my-keybind global-map
+ "\C-xpl" #'my-project-copy-license-file-to-project
+ "\C-xpS" #'my-project-shell-at
+ "\C-xpD" #'my-project-dired-at
+ "\C-xpR" #'my-project-rgrep-at
+ "\C-xpC" #'my-project-code-stats)
+ (my-server-idle-timer
+ my-project-remember-projects-timer
+ 300 t
+ 'my-project-remember-all-projects)
+ )
+
+(provide 'ycp-project)
+;;; ycp-project.el ends here
diff --git a/emacs/.emacs.d/init/ycp-system.el b/emacs/.emacs.d/init/ycp-system.el
new file mode 100644
index 0000000..3d52d34
--- /dev/null
+++ b/emacs/.emacs.d/init/ycp-system.el
@@ -0,0 +1,85 @@
+;;; ycp-system.el -- My config for things working with the underlying system -*- lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation.
+
+;; Author: Yuchen Pei <id@ypei.org>
+;; Protesilaos Stavrou <info@protesilaos.com>
+;; Maintainer: Yuchen Pei <id@ypei.org>
+;; Package-Requires: ((emacs "28.2"))
+
+;; This file is part of dotfiles.
+
+;; dotfiles is free software: you can redistribute it and/or modify it under
+;; the terms of the GNU Affero General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; dotfiles is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+;; Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public
+;; License along with dotfiles. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; My config for things working with the underlying system that do not
+;; seem to be clients to system utilities. Covers process monitor,
+;; tramp etc.
+
+;;; Code:
+
+
+;;; `proced' (process monitor, similar to `top')
+(my-package proced
+ (:delay 30)
+ (setq proced-auto-update-flag t)
+ (setq proced-auto-update-interval 5)
+ (setq proced-descend t)
+ (setq proced-filter 'user))
+
+;;; `tramp'
+(my-package tramp
+ (:delay 15)
+ (setq tramp-default-method "ssh")
+ (setq explicit-shell-file-name "/bin/bash")
+ (add-to-list 'tramp-remote-path 'tramp-own-remote-path)
+
+ (connection-local-set-profile-variables
+ 'termux-bash
+ '((explicit-shell-file-name . "/data/data/com.termux/files/usr/bin/bash")
+ (shell-file-name . "/data/data/com.termux/files/usr/bin/bash")
+ (tramp-remote-path . ("/data/data/com.termux/files/usr/bin"))))
+ (connection-local-set-profiles
+ `(:application tramp :protocol "ssh"
+ :machine ,(my-get-from-local my-tramp-termux-machine))
+ 'termux-bash)
+
+ (connection-local-set-profile-variables
+ 'ghcup-bash
+ '((tramp-remote-path . ("~/.ghcup/bin" "~/.local/bin" tramp-default-remote-path))))
+ (connection-local-set-profiles
+ `(:application tramp :protocol "ssh"
+ :machine ,(my-get-from-local my-tramp-ghcup-machine))
+ 'ghcup-bash)
+
+ (connection-local-set-profile-variables
+ 'guix-bash
+ '((explicit-shell-file-name . "/run/current-system/profile/bin/sh")
+ (shell-file-name . "/run/current-system/profile/bin/sh")
+ (tramp-remote-path . ("/run/current-system/profile/bin" "/run/current-system/profile/sbin"))))
+ (connection-local-set-profiles
+ `(:application tramp :protocol "ssh"
+ :machine ,(my-get-from-local my-tramp-guix-machine))
+ 'guix-bash)
+
+ (connection-local-set-profile-variables
+ 'adb-shell
+ '((explicit-shell-file-name . "/system/bin/sh")))
+ (connection-local-set-profiles
+ '(:application tramp :protocol "adb")
+ 'adb-shell))
+
+(provide 'ycp-system)
+;;; ycp-system.el ends here
diff --git a/emacs/.emacs.d/init/ycp-theme.el b/emacs/.emacs.d/init/ycp-theme.el
new file mode 100644
index 0000000..ee76311
--- /dev/null
+++ b/emacs/.emacs.d/init/ycp-theme.el
@@ -0,0 +1,46 @@
+;;; ycp-theme.el -- My configs for themes related -*- lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation.
+
+;; Author: Yuchen Pei <id@ypei.org>
+;; Package-Requires: ((emacs "28.2"))
+
+;; This file is part of dotfiles.
+
+;; dotfiles is free software: you can redistribute it and/or modify it under
+;; the terms of the GNU Affero General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; dotfiles is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+;; Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public
+;; License along with dotfiles. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; My configs for themes related. Covers themes, faces etc.
+
+;;; Code:
+
+
+
+(my-package modus-themes
+ (:install t)
+ (setq
+ custom-safe-themes
+ '("896e4305e7c10f3217c5c0a0ef9d99240c3342414ec5bfca4ec4bff27abe2d2d"))
+ (setq custom-enabled-themes '(modus-operandi-tinted))
+ (modus-themes-load-theme 'modus-operandi-tinted)
+)
+
+(set-face-attribute 'default nil :family "Ubuntu Mono" :foundry "DAMA" :slant
+ 'normal :weight 'normal :height 150 :width 'normal)
+(set-face-attribute 'fixed-pitch nil :family "Ubuntu Mono" :foundry "DAMA"
+ :slant 'normal :weight 'normal :height 150 :width 'normal)
+
+(provide 'ycp-theme)
+;;; ycp-theme.el ends here
diff --git a/emacs/.emacs.d/init/ycp-time.el b/emacs/.emacs.d/init/ycp-time.el
new file mode 100644
index 0000000..bc43764
--- /dev/null
+++ b/emacs/.emacs.d/init/ycp-time.el
@@ -0,0 +1,141 @@
+;;; ycp-time.el -- My config for time related -*- lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation.
+
+;; Author: Yuchen Pei <id@ypei.org>
+;; Protesilaos Stavrou <info@protesilaos.com>
+;; Maintainer: Yuchen Pei <id@ypei.org>
+;; Package-Requires: ((emacs "28.2"))
+
+;; This file is part of dotfiles.
+
+;; dotfiles is free software: you can redistribute it and/or modify it under
+;; the terms of the GNU Affero General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; dotfiles is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+;; Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public
+;; License along with dotfiles. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; My config for time related. Covers date, time, calendar, holidays etc.
+
+;;; Code:
+
+
+
+(my-configure
+ (my-setq-from-local calendar-latitude calendar-longitude calendar-location-name)
+ (setq calendar-mark-holidays-flag t)
+
+;;;;; World clock (M-x world-clock)
+ (setq display-time-world-list t)
+ (setq zoneinfo-style-world-list ; timedatectl list-timezones
+ '(("Pacific/Honolulu" "Honolulu")
+ ("America/Los_Angeles" "Los Angeles")
+ ("America/Chicago" "Chicago")
+ ("America/New_York" "Boston")
+ ("UTC" "UTC")
+ ("Europe/London" "Coventry")
+ ("Europe/Berlin" "Berlin")
+ ("Africa/Khartoum" "Khartoum")
+ ("Europe/Helsinki" "Helsinki")
+ ("Asia/Dubai" "Dubai")
+ ("Asia/Yekaterinburg" "Yekaterinburg")
+ ("Asia/Calcutta" "Delhi")
+ ("Asia/Shanghai" "Shanghai")
+ ("Pacific/Auckland" "Auckland")))
+
+ ;; All of the following variables are for Emacs 28
+ (require 'time)
+ (setq world-clock-list t)
+ (setq world-clock-time-format "%R %z %A %d %B")
+ (setq world-clock-buffer-name "*world-clock*") ; Placement handled by `display-buffer-alist'
+ (setq world-clock-timer-enable t)
+ (setq world-clock-timer-second 60)
+
+ ;; Holidays
+ (setq holiday-other-holidays
+ '(
+ (holiday-float 4 1 3 "Sechseläuten (Burning of Böögg)")
+ (holiday-fixed 3 8 "Women's Day")
+ (holiday-chinese 4 8 "Buddha's birthday (East Asia)")
+ (holiday-fixed 4 26 "World Intellectual Pooperty Day")
+ (holiday-fixed 4 30 "Walpurgis Night")
+ (holiday-fixed 5 1 "May Day")
+ (holiday-fixed 5 12 "International Nurses Day")
+ (holiday-fixed 6 4 "International Nothing Happened On This Day")
+ (holiday-float 6 6 1 "Midsommar" 20)
+ (holiday-float 9 6 3 "Software Freedom Day")
+ (holiday-islamic 10 1 "Hari Raya Puasa")
+ (holiday-fixed 12 13 "St Lucia Day")
+ (holiday-easter-etc -47 "Fat Tuesday / Fettisdagen / Pancake Tuesday / Mardi Gras")
+ (holiday-easter-etc 39 "Ascension Day")
+ (holiday-easter-etc 60 "Corpus Christi")
+ )
+ calendar-chinese-all-holidays-flag t
+ holiday-local-holidays
+ '(
+ (holiday-fixed 1 26 "Australia Day (Vic holiday)")
+ (holiday-float 3 1 2 "Labour Day (Vic holiday)")
+ (holiday-fixed 4 25 "Anzac Day (Vic holiday)")
+ (holiday-float 6 1 2 "Monarch's Birthday (Vic oliday)")
+ (holiday-fixed 6 30 "End of financial year")
+ (holiday-float 9 5 -1 "(Possibly) Friday before the AFL Grand Final (Vic holiday)")
+ (holiday-float 10 5 1 "(Possibly) Friday before the AFL Grand Final (Vic holiday)")
+ (holiday-float 11 2 1 "Melbourne Cup (Vic holiday)")
+ )
+ holiday-general-holidays
+ '(
+ (holiday-fixed 1 1 "New Year's Day")
+ (holiday-fixed 2 14 "Valentine's Day")
+ (holiday-fixed 3 17 "St. Patrick's Day")
+ (holiday-fixed 4 1 "April Fools' Day")
+ (holiday-float 5 0 2 "Mother's Day")
+ (holiday-float 6 0 3 "Father's Day")
+ (holiday-fixed 7 4 "US Independence Day")
+ (holiday-fixed 10 31 "Halloween")
+ (holiday-float 11 4 4 "Thanksgiving")
+ )
+ holiday-bahai-holidays
+ '()
+ holiday-hebrew-holidays
+ '()
+ )
+ (setq calendar-holidays
+ (append holiday-general-holidays holiday-local-holidays
+ holiday-other-holidays holiday-christian-holidays
+ holiday-hebrew-holidays holiday-islamic-holidays
+ holiday-bahai-holidays holiday-oriental-holidays
+ holiday-solar-holidays
+ (my-get-from-local my-holiday-personal-holidays)))
+ (put 'list-timers 'disabled nil)
+ )
+
+(my-package appt
+ (:delay 20)
+ (setq appt-message-warning-time 5)
+ (setq appt-display-duration 30)
+ (setq appt-display-interval 5)
+ ;; dbus notification of appt
+ (require 'my-time)
+ (setq appt-disp-window-function #'my-app-display-window)
+ ;; with org-agenda-to-appt
+ (require 'org-clock)
+ (require 'my-utils)
+ (when (boundp 'appt-to-agenda-timer)
+ (cancel-timer appt-to-agenda-timer))
+ (when (my-server-p)
+ (setq appt-to-agenda-timer
+ (run-at-time
+ "07:00am"
+ 86400 #'org-agenda-to-appt))))
+
+(provide 'ycp-time)
+;;; ycp-time.el ends here
diff --git a/emacs/.emacs.d/init/ycp-vc.el b/emacs/.emacs.d/init/ycp-vc.el
new file mode 100644
index 0000000..49ef58e
--- /dev/null
+++ b/emacs/.emacs.d/init/ycp-vc.el
@@ -0,0 +1,89 @@
+;;; ycp-vc.el -- My config for vcs related -*- lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation.
+
+;; Author: Yuchen Pei <id@ypei.org>
+;; Package-Requires: ((emacs "28.2"))
+
+;; This file is part of dotfiles.
+
+;; dotfiles is free software: you can redistribute it and/or modify it under
+;; the terms of the GNU Affero General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; dotfiles is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+;; Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public
+;; License along with dotfiles. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; My config for vcs related. Covers diff, vc, magit, ediff etc.
+
+;;; Code:
+
+
+
+;;; vc, magit, diff
+(my-package vc-hooks
+ (:delay 5)
+ ;;; avoid the "file is symlink to git controlled repo, follow?"
+ (setq vc-follow-symlinks t)
+)
+
+;;;; `diff-mode'
+(my-package diff-mode
+ (setq diff-default-read-only t)
+ (setq diff-advance-after-apply-hunk t)
+ (setq diff-update-on-the-fly t)
+ ;; The following are from Emacs 27.1
+ (setq diff-font-lock-prettify t)
+ (setq diff-font-lock-syntax 'hunk-also)
+ (add-to-list 'safe-local-variable-values '(diff-add-log-use-relative-names . t)))
+
+(my-package ediff
+ (:delay 30)
+;;;; `ediff'
+ (setq ediff-keep-variants nil)
+ (setq ediff-make-buffers-readonly-at-startup nil)
+ (setq ediff-show-clashes-only t)
+ (setq ediff-split-window-function 'split-window-horizontally)
+ (setq ediff-window-setup-function 'ediff-setup-windows-plain)
+ )
+
+(my-package vc-git
+ (:delay 30)
+ (add-to-list 'safe-local-variable-values
+ '(vc-git-annotate-switches . "-w")))
+
+(my-package git-commit
+ (:install t)
+ (:delay 30)
+ (setq git-commit-summary-max-length 50)
+ (setq git-commit-style-convention-checks '(non-empty-second-line)))
+
+(my-package magit
+ (:install t)
+ (:delay 30)
+
+ (require 'magit-diff)
+ (setq magit-diff-refine-hunk t)
+
+ (require 'magit-repos)
+ (my-setq-from-local magit-repository-directories)
+ (put 'magit-clean 'disabled nil)
+)
+
+(my-package my-magit
+ (:delay 30)
+ (my-keybind global-map
+ "\C-xpM" #'my-project-magit-at))
+
+(my-package magit-annex
+ (:delay 60))
+
+(provide 'ycp-vc)
diff --git a/emacs/.emacs.d/init/ycp-web.el b/emacs/.emacs.d/init/ycp-web.el
new file mode 100644
index 0000000..af13d5c
--- /dev/null
+++ b/emacs/.emacs.d/init/ycp-web.el
@@ -0,0 +1,165 @@
+;;; ycp-web.el -- My config for web related -*- lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation.
+
+;; Author: Yuchen Pei <id@ypei.org>
+;; Package-Requires: ((emacs "28.2"))
+
+;; This file is part of dotfiles.
+
+;; dotfiles is free software: you can redistribute it and/or modify it under
+;; the terms of the GNU Affero General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; dotfiles is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
+;; Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public
+;; License along with dotfiles. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; My config for web related. Covers cookies, web browsing, clients to
+;; web services like osm and openlibrary
+
+;;; Code:
+
+
+
+;; disable cookies
+(setq url-cookie-untrusted-urls ".*")
+(ignore-errors (cancel-timer url-cookie-timer))
+
+(setq shr-cookie-policy nil)
+
+(my-package luwak
+ (:delay 10)
+ (:install t)
+ (require 'luwak-org)
+ (require 'my-utils)
+ (setq luwak-url-rewrite-function 'my-rewrite-url)
+ (setq luwak-tor-switch nil)
+)
+
+;;; openlibrary
+(my-package my-openlibrary
+ (:delay 15))
+
+(my-package osm
+ (:install t)
+ (:delay 30)
+ (require 'my-osm)
+ (my-keybind osm-mode-map
+ "C-<left>" nil
+ "C-<right>" nil
+ "C-<up>" nil
+ "C-<down>" nil
+ "c" #'my-osm-show-center)
+ (require 'osm-ol)
+ )
+
+(my-package hnreader
+ (:delay 30)
+ (require 'my-hnreader)
+ (my-override hnreader--print-frontpage)
+ (my-override hnreader--print-frontpage-item)
+ (my-override hnreader--print-comments))
+
+(my-package buildbot
+ (:delay 30)
+ (my-setq-from-local buildbot-host buildbot-github-status-builders)
+ (setq buildbot-builders (ignore-error (buildbot-get-all-builders)))
+)
+
+(my-package eww
+ (:delay 60)
+ (advice-add 'eww-browse-url :filter-args #'my-rewrite-url-advice)
+ (advice-add 'eww :filter-args #'my-rewrite-url-advice)
+ (setq eww-restore-desktop t)
+ (setq eww-download-directory (expand-file-name "~/Downloads"))
+ (setq eww-bookmarks-directory (locate-user-emacs-file "eww-bookmarks"))
+ (setq eww-history-limit 150)
+ (setq eww-use-external-browser-for-content-type
+ "\\`\\(video/\\|audio\\)") ; On GNU/Linux check your mimeapps.list
+ (setq eww-browse-url-new-window-is-tab nil)
+ (my-keybind eww-link-keymap "v" nil) ; stop overriding `eww-view-source'
+ (my-keybind eww-mode-map "L" #'eww-list-bookmarks)
+ (my-keybind eww-bookmark-mode-map "d" #'eww-bookmark-kill)
+ )
+
+(my-package my-web
+ (:delay 60)
+ (my-keybind eww-mode-map
+ "N" #'my-eww-next-path
+ "P" #'my-eww-prev-path
+ "U" #'my-eww-up-path
+ "T" #'my-eww-top-path
+ "b" #'my-eww-switch-by-title)
+ (my-keybind global-map "\C-c\C-o" #'my-browse-url-at-point)
+ (my-override browse-url)
+ )
+
+(my-package my-semantic-scholar
+ (:delay 60))
+
+(my-package rt-liberation
+ (:delay 60)
+ (:install t)
+ (my-setq-from-local rt-liber-username rt-liber-rest-url
+ rt-liber-base-url)
+ (require 'my-rtliber)
+ (my-override rt-liber-viewer-visit-in-browser)
+)
+
+(my-package rt-liberation-org
+ (:delay 60))
+
+(my-package rt-liberation-gnus
+ (:delay 60)
+ (my-setq-from-local rt-liber-gnus-address
+ rt-liber-gnus-comment-address
+ rt-liber-gnus-subject-name)
+ (require 'my-rtliber)
+ (my-keybind global-map
+ "C-c t m" #'my-rt-liber-my-open-tickets
+ "C-c t M" #'my-rt-liber-my-tickets
+ "C-c t b" #'my-rt-liber-backlog
+ "C-c t i" #'my-rt-liber-get-ticket-by-id
+ "C-c t q" #'my-rt-liber-query-by-subject)
+ )
+
+;; sx: a stack exchange client
+(my-package sx
+ (:delay 60)
+ (require 'sx-load))
+
+;; mastodon
+(add-to-list 'load-path (locate-user-emacs-file "lisp/mastodon.el/lisp"))
+(my-package mastodon
+ (:delay 60)
+ (my-setq-from-local mastodon-active-user mastodon-instance-url))
+
+(add-to-list 'load-path (locate-user-emacs-file "lisp/servall/lisp"))
+(my-package servall-wikipedia
+ (:delay 60)
+ (require 'servall-ytdl)
+ (my-setq-from-local servall-endpoint)
+ (require 'my-servall)
+ (my-keybind servall-wikipedia-view-mode-map "C-'" 'my-servall-wikipedia-grok)
+)
+
+(my-package my-libgen
+ (:delay 60)
+ (my-setq-from-local my-libgen-hosts my-libgen-alt-hosts
+ my-libgen-library-hosts
+ my-libgen-download-dir)
+ (my-libgen-set-random-hosts))
+
+(my-package my-scihub
+ (:delay 60)
+ (my-setq-from-local my-scihub-host))
+
+(provide 'ycp-web)