Animated pet parrot for your modeline. This fork includes Org TODO and magit push integration to reward your hard work.
This repository is a fork and not yet reflected in MELPA. Be sure to get this version if you want this programming interface and behavior.
(use-package parrot
;; This package is not yet the version in MELPA, so you will need to explicitly specify it.
;; :straight '(parrot :type git :host github :repo "positron-solutions/parrot")
:elpaca (parrot :host github :repo "positron-solutions/parrot" :files (:defaults "img"))
:custom
(parrot-type 'emacs) ; see parrot types below
(parrot-animate 'hide-static) ; hides after animation
;; A selection of default values. M-x customize-group parrot to see full list of options
;; (parrot-animate-on-load t) ; do animation after load (also startup)
;; (parrot-rotate-animate-after-rotation t) ; enable animation on included rotation commands
;; (parrot-party-on-org-todo-states '("DONE"))
;; (parrot-party-on-magit-push t)
(parrot-mode t)) ; enable the global minor mode!
M-x parrot-start-animation
or click on the parrot to watch it animate.
parrot-animation-frame-interval
- seconds between animation frames; can be a decimal number.parrot-minimum-window-width
- minimum width of the window, below which party parrot mode will be disabled.parrot-animate - ='animate
to enable parrot animation,'no-animation
for a static image,'hide-static
to only show while animating.parrot-animate-on-load
- animate when mode started no matter other settings.parrot-spaces-before
- number of spaces of padding before the parrot.parrot-spaces-after
- number of spaces of padding after the parrot.parrot-num-rotations
- number of times the parrot will cycle through its gif.
By default, after a rotation is performed, the selected parrot in the modeline
will start rotating. You may select your desired parrot interactively with
M-x parrot-set-parrot-type
to preview.
Like the wonders of the ancient world, parrot comes in 7 original flavors:
Parrot | Name |
---|---|
default | |
confused | |
emacs | |
nyan | |
rotating | |
science | |
thumbsup |
There are many ways to incorporate animation into your daily life.
- Add
#'parrot-start-animation
to hooks - Add advice to arbitrary functions
- Add a command or function to the parrot click hook
- Add a process filter and animate while the process is running
For example, if you want the parrot to animate whenever you receive mail in mu4e, you can try:
(add-hook 'mu4e-index-updated-hook #'parrot-start-animation)
By default, the org-after-todo-state-change-hook
has parrot--todo-party
added so that if the org-state
is in parrot-party-on-org-todo-states
,
animation will occur.
If no hook is available, just add an advice to a function or command:
(advice-add #'jinx-correct :after #'parrot-start-animation)
You can also add functions to parrot-click-hook
so they will run whenever
you click on the parrot.
(add-hook 'parrot-click-hook 'flyspell-buffer)
Calling parrot-start-animation
with t will also run forever until you run
parrot-stop-animation
, and then will stop after parrot-num-rotations
more.
By default, magit-push
will animate the parrot until the process sentinel
stops it. This is configured by the custom variable
parrot-party-on-magit-push
.
Check out the parrot--maybe-advise-magit-push
for an example of how to
advise a function that returns a process to add an extra sentinel to that
process, allowing you to party on any process!
The parrot-party-while-process
function can be used to animate any
arbitrary process that will finish with a process sentinel.
This section covers the rotate commands and behavior. Try the command
parrot-rotate-prev-word-at-point
on the string “start” to preview the
behavior.
Use parrot-rotate-next-word-at-point
and parrot-rotate-prev-word-at-point
to rotate words at point. If a match is not found under the cursor, parrot
will hunt for the nearest match in the current whitespace-delimited word and
rotate it.
;; for vanilla emacs
(global-set-key (kbd "C-c p") 'parrot-rotate-prev-word-at-point)
(global-set-key (kbd "C-c n") 'parrot-rotate-next-word-at-point)
;; for evil users
(define-key evil-normal-state-map (kbd "[r") 'parrot-rotate-prev-word-at-point)
(define-key evil-normal-state-map (kbd "]r") 'parrot-rotate-next-word-at-point)
Parrot uses a dictionary list that defines word rotations. You can override the
default by setting parrot-rotate-dict
in your init file. A sample one is
provided below:
(setq parrot-rotate-dict
'(
(:rot ("alpha" "beta") :caps t :lower nil)
;; => rotations are "Alpha" "Beta"
(:rot ("snek" "snake" "stawp"))
;; => rotations are "snek" "snake" "stawp"
(:rot ("yes" "no") :caps t :upcase t)
;; => rotations are "yes" "no", "Yes" "No", "YES" "NO"
(:rot ("&" "|"))
;; => rotations are "&" "|"
;; default dictionary starts here ('v')
(:rot ("begin" "end") :caps t :upcase t)
(:rot ("enable" "disable") :caps t :upcase t)
(:rot ("enter" "exit") :caps t :upcase t)
(:rot ("forward" "backward") :caps t :upcase t)
(:rot ("front" "rear" "back") :caps t :upcase t)
(:rot ("get" "set") :caps t :upcase t)
(:rot ("high" "low") :caps t :upcase t)
(:rot ("in" "out") :caps t :upcase t)
(:rot ("left" "right") :caps t :upcase t)
(:rot ("min" "max") :caps t :upcase t)
(:rot ("on" "off") :caps t :upcase t)
(:rot ("prev" "next"))
(:rot ("start" "stop") :caps t :upcase t)
(:rot ("true" "false") :caps t :upcase t)
(:rot ("&&" "||"))
(:rot ("==" "!="))
(:rot ("." "->"))
(:rot ("if" "else" "elif"))
(:rot ("ifdef" "ifndef"))
(:rot ("int8_t" "int16_t" "int32_t" "int64_t"))
(:rot ("uint8_t" "uint16_t" "uint32_t" "uint64_t"))
(:rot ("1" "2" "3" "4" "5" "6" "7" "8" "9" "10"))
(:rot ("1st" "2nd" "3rd" "4th" "5th" "6th" "7th" "8th" "9th" "10th"))
))
The following labels are provided for defining rotations in a dictionary entry:
:upcase t
will add UPPER CASE rotations:caps t
will add Capitalized rotations:lower nil
will exclude lowercase rotations- If no labels are provided, the word list will default to lowercase rotations
- Defining a word list for which there are no rotations will result in an error, e.g.
(:rot ("yes" "no") :lower nil)
.
You can also append to the default dictionary:
(dolist (entry '((:rot ("hakuna" "matata"))
(:rot ("peeple" "sheeple"))))
(add-to-list 'parrot-rotate-dict entry))
parrot-rotate-hunt-for-words
-t
to rotate words that aren’t directly under the cursor.parrot-rotate-jump-to-word-after-hunt
-t
to jump to the word rotated if it isn’t under the cursor.parrot-rotate-animate-after-rotation
-t
to animate the party parrot after rotating a word.parrot-rotate-highlight-after-rotation
-t
to highlight a word after rotating.parrot-rotate-start-char-invalid-regexp
- regexp used to determine if parrot shouldn’t start a rotation.parrot-rotate-start-bound-regexp
- regexp used to find the start bound to search for rotations.parrot-rotate-end-bound-regexp
- regexp used to find the end bound to search for rotations.
d12 wrote the original version of this package. I decided to fork it mainly for independence. As d12 credits many, so do I credit d12 and many for enabling this package to reach its current form.
All parrots including the gifs in this README (with the exception of emacs parrot) were taken from @jmhobbs Cult of the Party Parrot site. Thanks to @mermop (default), @kyprifog (confused), @shiruken (science), @vaicine (nyan), @youngcba3 (rotating), @zeftilldeath (thumbsup parrot) for their respective parrots, and of course @jmhobbs for compiling them.
Thanks to @francoislg for Party Parrot as a Service, with which d12 created the emacs parrot.
Thanks to Aaron Hawley, from whom d12 borrowed a good deal of their rotation code. You can see his rotate text implementation on emacswiki.
Thanks to @rejeep for ecukes, an excellent Cucumber-like testing framework.
Thanks to @DamienCassou for his detailed and thoughtful code review comments.
A special thanks to @TeMPOral, without which parrot wouldn’t be possible. d12 heavily modified the source code of nyan-mode to create parrot spawn. All credit goes to him for paving the way to new heights of mode-line distraction.