mirror of
https://github.com/pestctrl/emacs-config.git
synced 2026-06-14 04:11:18 +00:00
Compare commits
3 commits
cca5ed04c8
...
42e67e873a
| Author | SHA1 | Date | |
|---|---|---|---|
| 42e67e873a | |||
| 7de2adae19 | |||
| c5eee2990d |
4 changed files with 209 additions and 10 deletions
|
|
@ -66,6 +66,15 @@
|
||||||
(dedicated . t)))
|
(dedicated . t)))
|
||||||
(window-width . 100)))
|
(window-width . 100)))
|
||||||
|
|
||||||
|
(add-to-list 'display-buffer-alist
|
||||||
|
`((major-mode . grep-mode)
|
||||||
|
display-buffer-in-side-window
|
||||||
|
(side . right)
|
||||||
|
(slot . 3)
|
||||||
|
(window-parameters . ((no-delete-other-windows . t)
|
||||||
|
(dedicated . t)))
|
||||||
|
(window-width . 100)))
|
||||||
|
|
||||||
(add-to-list 'display-buffer-alist
|
(add-to-list 'display-buffer-alist
|
||||||
`(my/is-compilation-buffer
|
`(my/is-compilation-buffer
|
||||||
display-buffer-in-side-window
|
display-buffer-in-side-window
|
||||||
|
|
|
||||||
|
|
@ -40,24 +40,22 @@
|
||||||
|
|
||||||
(setq mu4e-maildir-shortcuts
|
(setq mu4e-maildir-shortcuts
|
||||||
'(("/fastmail/INBOX" . ?i)
|
'(("/fastmail/INBOX" . ?i)
|
||||||
("/fastmail/INBOX/tracking" . ?t)
|
("/fastmail/important.Development" . ?d)
|
||||||
("/fastmail/INBOX/unsorted" . ?u)
|
("/fastmail/important.Puppet" . ?p)
|
||||||
|
("/fastmail/important.VIPs" . ?v)
|
||||||
("/fastmail/Archive" . ?a)))
|
("/fastmail/Archive" . ?a)))
|
||||||
|
|
||||||
(setq mu4e-bookmarks
|
(setq mu4e-bookmarks
|
||||||
'(( :name "Unread messages"
|
'(( :name "Inbox"
|
||||||
:query "flag:unread AND NOT flag:trashed"
|
:query "maildir:/fastmail/INBOX AND NOT flag:trashed"
|
||||||
:key ?u)
|
:key ?i)
|
||||||
( :name "Today's messages"
|
( :name "Today's messages"
|
||||||
:query "date:today..now"
|
:query "date:today..now"
|
||||||
:key ?t)
|
:key ?t)
|
||||||
( :name "Last 7 days"
|
( :name "Last 7 days"
|
||||||
:query "date:7d..now"
|
:query "date:7d..now"
|
||||||
:hide-unread t
|
:hide-unread t
|
||||||
:key ?w)
|
:key ?w)))
|
||||||
( :name "Messages with images"
|
|
||||||
:query "mime:image/*"
|
|
||||||
:key ?p)))
|
|
||||||
|
|
||||||
(setq mu4e-bookmarks
|
(setq mu4e-bookmarks
|
||||||
(mapcar (lambda (x)
|
(mapcar (lambda (x)
|
||||||
|
|
@ -74,7 +72,9 @@
|
||||||
"bensonchu457@gmail.com"
|
"bensonchu457@gmail.com"
|
||||||
"me@mail.pestctrl.io"
|
"me@mail.pestctrl.io"
|
||||||
"dev@mail.pestctrl.io"
|
"dev@mail.pestctrl.io"
|
||||||
"accounts@mail.pestctrl.io"))
|
"accounts@mail.pestctrl.io"
|
||||||
|
"chuan.chu01@fastmail.com"
|
||||||
|
"julie.chu01@fastmail.com"))
|
||||||
|
|
||||||
(defun my/mu-init ()
|
(defun my/mu-init ()
|
||||||
(interactive)
|
(interactive)
|
||||||
|
|
|
||||||
188
lisp/ripgrep.el
Normal file
188
lisp/ripgrep.el
Normal file
|
|
@ -0,0 +1,188 @@
|
||||||
|
;;; ripgrep.el --- -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; https://www.dyerdwelling.family/emacs/20260109094340-emacs--a-single-function-ripgrep-alternative-to-rgrep/
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(defconst ripgrep-error-regexp
|
||||||
|
`((,(concat "^\\(?:"
|
||||||
|
;; Parse using NUL characters when `--null' is used.
|
||||||
|
;; Note that we must still assume no newlines in
|
||||||
|
;; filenames due to "foo: Is a directory." type
|
||||||
|
;; messages.
|
||||||
|
"\\(?1:[^\0\n]+\\)\\(?3:\0\\)\\(?2:[0-9]+\\):"
|
||||||
|
"\\|"
|
||||||
|
;; Fallback if `--null' is not used, use a tight regexp
|
||||||
|
;; to handle weird file names (with colons in them) as
|
||||||
|
;; well as possible. E.g., use [1-9][0-9]* rather than
|
||||||
|
;; [0-9]+ so as to accept ":034:" in file names.
|
||||||
|
"\\(?1:"
|
||||||
|
"\\(?:[a-zA-Z]:\\)?" ; Allow "C:..." for w32.
|
||||||
|
"[^\n:]+?[^\n/:]\\):[\t ]*\\(?2:[1-9][0-9]*\\)[\t ]*:\\(?:[1-9][0-9]*\\)[\t ]*:"
|
||||||
|
"\\)")
|
||||||
|
1 2
|
||||||
|
;; Calculate column positions (col . end-col) of first grep match on a line
|
||||||
|
(,(lambda ()
|
||||||
|
(when grep-highlight-matches
|
||||||
|
(let* ((beg (match-end 0))
|
||||||
|
(end (save-excursion (goto-char beg) (line-end-position)))
|
||||||
|
(mbeg
|
||||||
|
(text-property-any beg end 'font-lock-face grep-match-face)))
|
||||||
|
(when mbeg
|
||||||
|
(- mbeg beg)))))
|
||||||
|
.
|
||||||
|
,(lambda ()
|
||||||
|
(when grep-highlight-matches
|
||||||
|
(let* ((beg (match-end 0))
|
||||||
|
(end (save-excursion (goto-char beg) (line-end-position)))
|
||||||
|
(mbeg
|
||||||
|
(text-property-any beg end 'font-lock-face grep-match-face))
|
||||||
|
(mend
|
||||||
|
(and mbeg (next-single-property-change
|
||||||
|
mbeg 'font-lock-face nil end))))
|
||||||
|
(when mend
|
||||||
|
(- mend beg 1))))))
|
||||||
|
nil nil
|
||||||
|
(3 '(face nil display ":")))
|
||||||
|
("^Binary file \\(.+\\) matches" 1 nil nil 0 1)))
|
||||||
|
|
||||||
|
(defun ripgrep (search-term &optional directory glob)
|
||||||
|
"Run ripgrep (rg) with SEARCH-TERM and optionally DIRECTORY and GLOB.
|
||||||
|
If ripgrep is unavailable, fall back to Emacs's rgrep command. Highlights SEARCH-TERM in results.
|
||||||
|
By default, only the SEARCH-TERM needs to be provided. If called with a
|
||||||
|
universal argument, DIRECTORY and GLOB are prompted for as well."
|
||||||
|
(interactive
|
||||||
|
(let* ((univ-arg current-prefix-arg)
|
||||||
|
(default-search-term
|
||||||
|
(cond
|
||||||
|
((use-region-p)
|
||||||
|
(buffer-substring-no-properties (region-beginning) (region-end)))
|
||||||
|
((thing-at-point 'symbol t))
|
||||||
|
((thing-at-point 'word t))
|
||||||
|
(t ""))))
|
||||||
|
(list
|
||||||
|
(read-string (if (string-empty-p default-search-term)
|
||||||
|
"Search for: "
|
||||||
|
(format "Search for (default `%s`): " default-search-term))
|
||||||
|
nil nil default-search-term)
|
||||||
|
(when univ-arg (read-directory-name "Directory: "))
|
||||||
|
(when univ-arg (read-string "File pattern (glob, default: ): " nil nil "")))))
|
||||||
|
(let* ((directory (expand-file-name (or directory default-directory)))
|
||||||
|
(glob (or glob ""))
|
||||||
|
(buffer-name "*grep*"))
|
||||||
|
(if (executable-find "rg")
|
||||||
|
(let ((buffer (get-buffer-create buffer-name)))
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(setq default-directory directory)
|
||||||
|
(let ((inhibit-read-only t))
|
||||||
|
(erase-buffer)
|
||||||
|
(insert (format "-*- mode: grep; default-directory: \"%s\" -*-\n\n" directory))
|
||||||
|
(if (not (string= "" glob))
|
||||||
|
(insert (format "[o] Glob: %s\n\n" glob)))
|
||||||
|
(insert "Searching...\n\n"))
|
||||||
|
(grep-mode)
|
||||||
|
(setq-local compilation-error-regexp-alist ripgrep-error-regexp)
|
||||||
|
(setq-local my/grep-search-term search-term)
|
||||||
|
(setq-local my/grep-directory directory)
|
||||||
|
(setq-local my/grep-glob glob))
|
||||||
|
|
||||||
|
(pop-to-buffer buffer)
|
||||||
|
(goto-char (point-min))
|
||||||
|
|
||||||
|
(make-process
|
||||||
|
:name "ripgrep"
|
||||||
|
:buffer buffer
|
||||||
|
:command `("rg" "--color=never" "--max-columns=500"
|
||||||
|
"--column" "--line-number" "--no-heading"
|
||||||
|
"--smart-case" "-e" ,search-term
|
||||||
|
"--glob" ,glob ,directory)
|
||||||
|
:filter `(lambda (proc string)
|
||||||
|
(when (buffer-live-p (process-buffer proc))
|
||||||
|
(with-current-buffer (process-buffer proc)
|
||||||
|
(let ((inhibit-read-only t)
|
||||||
|
(moving (= (point) (process-mark proc))))
|
||||||
|
(setq string (replace-regexp-in-string "[\r\0\x01-\x08\x0B-\x0C\x0E-\x1F]" "" string))
|
||||||
|
;; Replace full directory path with ./ in the incoming output
|
||||||
|
(setq string (replace-regexp-in-string
|
||||||
|
(concat "^" (regexp-quote ,directory))
|
||||||
|
"./"
|
||||||
|
string))
|
||||||
|
(save-excursion
|
||||||
|
(goto-char (process-mark proc))
|
||||||
|
(insert string)
|
||||||
|
(set-marker (process-mark proc) (point)))
|
||||||
|
(if moving (goto-char (process-mark proc)))))))
|
||||||
|
:sentinel
|
||||||
|
`(lambda (proc _event)
|
||||||
|
(when (memq (process-status proc) '(exit signal))
|
||||||
|
(with-current-buffer (process-buffer proc)
|
||||||
|
(let ((inhibit-read-only t))
|
||||||
|
;; Remove "Searching..." line
|
||||||
|
(goto-char (point-min))
|
||||||
|
(while (re-search-forward "Searching\\.\\.\\.\n\n" nil t)
|
||||||
|
(replace-match "" nil t))
|
||||||
|
|
||||||
|
;; Clean up the output - replace full paths with ./
|
||||||
|
(goto-char (point-min))
|
||||||
|
(forward-line 3)
|
||||||
|
(let ((start-pos (point)))
|
||||||
|
(while (re-search-forward (concat "^" (regexp-quote ,directory)) nil t)
|
||||||
|
(replace-match "./" t t))
|
||||||
|
|
||||||
|
;; Check if any results were found
|
||||||
|
(goto-char start-pos)
|
||||||
|
(when (= (point) (point-max))
|
||||||
|
(insert "No results found.\n")))
|
||||||
|
|
||||||
|
(goto-char (point-max))
|
||||||
|
(insert "\nRipgrep finished\n")
|
||||||
|
|
||||||
|
;; Highlight search terms using grep's match face
|
||||||
|
(goto-char (point-min))
|
||||||
|
(forward-line 3)
|
||||||
|
(save-excursion
|
||||||
|
(while (re-search-forward (regexp-quote ,search-term) nil t)
|
||||||
|
(put-text-property (match-beginning 0) (match-end 0)
|
||||||
|
'face 'match)
|
||||||
|
(put-text-property (match-beginning 0) (match-end 0)
|
||||||
|
'font-lock-face 'match))))
|
||||||
|
|
||||||
|
;; Set up keybindings
|
||||||
|
(local-set-key (kbd "D")
|
||||||
|
(lambda ()
|
||||||
|
(interactive)
|
||||||
|
(ripgrep my/grep-search-term
|
||||||
|
(read-directory-name "New search directory: ")
|
||||||
|
my/grep-glob)))
|
||||||
|
(local-set-key (kbd "S")
|
||||||
|
(lambda ()
|
||||||
|
(interactive)
|
||||||
|
(ripgrep (read-string "New search term: "
|
||||||
|
nil nil my/grep-search-term)
|
||||||
|
my/grep-directory
|
||||||
|
my/grep-glob)))
|
||||||
|
(local-set-key (kbd "o")
|
||||||
|
(lambda ()
|
||||||
|
(interactive)
|
||||||
|
(ripgrep my/grep-search-term
|
||||||
|
my/grep-directory
|
||||||
|
(read-string "New glob: "))))
|
||||||
|
(local-set-key (kbd "g")
|
||||||
|
(lambda ()
|
||||||
|
(interactive)
|
||||||
|
(ripgrep my/grep-search-term my/grep-directory my/grep-glob)))
|
||||||
|
|
||||||
|
(goto-char (point-min))
|
||||||
|
(message "ripgrep finished."))))
|
||||||
|
)
|
||||||
|
(message "ripgrep started..."))
|
||||||
|
;; Fallback to rgrep
|
||||||
|
(progn
|
||||||
|
(setq default-directory directory)
|
||||||
|
(message (format "%s : %s : %s" search-term glob directory))
|
||||||
|
(rgrep search-term (if (string= "" glob) "*" glob) directory)))))
|
||||||
|
|
||||||
|
(provide 'ripgrep)
|
||||||
|
;;; ripgrep.el ends here
|
||||||
|
|
@ -45,6 +45,8 @@
|
||||||
'(mode-line ((t :foreground "gray60" :background "black" :inverse-video nil)))
|
'(mode-line ((t :foreground "gray60" :background "black" :inverse-video nil)))
|
||||||
'(eldoc-highlight-function-argument ((t :foreground "dodger blue")))
|
'(eldoc-highlight-function-argument ((t :foreground "dodger blue")))
|
||||||
|
|
||||||
|
'(highlight ((t :background "gray20")))
|
||||||
|
|
||||||
'(sml/charging ((t (:inherit sml/global :foreground "forest green"))))
|
'(sml/charging ((t (:inherit sml/global :foreground "forest green"))))
|
||||||
|
|
||||||
;; TODO: Rework according to prot:
|
;; TODO: Rework according to prot:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue