Files
.emacs.d/lisp/init-kbd.el

460 lines
16 KiB
EmacsLisp
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
;;; init-kbd.el --- keybindings -*- lexical-binding: t -*-
;;; Commentary:
;;; Code:
(use-package hydra
:defines (consult-imenu-config posframe-border-width)
:functions childframe-completion-workable-p
:hook ((emacs-lisp-mode . hydra-add-imenu)
((after-init after-load-theme server-after-make-frame) . hydra-set-posframe))
:init
(with-eval-after-load 'consult-imenu
(setq consult-imenu-config
'((emacs-lisp-mode :toplevel "Functions"
:types ((?f "Functions" font-lock-function-name-face)
(?h "Hydras" font-lock-constant-face)
(?m "Macros" font-lock-function-name-face)
(?p "Packages" font-lock-constant-face)
(?t "Types" font-lock-type-face)
(?v "Variables" font-lock-variable-name-face))))))
(defun hydra-set-posframe ()
"Set display type and appearance of hydra."
;; Display type
(if (childframe-completion-workable-p)
(setq hydra-hint-display-type 'posframe)
(setq hydra-hint-display-type 'lv))
;; Appearance
(setq hydra-posframe-show-params
`(:left-fringe 8
:right-fringe 8
:internal-border-width ,posframe-border-width
:internal-border-color ,(face-background 'posframe-border nil t)
:background-color ,(face-background 'tooltip nil t)
:foreground-color ,(face-foreground 'tooltip nil t)
:lines-truncate t
:poshandler posframe-poshandler-frame-center-near-bottom))))
;; multiple-cursors
(defhydra hydra-multiple-cursors ()
"
^Mark^ ^Unmark^ ^Other^
------------------------------------------------------------------
_p_ : prev line _P_ : previous _c_ : edit lines
_n_ : next line _N_ : next _._ : pop
_f_ : next symbol _q_ : quit
_b_ : prev symbol
_s_ : in region
_a_ : all dwim
"
("p" mc/mark-previous-like-this)
("n" mc/mark-next-like-this)
("b" mc/mark-previous-like-this-symbol)
("f" mc/mark-next-like-this-symbol)
("P" mc/unmark-previous-like-this)
("N" mc/unmark-next-like-this)
("a" mc/mark-all-dwim)
("s" mc/mark-all-in-region)
("c" mc/edit-lines)
("." mc/mark-pop)
("q" nil))
(global-set-key (kbd "C-c c") 'hydra-multiple-cursors/body)
(use-package general)
;; 修改mac键位
(when *is-mac*
(setq mac-command-modifier 'meta)
(setq mac-option-modifier 'none))
;; 使用F2打开init.el
(defun open-init-file()
"Open user's init.el file in ~/.emacs.d ."
(interactive)
(find-file "~/.emacs.d/init.el"))
(global-set-key (kbd "<f2>") 'open-init-file)
;; 根据平台使用不同的重启方式
(if *is-windows*
(progn
(defun restart-emacs ()
"Restart emacs (for Windows)"
(interactive)
(save-some-buffers)
(w32-shell-execute "open" "runemacs.exe")
(kill-emacs))
(global-set-key (kbd "C-c r") 'restart-emacs))
(global-set-key (kbd "C-c r") 'restart-emacs))
;; expand region
(global-set-key (kbd "C-c e") 'er/expand-region)
(setq expand-region-reset-fast-key "r")
(setq expand-region-contract-fast-key "c")
;; 大小写
(global-set-key (kbd "M-c") 'capitalize-dwim)
(global-set-key (kbd "M-u") 'upcase-dwim)
(global-set-key (kbd "M-l") 'downcase-dwim)
;; jinx相关
(defun my/jinx-smart-toggle ()
"Toggle jinx-mode smartly.
Disable jinx-mode if it's enable and global-jinx-mode is disable , otherwise toggle global-jinx-mode."
(interactive)
(unless (featurep 'jinx)
(require 'jinx))
(let ((local-on (bound-and-true-p jinx-mode))
(global-on (bound-and-true-p global-jinx-mode)))
(cond
((and local-on (not global-on))
(message "disable jinx-mode in current buffer")
(jinx-mode -1))
(t
(if global-on
(progn
(message "disable global-jinx-mode")
(global-jinx-mode -1))
(progn
(message "enable global-jinx-mode")
(global-jinx-mode 1)))))))
(global-set-key (kbd "C-c j j") 'my/jinx-smart-toggle)
(with-eval-after-load 'init-jinx
(global-set-key (kbd "C-c f j") 'consult-jinx))
;; pair编辑
;; (global-set-key (kbd "C-c p d") 'delete-pair)
;; 快速复制当前行
(defun duplicate-and-move-to-next-line()
"Duplicate current line and move to next line."
(interactive)
(progn
(duplicate-line)
(next-line)))
(global-set-key (kbd "C-,") 'duplicate-and-move-to-next-line)
;; 切换buffer
(defun my-tab-line-buffers ()
"Get list of buffers shown in tab-line."
(mapcar (lambda (tab)
(if (consp tab) (cdr tab) tab))
(funcall tab-line-tabs-function)))
(defun previous-buffer-with-tab-line ()
"Switch to previous buffer in tab-line order."
(interactive)
(let ((already-enabled global-tab-line-mode))
(unless already-enabled
(global-tab-line-mode 1))
(let* ((buffers (my-tab-line-buffers))
(current (current-buffer))
(pos (cl-position current buffers)))
(when pos
(switch-to-buffer
(nth (mod (1- pos) (length buffers)) buffers))))
(unless already-enabled
(run-with-idle-timer 0.5 nil (lambda () (global-tab-line-mode -1))))))
(defun next-buffer-with-tab-line ()
"Switch to next buffer in tab-line order."
(interactive)
(let ((already-enabled global-tab-line-mode))
(unless already-enabled
(global-tab-line-mode 1))
(let* ((buffers (my-tab-line-buffers))
(current (current-buffer))
(pos (cl-position current buffers)))
(when pos
(switch-to-buffer
(nth (mod (1+ pos) (length buffers)) buffers))))
(unless already-enabled
(run-with-idle-timer 0.5 nil (lambda () (global-tab-line-mode -1))))))
(global-set-key (kbd "<f3>") 'previous-buffer-with-tab-line)
(global-set-key (kbd "<mouse-4>") 'previous-buffer)
(global-set-key (kbd "M-[") 'previous-buffer)
(global-set-key (kbd "<f4>") 'next-buffer-with-tab-line)
(global-set-key (kbd "<mouse-5>") 'next-buffer)
(global-set-key (kbd "M-]") 'next-buffer)
;; 打开tab-line-mode
(global-set-key (kbd "C-c u l") 'global-tab-line-mode)
(global-set-key (kbd "<mouse-3>") 'global-tab-line-mode)
;; 关闭主题
(global-set-key (kbd "C-c u d") 'disable-theme)
(global-set-key (kbd "C-c u f") 'describe-face)
(global-set-key (kbd "C-c u r") 'rainbow-mode)
;; indent-bars
(global-set-key (kbd "C-c u b") 'indent-bars-mode)
;; 打开ibuffer
(global-set-key (kbd "C-x C-b") 'ibuffer-other-window)
(setq ibuffer-default-sorting-mode 'filename)
;; 段落导航
(global-set-key (kbd "M-p") 'backward-paragraph)
(global-set-key (kbd "M-n") 'forward-paragraph)
;; 中键使用embark打开定义
(global-set-key (kbd "<mouse-2>") 'xref-find-definitions)
;; 使用快速切换到scratch buffer
(if *is-mac*
(global-set-key (kbd "C-C <f12>") 'scratch-buffer)
(global-set-key (kbd "C-c <delete>") 'scratch-buffer))
;; 调整window
(global-set-key (kbd "M-<left>") 'shrink-window-horizontally)
(global-set-key (kbd "M-<right>") 'enlarge-window-horizontally)
(global-set-key (kbd "M-<up>") 'enlarge-window)
(global-set-key (kbd "M-<down>") 'shrink-window)
;; es-windows
(global-set-key (kbd "<f10>") 'esw/swap-two-windows)
;; popper
(global-set-key (kbd "M-`") 'popper-toggle-latest)
(defun popper-toggle-type-delete-other-window()
"Toggle type of popper window and delete other window."
(interactive)
(popper-toggle-type)
(delete-other-windows))
(global-set-key (kbd "C-M-=") 'popper-toggle-type-delete-other-window)
;; crux相关
(global-set-key (kbd "C-<backspace>") 'crux-kill-line-backwards) ;; C-DEL kill line backwards
(global-set-key (kbd "C-c k") 'comment-line) ;; 快速注释
(global-set-key (kbd "C-k") 'crux-smart-kill-line) ;; smart kill line
(global-set-key (kbd "C-a") 'crux-move-beginning-of-line) ;; 移动到第一个缩进而非行首
(global-set-key (kbd "C-x K") 'crux-kill-other-buffers) ;; 删除除当前buffer之外的buffer
;; undo-fu
(global-set-key (kbd "C-/") 'undo-fu-only-undo)
(global-set-key (kbd "C-?") 'undo-fu-only-redo)
;; vundo
(global-set-key (kbd "C-x u") 'vundo)
;; consult
(global-set-key (kbd "C-x b") 'consult-buffer) ;; buffer菜单
(global-set-key (kbd "C-s") 'consult-line) ;; 搜索
(global-set-key (kbd "C-c s") 'consult-focus-lines) ;; focus line
(global-set-key (kbd "C-c i") 'consult-imenu) ;; imenu
(global-set-key (kbd "C-c f r") 'consult-recent-file) ;; 最近打开
(global-set-key (kbd "C-c f f") 'consult-fd) ;; 调用fd进行目录内搜索
(global-set-key (kbd "C-c f g") 'consult-ripgrep) ;; consult-ripgrep
(global-set-key (kbd "M-y") 'consult-yank-from-kill-ring) ;; 从kill ring中粘贴
(global-set-key (kbd "C-x r b") 'consult-bookmark) ;; 书签菜单embark中有更多操作
(define-key minibuffer-local-map (kbd "C-c C-e") 'embark-export) ;; 把minibuffer结果在一个菜单中显示
(global-set-key (kbd "C-c f e") 'consult-flycheck) ;; flycheck菜单
(global-set-key (kbd "C-c u t") 'consult-theme) ;; 主题预览
(if *is-mac*
(progn
(global-set-key (kbd "C-c f l") 'consult-fd-global)
(global-set-key (kbd "C-c f m") 'consult-locate))
(global-set-key (kbd "C-c f l") 'consult-locate)
(global-set-key (kbd "C-c f m") 'consult-fd-global))
;; flycheck
(global-set-key (kbd "C-c f c") 'global-flycheck-mode)
(with-eval-after-load 'flycheck
(define-key flycheck-mode-map (kbd "M-{") 'flycheck-previous-error)
(define-key flycheck-mode-map (kbd "M-}") 'flycheck-next-error))
;; avy
(global-set-key (kbd "C-M-;") 'avy-goto-char)
(global-set-key (kbd "C-M-'") 'avy-goto-word-1)
(global-set-key (kbd "M-g g") 'avy-goto-line)
;; hungry-delete
(global-set-key (kbd "C-c DEL") 'hungry-delete-backward) ;; 向后删除到第一个非空字符
(global-set-key (kbd "C-c C-<backspace>") 'hungry-delete-forward) ;; 向前删除到第一个非空字符
;; drag-stuff
(global-set-key (kbd "M-P") 'drag-stuff-up)
(global-set-key (kbd "M-N") 'drag-stuff-down)
;; ace-windows
(global-set-key (kbd "M-o") 'ace-window)
;; embark修饰键之后加C-h可以查看所有指令
(global-set-key (kbd "C-;") 'embark-act)
;; vterm
(global-set-key (kbd "C-c v") 'vterm)
(with-eval-after-load 'vterm
(define-key vterm-mode-map (kbd "M-]") nil)
(define-key vterm-mode-map (kbd "C-x C-x") 'vterm-send-C-x))
;; ;; eshell
;; (with-eval-after-load 'eshell
;; (define-key eshell-mode-map (kbd "M-n") nil)
;; (define-key eshell-mode-map (kbd "M-p") nil)
;; (define-key eshell-mode-map (kbd "M-{") 'eshell-previous-matching-input-from-input)
;; (define-key eshell-mode-map (kbd "M-}") 'eshell-next-matching-input-from-input))
;; 打开目录
(defun consult-directory-externally (file)
"Open FILE externally using the default application of the system."
(interactive "fOpen externally: ")
(if (and (eq system-type 'windows-nt)
(fboundp 'w32-shell-execute))
(shell-command-to-string (encode-coding-string (replace-regexp-in-string "/" "\\\\"
(format "explorer.exe %s" (file-name-directory (expand-file-name file))))
'gbk))
(call-process (pcase system-type
('darwin "open")
('cygwin "cygstart")
(_ "xdg-open"))
nil 0 nil
(file-name-directory (expand-file-name file)))))
(with-eval-after-load 'embark
(define-key embark-file-map (kbd "d") 'consult-directory-externally))
;;打开当前文件的目录
(defun my-open-current-directory ()
"Open current directory in default file explorer."
(interactive)
(consult-directory-externally default-directory))
(global-set-key (kbd "C-c f d") 'my-open-current-directory)
;; save-some-buffer时diff更改
(add-to-list 'save-some-buffers-action-alist
(list "d"
(lambda (buffer) (diff-buffer-with-file (buffer-file-name buffer)))
"show diff between the buffer and its file"))
;; markdown
(with-eval-after-load 'markdown-mode
(define-key markdown-mode-map (kbd "M-p") nil)
(define-key markdown-mode-map (kbd "M-n") nil))
;; org-mode相关
;; cycle当前subtree
(defun org-cycle-current-subtree()
"Cycle current subtree."
(interactive)
(org-back-to-heading)
(org-cycle))
(global-set-key (kbd "C-<tab>") 'org-cycle-current-subtree)
;; heading菜单
(with-eval-after-load 'org
(define-key org-mode-map (kbd "C-c i") 'consult-org-heading))
;; 用consult检索org-agenda-file标题
(global-set-key (kbd "C-c o s") 'consult-org-agenda)
;; 用ripgrep搜索org-agenda-file
(defun my/org-agenda-rifle ()
"Jump to org agenda files use consult-ripgrep."
(interactive)
(consult-ripgrep org-agenda-files))
(global-set-key (kbd "C-c o g") 'my/org-agenda-rifle)
;; 存储一个链接
(global-set-key (kbd "C-c l") 'org-store-link)
;; 打开calendar
(global-set-key (kbd "C-c o C") 'calendar)
;; 在calendar中快速打开当天日记
(eval-after-load "calendar"
(progn
'(define-key calendar-mode-map (kbd "j o") 'org-journal-open-entry-for-editing)
'(define-key calendar-mode-map (kbd "<RET>") 'org-journal-open-entry-for-editing)))
;; org-ql
(global-set-key (kbd "C-c q s") 'org-ql-search)
(global-set-key (kbd "C-c q v") 'org-ql-view)
;; 日记
(defun org-journal-open-current-journal-file-delete-other-window()
"Call org-journal-open-current-journal-file and delete other window."
(interactive)
(org-journal-open-current-journal-file)
(delete-other-windows))
(defun org-journal-new-entry-delete-other-window()
"Call org-journal-new-entry and delete other window."
(interactive)
(org-journal-new-entry nil)
(delete-other-windows))
(global-set-key (kbd "C-c j o") 'org-journal-open-current-journal-file-delete-other-window)
(global-set-key (kbd "C-c j n") 'org-journal-new-entry-delete-other-window)
;; emms
(global-set-key (kbd "C-c m n") 'emms-next)
(global-set-key (kbd "C-c m p") 'emms-previous)
(global-set-key (kbd "C-c m b") 'emms-browser)
(global-set-key (kbd "C-c m q") 'emms-stop)
(global-set-key (kbd "C-c m S") 'emms-toggle-single-track) ;自动连播开关
(with-eval-after-load 'embark
(define-key embark-file-map (kbd "p") 'emms-play-dired))
(add-hook 'dired-mode-hook
(lambda ()
(local-unset-key (kbd "<mouse-2>"))
(local-set-key (kbd "<mouse-2>") 'emms-play-dired)
(local-set-key (kbd "C-c m a") 'emms-add-dired)))
(add-hook 'emms-playlist-mode-hook
(lambda ()
(local-unset-key (kbd "<prior>"))
(local-unset-key (kbd "<next>"))
(local-set-key (kbd "<prior>") 'emms-previous)
(local-set-key (kbd "<next>") 'emms-next)))
(defun switch-to-emms-playlist()
"Switch to emms playlist."
(interactive)
(switch-to-buffer "*EMMS Playlist*"))
(global-set-key (kbd "C-c m l") 'switch-to-emms-playlist)
(global-set-key (kbd "C-c m d") 'my-emms-play-directory)
;; dashboard
(global-set-key (kbd "C-c D") 'dashboard-open)
;; dired
(with-eval-after-load 'dirvish
(global-set-key (kbd "C-c d a") 'dirvish-quick-access)
(global-set-key (kbd "C-c d s") 'dirvish-side)
(global-set-key (kbd "C-c d h") 'dirvish-history-menu)
(global-set-key (kbd "C-x d") 'dired-jump)
(global-set-key (kbd "C-x C-j") 'dired)
(define-key dired-mode-map (kbd "h") 'dirvish-history-menu)
(define-key dired-mode-map (kbd "M-,") 'scroll-other-window-down)
(define-key dired-mode-map (kbd "M-.") 'scroll-other-window))
;; perspective
(global-set-key (kbd "C-M-<left>") 'persp-prev)
(global-set-key (kbd "C-M-<right>") 'persp-next)
(define-key persp-mode-map (kbd "C-c p c") nil)
(global-set-key (kbd "C-c p d") 'persp-kill)
;; gptel
(general-def
:prefix "C-c g"
"o" 'gptel
"m" 'gptel-menu
"s" 'gptel-send
"a" 'gptel-agent)
(provide 'init-kbd)
;;; init-kbd.el ends here