Coder Social home page Coder Social logo

eshell-atuin's Introduction

Pavel Korytov

GitHub stats

WakaTime stats

eshell-atuin's People

Contributors

jeffkreeftmeijer avatar purcell avatar sqrtminusone avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

eshell-atuin's Issues

Initialization fails if process-environment is buffer-local (from envrc)

If eshell-atuin-mode is run from a directory with a buffer-local process-environment, then ATUIN_SESSION does not get set globally and eshell-atuin never tries to reinitialize it. This can happen when using a package such as envrc, for example.

Currently I work around the problem by initializing eshell-atuin in a temporary buffer:

(with-temp-buffer
  (eshell-atuin-mode))

But another solution might be to store ATUIN_SESSION in a lisp variable and wrap each call to atuin in with-environment-variables.

"atuin history end" throws an error

With eshell-atuin-mode turned on, running any command causes the following error:

Debugger entered--Lisp error: (error "‘atuin history end’ returned 2: error: unexpected argument '--duration' found\n\n  tip: to pass '--duration' as a value, use '-- --duration'\n\nUsage: atuin history end <ID|--exit <EXIT>>\n\nFor more information, try '--help'.\n")
  (error "`atuin history end' returned %s: %s" 2 "error: unexpected argument '--duration' found\n\n  tip: to pass '--duration' as a value, use '-- --duration'\n\nUsage: atuin history end <ID|--exit <EXIT>>\n\nFor more information, try '--help'.\n")
  (if (= (process-exit-status process) 0) nil (error "`atuin history end' returned %s: %s" (process-exit-status process) (save-current-buffer (set-buffer buf) (buffer-string))))
  (unwind-protect (if (= (process-exit-status process) 0) nil (error "`atuin history end' returned %s: %s" (process-exit-status process) (save-current-buffer (set-buffer buf) (buffer-string)))) (kill-buffer buf))
  (progn (unwind-protect (if (= (process-exit-status process) 0) nil (error "`atuin history end' returned %s: %s" (process-exit-status process) (save-current-buffer (set-buffer buf) (buffer-string)))) (kill-buffer buf)))
  (if (eq (process-status process) 'exit) (progn (unwind-protect (if (= (process-exit-status process) 0) nil (error "`atuin history end' returned %s: %s" (process-exit-status process) (save-current-buffer (set-buffer buf) (buffer-string)))) (kill-buffer buf))))
  ((closure ((buf . #<buffer *atuin-output*>)) (process _msg) (if (eq (process-status process) 'exit) (progn (unwind-protect (if (= (process-exit-status process) 0) nil (error "`atuin history end' returned %s: %s" (process-exit-status process) (save-current-buffer ... ...))) (kill-buffer buf))))) #<process atuin-history-stop> "exited abnormally with code 2\n")

The error is from eshell-atuin--post-exec, and is caused by atuin history end not understanding the --duration argument.

Here is the output of atuin history end --help:

~ ❯ atuin history end --help
Finishes a new command in the history (adds time, exit code)

Usage: atuin history end --exit <EXIT> <ID>

Arguments:
  <ID>

Options:
  -e, --exit <EXIT>
  -h, --help         Print help

There appears to be no --duration option.

I don't see --duration mentioned in the atuin docs either, so I'm not sure what's going on.

My atuin version:

~ ❯ atuin --version
atuin 17.0.1

Invalid format character %i

I tried to include directories in the history format:

(setopt eshell-atuin-search-fields '(time duration command directory)
        eshell-atuin-history-format "%-80c %t + %i")

but ran into the following error:

Debugger entered--Lisp error: (error "Invalid format character: ‘%i")
  (error "Invalid format character: `%%%c'" 105)
  (format-spec "%-80c %t + %i" ((116 . "2024-02-26 07:43:55") (101) (100 . "90ms") (99 . "for archive in *.zip; do") (105) (104) (114)))
  (let* ((p (if (and nil (not (eq nil 'eq))) (assoc 'formatted-value e nil) (assq 'formatted-value e))) (v (format-spec eshell-atuin-history-format (list (cons 116 (alist-get 'time e)) (cons 101 (alist-get 'exit e)) (cons 100 (alist-get 'duration e)) (cons 99 (alist-get 'command e)) (cons 105 (alist-get 'directory e)) (cons 104 (alist-get 'host e)) (cons 114 (alist-get 'relativetime e)))))) (progn (if p (setcdr p v) (setq e (cons (setq p (cons 'formatted-value v)) e))) v))
  (progn (let* ((p (if (and nil (not (eq nil ...))) (assoc 'formatted-value e nil) (assq 'formatted-value e))) (v (format-spec eshell-atuin-history-format (list (cons 116 (alist-get ... e)) (cons 101 (alist-get ... e)) (cons 100 (alist-get ... e)) (cons 99 (alist-get ... e)) (cons 105 (alist-get ... e)) (cons 104 (alist-get ... e)) (cons 114 (alist-get ... e)))))) (progn (if p (setcdr p v) (setq e (cons (setq p (cons ... v)) e))) v)))
  (if (alist-get 'command e) (progn (let* ((p (if (and nil (not ...)) (assoc 'formatted-value e nil) (assq 'formatted-value e))) (v (format-spec eshell-atuin-history-format (list (cons 116 ...) (cons 101 ...) (cons 100 ...) (cons 99 ...) (cons 105 ...) (cons 104 ...) (cons 114 ...))))) (progn (if p (setcdr p v) (setq e (cons (setq p ...) e))) v))))
  (let ((e (let* ((--cl-var-- eshell-atuin-search-fields) (field nil) (--cl-var-- (string-split line "\11")) (value nil) (--cl-var-- nil)) (while (and (consp --cl-var--) (progn (setq field ...) (consp --cl-var--))) (setq value (car --cl-var--)) (setq --cl-var-- (cons (cons field value) --cl-var--)) (setq --cl-var-- (cdr --cl-var--)) (setq --cl-var-- (cdr --cl-var--))) (nreverse --cl-var--)))) (if (alist-get 'command e) (progn (let* ((p (if (and nil ...) (assoc ... e nil) (assq ... e))) (v (format-spec eshell-atuin-history-format (list ... ... ... ... ... ... ...)))) (progn (if p (setcdr p v) (setq e (cons ... e))) v)))) e)
  (eshell-atuin--parse-history-line "2024-02-26 07:43:55\1190ms\11for archive in *.zip; do")
  (eshell-atuin--history-update)
  (eshell-atuin-history)
  (funcall-interactively eshell-atuin-history)
  (command-execute eshell-atuin-history)

I narrowed it down to the following:

(let ((e '((time . "2024-02-26 07:43:55")
           (duration . "90ms")
           (command . "for archive in *.zip; do"))))
  (format-spec eshell-atuin-history-format ; "%-80c %t + %i"
               `((?t . ,(alist-get 'time e))
                 (?e . ,(alist-get 'exit e))
                 (?d . ,(alist-get 'duration e))
                 (?c . ,(alist-get 'command e))
                 (?i . ,(alist-get 'directory e))
                 (?h . ,(alist-get 'host e))
                 (?r . ,(alist-get 'relativetime e)))))
;; => Fails with the above error

The alist e here is what's constructed on atuin's output for the failing string. The problem is that atuin does not return a directory for the first line of the above multiline bash for loop. The format-spec fails since ?i is mapped to nil via (alist-get 'directory e).

I was able to solve it by specifying a delete option when using format-spec, which removes missing specifiers. This version is fine:

(let ((e '((time . "2024-02-26 07:43:55")
           (duration . "90ms")
           (command . "for archive in *.zip; do"))))
  (format-spec eshell-atuin-history-format ; "%-80c %t + %i"
               `((?t . ,(alist-get 'time e))
                 (?e . ,(alist-get 'exit e))
                 (?d . ,(alist-get 'duration e))
                 (?c . ,(alist-get 'command e))
                 (?i . ,(alist-get 'directory e))
                 (?h . ,(alist-get 'host e))
                 (?r . ,(alist-get 'relativetime e)))
               'delete))

Another way to fix it would be to make alist-get return a non-nil default, as in (alist-get 'directory e ""). This is probably the better solution when you have a history format with missing entries in the middle, like %-80c %-40i %t, since format-spec will remove the whole specifier (%-40i in this case) and misalign the result.

Thank you

@SqrtMinusOne Thanks for writing eshell-atuin. Incidentally, I was trying to write the exact same functionality this week, but using a dynamic completion table (and thus no cache). It wasn't going well, now I don't need to bother!

While we're here, thanks for your emacs-i3-integration code as well! I've been using it for quite some time now.

I did have an issue to report, but I'll do it separately -- feel free to close this one.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.