Skip to content

Commit

Permalink
add grep support
Browse files Browse the repository at this point in the history
  • Loading branch information
codesensei-courses committed Jan 20, 2025
1 parent 8f22570 commit 479c5c6
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 10 deletions.
12 changes: 9 additions & 3 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ The package adds a bunch of useful features, including:
- Generating passwords with arguments (e.g. length, no-symbols)
- Showing password QR code inside emacs in text or image format
- Generating QR Codes for fields as well as secrets

- Grep with support for emacs grep mode

** Features to be added
I have some plans to support the following in the future:
- searching password files using emacs *grep*
- pass-otp
- otp
- multiple password folders
- adding files to the password store


** QR Code support
Expand Down Expand Up @@ -98,3 +99,8 @@ The following menu items are available:
| Vp | Pull | Pull from VC |
| VP | Push | Push to VC |

** Discover
| Key | Name | Description |
| d | Dired | Open password store folder with dired |
| G | Grep | Search password entries for text patterns |

110 changes: 103 additions & 7 deletions password-store-menu.el
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ This is used by the `password-store-menu-enable' command."
(password-store-menu--qr-transient)
(message "Please install qrencode to create QR Codes.")))

;;;###autoload (autoload 'password-store-menu-grp "password-store-menu")
(defun password-store-menu-grep ()
"Search for text in password files."
(interactive)
(password-store-menu--grep-transient))


;;; Inserting new entries
;;;###autoload (autoload 'password-store-menu-insert "password-store-menu")
Expand Down Expand Up @@ -202,9 +208,8 @@ Ask for confirmation unless FORCE is t."

(defun password-store-menu--completing-read-new-entry ()
"Prompt for name of new pass entry, ask confirmation if it exists."
(let*
((entry (password-store--completing-read))
(exists (file-exists-p (password-store--entry-to-file entry))))
(let* ((entry (password-store--completing-read))
(exists (file-exists-p (password-store--entry-to-file entry))))
(when (or (not exists)
(yes-or-no-p (format "Overwrite entry %s?" entry)))
entry)))
Expand Down Expand Up @@ -296,8 +301,7 @@ from ENTRY and return it."

(declare-function qrencode-string "qrencode")

(transient-define-suffix password-store-menu--qr-dispatch
(entry &rest args)
(transient-define-suffix password-store-menu--qr-dispatch (entry &rest args)
"Show QR code for ENTRY."
(interactive (list (password-store--completing-read)
(transient-args transient-current-command)))
Expand All @@ -312,7 +316,7 @@ from ENTRY and return it."
(qrencode-string secret))))


;;;###autoload (autoload 'transient-define-prefix "password-store-menu-qr-transient")
;;;###autoload (autoload 'transient-define-prefix "password-store-menu--qr-transient")
(transient-define-prefix password-store-menu--qr-transient ()
"Generate qr codes for passwords using transient."
:value '("secret" "text")
Expand All @@ -326,6 +330,97 @@ from ENTRY and return it."
[("q" "Create QR Code" password-store-menu--qr-dispatch)])


(defun password-store-menu--grep-entry (entry pattern grep-args output-buf)
"Run grep on a single ENTRY, searching for PATTERN given GREP-ARGS.
Output will be sent to OUTPUT-BUF."
(with-temp-buffer
(let* ((cmd (format "%s show %s | grep -n --null %s %s"
password-store-executable
(shell-quote-argument entry)
(mapconcat 'identity grep-args " ")
(shell-quote-argument pattern)))
(retval (call-process-shell-command cmd nil t)))
(message "Grepping %s" entry)
(when (eq 0 retval)
(goto-char (point-min))
(while (not (eobp))
(insert (format "./%s.gpg:" entry))
(when (member "--count" grep-args)
;; Fix output to match grep-mode expected format
(insert "1:"))
(forward-line))
(with-current-buffer output-buf
(setq buffer-read-only nil)
(goto-char (point-max)))
(insert-into-buffer output-buf)
(with-current-buffer output-buf (setq buffer-read-only t))))))


;;;###autoload
(defvar password-store-menu-grep-history nil "History list for password-store-menu grep.")

(transient-define-suffix password-store-menu--grep (pattern args)
"Run grep for all password entries searching for PATTERN with ARGS."
(interactive (list
(read-string "Search pattern: " nil password-store-menu-grep-history)
(transient-args transient-current-command)))
(let ((buf (get-buffer-create "*password-store-grep*"))
(dir (car args))
(grep-args (cdr args)))
(with-current-buffer buf
(setq-local default-directory (password-store-dir)
buffer-read-only nil)
(fundamental-mode)
(erase-buffer)
(insert (format "-*- mode: grep; default-directory: \"%s\" -*-\n" default-directory))
(insert (concat "grep: " (mapconcat 'identity grep-args " ") "\n\n"))
(grep-mode))
(pop-to-buffer buf)
(dolist (entry (password-store-list dir))
(password-store-menu--grep-entry entry pattern grep-args buf))
(pop-to-buffer buf)))


(defun password-store-menu--grep-dir-reader (prompt &rest _)
"Reader for folder to grep in."
(read-directory-name prompt
(expand-file-name "./" (password-store-dir))
nil
t))


(transient-define-infix password-store-menu--grep-dir ()
:description "Subdir"
:class 'transient-option
:key "d"
:argument ""
:prompt "Search folder: "
:reader #'password-store-menu--grep-dir-reader
:always-read t)


;;;###autoload (autoload 'transient-define-prefix "password-store-menu--grep-transient")
(transient-define-prefix password-store-menu--grep-transient ()
"Search for text in password files."
:incompatible '(("--count" "--files-with-matches" "--files-without-matches")
("--extended-regexp" "--fixed-strings" "--basic-regexp")
("--word-regexp" "--line-regexp"))
:value `(,(password-store-dir) "--basic-regexp" "--count")
["Search in"
(password-store-menu--grep-dir)]
["Grep options"
["Pattern"
("E" "Regex" "--extended-regexp")
("F" "Fixed string" "--fixed-strings")
("G" "Basic pattern" "--basic-regexp")]
["Match"
("i" "Ignore case" "--ignore-case")
("v" "Invert" "--invert-match")]
["Output"
("c" "Count only" "--count")]
[("g" "Run grep" password-store-menu--grep)]])


;;;###autoload (autoload 'transient-define-prefix "password-store-menu")
(transient-define-prefix password-store-menu ()
"Entry point for password store actions."
Expand All @@ -352,7 +447,8 @@ from ENTRY and return it."
("Vp" "Pull" password-store-menu-pull)
("VP" "Push" password-store-menu-push)]
["Explore"
("d" "Dired" password-store-menu-dired)]]
("d" "Dired" password-store-menu-dired)
("G" "Grep" password-store-menu--grep-transient)]]
[("!" "Clear secret from kill ring" password-store-clear)])

;;;###autoload (autoload 'password-store-menu-enable "password-store-menu")
Expand Down

0 comments on commit 479c5c6

Please sign in to comment.