summaryrefslogtreecommitdiff
path: root/emacs/.config/emacs-kj/lisp/kj-history.el
blob: 2e90e8158b18f1efddeb88de0eb8bc7e808f7950 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
(defvar kj/history-command "fc -R $HISTFILE && fc -l 1"
  "History command used to get shell history.")

(defvar kj/history-regexp
  (rx bol (* " ")
      ;; Index
      (* digit)
      (* " ")
      ;; Command
      (group (1+ (not "\n")))))

(defun kj/get-shell-history ()
  (with-temp-buffer
    (unless (process-file
             "zsh"
             nil
             (current-buffer)
             nil
             "-c"
             kj/history-command)
      (error "Getting history failed: %s" (buffer-string)))
    (goto-char (point-min))
    (let ((result))
      (save-match-data
        (while (re-search-forward kj/history-regexp nil t)
          (let ((command
                 ;; Fix up multi-line commands.
                 (string-replace "\\\\n" "\\\n" (match-string-no-properties 1))))
            (push command result))))
      result)))

(defun kj/consult-history ()
  (interactive)
  (if (not
       (or (and (minibufferp)
                (eq minibuffer-history-variable 'shell-command-history))
           (derived-mode-p '(term-mode shell-mode))
           ))
      (call-interactively 'consult-history)
    (pcase-let* ((bol
                  (cond ((derived-mode-p 'eshell-mode) 'eshell-bol)
                        ((derived-mode-p 'term-mode) 'term-bol)
                        ((derived-mode-p 'comint-mode) 'comint-bol)))
                 (`(,beg . ,end)
                  (cond ((minibufferp)
                           (cons (minibuffer-prompt-end) (point-max)))
                        (bol (save-excursion
                               (funcall bol)
                               (cons (point) (pos-eol))))
                        (t (cons (point) (point)))))
                 (str (consult--read
                       (kj/get-shell-history)
                       :prompt "Shell history: "
                       :history t
                       :sort nil
                       :initial (buffer-substring-no-properties beg end)
                       :state (consult--insertion-preview beg end))))
      (delete-region beg end)
      (insert (substring-no-properties str)))))

(provide 'kj-history)