diff --git a/.gitignore b/.gitignore index cc39713..ee53226 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,4 @@ site-lisp/package/ /forge-database.sqlite /server /transient +/.lsp-* diff --git a/init.el b/init.el index 063cb38..f77fb1a 100644 --- a/init.el +++ b/init.el @@ -72,18 +72,19 @@ (require 'init-vc) (require 'init-git) +(require 'init-compile) + +(require 'init-paredit) (require 'init-lisp) -;; (require 'init-scheme) +(require 'init-scheme) ;; (require 'init-slime) ;; (require 'init-clojure) ;; (require 'init-clojure-cider) ;; (require 'init-common-lisp) -(require 'init-paredit) (require 'init-lsp) (require 'init-jump) -;; (require 'init-compile) (require 'init-text) (require 'init-org) (require 'init-markdown) diff --git a/modes/init-company.el b/modes/init-company.el index c8756d4..2095531 100644 --- a/modes/init-company.el +++ b/modes/init-company.el @@ -31,7 +31,6 @@ "C-p" #'company-select-previous "" 'company-complete-common "" 'expand-snippet-or-complete-selection - "C-b" 'company-show-doc-buffer "C-g" 'company-abort "" (lambda! (company-abort) (evil-normal-state))) (dotimes (i 10) @@ -75,10 +74,6 @@ (backward-char 1) (if (looking-at "->") t nil))))) -(defun do-yas-expand () - (let ((yas-fallback-behavior 'return-nil)) - (yas-expand))) - (defun tab-indent-or-complete () (interactive) (cond @@ -87,7 +82,7 @@ (t ;; (indent-for-tab-command) (if (and (or (not yas-minor-mode) - (null (do-yas-expand))) + (null (yas-expand))) (check-expansion)) (progn (company-manual-begin) @@ -99,25 +94,10 @@ ))) )))) -;; (defun tab-complete-or-next-field () -;; (interactive) -;; (if (or (not yas-minor-mode) -;; (null (do-yas-expand))) -;; (if company-candidates -;; (company-complete-selection) -;; (if (check-expansion) -;; (progn -;; (company-manual-begin) -;; (if (null company-candidates) -;; (progn -;; (company-abort) -;; (yas-next-field)))) -;; (yas-next-field))))) - (defun expand-snippet-or-complete-selection () (interactive) (if (or (not yas-minor-mode) - (null (do-yas-expand)) + (null (yas-expand)) (company-abort)) (company-complete-selection))) diff --git a/modes/init-compile.el b/modes/init-compile.el index adba0ce..c894357 100644 --- a/modes/init-compile.el +++ b/modes/init-compile.el @@ -1,8 +1,12 @@ -(setq-default compilation-scroll-output t) +(setq compilation-read-command nil + compilation-scroll-output t) + (require-package 'alert) - -;; Customize `alert-default-style' to get messages after compilation +(setq alert-default-style (pcase window-system + ('x 'x11) + ('mac 'osx-notifier) + (_ 'message))) (defun jester/alert-after-compilation-finish (buf result) "Use `alert' to report compilation RESULT if BUF is hidden." @@ -20,36 +24,7 @@ (add-hook 'compilation-finish-functions 'jester/alert-after-compilation-finish)) -(defvar jester/last-compilation-buffer nil - "The last buffer in which compilation took place.") - -(after-load 'compile - (defadvice compilation-start (after jester/save-compilation-buffer activate) - "Save the compilation buffer to find it later." - (setq jester/last-compilation-buffer next-error-last-buffer)) - - (defadvice recompile (around jester/find-prev-compilation (&optional edit-command) activate) - "Find the previous compilation buffer, if present, and recompile there." - (if (and (null edit-command) - (not (derived-mode-p 'compilation-mode)) - jester/last-compilation-buffer - (buffer-live-p (get-buffer jester/last-compilation-buffer))) - (with-current-buffer jester/last-compilation-buffer - ad-do-it) - ad-do-it))) - -(global-set-key [f6] 'recompile) - -(defadvice shell-command-on-region - (after jester/shell-command-in-view-mode - (start end command &optional output-buffer replace &rest other-args) - activate) - "Put \"*Shell Command Output*\" buffers into view-mode." - (unless (or output-buffer replace) - (with-current-buffer "*Shell Command Output*" - (view-mode 1)))) - - + (after-load 'compile (require 'ansi-color) (defun jester/colourise-compilation-buffer () @@ -57,8 +32,29 @@ (ansi-color-apply-on-region compilation-filter-start (point-max)))) (add-hook 'compilation-filter-hook 'jester/colourise-compilation-buffer)) - -(maybe-require-package 'cmd-to-echo) + +(defvar-local jester-run-command nil + "shell command to run the project.") + +(defun jester/run-project () + "Run it with `compile' and `jester-run-command'." + (interactive) + (if jester-run-command + (compile jester-run-command) + (user-error "no run command configured for %s" major-mode)) + ;; switch to "*compilation*" buffer because it's configured not to show when `compile' + (switch-to-buffer "*compilation*")) + +(jester/with-leader + ;; TODO assign a key to "cargo check"? + "c i" 'compile ;; "compile it!" + "c l" (lambda! (switch-to-buffer "*compilation*")) + "c r" 'jester/run-project) + +(general-define-key + :states '(motion) + :keymaps 'compilation-mode-map + "f" 'link-hint-open-link) (provide 'init-compile) diff --git a/modes/init-dired.el b/modes/init-dired.el index 65decc9..8127dfc 100644 --- a/modes/init-dired.el +++ b/modes/init-dired.el @@ -16,6 +16,7 @@ ;; NOTE: remap doesn't change when dired-* is called from code (jester/with-leader "f d" 'dired-jump) + :custom (ranger-show-hidden 'format) :bind (([remap dired-jump] . deer) :map ranger-mode-map ("s" . 'ranger-sort-criteria)) diff --git a/modes/init-editing-utils.el b/modes/init-editing-utils.el index 237dea6..93bc595 100644 --- a/modes/init-editing-utils.el +++ b/modes/init-editing-utils.el @@ -92,7 +92,7 @@ :hook ((js2-mode . electric-operator-mode) (css-mode . electric-operator-mode) (sass-mode . electric-operator-mode) - (rust-mode . electric-operator-mode) + ;; (rust-mode . electric-operator-mode) (java-mode . electric-operator-mode) (python-mode . electric-operator-mode) (sql-mode . electric-operator-mode) @@ -225,21 +225,34 @@ Effectively using symbol before point as the key." "" 'jester/make-key-value-pair) ;;---------------------------------------------------------------------------- -;; Make a "foo: bar;" key-value pair +;; Insert " = " for me, please. ;;---------------------------------------------------------------------------- -(defun jester/make-css-pair () - "Make a key-value pair for css etc., by inserting \": ;\" at point." - (interactive) - (insert ": ;") (backward-char)) +(defmacro jester/def-make-assignment-function (fun-name eol-str &rest forms-for-bolt) + "Define a function with the name of `FUN-NAME'. +`FORMS-FOR-BOLT' is some forms evaluated when point is at beginning of line text, +who decides which type of assignment we currently have, and change it to the next one. +Use `eol-str' as the tail." + `(defun ,fun-name () + "Make a mode specific assignment statement, +using things left of point as left value, things right as right value. -(general-define-key - :states '(insert emacs) - :keymaps 'prog-mode-map - "M-;" 'jester/make-css-pair) +If nothing is at left, move point to the left value's position, +otherwise move to before semicolon. + +If this line is already an assignment (has a \"=\"), cycle through some styles." + (interactive) + (save-match-data + (let ((need-signs (save-excursion + (beginning-of-line-text) (not (looking-at ".* = .*$")))) + (something-left-p (not (looking-back "^\s*")))) + (save-excursion + (if need-signs + (progn (insert " = ") (move-end-of-line 1) + (unless (looking-back ,eol-str) (insert ,eol-str))) + (beginning-of-line-text) + ,@forms-for-bolt)) + (when (and need-signs something-left-p) (move-end-of-line 1) (left-char)))))) -;;---------------------------------------------------------------------------- -;; Insert " = " for me, please. -;;---------------------------------------------------------------------------- (defvar jester-javascript-assignment-declarer 'var "What word to use when making a javascript assignment. @@ -258,26 +271,24 @@ If this line is already an assignment (has a \"=\"), cycle through styles in thi a \"const\" assignment, a \"let\" assignment." (interactive) - (let ((need-signs (save-excursion (beginning-of-line-text) (not (looking-at ".* = .*$")))) - (something-left-p (not (looking-back "^\s*")))) - (save-excursion - (if need-signs - (progn (insert " = ") (move-end-of-line 1) - (unless (looking-back ";") (insert ";"))) - (beginning-of-line-text) - (cond - ((eq jester-javascript-assignment-declarer 'let) - (cond - ((looking-at "const ") (kill-word 1) (insert "let")) - ((looking-at "let ") (kill-word 1) (delete-char 1)) - (t (insert "const ")))) - ((eq jester-javascript-assignment-declarer 'var) - (cond - ((looking-at "var ") (kill-word 1) (delete-char 1)) - (t (insert "var ")))) - (t (user-error "Plz set `jester-javascript-assignment-declarer' to `let' or `var'"))) - )) - (when (and need-signs something-left-p) (move-end-of-line 1) (left-char)))) + (save-match-data + (let ((need-signs (save-excursion (beginning-of-line-text) (not (looking-at ".* = .*$")))) + (something-left-p (not (looking-back "^\s*")))) + (save-excursion + (if need-signs + (progn (insert " = ") (move-end-of-line 1) + (unless (looking-back ";") (insert ";"))) + (beginning-of-line-text) + (pcase jester-javascript-assignment-declarer + ('let (cond + ((looking-at "const ") (replace-match "let ")) + ((looking-at "let ") (replace-match "")) + (t (insert "const ")))) + ('var (cond + ((looking-at "var ") (replace-match "")) + (t (insert "var ")))) + (_ (user-error "Plz set `jester-javascript-assignment-declarer' to `let' or `var'"))))) + (when (and need-signs something-left-p) (move-end-of-line 1) (left-char))))) (general-define-key :states '(insert emacs) @@ -288,6 +299,8 @@ If this line is already an assignment (has a \"=\"), cycle through styles in thi "Make a assignment statement, using things left of point as left value, things right as right value. +Additional formats are added to this line as declared in `jester-assignment-format-alist'. + If nothing is at left, move point to the left value's position, otherwise move to before semicolon." (interactive) @@ -295,7 +308,7 @@ otherwise move to before semicolon." (something-left-p (not (looking-back "^\s*")))) (save-excursion (when need-signs - (progn (insert " = ")))) + (progn (insert " = ")))) (when (and need-signs something-left-p) (move-end-of-line 1)))) (general-define-key @@ -480,12 +493,21 @@ If use-indirect-buffer is not nil, use `indirect-buffer' to hold the widen conte "Select an argument, without the punctuations." :extend-selection nil (list (progn - (re-search-backward "[,(] ?") + (re-search-backward (rx (sequence (or "," + "(" + "[" + "{") + (optional " ")))) (forward-char) (when (eq (char-after (point)) ? ) (forward-char)) (point)) - (progn (re-search-forward "[,] ?\\| ?)") - (while (memq (char-before) (list ?, ? ?\))) (backward-char)) + (progn (re-search-forward (rx (or (sequence "," + (optional " ")) + (sequence (optional " ") + (or ")" + "]" + "}"))))) + (while (memq (char-before) (list ?, ? ?\) ?\] ?})) (backward-char)) (point)))) (evil-define-text-object jester/evil-a-arg (count &optional beg end type) @@ -493,14 +515,23 @@ If use-indirect-buffer is not nil, use `indirect-buffer' to hold the widen conte :extend-selection nil (let* (last-arg-p (head (progn - (re-search-backward "[,(] ?") + (re-search-backward (rx (sequence (or "," + "(" + "[" + "{") + (optional " ")))) (forward-char) (when (eq (char-after (point)) ? ) (forward-char)) (point))) - (tail (progn (re-search-forward "[,] ?\\| ?)") - (setq last-arg-p (eq (char-before) ?\))) - (when (eq (char-before) ?\)) - (while (memq (char-before) (list ? ?\))) (backward-char))) + (tail (progn (re-search-forward (rx (or (sequence "," + (optional " ")) + (sequence (optional " ") + (or ")" + "]" + "}"))))) + (setq last-arg-p (memq (char-before) (list ?\) ?\] ?}))) + (when (memq (char-before) (list ?\) ?\] ?})) + (while (memq (char-before) (list ? ?\) ?\] ?})) (backward-char))) (point)))) (when last-arg-p (setq head (progn (goto-char head) diff --git a/modes/init-elpa.el b/modes/init-elpa.el index b628a1f..ae7eeb9 100644 --- a/modes/init-elpa.el +++ b/modes/init-elpa.el @@ -17,10 +17,10 @@ ;; ("org-cn" . "https://elpa.emacs-china.org/org/") ;; ("gnu-cn" . "https://elpa.emacs-china.org/gnu/") ;; ("melpa-stable-cn" . "https://elpa.emacs-china.org/melpa-stable/") - ("melpa-tuna" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/melpa/") - ("org-tuna" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/org/") - ("gnu-tuna" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/gnu/") - ("melpa-stable-tuna" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/melpa-stable/") + ("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/") ) package-archives)) diff --git a/modes/init-evil.el b/modes/init-evil.el index 2b1b4f9..a935698 100644 --- a/modes/init-evil.el +++ b/modes/init-evil.el @@ -41,10 +41,12 @@ (jester/leader-emacs-def ,@args))) (defmacro jester/with-major-leader (keymaps &rest args) "Define a major-leader key sequence." + (declare (indent 1)) `(progn (jester/major-leader-def :keymaps ,keymaps ,@args) (jester/major-leader-emacs-def :keymaps ,keymaps ,@args))) (defmacro jester/with-minor-leader (mode &rest args) "Define a leader key sequence using major leader key, but for a minor mode." + (declare (indent 1)) `(progn (jester/minor-leader-def :keymaps ,mode ,@args) (jester/minor-leader-emacs-def :keymaps ,mode ,@args))) ) @@ -245,15 +247,52 @@ "-" 'evil-numbers/dec-at-pt)) -;; TODO support for lispyville & `general-key-dispatch' (use-package evil-goggles :after evil + :demand t :custom (evil-goggles-duration 0.1) - :hook (evil-mode . evil-goggles-mode) + :init + ;; (lispyville-> :face evil-goggles-shift-face :switch evil-goggles-enable-shift :advice evil-goggles--generic-async-advice) + ;; (lispyville-< :face evil-goggles-shift-face :switch evil-goggles-enable-shift :advice evil-goggles--generic-async-advice) + (setq evil-goggles--commands + '((evil-delete :face evil-goggles-delete-face :switch evil-goggles-enable-delete :advice evil-goggles--generic-blocking-advice) + (evil-delete-line :face evil-goggles-delete-face :switch evil-goggles-enable-delete :advice evil-goggles--delete-line-advice) + (evil-org-delete :face evil-goggles-delete-face :switch evil-goggles-enable-delete :advice evil-goggles--delete-line-advice) + (evil-yank :face evil-goggles-yank-face :switch evil-goggles-enable-yank :advice evil-goggles--generic-async-advice) + (evil-yank-line :face evil-goggles-yank-face :switch evil-goggles-enable-yank :advice evil-goggles--generic-async-advice) + (evil-change :face evil-goggles-change-face :switch evil-goggles-enable-change :advice evil-goggles--generic-blocking-advice) + (evil-change-line :face evil-goggles-change-face :switch evil-goggles-enable-change :advice evil-goggles--generic-blocking-advice) + (evil-change-whole-line :face evil-goggles-change-face :switch evil-goggles-enable-change :advice evil-goggles--generic-blocking-advice) + (evil-indent :face evil-goggles-indent-face :switch evil-goggles-enable-indent :advice evil-goggles--generic-async-advice) + (evil-join :face evil-goggles-join-face :switch evil-goggles-enable-join :advice evil-goggles--join-advice) + (evil-join-whitespace :face evil-goggles-join-face :switch evil-goggles-enable-join :advice evil-goggles--join-advice) + (evil-fill-and-move :face evil-goggles-fill-and-move-face :switch evil-goggles-enable-fill-and-move :advice evil-goggles--generic-async-advice) + (evil-shift-left :face evil-goggles-shift-face :switch evil-goggles-enable-shift :advice evil-goggles--generic-async-advice) + (evil-shift-right :face evil-goggles-shift-face :switch evil-goggles-enable-shift :advice evil-goggles--generic-async-advice) + (evil-org-< :face evil-goggles-shift-face :switch evil-goggles-enable-shift :advice evil-goggles--generic-async-advice) + (evil-org-> :face evil-goggles-shift-face :switch evil-goggles-enable-shift :advice evil-goggles--generic-async-advice) + (evil-surround-region :face evil-goggles-surround-face :switch evil-goggles-enable-surround :advice evil-goggles--generic-async-advice) + (evil-commentary :face evil-goggles-commentary-face :switch evil-goggles-enable-commentary :advice evil-goggles--generic-async-advice) + (evilnc-comment-operator :face evil-goggles-nerd-commenter-face :switch evil-goggles-enable-nerd-commenter :advice evil-goggles--generic-async-advice) + (evil-replace-with-register :face evil-goggles-replace-with-register-face :switch evil-goggles-enable-replace-with-register :advice evil-goggles--generic-async-advice-1) + (evil-set-marker :face evil-goggles-set-marker-face :switch evil-goggles-enable-set-marker :advice evil-goggles--set-marker-advice) + (evil-record-macro :face evil-goggles-record-macro-face :switch evil-goggles-enable-record-macro :advice evil-goggles--record-macro-advice) + (evil-paste-before :face evil-goggles-paste-face :switch evil-goggles-enable-paste :advice evil-goggles--paste-advice :after t) + (evil-paste-after :face evil-goggles-paste-face :switch evil-goggles-enable-paste :advice evil-goggles--paste-advice :after t) + (lispyville-yank :face evil-goggles-yank-face :switch evil-goggles-enable-yank :advice evil-goggles--generic-async-advice) + (lispyville-delete :face evil-goggles-delete-face :switch evil-goggles-enable-delete :advice evil-goggles--generic-blocking-advice) + (lispyville-change :face evil-goggles-change-face :switch evil-goggles-enable-change :advice evil-goggles--generic-blocking-advice) + (lispyville-yank-line :face evil-goggles-yank-face :switch evil-goggles-enable-yank :advice evil-goggles--generic-async-advice) + (lispyville-delete-line :face evil-goggles-delete-face :switch evil-goggles-enable-delete :advice evil-goggles--delete-line-advice) + (lispyville-change-line :face evil-goggles-change-face :switch evil-goggles-enable-change :advice evil-goggles--generic-blocking-advice) + (lispyville-change-whole-line :face evil-goggles-change-face :switch evil-goggles-enable-change :advice evil-goggles--generic-blocking-advice) + (lispyville-join :face evil-goggles-join-face :switch evil-goggles-enable-join :advice evil-goggles--join-advice) + (lispyville-comment-or-uncomment :face evil-goggles-nerd-commenter-face :switch evil-goggles-enable-nerd-commenter :advice evil-goggles--generic-async-advice) + (lispyville-prettify :face evil-goggles-indent-face :switch evil-goggles-enable-indent :advice evil-goggles--generic-async-advice))) + :hook (after-init . evil-goggles-mode) :config ;; (evil-goggles-use-diff-faces) - (evil-goggles-use-diff-refine-faces) - ) + (evil-goggles-use-diff-refine-faces)) (push (expand-file-name "targets" jester-submodules-dir) load-path) @@ -397,10 +436,7 @@ "C-u" 'evil-scroll-up "C-j" 'evil-scroll-line-down "C-k" 'evil-scroll-line-up - "'" 'evil-goto-mark - "C-h C-f" 'list-faces-display - "C-h p" 'describe-package - "C-h c" 'describe-char) + "'" 'evil-goto-mark) (general-define-key :states '(normal visual motion operator) @@ -430,7 +466,10 @@ ;; Not-so-evil keys... ;;---------------------------------------------------------------------------- (general-define-key - "C-h p" 'describe-package) + "C-h C-f" 'list-faces-display + "C-h p" 'describe-package + "C-h c" 'describe-char + "C-h K" 'find-function-on-key) ;;---------------------------------------------------------------------------- ;; Some functions. diff --git a/modes/init-face.el b/modes/init-face.el index be043f9..4d0bca7 100644 --- a/modes/init-face.el +++ b/modes/init-face.el @@ -143,5 +143,11 @@ This is helpful for writeroom-mode, in particular." (add-hook 'visual-fill-column-mode-hook 'jester/maybe-adjust-visual-fill-column) +;;---------------------------------------------------------------------------- +;; face related key bindings +;;---------------------------------------------------------------------------- +(jester/with-leader + "t c" 'text-scale-adjust) + (provide 'init-face) diff --git a/modes/init-file.el b/modes/init-file.el index 8b3f408..0ab8e63 100644 --- a/modes/init-file.el +++ b/modes/init-file.el @@ -17,7 +17,7 @@ (defvar jester-auto-save-idle 1 "Time in seconds before auto-saving all buffers.") (run-with-idle-timer jester-auto-save-idle t #'jester/save-all-buffers) -;; (cancel-function-timers 'jester/save-all-buffers) ;; for debugging +;; (cancel-function-timers 'jester/save-all-buffers) ; for debugging (add-hook 'focus-out-hook #'jester/save-all-buffers) ;;---------------------------------------------------------------------------- @@ -30,9 +30,13 @@ (not company-candidates) (not (eq major-mode 'snippet-mode))) ;; https://github.com/manateelazycat/lazycat-emacs/commit/da13a688ef89f8ab2c577a3e9d2a7bcf0ef9b71d + ;; https://emacs-china.org/t/topic/7687/30?u=jjpandari + ;; this prevents blink of eldoc (with-temp-message - (with-current-buffer " *Minibuf-0*" (buffer-string)) - (save-some-buffers t #'(lambda () (and (buffer-file-name) (buffer-modified-p))))))) + (with-current-buffer " *Minibuf-0*" (buffer-string)) + ;; this prevents blink of ivy + (let ((inhibit-message t)) + (save-some-buffers t #'(lambda () (and (buffer-file-name) (buffer-modified-p)))))))) ;;---------------------------------------------------------------------------- ;; Delete the current file diff --git a/modes/init-ivy.el b/modes/init-ivy.el index 5ac218d..27b6340 100644 --- a/modes/init-ivy.el +++ b/modes/init-ivy.el @@ -1,19 +1,19 @@ (use-package ivy :demand t + :custom + ((ivy-use-virtual-buffers t) + (ivy-virtual-abbreviate 'full) + (ivy-initial-inputs-alist nil) + (ivy-use-selectable-prompt t) + (completing-read-function 'ivy-completing-read)) :config - (setq - ivy-use-virtual-buffers t - ivy-virtual-abbreviate 'full - ivy-initial-inputs-alist nil - ivy-use-selectable-prompt t - completing-read-function 'ivy-completing-read) (general-define-key :keymaps 'ivy-switch-buffer-map "M-k" 'ivy-switch-buffer-kill) (jester/with-major-leader '(ivy-occur-mode-map ivy-occur-grep-mode-map wgrep-mode-map) - "w" (lambda! (ivy-wgrep-change-to-wgrep-mode) (evil-normal-state)) - "," (lambda! (wgrep-finish-edit) (evil-motion-state)) - "a" (lambda! (wgrep-abort-changes) (evil-motion-state)))) + "w" (lambda! (ivy-wgrep-change-to-wgrep-mode) (evil-normal-state)) + "," (lambda! (wgrep-finish-edit) (evil-motion-state)) + "a" (lambda! (wgrep-abort-changes) (evil-motion-state)))) (use-package counsel :demand t @@ -22,11 +22,11 @@ ;; --no-sort is much faster (setq counsel-fzf-cmd "fzf --no-sort -f \"%s\"" ;; limit file size and line length to be faster. long lines doesn't matter when search but is laggy to display - counsel-rg-base-command "rg -S --no-heading --line-number --color never --max-filesize 1M --max-columns 233 --max-columns-preview %s .") + counsel-rg-base-command "rg --no-heading --line-number --color never --max-filesize 1M --max-columns 233 --max-columns-preview %s .") (jester/with-leader "p f" 'jester/open-project-file - "p F" (lambda! (jester/open-project-file (thing-at-point 'filename))) + "p i" 'counsel-package ;; https://sam217pa.github.io/2016/09/13/from-helm-to-ivy/ "/" 'counsel-rg "*" (lambda! (counsel-rg (jester/region-or-symbol))) @@ -37,7 +37,9 @@ "." 'counsel-imenu "s b" 'swiper-all "s B" (lambda! (swiper-all (jester/region-or-symbol))) - "i u" 'counsel-unicode-char) + "i u" 'counsel-unicode-char + "i f" 'counsel-fonts + "v s" 'counsel-set-variable) (general-define-key "M-x" 'counsel-M-x @@ -80,6 +82,7 @@ If called interactively, let the user select start directory first." ((locate-dominating-file default-directory ".git") (counsel-git)) (t (jester/fzf-somewhere)))) + ;; see doc for `counsel-mode' (general-define-key [remap switch-to-buffer] 'ivy-switch-buffer [remap bookmark-jump] 'counsel-bookmark @@ -87,6 +90,7 @@ If called interactively, let the user select start directory first." [remap describe-face] 'counsel-describe-face [remap describe-function] 'counsel-describe-function [remap describe-variable] 'counsel-describe-variable + [remap execute-extended-command] 'counsel-M-x [remap find-file] 'counsel-find-file [remap find-library] 'counsel-find-library [remap imenu] 'counsel-imenu @@ -94,7 +98,8 @@ If called interactively, let the user select start directory first." [remap list-faces-display] 'counsel-faces [remap load-library] 'counsel-load-library [remap load-theme] 'counsel-load-theme - [remap pop-to-mark-command] 'counsel-mark-ring)) + [remap pop-to-mark-command] 'counsel-mark-ring + [remap yank-pop] 'counsel-yank-pop)) (use-package wgrep :commands ivy-wgrep-change-to-wgrep-mode) diff --git a/modes/init-javascript.el b/modes/init-javascript.el index e86cb68..b69b341 100644 --- a/modes/init-javascript.el +++ b/modes/init-javascript.el @@ -52,32 +52,31 @@ (evil-set-initial-state 'skewer-error-mode 'motion)) -;; (use-package rjsx-mode -;; :init -;; (setq -;; magic-mode-alist (append -;; '(("import\s+.+\s+from\s+['\"]react['\"]" . rjsx-mode)) -;; magic-mode-alist)) -;; (add-hook -;; 'rjsx-mode-hook -;; (lambda () (flycheck-mode 1) -;; (evil-matchit-mode 1) -;; (add-hook 'post-command-hook 'jester/on-post-newline nil t) -;; (setq imenu-create-index-function (lambda () (jester/merge-imenu 'js2-mode-create-imenu-index))) -;; (setq -;; imenu-generic-expression -;; '((nil "^ \\(state\\) = {" 1))))) -;; :config -;; (evil-define-key 'insert rjsx-mode-map (kbd "C-b") #'rjsx-delete-creates-full-tag) -;; (modify-syntax-entry ?_ "w" rjsx-mode-syntax-table) - -;; (defun jester/import-antd-form-function () -;; "import the function at point as an antd form util function" -;; (interactive) -;; (let ((fun (thing-at-point 'symbol))) -;; (evil-open-above 1) -;; (insert (format "const { %s } = this.props.form;" fun)) -;; (evil-normal-state)))) +(use-package rjsx-mode + :init + (defun jester/jsx-file-p () + "Check whether current buffer is a jsx file." + (point-min) + (while (looking-at "^//") + (beginning-of-line 2)) + (looking-at (rx (sequence bol + "import" + (1+ (or word "," "{" "}" whitespace)) + "from 'react'" + (optional ";") + eol)))) + (setq magic-mode-alist + (append '((jester/jsx-file-p . rjsx-mode)) magic-mode-alist)) + (add-hook! 'rjsx-mode-hook + (add-hook 'post-command-hook 'jester/on-post-newline nil t) + (setq imenu-create-index-function (lambda () (jester/merge-imenu 'js2-mode-create-imenu-index)) + imenu-generic-expression '((nil "^ *static \\(propTypes\\|defaultProps\\) = {$" 1)) + mode-name "JSX")) + (custom-set-faces '(rjsx-tag + ((t (:inherit web-mode-html-tag-face))))) + :config + (evil-define-key 'insert rjsx-mode-map (kbd "C-b") #'rjsx-delete-creates-full-tag) + (modify-syntax-entry ?_ "w" rjsx-mode-syntax-table)) ;; https://emacs-china.org/t/javascript/7860?u=jjpandari diff --git a/modes/init-lisp.el b/modes/init-lisp.el index 3a9c8ab..47cf83e 100644 --- a/modes/init-lisp.el +++ b/modes/init-lisp.el @@ -64,7 +64,7 @@ (defconst jester-lispy-modes (append jester-elispy-modes - '(lisp-mode lisp-interaction-mode)) + '(lisp-mode lisp-interaction-mode scheme-mode inferior-scheme-mode racket-mode)) "Major modes relating to lisp.") (defconst jester-elispy-maps @@ -87,9 +87,6 @@ (use-package cl-lib-highlight :hook (lisp-mode . cl-lib-highlight-initialize)) -;; A quick way to jump to the definition of a function given its key binding -(global-set-key (kbd "C-h K") 'find-function-on-key) - ;; Extras for theme editing @@ -141,6 +138,7 @@ ;; https://emacs-china.org/t/minibuffer-point-elisp/10048/6?u=jjpandari ;; show docstring after param list when point is on a function +;; TODO ditch line if it's "advice" (advice-add 'elisp-get-fnsym-args-string :around (lambda (oldfun sym &rest args) @@ -179,9 +177,9 @@ :init (add-hook! (emacs-lisp-mode lisp-mode) (flycheck-mode -1)) (add-hook! 'emacs-lisp-mode-hook (setq mode-name "ELisp")) + (add-hook! 'jester-lispy-modes-hook (lispyville-mode 1)) ;; load it everywhere ;; :hook (prog-mode . lispyville-mode) - :hook ((emacs-lisp-mode lisp-mode inferior-emacs-lisp-mode lisp-interaction-mode) . lispyville-mode) :config (lispyville-set-key-theme '(operators diff --git a/modes/init-lsp.el b/modes/init-lsp.el index ef48919..2dc45ff 100644 --- a/modes/init-lsp.el +++ b/modes/init-lsp.el @@ -1,15 +1,79 @@ -(use-package eglot - :commands (eglot eglot-ensure)) +;; (use-package eglot +;; :commands (eglot eglot-ensure)) -;; not needed when using eglot -;; (use-package company-lsp -;; :after company -;; :init -;; (add-hook! 'company-mode-hook (require 'company-lsp)) -;; :config -;; (push 'company-lsp company-backends)) +(use-package lsp-mode + :custom + (lsp-prefer-flymake nil) + (lsp-restart 'auto-restart) + :hook (rust-mode . lsp) + :commands (lsp lsp-deferred)) + +;; lsp-ui and company-lsp auto configured by lsp-mode +(use-package lsp-ui + :custom ((lsp-ui-sideline-enable nil) + (lsp-ui-flycheck-enable t) + (lsp-ui-doc-max-height 50) + (lsp-ui-doc-alignment 'frame-left-or-right-other)) + :init + ;; (custom-set-faces `(lsp-ui-doc-background + ;; ((t (:background ,(face-attribute 'hl-line :background)))))) + (setq lsp-ui-doc-border (face-attribute 'default :foreground)) + :commands lsp-ui-mode + :config + (defun lsp-ui-doc--move-frame (frame) + "Place our FRAME on screen." + (-let* (((left top right _bottom) (window-edges nil nil nil t)) + (window (frame-root-window frame)) + ((width . height) (window-text-pixel-size window nil nil 10000 10000 t)) + (width (+ width (* (frame-char-width frame) 1))) ;; margins + (char-h (frame-char-height)) + (height (min (- (* lsp-ui-doc-max-height char-h) (/ char-h 2)) height)) + (frame-right (pcase lsp-ui-doc-alignment + ('window right) + (_ (frame-pixel-width)))) + (frame-resize-pixelwise t) + ((window-left-edge window-top-edge window-right-edge _) (window-absolute-pixel-edges)) + (window-left-right-center (/ (+ window-left-edge window-right-edge) 2)) + ((frame-left-edge frame-top-edge frame-right-edge _) (frame-edges)) + (frame-left-right-center (/ (+ frame-left-edge frame-right-edge) 2))) + (set-frame-size frame width height t) + (if (eq lsp-ui-doc-position 'at-point) + (lsp-ui-doc--mv-at-point frame height left top) + (set-frame-position frame + (if (and (eq lsp-ui-doc-alignment 'frame-left-or-right-other) + (> window-left-right-center frame-left-right-center)) + 10 + (max (- frame-right width 10 (frame-char-width)) 10)) + (pcase lsp-ui-doc-position + ('top (pcase lsp-ui-doc-alignment + ('window (+ top 10)) + (_ 10))) + ('bottom (pcase lsp-ui-doc-alignment + ('window (- (+ (lsp-ui-doc--line-height 'mode-line) (- window-top-edge frame-top-edge)) + height + 10)) + (_ (- (frame-pixel-height) + height + 10))))))))) + ) + +(use-package company-lsp + :after company + :commands company-lsp) + +(use-package projectile + :demand t + :config + (projectile-mode 1)) + +;; TODO +;; (set-lookup-handlers! 'lsp-ui-mode :async t +;; :definition 'lsp-ui-peek-find-definitions +;; :references 'lsp-ui-peek-find-references) + ;; (use-package lsp-vue ;; :demand t) + (provide 'init-lsp) diff --git a/modes/init-mode-line.el b/modes/init-mode-line.el index 90048f8..1b1eddf 100644 --- a/modes/init-mode-line.el +++ b/modes/init-mode-line.el @@ -11,7 +11,7 @@ (defvar jester/flycheck-mode-line '(:eval - (when (featurep 'flycheck) + (when (and (featurep 'flycheck) flycheck-mode) (pcase flycheck-last-status-change (`not-checked nil) (`no-checker "❄") @@ -82,7 +82,7 @@ ;; the current major mode for the buffer. '(:eval mode-name) - "%1" + " %1" jester/flycheck-mode-line '(:eval (when (and (featurep 'which-func) (not (member major-mode jester/which-function-mode-line-off-modes))) " ")) diff --git a/modes/init-org.el b/modes/init-org.el index b408032..628ed0e 100644 --- a/modes/init-org.el +++ b/modes/init-org.el @@ -285,6 +285,11 @@ typical word processor." (use-package org :config + (setq geiser-default-implementation 'racket) + (org-babel-do-load-languages + 'org-babel-load-languages + '((emacs-lisp . t) + (scheme . t))) (general-define-key :states '(normal) :keymaps 'org-mode-map @@ -292,7 +297,11 @@ typical word processor." "H" 'org-shiftleft "L" 'org-shiftright) (jester/with-major-leader 'org-mode-map - "t t" 'org-todo)) + "t t" 'org-todo) + (general-define-key + :states '(insert emacs) + :keymaps 'org-mode-map + "" 'org-cycle)) (use-package org-bullets :if *is-a-mac* diff --git a/modes/init-paredit.el b/modes/init-paredit.el index 82ed7ea..d409ee5 100644 --- a/modes/init-paredit.el +++ b/modes/init-paredit.el @@ -9,12 +9,12 @@ awesome-pair-close-round awesome-pair-close-bracket awesome-pair-close-curly) :bind (("M-u" . awesome-pair-wrap-round)) :init - (general-define-key :states '(insert emacs) "(" 'awesome-pair-open-round) - (general-define-key :states '(insert emacs) "[" 'awesome-pair-open-bracket) - (general-define-key :states '(insert emacs) "{" 'awesome-pair-open-curly) - (general-define-key :states '(insert emacs) ")" 'awesome-pair-close-round) - (general-define-key :states '(insert emacs) "]" 'awesome-pair-close-bracket) - (general-define-key :states '(insert emacs) "}" 'awesome-pair-close-curly) + ;; (general-define-key :states '(insert emacs) "(" 'awesome-pair-open-round) + ;; (general-define-key :states '(insert emacs) "[" 'awesome-pair-open-bracket) + ;; (general-define-key :states '(insert emacs) "{" 'awesome-pair-open-curly) + ;; (general-define-key :states '(insert emacs) ")" 'awesome-pair-close-round) + ;; (general-define-key :states '(insert emacs) "]" 'awesome-pair-close-bracket) + ;; (general-define-key :states '(insert emacs) "}" 'awesome-pair-close-curly) (defun jester/semantic-kill-maybe-whole-line () "Kill semantic unit after point, if only whitespace is left afterwards, delete this line." diff --git a/modes/init-rust.el b/modes/init-rust.el index 14a7187..4f133c1 100644 --- a/modes/init-rust.el +++ b/modes/init-rust.el @@ -1,4 +1,40 @@ (use-package rust-mode + ;; :custom (rust-indent-offset 2) + :init + (add-hook! 'rust-mode-hook + (setq compile-command "cargo build") + (setq jester-run-command "cargo run")) :mode "\\.rs\\'") +(use-package flycheck-rust + :init + (add-hook! 'flycheck-mode-hook #'flycheck-rust-setup)) + + +(jester/def-make-assignment-function + jester/make-rust-assignment + ";" + ;; [empty] <=> let <=> let mut + (cond + ((looking-at "let mut ") (replace-match "")) + ((looking-at "let ") (replace-match "let mut ")) + (t (insert "let ")))) + +(defun jester/rust-insert-fat-or-slim-arrow () + "Insert a fat or slim arrow, depending on whether in a match body." + (interactive) + (save-match-data + (insert (if (save-excursion + (search-backward "{") + (beginning-of-line-text) + (looking-at "match")) + " => " + " -> ")))) + +(general-define-key + :states '(insert emacs) + :keymaps 'rust-mode-map + "C-j" 'jester/make-rust-assignment + "C-l" 'jester/rust-insert-fat-or-slim-arrow) + (provide 'init-rust) diff --git a/modes/init-scheme.el b/modes/init-scheme.el index 34b1170..8b2c01c 100644 --- a/modes/init-scheme.el +++ b/modes/init-scheme.el @@ -1,4 +1,15 @@ -(setq scheme-program-name "csi -:c") -(spacemacs/set-leader-keys "oe" (lambda () (interactive) (shell-command (concat "csi " buffer-file-name)))) +;; (setq scheme-program-name "csi -:c") ; for `run-scheme' +(setq scheme-program-name "racket -i") ; for `run-scheme' + +(add-hook! 'racket-mode-hook + (setq compile-command (concat "racket -f " (shell-quote-argument (buffer-file-name)))) + (setq jester-run-command (concat "racket -f " (shell-quote-argument (buffer-file-name))))) + +(use-package racket-mode + :mode "\\.\\(rkt[dl]?\\)\\|\\(scm\\)\\'" + :config + (jester/with-major-leader 'racket-mode-map + "i" 'run-scheme)) + (provide 'init-scheme) diff --git a/modes/init-shell.el b/modes/init-shell.el index 9661336..3b16c33 100644 --- a/modes/init-shell.el +++ b/modes/init-shell.el @@ -1,3 +1,6 @@ +(setq shell-file-name "/bin/bash" + explicit-shell-file-name "/bin/zsh") + (general-define-key :states '(insert emacs) :keymaps 'comint-mode-map diff --git a/modes/init-utils.el b/modes/init-utils.el index ff95526..a4ae4aa 100644 --- a/modes/init-utils.el +++ b/modes/init-utils.el @@ -75,8 +75,7 @@ ;;---------------------------------------------------------------------------- ;; https://stackoverflow.com/a/21656063/4788022 (defun jester/merge-imenu (INDEX-FUN) - "Merge major-mode-provided imenu, which is generated by `INDEX-FUN', -with traditional regex based imenu." + "Merge major-mode-provided imenu, which is generated by `INDEX-FUN', with traditional regex based imenu." (interactive) (let ((mode-imenu (funcall INDEX-FUN)) (custom-imenu (imenu--generic-function imenu-generic-expression))) diff --git a/modes/init-windows.el b/modes/init-windows.el index 06c646d..9ce8562 100644 --- a/modes/init-windows.el +++ b/modes/init-windows.el @@ -73,6 +73,7 @@ (defvar jester-shackle-same-window-rule-cars '("*Help*" "*Warnings*" + "*shell*" "*Youdao Dictionary*" "JsDocTagDescription" "*skewer-error*" @@ -92,7 +93,8 @@ shackle-rules (append (mapcar (lambda (condition) (append (doom-enlist condition) jester-shackle-same-window-rule)) jester-shackle-same-window-rule-cars) - '((flycheck-error-list-mode :other t :select t :inhibit-window-quit t)))) + '((flycheck-error-list-mode :other t :select t :inhibit-window-quit t) + ("*compilation*" :ignore t)))) (shackle-mode 1)) ;; https://emacs-china.org/t/display-buffer-alist/8162/4?u=jjpandari diff --git a/snippets/prog-mode/if-block b/snippets/js2-mode/if-block similarity index 100% rename from snippets/prog-mode/if-block rename to snippets/js2-mode/if-block diff --git a/snippets/php-mode/if-block b/snippets/php-mode/if-block new file mode 100644 index 0000000..9f97eee --- /dev/null +++ b/snippets/php-mode/if-block @@ -0,0 +1,6 @@ +# key: if +# name: if block +# -- +if ($1) { + $0 +} \ No newline at end of file diff --git a/snippets/racket-mode/define b/snippets/racket-mode/define new file mode 100644 index 0000000..a9c5807 --- /dev/null +++ b/snippets/racket-mode/define @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: (define ... ...) +# key: def +# -- +(define ${1:()} $0) \ No newline at end of file diff --git a/snippets/racket-mode/define-syntax-rule b/snippets/racket-mode/define-syntax-rule new file mode 100644 index 0000000..3c42290 --- /dev/null +++ b/snippets/racket-mode/define-syntax-rule @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# name: define-syntax-rule +# key: defm +# -- +(define-syntax-rule (${1:name} $2) + $0) \ No newline at end of file diff --git a/snippets/racket-mode/lambda b/snippets/racket-mode/lambda new file mode 100644 index 0000000..7c95962 --- /dev/null +++ b/snippets/racket-mode/lambda @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: (lambda (...) ...) +# key: lam +# -- +(lambda ($1) $0) \ No newline at end of file diff --git a/snippets/rust-mode/for-in b/snippets/rust-mode/for-in new file mode 100644 index 0000000..ab28c8b --- /dev/null +++ b/snippets/rust-mode/for-in @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# name: for in +# key: forin +# -- +for $2 in $1 { + $0 +} \ No newline at end of file diff --git a/snippets/rust-mode/function b/snippets/rust-mode/function new file mode 100644 index 0000000..11c81fb --- /dev/null +++ b/snippets/rust-mode/function @@ -0,0 +1,6 @@ +# key: fn +# name: function +# -- +fn $1($2)${3: -> $4} { + $0 +} \ No newline at end of file diff --git a/snippets/rust-mode/if-block b/snippets/rust-mode/if-block new file mode 100644 index 0000000..d4db910 --- /dev/null +++ b/snippets/rust-mode/if-block @@ -0,0 +1,6 @@ +# key: if +# name: if block +# -- +if $1 { + $0 +} \ No newline at end of file diff --git a/snippets/rust-mode/impl b/snippets/rust-mode/impl new file mode 100644 index 0000000..f820dde --- /dev/null +++ b/snippets/rust-mode/impl @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# name: impl +# key: imp +# -- +impl $1 { + $0 +} \ No newline at end of file diff --git a/snippets/scheme-mode/define b/snippets/scheme-mode/define new file mode 100644 index 0000000..9494d1a --- /dev/null +++ b/snippets/scheme-mode/define @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: (define ... ...) +# key: def +# -- +(define ${1:(${2:name} ${3:args})} $0) \ No newline at end of file diff --git a/snippets/scheme-mode/df b/snippets/scheme-mode/df deleted file mode 100755 index 6bb5419..0000000 --- a/snippets/scheme-mode/df +++ /dev/null @@ -1,8 +0,0 @@ -# -*- mode: snippet -*- -# contributor: -# name: df -# key: df -# -- -(define ($1) - $2 - ) diff --git a/snippets/scheme-mode/lambda b/snippets/scheme-mode/lambda new file mode 100644 index 0000000..7c95962 --- /dev/null +++ b/snippets/scheme-mode/lambda @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: (lambda (...) ...) +# key: lam +# -- +(lambda ($1) $0) \ No newline at end of file diff --git a/snippets/web-mode/if-block b/snippets/web-mode/if-block new file mode 100644 index 0000000..9f97eee --- /dev/null +++ b/snippets/web-mode/if-block @@ -0,0 +1,6 @@ +# key: if +# name: if block +# -- +if ($1) { + $0 +} \ No newline at end of file