Git Product home page Git Product logo

spinner.el's Introduction

spinner.el

Add spinners and progress-bars to the mode-line for ongoing operations.

some-spinners.gif

all-spinners.gif

Usage

First of all, don’t forget to add (spinner "VERSION") to your package’s dependencies.

Major-modes

  1. Just call (spinner-start) and a spinner will be added to the mode-line.
  2. Call (spinner-stop) on the same buffer when you want to remove it.

The default spinner is a line drawing that rotates. You can pass an argument to spinner-start to specify which spinner you want. All possibilities are listed in the spinner-types variable, but here are a few examples for you to try:

  • (spinner-start 'vertical-breathing 10)
  • (spinner-start 'minibox)
  • (spinner-start 'moon)
  • (spinner-start 'triangle)

You can also define your own as a vector of strings (see the examples in spinner-types).

Minor-modes

Minor-modes can create a spinner with spinner-create and then add it to their mode-line lighter. They can then start the spinner by setting a variable and calling spinner-start-timer. Finally, they can stop the spinner (and the timer) by just setting the same variable to nil.

Here’s an example for a minor-mode named foo. Assuming that foo--lighter is used as the mode-line lighter, the following code will add an inactive global spinner to the mode-line.

(defvar foo--spinner (spinner-create 'rotating-line))
(defconst foo--lighter
  '(" foo" (:eval (spinner-print foo--spinner))))
  1. To activate the spinner, just call (spinner-start foo--spinner). It will show up on the mode-line and start animating.
  2. To get rid of it, call (spinner-stop foo--spinner). It will then disappear again.

Some minor-modes will need spinners to be buffer-local. To achieve that, just make the foo--spinner variable buffer-local and use the third argument of the spinner-create function. The snippet below is an example.

(defvar-local foo--spinner nil)
(defconst foo--lighter
  '(" foo" (:eval (spinner-print foo--spinner))))
(defun foo--start-spinner ()
  "Create and start a spinner on this buffer."
  (unless foo--spinner
    (setq foo--spinner (spinner-create 'moon t)))
  (spinner-start foo--spinner))
  1. To activate the spinner, just call (foo--start-spinner).
  2. To get rid of it, call (spinner-stop foo--spinner).

This will use the moon spinner, but you can use any of the names defined in the spinner-types variable or even define your own.

Extra options

Both spinner-start and spinner-create take extra options to configure the spinner, these are:

  • FPS: The number of frames to display per second. Defaults to spinner-frames-per-second.
  • DELAY: After starting a spinner, it still won’t be displayed for this many seconds.

spinner.el's People

Contributors

malabarba avatar notetiene avatar tarsius avatar twmr avatar wilfred avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar

spinner.el's Issues

wrong-type-argument timerp

Hi,

on a recent Emacs 28 (commit: 03dcceeeeeda6cefe4c0a79be328dd44b289b20b), I did this:

  • emacs -Q
  • M-x package-initialize
  • M-x toggle-debug-on-error
  • (spinner-start)

And then I got

Debugger entered--Lisp error: (wrong-type-argument timerp [t nil nil nil nil nil nil nil nil])
  timer--time-setter([t nil nil nil nil nil nil nil nil] (24878 14508 400000 0))
  timer-set-time([t nil nil nil nil nil nil nil nil] (24878 14508 400000 0) 0.1)
  spinner--start-timer(#s(spinner :frames ["┤" "┘" "┴" "└" "├" "┌" "┬" "┐"] :counter 0 :fps 10 :timer [t nil nil nil nil nil nil nil nil] :active-p t :buffer #<buffer *scratch*> :delay 0))
  spinner-start()
  (progn (spinner-start))
  eval((progn (spinner-start)) t)
  elisp--eval-last-sexp(nil)
  eval-last-sexp(nil)
  funcall-interactively(eval-last-sexp nil)
  call-interactively(eval-last-sexp nil nil)
  command-execute(eval-last-sexp)

Assumes mode-line-format is a list.

The package assumes that mode-line-format is a list and tries modify it, however the mode line format is not always a list. Fromt the docs:

The value may be nil, a string, a symbol or a list.

The package errors when it is not a list. If it is not a list you could simply take the current symbol or string and set the mode-line-format to a list where the existing value is the car.

spinner doesn't spin

If I call (spinner-start) in a buffer, a spinner shows up in the mode line but it doesn't start spinning. This is on Emacs 28.1 on Arch Linux. On another laptop with an almost identical setup on Elementary OS, the spinner works.

Any idea what could be wrong here? The value of system-configuration-features is almost identical between the two systems, except that the one where spinner works has LIBSELINUX and NATIVE_COMP, which the other system lacks, but it seems unlikely to me that those play a role.

Is there anything in particular I should be looking at to narrow this down?

Compilation warnings under Emacs 29.2

I recently upgraded my Emacs to version 29.2, and I noticed the following compilation warnings:

⛔ Warning (comp): spinner.el:153:2: Warning: docstring has wrong usage of unescaped single quotes (use \= or different quoting)
⛔ Warning (comp): spinner.el:275:2: Warning: docstring has wrong usage of unescaped single quotes (use \= or different quoting)

eldev complained about "expired key"

Started getting the following error when compiling cider:

eldev compile
[1/8] Installing package ‘clojure-mode’ (20240526.1825) from ‘melpa-unstable’...
[2/8] Installing package ‘parseclj’ (20231203.1905) from ‘melpa-unstable’...
[3/8] Installing package ‘parseedn’ (20231203.1909) from ‘melpa-unstable’...
[4/8] Installing package ‘queue’ (0.2) from ‘gnu’...
[5/8] Installing package ‘spinner’ (1.7.4) from ‘gnu’...
Failed to verify signature: "spinner-1.7.4.tar.sig"
Failed to verify signature spinner-1.7.4.tar.sig:
Signature made by expired key 066DAFCB81E42C40 GNU ELPA Signing Agent (2019) <[email protected]>
Command output:
gpg: Signature made Fri Jul  2 11:10:02 2021 CEST
gpg:                using RSA key C433554766D3DDC64221BFAA066DAFCB81E42C40
gpg: Good signature from "GNU ELPA Signing Agent (2019) <[email protected]>" [expired]
gpg: Note: This key has expired!
Primary key fingerprint: C433 5547 66D3 DDC6 4221  BFAA 066D AFCB 81E4 2C40

Adding spinner manually in package-list-packages worked fine, but didn't solve it.

Fiddling with the keys with gnu-elpa-keyring-update didn't seem to help, but might have been necessary.

Deleting the ~/.cache/eldev directory finally solved the issue.

Just adding it here as a tip. Took me quite a while to conquer.
Started appearing after an upgrade of emacs to 29.4, but not sure about the cause.

Spinner blinking *invalid* (emacs 26.x)

While debugging the issue in Malabarba/paradox#139, I force byte recompiled my whole elpa dir. While that did not solve that issue, the spinner has now stopped working.. It blinks *invalid*.

spinner-gone-bad

Error during redisplay: (eval (spinner-print paradox--spinner)) signaled (wrong-type-argument spinner [cl-struct-spinner ["  " "▌ " "█ " "▐▌" " █" " ▐"] 0 10 [t nil nil nil nil nil nil nil nil] nil #<buffer *Packages*> 0]) [11774 times]

This occurs even after I deleted spinner.elc and restarted emacs.

Issue installing from gnu elpa due to bad signature.

I'm trying to install a package that depends on spinner but get the following when trying to install both the depending package or this package alone

Bad signature from 474F05837FBDEF9B GNU ELPA Signing Agent <[email protected]>
Command output:
gpg: Signature made Thu 17 Nov 2016 02:05:02 PM PST
gpg:                using DSA key 474F05837FBDEF9B
gpg: BAD signature from "GNU ELPA Signing Agent <[email protected]>" [unknown]

I am using emacs 25. One thing is that I am in an isolated environment by changing HOME when running emacs to another directory with a particular .emacs.d as I have another folder by that name in my home folder.

Optional help-echo property for spinner

Does it make sense to add another optional parameter to start-spinner and then, if it is not nil, propertize the spinner with it? I'm thinking something like (propertize (elt (spinner--frames spinner) frame) 'help-echo optional-parameter) in spinner-print. That way a spinner can be given a tooltip.

missing public key

When I go to install a mode with this as a requirement I get an error that this package's public key is missing. Do you need to make a new point release to fix that

Publish on MELPA

Would be great if this package could be installed from MELPA.

(void-variable please\.<br)

I upgraded from MELPA last night. Upon calling paradox-list-packages, this is what I get:

Debugger entered--Lisp error: (void-variable please\.<br)
  byte-code("\301�!\210\302 \207" [please\.<br \, Debian] 2)
  require(spinner)
  byte-code("\301\302!\210\303\304\305\306\307DD\310\311\312\211\313\314\315\316�\"BBB\317\320\313\321\312\313\314\315\322�\"BBBF\323BBBB\324\325\326\327&  \207" [spinner-types require spinner custom-declare-variable paradox-spinner-type funcall function #[0 "\300\207" [horizontal-moving] 1] "Holds the type of spinner to be used in the mode-line.\nTakes a value accepted by `spinner-start'." :type choice :tag "Choose a spinner by name" mapcar #[257 "\300�@D\207" [const] 3 "\n\n(fn C)"] (const :tag "A random spinner" random) repeat "A list of symbols from `spinner-types' to randomly choose from" #[257 "\300�@D\207" [const] 3 "\n\n(fn C)"] ((vector :tag "A user defined vector" (repeat :inline t string))) :package-version (paradox . "2.1") :group paradox-execute] 17)
  require(paradox-core)
  byte-code("\300\301!\210\300\302!\210\300\303!\210\300\304!\210\300\305!\207" [require package cl-lib paradox-core paradox-execute paradox-menu] 2)
  autoload-do-load((autoload "paradox" "Improved version of `package-list-packages'.  The heart of Paradox.\nFunction is equivalent to `package-list-packages' (including the\nprefix NO-FETCH), but the resulting Package Menu is improved in\nseveral ways.\n\nAmong them:\n\n1. Uses `paradox-menu-mode', which has more functionality and\nkeybinds than `package-menu-mode'.\n\n2. Uses some font-locking to improve readability.\n\n3. Optionally shows the number GitHub stars and Melpa downloads\nfor packages.\n\n4. Adds useful information in the mode-line.\n\n(fn NO-FETCH)" t nil) paradox-list-packages)
  command-execute(paradox-list-packages)

spinner.el pollutes mode-line-process

Hi there,

To add itself to mode-line-process spinner.el creates a new mode line format that embeds the previous mode line as a sublist instead of appending itself to the existing mode-line-format.

    (unless (and (listp mode-line-process)
                 (memq 'spinner--mode-line-construct mode-line-process))
      (setq mode-line-process
            (list (or mode-line-process "")
                  'spinner--mode-line-construct))))

The problem with this approach is that if other modes do like spinner.el they will step on each other's toes: when the mode line format (A1 ... An), spinner.el changes it to ((A1 ... An) spinner--mode-line-construct). This breaks the type of membership tests that spinner itself uses: (memq 'A1 mode-line-process) returns nil after the changes that spinner applies.

Error with Emacs 26

With Emacs 26 I get the following error from Paradox but originating from spinner.el

Debugger entered--Lisp error: (error "Invalid options for slot timer in spinner")
  signal(error ("Invalid options for slot timer in spinner"))
  error("Invalid options for slot %s in %s" timer spinner)
  #[385 "�:\203\n��@\202����\243\303\211\304�!\305P\306\307\310��\"!\303\306\307\311�   \"!\306\307\312�\n\"!\303\211\313 \2035��\2026�\314\303\306\307\315��\"!\306\307\316��\"!\303\211\211\211\211��@;\205X���\211A\262�\242\303\211\317\320\321��\"B\262���\203I���@:\203v���@@\202y���@��\211A\262�\242\243�\322=\203\235�\211\203D�\211@\203\227�\304�@!\202\230�\323\262�\202D��\324=\203\307�\211A\203\274�\211@��=\203\263�\303\262�\211��B\262�\202D�\211\203D�\211@\262�\202D��\325=\203\330�\211\203D�\211@\262�\202D��\326=\203\351�\211\203D�\211@\262�\202D��\327=\203����\203\370�\330\331!\210\211@\262    \320\332�A\"\262\n\202D��\333=\203��\211@\262�\202D��\334=\203 �\211@\262�\202D��\335=\203,�\336\262�\202D��\337=\203?�\340�@\341\"��\244\262�\202D�\330\342�\"\210\266�\202c���\204U��\204U�   \262���\203`�\343��!\262��
\203v�\344\345\346��D\347BB\350BB\262�\202\266��\204\266��\n\203\227��\n\351H\n>\204\220�\352\353\354�
D\"\210�\n\355H\203\266�\336\262
�\n\204\243��\203\251��
?\205\264�\344\356\307\357��\"\360BBD\262��\n\203N��\n\351H\n>\204\314�\352\353\354�
D\"\210�\n\361H\362�\f!��\203\346����=\204\346�\330\363��\"\210�    \203��� @@�\236\206\375�\330\364��@@��#�>�\n\211A\262\f\242\240\210\202\346�\365�\366\367��\236��\"\"\262��\262���\203'�\367��\236\202(�\370\262��\f\351H\n>\204;�\352\353\354��D\"\210�\f\371H\203I���\262\f\336\262�\266�\202l��\203i��\372>\204^�\330\373��\"\210�\203l���\262\n\202l�\370\262��\204z�\366\367��\236��\"\262���\204\214��\203\214�\306\307\374��\"!\262��\205\352���G\367��\236��>GZ��\375>\203\302�\376\377\201@�\201A���GE\201B�\201C�\201D���E��EF\202\350�\211\351U\203\324�\201B�\201E���E\202\350�\376\201F�\201B�\201G��\201H�BB�
EE\262�\262��\205����\351V\205���A@@\201I�=\203����\201J�U\203��\376�AAAB\202����\201K�B\262�\351��\211\203L�\211�A\262�\242\211�A\262�\242\211\201L�>\203Q�\303��B\262�\211\367=\205I�\201M���D��B\262�\202C�\211�\236\203`�\330\201N����#\210\306\307\201O����#!���B\262��\211A\262�\242��B\262�\201P��\201Q�\307\201R����##\201S�\365��\205\256�\201T��\f\352\201U�\201V�\201M��'D\201W�BBEEC��\201X�>\203\303�\201C�\201D��
E\202\332���\351U\203\320�\201Y�\202\332�\201G��\f\201Z�BBC\"BBBBB� B\262   \201[��G!\203\370�\330\201\\����#\210\201]��\201^�\"\203��\201_��\201`�\201a�\330\201b�\201M���DEEE�    B\262   ��\203B���\356\307\201c��\"\201d�BB\201e��\201f�B\201g�BBD\244\210\210\266��T\262�\202��\266���\237\262���\237\262��\203\235�\201P���\201h�\201i��@\376=\203x�\365��\201j�\"\202\200�\376��\201k�BB\257��B\262�\201l�\201M���D\201m�\201M���DF�B\262���\203\264�\201n�\201M���D\201o�BB�B\262���\203\316���\201p�\366\303\201q���!\"BD��B\262���\211\203d�\211@\211@�A\211@�A\211@�A����\201r��!\201s�\201t�\201u�\201v�\201w�\201x���!\201y�\"\201z�\201{�%�\"�\"#\201P��\201|�\303�(B��BB��;\203*���\2021�\307\201}��(\"\365\201~�\344\320\201���-\"B!\205E�\201\200���\206M�\201x���BC\"BBBB��B\262�\266��A\266\202\202\320�\210�\f\203s��
\201\201�\336D\244\210\344\201\202��\nD\365��\237\201\203�\201\204�\201M���D�   \201M���D\201M���D��\336=\201M��#D\201M���D\201M���D\201M���D\257\nD\201M���DD\"BB\207" [cl--optimize-safety cl--struct-default-parent cl-struct-cl-structure-class-tags nil symbol-name "-" intern format "make-%s" "copy-%s" "%s-p" cl--compiling-file 3 "cl-struct-%s" "cl-struct-%s-tags" (cl-tag-slot) mapcar #[257 "\211:\203��\207\211C\207" [] 2 "\n\n(fn X)"] :conc-name "" :constructor :copier :predicate :include error "Can't :include more than once" #[257 "\211:\203��\207\211C\207" [] 2 "\n\n(fn X)"] :print-function :type :named t :initial-offset make-list (cl-skip-slot) "Structure option %s unrecognized" cl--struct-get-class progn funcall function (cl-x cl-s cl-n) (t) 0 signal wrong-type-argument cl-structure-class 9 princ "#S(%s" (cl-s) 7 ...] 48 ("/usr/share/emacs/26.0.50/lisp/emacs-lisp/cl-macs.elc" . 66994)]((spinner (:copier nil) (:conc-name spinner--) (:constructor make-spinner (&optional type buffer-local frames-per-second delay-before-start))) (frames (spinner--type-to-frames type)) (counter 0) (fps (or frames-per-second spinner-frames-per-second)) (timer (timer-create) :read-only) (active-p nil) (buffer (when buffer-local (if (bufferp buffer-local) buffer-local (current-buffer)))) (delay (or delay-before-start 0)))
  (defstruct (spinner (:copier nil) (:conc-name spinner--) (:constructor make-spinner (&optional type buffer-local frames-per-second delay-before-start))) (frames (spinner--type-to-frames type)) (counter 0) (fps (or frames-per-second spinner-frames-per-second)) (timer (timer-create) :read-only) (active-p nil) (buffer (when buffer-local (if (bufferp buffer-local) buffer-local (current-buffer)))) (delay (or delay-before-start 0)))
  eval-buffer(#<buffer  *load*-217527> nil "/home/peter/.emacs.d/elpa/spinner-1.7.1/spinner.el" nil t)  ; Reading at buffer position 7645
  load-with-code-conversion("/home/peter/.emacs.d/elpa/spinner-1.7.1/spinner.el" "/home/peter/.emacs.d/elpa/spinner-1.7.1/spinner.el" nil t)
  require(spinner)
  (progn (require (quote spinner)))
  eval((progn (require (quote spinner))) t)
  #[128 "\301\302\303�B�\"D\207" [lexical-binding quote eval progn] 5 1798581]((require (quote spinner)))
  (eval-and-compile (require (quote spinner)))
  eval-buffer(#<buffer  *load*-917441> nil "/home/peter/.emacs.d/elpa/paradox-20161020.1842/paradox-core.el" nil t)  ; Reading at buffer position 4324
  load-with-code-conversion("/home/peter/.emacs.d/elpa/paradox-20161020.1842/paradox-core.el" "/home/peter/.emacs.d/elpa/paradox-20161020.1842/paradox-core.el" nil t)
  require(paradox-core)
  eval-buffer(#<buffer  *load*> nil "/home/peter/.emacs.d/elpa/paradox-20161020.1842/paradox.el" nil t)  ; Reading at buffer position 4222
  load-with-code-conversion("/home/peter/.emacs.d/elpa/paradox-20161020.1842/paradox.el" "/home/peter/.emacs.d/elpa/paradox-20161020.1842/paradox.el" nil t)
  autoload-do-load((autoload "paradox" "Improved version of `package-list-packages'.  The heart of Paradox.\nFunction is equivalent to `package-list-packages' (including the\nprefix NO-FETCH), but the resulting Package Menu is improved in\nseveral ways.\n\nAmong them:\n\n1. Uses `paradox-menu-mode', which has more functionality and\nkeybinds than `package-menu-mode'.\n\n2. Uses some font-locking to improve readability.\n\n3. Optionally shows the number GitHub stars and Melpa downloads\nfor packages.\n\n4. Adds useful information in the mode-line.\n\n(fn NO-FETCH)" t nil) paradox-list-packages)
  command-execute(paradox-list-packages)

Commit eb610f270ea919107b10bb8ece200a87abac6e0e in Emacs source intruduced a check in defstruct which checks the options for a slot and causes the issue.

Should I rather report the issue on emacs-devel?

Thanks

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.