1 ;;; eh-basic.el --- Tumashu's basic emacs configuation -*- lexical-binding: t; -*-
4 ;; Copyright (c) 2011-2019, Feng Shu
6 ;; Author: Feng Shu <tumashu@gmail.com>
7 ;; URL: https://github.com/tumashu/emacs-helper
10 ;; This file is not part of GNU Emacs.
14 ;; This program is free software; you can redistribute it and/or
15 ;; modify it under the terms of the GNU General Public License
16 ;; as published by the Free Software Foundation; either version 3
17 ;; of the License, or (at your option) any later version.
19 ;; This program is distributed in the hope that it will be useful,
20 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 ;; GNU General Public License for more details.
24 ;; You should have received a copy of the GNU General Public License
25 ;; along with GNU Emacs; see the file COPYING. If not, write to the
26 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
27 ;; Boston, MA 02110-1301, USA.
32 ;; 这个文件是tumashu个人专用的emacs配置文件,emacs中文用户可以参考。
39 (defun eh-directory ()
40 "返回 emacs-helper 所在的目录。"
42 (locate-library "eh-basic.el")))
44 (defun eh-system-open (path &rest _args
)
45 (let ((path (expand-file-name path
)))
46 (cond ((string-equal system-type
"windows-nt")
47 (with-no-warnings (w32-shell-execute "open" path
)))
48 ((string-equal system-type
"darwin")
49 (concat "open " (shell-quote-argument path
)))
50 ((string-equal system-type
"gnu/linux")
51 (let ((process-connection-type nil
))
52 (start-process "" nil
"xdg-open" path
))))))
54 (defun eh-file-extension-match-p (file-name extensions
)
57 (string-match-p (format "\\.%s\\'" extension
) file-name
))
60 (defun eh-find-file (orig-fun &rest args
)
61 (let ((file-name (car args
))
62 ;; this-command may be a lambda
63 (cmd (ignore-errors (symbol-name this-command
))))
64 (cond ((and (file-exists-p file-name
)
65 (eh-file-extension-match-p
67 '("doc" "docx" "xls" "xlsx" "ppt" "pptx" "wps"
68 "pdf" "xps" "oxps" "cbz" "epub" "fb2" "fbz" "djvu"
69 "jpg" "jpeg" "png" "bmp" "gif" "svg" "webp"
70 "avi" "rmvb" "mp4" "mkv" "mp3" "ogg")))
71 (eh-system-open file-name
))
73 (or (string-match "^org-" cmd
)
74 (string-match "^eh-org-" cmd
)
75 (string-match "^eh-share2computer-" cmd
))
76 (file-directory-p file-name
))
77 (eh-system-open file-name
))
78 (t (apply orig-fun args
)))))
80 (dolist (f '(find-file
82 find-file-other-window
83 find-file-other-frame
))
84 (advice-add f
:around
'eh-find-file
))
86 ;; ** Full name and Email
87 (setq user-full-name
"Feng Shu")
88 (setq user-mail-address
"tumashu@163.com")
90 ;; ** 启动时默认打开的 buffer.
91 (setq inhibit-startup-screen t
)
92 (setq initial-buffer-choice nil
)
93 (setq initial-major-mode
'emacs-lisp-mode
)
94 (setq initial-scratch-message
"")
97 (defalias 'yes-or-no-p
'y-or-n-p
)
100 (setq-default indent-tabs-mode nil
)
103 (setq visible-bell t
)
106 (setq use-dialog-box nil
)
109 (setq nobreak-char-display nil
)
110 ;; (setq eh-space (propertize " " 'face '(:weight 'bold)))
111 (defvar eh-space
" ")
114 ;; 在 mode-line 最后追加一个半角空格,一个全角空格,防止因为字体高度原
115 ;; 因,导致 mode-line 抖动。
116 (setq mode-line-end-spaces
117 '(:eval
(if (display-graphic-p) eh-space
"-%-")))
119 ;; ** 让 *scratch* buffer 无法删除
120 (defun eh-unkillable-scratch-buffer ()
121 (if (string= (buffer-name (current-buffer)) "*scratch*")
123 (delete-region (point-min) (point-max))
124 (insert initial-scratch-message
)
128 (add-hook 'kill-buffer-query-functions
129 #'eh-unkillable-scratch-buffer
)
132 (global-set-key (kbd "C-x k") #'kill-current-buffer
)
136 (setq package-archives
137 '(("gnu" .
"https://elpa.gnu.org/packages/")
138 ("nongnu" .
"https://elpa.nongnu.org/nongnu/")
139 ("melpa" .
"https://melpa.org/packages/")))
141 (setq package-archive-priorities
146 (unless package--initialized
147 (package-initialize))
150 (set-language-environment "UTF-8")
151 (set-buffer-file-coding-system 'utf-8-unix
)
152 (set-clipboard-coding-system 'utf-8-unix
)
153 (set-file-name-coding-system 'utf-8-unix
)
154 (set-keyboard-coding-system 'utf-8-unix
)
155 (set-next-selection-coding-system 'utf-8-unix
)
156 (set-selection-coding-system 'utf-8-unix
)
157 (set-terminal-coding-system 'utf-8-unix
)
159 (when (eq system-type
'windows-nt
)
160 (set-language-environment "Chinese-GBK")
161 (set-selection-coding-system 'gbk-dos
)
162 (set-next-selection-coding-system 'gbk-dos
)
163 (set-clipboard-coding-system 'gbk-dos
))
165 ;; ** Window 系统下关闭 Emacs 时,强制确认,防止误操作。
166 (when (eq system-type
'windows-nt
)
167 (setq confirm-kill-emacs
'yes-or-no-p
))
169 ;; ** 关闭自动备份功能,我有 git :-)
170 (setq make-backup-files nil
)
173 ;; (require 'whitespace)
174 ;; 使用下面这一行配置后,org-mode 的源代码总是莫名其妙的
175 ;; (add-hook 'before-save-hook #'whitespace-cleanup)
176 ;; 更改,这会导致生成的 diff 相当乱。
178 ;; (add-hook 'before-save-hook
180 ;; (delete-trailing-whitespace)))
184 (setq recentf-auto-cleanup
'never
)
186 (setq recentf-max-saved-items
99)
187 (setq recentf-max-menu-items
99)
188 (setq recentf-show-file-shortcuts-flag nil
)
189 (setq recentf-exclude
190 '("COMMIT" "autoloads" "archive-contents" "eld" "newsrc"
191 ".recentf" "emacs-font-size.conf" "eh-scratch"
194 (add-hook 'find-file-hook
#'recentf-save-list
)
197 (global-unset-key (kbd "C-x C-x"))
198 (global-set-key (kbd "C-x <SPC>") 'set-mark-command
)
199 ;; QQ 将会在 emacs 之前捕捉 M-w 快捷键,记得取消。
201 (global-set-key (kbd "C-c w") 'kill-ring-save
)
202 (global-set-key (kbd "C-x C-x C-x") 'exchange-point-and-mark
)
203 (global-set-key (kbd "C-x C-x <SPC>") 'rectangle-mark-mode
)
206 ;; (desktop-save-mode 1)
209 (when (functionp 'tool-bar-mode
)
213 (when (functionp 'scroll-bar-mode
)
214 (scroll-bar-mode -
1))
217 (when (functionp 'pixel-scroll-precision-mode
)
218 (pixel-scroll-precision-mode 1))
221 (setq frame-resize-pixelwise t
)
225 (bookmark-maybe-load-default-file)
233 (electric-pair-mode 1)
236 (global-so-long-mode 1)
240 (setq word-wrap-by-category t
)
243 (if (> emacs-major-version
28)
248 (when (functionp 'context-menu-mode
)
249 (context-menu-mode 1))
252 (setq ring-bell-function
'ignore
)
255 (require 'switch-window
)
257 (unless (display-graphic-p)
258 (setq switch-window-shortcut-appearance
'asciiart
))
259 (setq switch-window-shortcut-style
'qwerty
)
260 (setq switch-window-input-style
'minibuffer
)
261 (global-set-key (kbd "C-x o") 'switch-window
)
265 (global-tab-line-mode 1)
266 (setq tab-line-close-tab-function
#'kill-buffer
)
267 (setq tab-line-tab-name-truncated-max
22)
268 (setq tab-line-tab-name-ellipsis
"…")
269 (setq tab-line-tab-name-function
270 #'tab-line-tab-name-truncated-buffer
)
272 (defun eh-tab-line-format (orig_func)
273 "在 tab-line 的最后添加一个全角空格,防止 tab-line 抖动。"
274 (list (funcall orig_func
) eh-space
))
276 (advice-add 'tab-line-format
:around
#'eh-tab-line-format
)
282 ;; ** minibuffer and completing-read
284 (require 'minibuffer
)
285 (setq completion-auto-help t
)
286 (setq completion-auto-select nil
)
287 (setq completion-show-help nil
)
288 (setq completion-show-inline-help t
)
289 (setq completions-max-height
15)
290 (setq completions-format
'one-column
)
291 (setq enable-recursive-minibuffers t
)
292 (setq history-delete-duplicates t
)
293 (setq minibuffer-prompt-properties
294 '(read-only t cursor-intangible t face minibuffer-prompt
))
295 (add-hook 'minibuffer-setup-hook
#'cursor-intangible-mode
)
297 (defun eh-crm-indicator (args)
298 (cons (concat "[CRM] " (car args
))
301 (advice-add #'completing-read-multiple
:filter-args
#'eh-crm-indicator
)
305 (require 'vertico-directory
)
307 (define-key vertico-map
"\r" #'vertico-directory-enter
)
308 (define-key vertico-map
"\d" #'vertico-directory-delete-char
)
309 (define-key vertico-map
"\M-\d" #'vertico-directory-delete-word
)
310 (add-hook 'rfn-eshadow-update-overlay-hook
#'vertico-directory-tidy
)
314 (require 'pyim-cregexp
)
315 (setq completion-styles
'(basic orderless
)
316 completion-category-defaults nil
317 completion-category-overrides
'((file (styles partial-completion
))))
319 (defun eh-orderless-regexp (orig_func component
)
320 (let ((result (funcall orig_func component
)))
321 (pyim-cregexp-build result
)))
323 (advice-add 'orderless-regexp
:around
#'eh-orderless-regexp
)
327 (setq consult-preview-key nil
)
328 (global-set-key (kbd "C-x b") 'consult-buffer
)
329 (global-set-key (kbd "C-x f") 'consult-recent-file
)
330 (global-set-key (kbd "C-x C-b") 'ibuffer
)
331 (global-set-key (kbd "C-c y") 'consult-yank-pop
)
336 (setq vc-handled-backends
'(Hg Git
))
337 (setq vc-hg-revert-switches
'("--no-backup"))
341 (setq add-log-dont-create-changelog-file t
)
342 ;; 大多数情况,我不会手动编辑 ChangeLog 文件,防止误操作。
343 (setq change-log-default-name
"01-dont-edit-changelog")
346 (require 'elisp-mode
)
349 (electric-indent-mode -
1)
357 (require 'pyim-cregexp-utils
)
359 (global-set-key (kbd "M-j") 'pyim-convert-string-at-point
)
360 (define-key minibuffer-local-map
(kbd "C-<return>") 'pyim-cregexp-convert-at-point
)
362 (setq default-input-method
"pyim")
365 (pyim-default-scheme 'quanpin
)
368 (setq-default pyim-english-input-switch-functions
369 '(pyim-probe-dynamic-english
370 pyim-probe-isearch-mode
371 pyim-probe-program-mode
372 pyim-probe-org-structure-template
))
374 (setq-default pyim-punctuation-half-width-functions
375 '(pyim-probe-punctuation-line-beginning
376 pyim-probe-punctuation-after-punctuation
))
379 (pyim-isearch-mode 1)
382 (setq pyim-page-length
5)
385 (require 'pyim-basedict
)
386 (pyim-basedict-enable)
389 ;; (setq liberime-auto-build t)
390 ;; (require 'liberime nil t)
391 ;; (require 'pyim-liberime nil t)
392 ;; (with-eval-after-load "liberime"
393 ;; (liberime-try-select-schema "luna_pinyin_simp")
394 ;; (pyim-default-scheme 'rime-quanpin))
398 (require 'cal-china-x
)
400 ;; 使用英文 day-name, 而不是中文: “星期XX”
401 (setq system-time-locale
"C")
403 ;; 一周第一天,0表示星期天, 1表示星期一
404 (setq calendar-week-start-day
0)
406 (setq calendar-holidays
408 (holiday-fixed 1 1 "元旦")
409 (holiday-fixed 2 14 "情人节")
410 (holiday-fixed 3 8 "妇女节")
411 (holiday-fixed 3 14 "白色情人节")
412 (holiday-fixed 4 1 "愚人节")
413 (holiday-fixed 5 1 "劳动节")
414 (holiday-fixed 5 4 "青年节")
415 (holiday-float 5 0 2 "母亲节")
416 (holiday-fixed 6 1 "儿童节")
417 (holiday-float 6 0 3 "父亲节")
418 (holiday-fixed 9 10 "教师节")
419 (holiday-fixed 10 1 "国庆节")
420 (holiday-fixed 10 24 "程序员节")
421 (holiday-fixed 12 25 "圣诞节")
423 (holiday-lunar 1 1 "春节" 0)
424 (holiday-lunar 1 2 "春节" 0)
425 (holiday-lunar 1 3 "春节" 0)
426 (holiday-lunar 1 15 "元宵节" 0)
427 (holiday-solar-term "清明" "清明节")
428 (holiday-solar-term "小寒" "小寒")
429 (holiday-solar-term "大寒" "大寒")
430 (holiday-solar-term "立春" "立春")
431 (holiday-solar-term "雨水" "雨水")
432 (holiday-solar-term "惊蛰" "惊蛰")
433 (holiday-solar-term "春分" "春分")
434 (holiday-solar-term "谷雨" "谷雨")
435 (holiday-solar-term "立夏" "立夏")
436 (holiday-solar-term "小满" "小满")
437 (holiday-solar-term "芒种" "芒种")
438 (holiday-solar-term "夏至" "夏至")
439 (holiday-solar-term "小暑" "小暑")
440 (holiday-solar-term "大暑" "大暑")
441 (holiday-solar-term "立秋" "立秋")
442 (holiday-solar-term "处暑" "处暑")
443 (holiday-solar-term "白露" "白露")
444 (holiday-solar-term "秋分" "秋分")
445 (holiday-solar-term "寒露" "寒露")
446 (holiday-solar-term "霜降" "霜降")
447 (holiday-solar-term "立冬" "立冬")
448 (holiday-solar-term "小雪" "小雪")
449 (holiday-solar-term "大雪" "大雪")
450 (holiday-solar-term "冬至" "冬至")
451 (holiday-lunar 5 5 "端午节" 0)
452 (holiday-lunar 8 15 "中秋节" 0)
453 (holiday-lunar 7 7 "七夕情人节" 0)
454 (holiday-lunar 12 8 "腊八节" 0)
455 (holiday-lunar 9 9 "重阳节" 0)))
457 (setq calendar-month-name-array
458 ["一月" "二月" "三月" "四月" "五月" "六月"
459 "七月" "八月" "九月" "十月" "十一月" "十二月"])
461 (setq calendar-day-name-array
462 ["周日" "周一" "周二" "周三" "周四" "周五" "周六"])
464 (defun eh-org-chinese-anniversary (year lunar-month lunar-day
&optional mark
)
466 (let* ((d-date (diary-make-date lunar-month lunar-day year
))
467 (a-date (calendar-absolute-from-gregorian d-date
))
468 (c-date (calendar-chinese-from-absolute a-date
))
471 (y (+ (* 100 cycle
) yy
)))
472 (diary-chinese-anniversary lunar-month lunar-day y mark
))
473 (diary-chinese-anniversary lunar-month lunar-day year mark
)))
479 ;; coding: utf-8-unix
482 ;;; eh-basic.el ends here