summaryrefslogtreecommitdiff
path: root/emacs/.config/emacs-v2/lisp/kj-history.el
blob: 5c9c0fe997f4399d6a64146c0256a244e0904ca3 (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
62
63
64
65
66
;; -*- lexical-binding: t; -*-

(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")))))

(use-package emacs :elpaca nil
  :after consult
  :config
  (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)