diff --git a/.gitignore b/.gitignore index 6ec388e..610d4ea 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ /url/cache -/.emacs.desktop +/*.desktop /auto-save-list /network-security.data /.session diff --git a/.gitmodules b/.gitmodules index 44b8679..b16fc17 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,3 +19,6 @@ [submodule "company-anywhere"] path = extensions/company-anywhere url = https://github.com/zk-phi/company-anywhere.git +[submodule "popweb"] + path = extensions/popweb + url = https://github.com/manateelazycat/popweb.git diff --git a/extensions/popweb b/extensions/popweb new file mode 160000 index 0000000..e830b3c --- /dev/null +++ b/extensions/popweb @@ -0,0 +1 @@ +Subproject commit e830b3c5f54227ae57117c7262b5d0c9fcc73334 diff --git a/init.el b/init.el index 619d00c..326ab6a 100644 --- a/init.el +++ b/init.el @@ -41,6 +41,7 @@ ;;---------------------------------------------------------------------------- ;; Load configs for specific features and modes ;;---------------------------------------------------------------------------- +(require 'init-emacs-server) ; need to put this first to know which instance/server we are in, for initing other features (require 'init-frame-hooks) (require 'init-themes) @@ -138,20 +139,6 @@ (maybe-require-package 'daemons)) -;;---------------------------------------------------------------------------- -;; Allow access from emacsclient -;;---------------------------------------------------------------------------- -(require 'server) -;; "unless running" is to avoid prompting error when starting a second Emacs -;; when app opened as main editor, start default server -(unless (server-running-p) - (server-start)) -;; when opened as maid, start server with name "maid" -(when (string= (getenv "EMACS_SOCKET") "maid") - (unless (server-running-p "maid") - (setq server-name "maid") - (server-start))) - ;;---------------------------------------------------------------------------- ;; Variables configured via the interactive 'customize' interface ;;---------------------------------------------------------------------------- diff --git a/modes/init-avy.el b/modes/init-avy.el index 614804b..f4c0708 100644 --- a/modes/init-avy.el +++ b/modes/init-avy.el @@ -1,7 +1,7 @@ (use-package avy :init - (setq avy-all-windows nil) - (jester/with-leader "j j" 'avy-goto-char-timer) + (setq avy-all-windows t) + ;; (jester/with-leader "j j" 'avy-goto-char-timer) :commands (avy-goto-char-timer)) (use-package link-hint diff --git a/modes/init-chinese.el b/modes/init-chinese.el index 737a213..d9b32a0 100644 --- a/modes/init-chinese.el +++ b/modes/init-chinese.el @@ -11,6 +11,13 @@ :bind ("C-c y" . youdao-dictionary-search-at-point+) :hook (youdao-dictionary-mode . evil-motion-state)) + +(push (expand-file-name "popweb" jester-submodules-dir) load-path) +(push (expand-file-name "popweb/extension/dict" jester-submodules-dir) load-path) +(use-package popweb-dict + :ensure nil + :commands popweb-dict-bing-pointer) + (use-package pyim :demand t diff --git a/modes/init-compile.el b/modes/init-compile.el index dd75d8c..6d3942f 100644 --- a/modes/init-compile.el +++ b/modes/init-compile.el @@ -61,7 +61,7 @@ (jester/with-leader ;; TODO assign a key to "cargo check"? "c i" 'compile ; "compile it!" - "c l" (lambda! (switch-to-buffer "*compilation*")) ; "compilation log" + "b c" (lambda! (switch-to-buffer "*compilation*")) "c r" 'jester/run-project "c t" 'jester/run-test) diff --git a/modes/init-dired.el b/modes/init-dired.el index e47c913..200f928 100644 --- a/modes/init-dired.el +++ b/modes/init-dired.el @@ -30,4 +30,8 @@ :hook ((dired-mode . all-the-icons-dired-mode) (ranger-mode . all-the-icons-dired-mode))) +;; (use-package dirvish +;; ) + + (provide 'init-dired) diff --git a/modes/init-docker.el b/modes/init-docker.el index d261074..3747823 100644 --- a/modes/init-docker.el +++ b/modes/init-docker.el @@ -1,6 +1,6 @@ (use-package docker :init - (jester/with-leader "d d" 'docker) + ;; (jester/with-leader "d d" 'docker) :commands docker :config (fullframe docker-images tablist-quit) diff --git a/modes/init-elpa.el b/modes/init-elpa.el index 1032a42..c79ccea 100644 --- a/modes/init-elpa.el +++ b/modes/init-elpa.el @@ -13,8 +13,8 @@ (setq package-archives '(("melpa-tuna" . "https://mirrors.tuna.tsinghua.edu.cn/elpa/melpa/") ("org-tuna" . "https://mirrors.tuna.tsinghua.edu.cn/elpa/org/") - ("gnu-tuna" . "https://mirrors.tuna.tsinghua.edu.cn/elpa/gnu/") - ("melpa-stable-tuna" . "https://mirrors.tuna.tsinghua.edu.cn/elpa/melpa-stable/"))) + ("gnu-elpa-tuna" . "https://mirrors.tuna.tsinghua.edu.cn/elpa/gnu/") + ("melpa-stable-tuna" . "https://mirrors.tuna.tsinghua.edu.cn/elpa/stable-melpa/"))) diff --git a/modes/init-emacs-server.el b/modes/init-emacs-server.el new file mode 100644 index 0000000..12a4624 --- /dev/null +++ b/modes/init-emacs-server.el @@ -0,0 +1,18 @@ +;;---------------------------------------------------------------------------- +;; Allow access from emacsclient +;;---------------------------------------------------------------------------- +(require 'server) +;; "unless running" is to avoid prompting error when starting a second Emacs +;; when app opened as main editor, start default server +(unless (server-running-p) + (server-start)) +;; when opened as maid, start server with name "maid" +(when (string= (getenv "EMACS_SOCKET") "maid") + (unless (server-running-p "maid") + (setq server-name "maid") + (setq frame-title-format "maid") + (setq desktop-base-file-name ".emacs.maid.desktop" + desktop-base-lock-name ".emacs.maid.desktop.lock") + (server-start))) + +(provide 'init-emacs-server) diff --git a/modes/init-evil.el b/modes/init-evil.el index 1a429c0..4847611 100644 --- a/modes/init-evil.el +++ b/modes/init-evil.el @@ -61,6 +61,7 @@ (evil-want-visual-char-semi-exclusive t "don't include line feed in visual select") (evil-move-beyond-eol nil "stay at eol but no further") (evil-undo-system 'undo-tree "use undo-tree, evil") + (evil-want-keybinding nil) ; required by evil-collection :init :config (evil-mode 1) @@ -215,8 +216,8 @@ (general-define-key :states '(normal visual) "R" 'jester/evil-multiedit-match-all - "C-n" 'evil-multiedit-match-symbol-and-next - "C-p" 'evil-multiedit-match-symbol-and-prev) + "C-n" 'evil-multiedit-match-and-next + "C-p" 'evil-multiedit-match-and-prev) (defun jester/evil-multiedit-match-all () "Match all occurences. with prefix arg, exclude those in comments or strings." (interactive) @@ -233,14 +234,22 @@ (evil-multiedit-toggle-or-restrict-region))))))) :config (general-define-key - :keymaps 'evil-multiedit-state-map + :keymaps 'evil-multiedit-mode-map "" 'evil-multiedit-toggle-or-restrict-region - "" 'evil-multiedit-prev - "C-a" 'evil-multiedit--beginning-of-line - "C-e" 'evil-multiedit--end-of-line) + "" 'evil-multiedit-prev) ;; these have to be loaded before company so they don't shadow tab bindings in `company-active-map' - (define-key evil-multiedit-state-map (kbd "") 'evil-multiedit-next) - (define-key evil-multiedit-insert-state-map (kbd "") 'jester/yas-or-company-or-hippie) + (general-define-key + :states '(normal) + :keymaps 'evil-multiedit-mode-map + "" 'evil-multiedit-next + "C-n" 'evil-multiedit-match-and-next + "C-p" 'evil-multiedit-match-and-prev) + (general-define-key + :states '(insert emacs) + :keymaps 'evil-multiedit-mode-map + "" 'jester/yas-or-company-or-hippie + "C-a" 'evil-multiedit-beginning-of-line + "C-e" 'evil-multiedit-end-of-line) ) @@ -279,9 +288,20 @@ evil-mc-custom-known-commands))) -(use-package evil-ediff - :init - (evil-ediff-init)) +(use-package evil-collection + :demand t + :after evil + :config + ;; modes I don't want evil-collection to setup + (dolist (mode '(vterm (term term ansi-term multi-term))) + (setq evil-collection-mode-list (delete mode evil-collection-mode-list))) + (evil-collection-init) + + ;; modify a bit after evil-collection setup + (general-define-key + :states '(normal) + :keymaps 'magit-mode-map + "/" 'jester/swiper-dwim)) (use-package evil-numbers @@ -342,7 +362,18 @@ (evil-goggles-use-diff-refine-faces)) -;; TODO use more "y i remote o"; bind it to be "y i m"? +(use-package evil-escape + :init + (setq evil-escape-excluded-states '(normal visual multiedit emacs motion) + evil-escape-excluded-major-modes '(neotree-mode treemacs-mode vterm-mode) + evil-escape-key-sequence "fd" + evil-escape-unordered-key-sequence t) + ;; (evil-define-key* '(insert replace visual operator) 'global "\C-g" #'evil-escape) + :demand t + :config + (evil-escape-mode)) + + (push (expand-file-name "targets" jester-submodules-dir) load-path) (require 'targets) ;; not needed if `targets-setup'? @@ -399,9 +430,6 @@ ;;---------------------------------------------------------------------------- (evil-set-initial-state 'debugger-mode 'motion) (evil-set-initial-state 'messages-buffer-mode 'motion) -;; special mode is for viewing info, e.g. "q" is bound to quit, -;; but it's normal state there so we lose the bindings. Use motion state. -(evil-set-initial-state 'special-mode 'motion) (advice-add 'yas-new-snippet :after @@ -417,15 +445,12 @@ ;; With-leader keys... ;;---------------------------------------------------------------------------- (jester/with-leader - "u" 'universal-argument "f i" (lambda! (find-file (expand-file-name "init.el" user-emacs-directory))) "f a" 'find-alternate-file - "j f" 'find-function - "j k" 'find-function-on-key - "j v" 'find-variable "h f" 'describe-function "h F" 'list-faces-display "h v" 'describe-variable + "h s" 'describe-symbol "h c" 'describe-char "h k" 'describe-key "h p" 'describe-package @@ -439,7 +464,7 @@ "q q" 'save-buffers-kill-terminal "t o" 'just-one-space "t a" 'aggressive-indent-mode - ;; NOTE: "a" "d" "'" are still there for the taking + ;; NOTE: "a" "'" are still there for the taking "," 'evil-indent "." 'jester/evil-portal-set-portal-location ">" 'jester/evil-portal-clear-portal-location @@ -459,10 +484,12 @@ (eval `(jester/major-leader-def ,jester-mode-leader-emacs (general-key "C-c C-c"))) ;;---------------------------------------------------------------------------- -;; Other evil keys... +;; other evil keys / keys for specific evil states ;;---------------------------------------------------------------------------- (general-define-key :states '(normal) + "r" 'evil-redo + "t" 'evil-replace "Q" "@q" "gJ" 'jester/evil-join-no-whitespace "<" nil @@ -512,9 +539,6 @@ (general-define-key :states '(normal motion visual) - "C-u" 'evil-scroll-up - "C-j" 'evil-scroll-line-down - "C-k" 'evil-scroll-line-up "'" 'evil-goto-mark) (general-define-key @@ -535,6 +559,8 @@ "C-k" 'kill-line "C-w" 'evil-delete-backward-word "C-v" 'yank + ;; leave C-r for commands similar to backward-search + "C-y" 'evil-paste-from-register "M-d" 'backward-word "M-b" 'kill-word "H-x" 'kill-region) @@ -579,8 +605,21 @@ "z p" 'jester/evil-paste-after--from-copy-register "z P" 'jester/evil-paste-before--from-copy-register) + (setq isearch-lazy-count t) ;; TODO use symbol-overlay ... or? +;; (defun jester/evil-search-region-or-symbol-forward (count forward) +;; "Search the region." +;; (isearch-forward nil )) + +;; (evil-define-command jester/evil-search-under-point-forward (&optional count) +;; "Search symbol under point forward." +;; :repeat nil +;; (interactive "p") +;; (jester/evil-search-region-or-symbol-forward (or count 1) t)) + + + (evil-define-command jester/evil-normal-search-forward (&optional count) "Search symbol under point forward." :repeat nil @@ -643,6 +682,18 @@ (dolist (cmd '(evil-yank evil-delete lispyville-yank lispyville-delete)) (advice-add cmd :after 'jester/evil-portal-jump-advice)) +(defun jester/goto-line-beginning-or-end () + "Go to line text beginning, line end, line very beginning, in turn." + (interactive) + (cl-block 'my-return + (when (and (looking-at "[^\s]") (looking-back "^\s+")) (evil-end-of-line) (cl-return-from 'my-return)) ; at beg of line text + (when (looking-at ".$") (evil-beginning-of-line) (cl-return-from 'my-return)) ; at end of line + (when (bolp) (evil-first-non-blank) (cl-return-from 'my-return)) ; at very beg of line + (evil-first-non-blank))) +(general-define-key + :states '(normal visual operator) + "0" 'jester/goto-line-beginning-or-end) + ;; TODO try citre-read ;; TODO "vio" vs "yio": make visual "auto line-wise"? diff --git a/modes/init-git.el b/modes/init-git.el index a08cfff..b52ed83 100644 --- a/modes/init-git.el +++ b/modes/init-git.el @@ -6,16 +6,13 @@ :hook (magit-post-refresh . diff-hl-magit-post-refresh) :config (jester/with-leader - "d n" 'diff-hl-next-hunk - "d p" 'diff-hl-previous-hunk)) + "v n" 'diff-hl-next-hunk + "v p" 'diff-hl-previous-hunk)) ;;---------------------------------------------------------------------------- ;; major modes for git files. ;;---------------------------------------------------------------------------- -(use-package gitignore-mode - :mode "\\.gitignore\\'") -(use-package gitconfig-mode - :mode "\\.gitconfig\\'") +(use-package git-modes) ;;---------------------------------------------------------------------------- ;; browse current file history @@ -54,6 +51,7 @@ :init (setq magit-diff-refine-hunk t magit-display-buffer-function 'magit-display-buffer-fullframe-status-v1 + magit-bury-buffer-function 'magit-restore-window-configuration magit-log-margin '(t "周%u %Y-%m-%d %H:%M:%S %z" magit-log-margin-width t 18)) (jester/with-leader "g s" 'magit-status @@ -73,9 +71,6 @@ :keymaps 'transient-base-map "" 'transient-quit-one)) -(use-package evil-magit - :hook (magit-mode . evil-magit-init)) - ;; not using this for now: 1. only 1 hunk per file because magit no longer does the hunking 2. colors not fit theme well ;; (use-package magit-delta ;; :hook (magit-mode . magit-delta-mode)) diff --git a/modes/init-gui-frames.el b/modes/init-gui-frames.el index 3ce8c4e..9fd34c0 100644 --- a/modes/init-gui-frames.el +++ b/modes/init-gui-frames.el @@ -38,6 +38,8 @@ (setq frame-title-format "看,灰机! ✈✈✈✈✈✈✈✈✈" frame-resize-pixelwise t) +(when (and (boundp 'server-name) (string= server-name "maid")) + (setq frame-title-format "maid")) ;; Non-zero values for `line-spacing' can mess up ansi-term and co, ;; so we zero it explicitly in those cases. diff --git a/modes/init-hydra.el b/modes/init-hydra.el index a35faa1..7d21877 100644 --- a/modes/init-hydra.el +++ b/modes/init-hydra.el @@ -1,4 +1,7 @@ (use-package hydra :demand t) +;; hydras are defined in other files grouped by their functionalities. + + (provide 'init-hydra) diff --git a/modes/init-ivy.el b/modes/init-ivy.el index f24fcc7..da3b747 100644 --- a/modes/init-ivy.el +++ b/modes/init-ivy.el @@ -16,7 +16,6 @@ (general-define-key :states '(motion) :keymaps '(ivy-occur-mode-map ivy-occur-grep-mode-map) - "C-d" 'evil-scroll-down "H-d" 'ivy-occur-delete-candidate "g g" 'evil-goto-first-line "g r" 'ivy-occur-revert-buffer @@ -29,10 +28,67 @@ (ivy-state-current ivy-last) 0 nil)) (keyboard-escape-quit))) -(use-package counsel + +(use-package swiper :demand t :after ivy :config + (jester/with-leader + "s b" (lambda! (swiper-all (jester/region-or-empty))) + "s B" (lambda! (swiper-all (jester/region-or-symbol)))) + + (general-define-key + "C-s" 'swiper + "C-S-s" (lambda! (swiper (jester/region-or-symbol))) + "H-s" 'swiper-isearch) + + (defun jester/maybe-run-ivy-hydra () + "Run `hydra-ivy/body' if there is any content in minibuffer." + (unless (save-excursion (beginning-of-line) (looking-at "$")) + (hydra-ivy/body))) + + (defmacro jester/make-fuzzy-search-dwim-command (search-cmd) + "Make a fuzzy search dwim command with the search command `search-cmd'." + ;; TODO ... + ()) + + (defun jester/swiper-dwim () + "If region is not active, just start swiper. If region contain 1 char, grab the symbol as swiper input, otherwise use the region content. +If swiper started with any input, enable ivy-hydra automatically. (so I can h/j/k/l the list)" + (interactive) + (if (region-active-p) + (minibuffer-with-setup-hook 'jester/maybe-run-ivy-hydra + (swiper (regexp-quote (let* ((beg (region-beginning)) + (end (region-end)) + (text (progn (deactivate-mark) + (buffer-substring-no-properties + beg end)))) + (if (= (- end beg) 1) + (thing-at-point 'symbol t) + text))))) + (swiper))) + + (general-define-key + :states '(normal motion) + "/" 'jester/swiper-dwim) + + (defun jester/self-insert-or-search-previous () + "Search previous if nothing in the input area, otherwise self insert." + (interactive) + (if (save-excursion (beginning-of-line) (looking-at "$")) + (progn (call-interactively 'previous-complete-history-element) + (end-of-line)) + (call-interactively 'self-insert-command))) + (general-define-key + :keymaps 'swiper-map + "/" 'jester/self-insert-or-search-previous + "M-/" (lambda! (insert "/")))) + + +(use-package counsel + :demand t + :after swiper + :config ;; --no-sort is much faster (setq counsel-fzf-cmd "fzf --no-sort --exact -f \"%s\"" ;; https://github.com/hlissner/doom-emacs/issues/3038 @@ -45,24 +101,22 @@ "p i" 'counsel-package ;; https://sam217pa.github.io/2016/09/13/from-helm-to-ivy/ "x" 'counsel-M-x - "/" 'counsel-rg + "/" 'jester/counsel-rg-dwim "*" (lambda! (counsel-rg (jester/region-or-symbol))) "f r" 'counsel-recentf "f z" 'jester/fzf-somewhere "t s" 'counsel-load-theme "s j" 'counsel-imenu - "s b" 'swiper-all - "s B" (lambda! (swiper-all (jester/region-or-symbol))) "i u" 'counsel-unicode-char "i f" 'counsel-fonts "v s" 'counsel-set-variable) (general-define-key "M-x" 'counsel-M-x - "M-y" 'counsel-yank-pop - "C-s" 'swiper - "C-S-s" (lambda! (swiper (jester/region-or-symbol))) - "H-s" 'swiper-isearch) + "M-y" 'counsel-yank-pop) + + (general-define-key + :states '(normal motion)) ;; key bindings in ivy popup (general-define-key @@ -82,6 +136,27 @@ "M-w" 'jester/ivy-copy-current-line "" 'ivy-call) + (general-define-key + :keymaps 'counsel-ag-map + "/" 'jester/self-insert-or-search-previous + "M-/" (lambda! (insert "/"))) + + (defun jester/counsel-rg-dwim () + "If region is not active, just start counsel-rg. If region contain 1 char, grab the symbol as counsel-rg input, otherwise use the region content. +If counsel-rg started with any input, enable ivy-hydra automatically. (so I can h/j/k/l the list)" + (interactive) + (if (region-active-p) + (minibuffer-with-setup-hook 'jester/maybe-run-ivy-hydra + (counsel-rg (regexp-quote (let* ((beg (region-beginning)) + (end (region-end)) + (text (progn (deactivate-mark) + (buffer-substring-no-properties + beg end)))) + (if (= (- end beg) 1) + (thing-at-point 'symbol t) + text))))) + (counsel-rg))) + (defun jester/fzf-somewhere (&optional start-dir) "Do `counsel-fzf' in directory START-DIR. If called interactively, let the user select start directory first." @@ -120,6 +195,16 @@ If called interactively, let the user select start directory first." [remap pop-to-mark-command] 'counsel-mark-ring [remap yank-pop] 'counsel-yank-pop)) + +(use-package ivy-hydra + :demand t + :after ivy + :config + (defhydra+ hydra-ivy () + ("a" nil) + ("" keyboard-escape-quit :exit t) + ("q" keyboard-escape-quit :exit t))) + (use-package wgrep :commands ivy-wgrep-change-to-wgrep-mode) diff --git a/modes/init-keyfreq.el b/modes/init-keyfreq.el index a746fc6..2b63f24 100644 --- a/modes/init-keyfreq.el +++ b/modes/init-keyfreq.el @@ -1,114 +1,115 @@ -(use-package keyfreq - :hook (after-init . keyfreq-mode) - :config - (keyfreq-autosave-mode 1) - (setq keyfreq-excluded-commands '( - ;; self insert and alike - self-insert-command - newline - org-self-insert-command - awesome-pair-space - term-send-raw - ;; cursor moving commands - forward-char - backward-char - next-line - previous-line - evil-a-WORD - evil-append - evil-backward-char - evil-backward-word-begin - evil-change - evil-change-line - evil-complete-next - evil-complete-previous - evil-delete - evil-delete-backward-char-and-join - evil-delete-char - evil-delete-line - evil-emacs-state - evil-end-of-line - evil-escape-emacs-state - evil-escape-insert-state - evil-escape-isearch - evil-escape-minibuffer - evil-escape-motion-state - evil-escape-visual-state - evil-ex - evil-ex-command - evil-ex-completion - evil-ex-delete-backward-char - evil-exit-emacs-state - evil-exit-visual-state - evil-filepath-inner-text-object - evil-filepath-outer-text-object - evil-find-char - evil-find-char-to - evil-first-non-blank - evil-force-normal-state - evil-forward-char - evil-forward-word-begin - evil-forward-word-end - evil-forward-WORD-end - evil-forward-WORD-begin - evil-backward-WORD-begin - evil-backward-WORD-end - evil-goto-definition - evil-goto-first-line - evil-goto-line - evil-goto-mark-line - evil-indent - evil-inner-WORD - evil-inner-double-quote - evil-inner-single-quote - evil-inner-word - evil-insert - evil-join - evil-jump-backward - evil-jump-forward - evil-mc-make-and-goto-next-match - evil-next-line - evil-next-visual-line - evil-normal-state - evil-open-below - evil-paste-after - evil-paste-before - evil-previous-line - evil-previous-visual-line - evil-record-macro - evil-repeat - evil-replace - evil-ret - evil-scroll-page-down - evil-scroll-page-up - evil-search-forward - evil-search-next - evil-search-word-forward - evil-set-marker - evil-substitute - evil-visual-block - evil-visual-char - evil-visual-line - evil-yank - evil-ex-search-next - evil-ex-search-previous - evil-scroll-down - evil-scroll-up - evil-scroll-line-down - evil-scroll-line-up - ranger-prev-file - ranger-next-file - ;; ivy - ivy-done - ivy-next-line - ivy-previous-line - ivy-backward-delete-char - ivy-occur-next-line - ivy-occur-previous-line - ;; other - magit-section-toggle - undo-tree-undo - undo-tree-redo - company-ignore))) +(when (string= server-name "server") + (use-package keyfreq + :hook (after-init . keyfreq-mode) + :config + (keyfreq-autosave-mode 1) + (setq keyfreq-excluded-commands '( + ;; self insert and alike + self-insert-command + newline + org-self-insert-command + awesome-pair-space + term-send-raw + ;; cursor moving commands + forward-char + backward-char + next-line + previous-line + evil-a-WORD + evil-append + evil-backward-char + evil-backward-word-begin + evil-change + evil-change-line + evil-complete-next + evil-complete-previous + evil-delete + evil-delete-backward-char-and-join + evil-delete-char + evil-delete-line + evil-emacs-state + evil-end-of-line + evil-escape-emacs-state + evil-escape-insert-state + evil-escape-isearch + evil-escape-minibuffer + evil-escape-motion-state + evil-escape-visual-state + evil-ex + evil-ex-command + evil-ex-completion + evil-ex-delete-backward-char + evil-exit-emacs-state + evil-exit-visual-state + evil-filepath-inner-text-object + evil-filepath-outer-text-object + evil-find-char + evil-find-char-to + evil-first-non-blank + evil-force-normal-state + evil-forward-char + evil-forward-word-begin + evil-forward-word-end + evil-forward-WORD-end + evil-forward-WORD-begin + evil-backward-WORD-begin + evil-backward-WORD-end + evil-goto-definition + evil-goto-first-line + evil-goto-line + evil-goto-mark-line + evil-indent + evil-inner-WORD + evil-inner-double-quote + evil-inner-single-quote + evil-inner-word + evil-insert + evil-join + evil-jump-backward + evil-jump-forward + evil-mc-make-and-goto-next-match + evil-next-line + evil-next-visual-line + evil-normal-state + evil-open-below + evil-paste-after + evil-paste-before + evil-previous-line + evil-previous-visual-line + evil-record-macro + evil-repeat + ;; evil-replace + evil-ret + evil-scroll-page-down + evil-scroll-page-up + evil-search-forward + evil-search-next + evil-search-word-forward + evil-set-marker + evil-substitute + evil-visual-block + evil-visual-char + evil-visual-line + evil-yank + evil-ex-search-next + evil-ex-search-previous + evil-scroll-down + evil-scroll-up + evil-scroll-line-down + evil-scroll-line-up + ranger-prev-file + ranger-next-file + ;; ivy + ivy-done + ivy-next-line + ivy-previous-line + ivy-backward-delete-char + ivy-occur-next-line + ivy-occur-previous-line + ;; other + magit-section-toggle + undo-tree-undo + ;; undo-tree-redo + company-ignore)))) (provide 'init-keyfreq) diff --git a/modes/init-lisp.el b/modes/init-lisp.el index e53f1cb..6debce0 100644 --- a/modes/init-lisp.el +++ b/modes/init-lisp.el @@ -42,6 +42,9 @@ "Run `check-parens' when the current buffer is saved." (add-hook 'after-save-hook #'check-parens nil t)) +(defvar jester-lispy-modes-hook (list) "hook to run for all lisp modes.") +(defvar jester-elispy-modes-hook (list) "hook to run for all elisp modes.") + (add-hook 'jester-lispy-modes-hook 'jester/enable-check-parens-on-save) (after-load 'aggressive-indent (add-hook! 'jester-lispy-modes-hook @@ -85,11 +88,6 @@ (add-hook hook 'jester/elisp-setup)) -(use-package cl-lib-highlight - :hook (lisp-mode . cl-lib-highlight-initialize)) - - - ;; Extras for theme editing (defvar jester/theme-mode-hook nil @@ -144,7 +142,7 @@ (interactive) (if (looking-back "^\s*") (insert ";; ") - (insert "; "))) + (insert " ; "))) (general-define-key :states '(emacs insert) @@ -160,7 +158,7 @@ (use-package lispyville - :bind (("M-r" . lispy-raise) ("H-r" . lispy-raise-some)) + :bind (("H-r" . lispy-raise) ("M-r" . lispy-raise-some)) :init (add-hook! (emacs-lisp-mode lisp-mode) (flycheck-mode -1)) (add-hook! 'emacs-lisp-mode-hook (setq mode-name "ELisp")) @@ -198,16 +196,29 @@ ";" (general-predicate-dispatch 'evilnc-comment-operator (memq major-mode jester-lispy-modes) 'lispyville-comment-or-uncomment)) + ;; change some operator/movements + (general-define-key + :states '(normal visual motion operator) + :keymaps jester-lispy-maps + "(" 'lispyville-previous-opening + ")" 'lispyville-next-closing + "[" 'jester/backward-paragraph + "]" 'jester/forward-paragraph) + ;; need to combine `backward-up-list' and `lispyville-backward-up-list' into 1 func before binding + ;; (jester/with-leader + ;; "(" 'lispyville-backward-up-list + ;; ")" 'lispyville-up-list) + ;; some other lispy{,ville} keys (general-define-key :states '(emacs insert normal visual) :keymaps jester-lispy-maps - "M-u" 'lispyville-wrap-round) + "H-w" 'lispyville-wrap-round) ;; ugly fix (general-define-key :states '(emacs insert normal visual) :keymaps 'inferior-emacs-lisp-mode-map - "M-r" 'lispy-raise)) + "H-r" 'lispy-raise)) (use-package macrostep diff --git a/modes/init-minibuffer.el b/modes/init-minibuffer.el index 9624c76..166df1a 100644 --- a/modes/init-minibuffer.el +++ b/modes/init-minibuffer.el @@ -11,6 +11,7 @@ "C-d" #'backward-char "C-b" #'delete-char "C-v" #'yank + "C-y" #'evil-paste-from-register "C-S-k" 'jester/kill-back-to-indentation "C-r" 'counsel-minibuffer-history "H-x" 'kill-region diff --git a/modes/init-mode-line.el b/modes/init-mode-line.el index 8edb7fd..595597e 100644 --- a/modes/init-mode-line.el +++ b/modes/init-mode-line.el @@ -98,10 +98,10 @@ (propertize (concat " " (file-name-as-directory (file-name-nondirectory (directory-file-name full-dir)))) 'face 'dired-directory))) - "%1" - ;; git info - '(:eval (when vc-mode - (s-replace "Git" (propertize "" 'face '(:family "github-octicons")) vc-mode))) + ;; "%1" + ;; ;; git info + ;; '(:eval (when vc-mode + ;; (s-replace "Git" (propertize "" 'face '(:family "github-octicons")) vc-mode))) ;; minor modes ;; minor-mode-alist diff --git a/modes/init-paredit.el b/modes/init-paredit.el index f940665..3981c2a 100644 --- a/modes/init-paredit.el +++ b/modes/init-paredit.el @@ -29,7 +29,7 @@ ) (general-define-key :states '(emacs insert normal visual) - "M-u" (lambda! (awesome-pair-wrap-round-pair))) + "H-w" (lambda! (awesome-pair-wrap-round-pair))) ;; TODO append \n to make it evil style (defun jester/semantic-kill-maybe-whole-line () @@ -78,8 +78,8 @@ :states '(normal) :keymaps 'prog-mode-map ;; manipulating commands - "<" 'puni-slurp-forward - ">" 'puni-barf-forward + ">" 'puni-slurp-forward + "<" 'puni-barf-forward "M->" 'puni-slurp-backward "M-<" 'puni-barf-backward)) diff --git a/modes/init-projects.el b/modes/init-projects.el index 89130cb..1a5d095 100644 --- a/modes/init-projects.el +++ b/modes/init-projects.el @@ -34,6 +34,7 @@ (lambda (project-dir) (let ((default-directory project-dir)) (magit-status))) "magit")) + ;; TODO pre select the same file name as current buffer (defun jester/select-project-and-open-file () "Select a project with projectile, and open a file." (interactive) diff --git a/modes/init-sessions.el b/modes/init-sessions.el index 4a174e2..c1c3bca 100644 --- a/modes/init-sessions.el +++ b/modes/init-sessions.el @@ -76,7 +76,8 @@ (shell-command-history . 50) tags-file-name tags-table-list - evil-markers-alist)) + evil-markers-alist + jester/eyebrowse-random-number-seed)) (setq desktop-locals-to-save '(evil-markers-alist diff --git a/modes/init-shell.el b/modes/init-shell.el index a61e923..0a8bfdc 100644 --- a/modes/init-shell.el +++ b/modes/init-shell.el @@ -9,11 +9,6 @@ "C-r" 'comint-history-isearch-backward "C-l" 'comint-clear-buffer) -(general-define-key - :states '(normal motion) - :keymaps 'shell-mode-map - "C-d" 'evil-scroll-down) - (general-define-key :states '(insert emacs) :keymaps 'shell-mode-map @@ -36,6 +31,7 @@ (add-hook 'comint-mode-hook 'jester/set-shell-buffer-face) (add-hook 'eshell-mode-hook 'jester/set-shell-buffer-face) (add-hook 'term-mode-hook 'jester/set-shell-buffer-face) +(add-hook 'vterm-mode-hook 'jester/set-shell-buffer-face) (defun jester/shell-for-node.js () "For buffer file, look up directories and find package.json, open a shell there." @@ -60,7 +56,7 @@ (use-package term :ensure nil :init - (jester/with-leader "t n" (lambda! (ansi-term "/bin/zsh"))) + ;; (jester/with-leader "t n" (lambda! (ansi-term "/bin/zsh"))) :custom (term-prompt-regexp "^[^#$%>\n]*[#$%>] *") :config ;; unleash some keys @@ -107,34 +103,41 @@ ;; vterm ;;---------------------------------------------------------------------------- (use-package vterm - :custom (vterm-shell "/bin/zsh") + :custom ((vterm-shell "/bin/zsh") + (vterm-kill-buffer-on-exit t)) :init - ;; (jester/with-leader "t n" (lambda! (vterm 'new-session))) + (jester/with-leader "t n" (lambda! (vterm 'new-session))) + :hook (vterm-mode . evil-insert-state) :config + ;; vterm-mode-map won't work because evil-insert-state-map takes precedence + ;; copy them to insert-state|vterm-mode map + (dolist (key '("" + "C-f" "C-d" "C-a" "C-e" "C-n" "C-p" + "C-b" "C-w" "C-k" + "C-r" "C-t" "C-v" "C-/" + "M-c" "M-f" "M-d" "M-b")) + (general-define-key + :states '(insert emacs) + :keymaps 'vterm-mode-map + key (lookup-key vterm-mode-map (kbd key)))) + + (general-define-key + :keymaps 'vterm-mode-map + "M-:" 'eval-expression) + (general-define-key :states '(insert emacs) :keymaps 'vterm-mode-map - "" nil - "C-a" nil - "C-e" nil - "C-n" nil - "C-p" nil - "C-f" 'vterm--self-insert - "C-d" nil "C-h" nil - "C-b" 'vterm--self-insert - "C-w" 'vterm--self-insert - "C-k" nil - "C-r" nil - "C-t" nil - "C-v" nil - "C-/" nil - "C-c" 'vterm-send-C-c - "C-s" 'swiper - "M-c" nil - "M-f" nil - "M-d" nil - "M-b" nil)) + "C-c" 'vterm--self-insert + "C-s" 'swiper) + + (general-define-key + :states '(normal motion) + :keymaps 'vterm-mode-map + "" 'switch-to-buffer + "i" (lambda! (vterm-reset-cursor-point) (evil-insert-state)) + "a" (lambda! (vterm-reset-cursor-point) (evil-insert-state)))) (provide 'init-shell) diff --git a/modes/init-utils.el b/modes/init-utils.el index e5de77b..a2bcc02 100644 --- a/modes/init-utils.el +++ b/modes/init-utils.el @@ -73,6 +73,16 @@ beg end)) (thing-at-point 'symbol t)))) +(defun jester/region-or-empty () + "Get active region or return empthy string." + (regexp-quote (if (region-active-p) + (let ((beg (region-beginning)) + (end (region-end))) + (deactivate-mark) + (buffer-substring-no-properties + beg end)) + ""))) + ;;---------------------------------------------------------------------------- ;; Merge imenus. ;;---------------------------------------------------------------------------- diff --git a/modes/init-vc.el b/modes/init-vc.el index ff4c51a..02e6c4e 100644 --- a/modes/init-vc.el +++ b/modes/init-vc.el @@ -5,6 +5,7 @@ "m u" 'smerge-keep-upper "m l" 'smerge-keep-lower "m b" 'smerge-keep-all - "m n" 'smerge-next)) + "m n" 'smerge-next + "m p" 'smerge-prev)) (provide 'init-vc) diff --git a/modes/init-web.el b/modes/init-web.el index e8d5df3..547e4ff 100644 --- a/modes/init-web.el +++ b/modes/init-web.el @@ -1,3 +1,4 @@ +;; TODO in ts & tsx file, electric "<" when last symbol starts with Upper case (probably type) (use-package web-mode :init (after-load 'flycheck @@ -23,7 +24,12 @@ web-mode-block-padding 0 web-mode-enable-current-element-highlight nil web-mode-enable-auto-indentation nil - web-mode-comment-formats '(("java" . "//") ("javascript" . "//") ("typescript" . "//") ("php" . "//") ("css" . "/*"))) + web-mode-comment-formats '(("java" . "//") + ("javascript" . "//") + ("typescript" . "//") + ("jsx" . "//") + ("php" . "//") + ("css" . "/*"))) (setq-default web-mode-markup-indent-offset 2 web-mode-code-indent-offset 2 @@ -57,12 +63,15 @@ (defun jester/web-mode-maybe-setup-tsx () "Do something if it's a .tsx file." (when (string-equal (file-name-extension (buffer-name)) "tsx") + (lsp-diagnostics--enable) + (flycheck-add-next-checker 'javascript-eslint 'lsp) (lsp) ;; lsp sets checker to lsp, set it back ;; `flycheck-add-next-checker' (setq flycheck-checker 'javascript-eslint) (jester/make-default-evil-markers-for-js) - (setq-local emmet-expand-jsx-className? t) + (setq-local emmet-expand-jsx-className? t + web-mode-auto-quote-style 3) (aggressive-indent-mode -1))) (add-hook 'web-mode-hook 'jester/web-mode-maybe-setup-xml) diff --git a/modes/init-which-key.el b/modes/init-which-key.el index b48572f..8694ca2 100644 --- a/modes/init-which-key.el +++ b/modes/init-which-key.el @@ -1,9 +1,15 @@ (use-package which-key :init - (jester/with-leader - "k w" 'which-key-show-major-mode) + ;; (jester/with-leader + ;; "k w" 'which-key-show-major-mode) :demand t :config (which-key-mode)) +(use-package which-key-posframe + :demand t + :after which-key + :config + (which-key-posframe-mode)) + (provide 'init-which-key) diff --git a/modes/init-windows.el b/modes/init-windows.el index 5da3d01..2c0d824 100644 --- a/modes/init-windows.el +++ b/modes/init-windows.el @@ -163,6 +163,57 @@ bound to KEY in the leader sub-keymap." (cl-incf jester/eyebrowse-random-number-seed) (eyebrowse-switch-to-window-config (+ jester/eyebrowse-random-number-seed 10000))) + +;; set to 0 so we jump a lot by default, making sure we land at middle of window when using marks +(setq scroll-conservatively 0) +;; use 999 when moving the cursor, so it stays at top/bottom of window, not being jumpy +;; TODO not work +(dolist (no-jumpy-command '(evil-next-line evil-previous-line next-line previous-line)) + (advice-add no-jumpy-command :around 'jester/run-command-no-jumpy)) +(defun jester/run-command-no-jumpy (old-fun &rest args) + "Around advice. Run OLD-FUN (next-line, prev-line etc.) without jumping cursor to middle of screen." + (let ((scroll-conservatively 999)) + (apply old-fun args))) + +(use-package smooth-scroll + :demand t + :config + (smooth-scroll-mode 1) + (setq smooth-scroll/hscroll-step-size 2 + smooth-scroll/vscroll-step-size 2) + (general-define-key + :states '(normal motion) + "C-j" 'evil-scroll-line-down + "C-k" 'evil-scroll-line-up)) + +(defhydra jester/hydra-scroll () + "scroll" + ("d" evil-scroll-down "down") + ("u" evil-scroll-up "up")) +(hydra-set-property 'jester/hydra-scroll :verbosity 0) + +(jester/with-leader + "d" 'jester/hydra-scroll/evil-scroll-down + "u" 'jester/hydra-scroll/evil-scroll-up) + +(defhydra jester/hydra-scroll-line () + "scroll line" + ;; the function names ("up" "down") are the opposite from intuition + ;; scroll-up-1 + ;; scroll-down-1 + ("k" scroll-down-line "up") + ("j" scroll-up-line "down") + ;; put "f" in body so (SPC j f) actually runs find-function + ("f" find-function "(j f) find-function" :exit t) + ("K" find-function-on-key "(j K) find-function-on-key" :exit t) + ("v" find-variable "(j v) find-variable" :exit t) + ("w" which-key-show-major-mode "(k w) which-key-show-major-mode" :exit t)) +(hydra-set-property 'jester/hydra-scroll-line :verbosity 0) + +(jester/with-leader + "k" 'jester/hydra-scroll-line/scroll-down-line + "j" 'jester/hydra-scroll-line/scroll-up-line) + (defun jester/kill-buffer-and-window () "Kill current buffer and window." diff --git a/snippets/prog-mode/export b/snippets/prog-mode/export new file mode 100644 index 0000000..b9acaf9 --- /dev/null +++ b/snippets/prog-mode/export @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: export +# key: ex +# -- +export \ No newline at end of file diff --git a/snippets/web-mode/props-declaration-for-vue b/snippets/web-mode/props-declaration-for-vue deleted file mode 100644 index 128d382..0000000 --- a/snippets/web-mode/props-declaration-for-vue +++ /dev/null @@ -1,10 +0,0 @@ -# key: props -# name: props declaration for vue -# -- -props: { - $1: { - type: $2, - ${3:required: $4, -} ${5:default: $6, -} }, -}, \ No newline at end of file