The package is mostly a joke, so the documentation shouldn't take itself so seriously. Updated all prose sections to be more self-aware and humorous while remaining technically useful. Key changes: - Introduction now acknowledges the absurdity upfront - Level descriptions embrace the silliness (especially 7-11) - "Part of Month" described as "telling time with vibes" - "Part of Season" admits "we've abandoned all pretense" - "Year" level: "We've achieved maximum vagueness" - Pattern section: "Is this even a clock anymore" - Philosophy section: "Wait, Is This Actually Deep?" - Acknowledges this might help focus OR just be silly Technical content remains unchanged - all the actual information is still there, just presented with appropriate self-awareness about displaying "Middle Fall" as a time. Teach-don't-tell approach maintained, but now with jokes.
959 lines
30 KiB
Org Mode
959 lines
30 KiB
Org Mode
#+TITLE: Fuzzy Clock Technical Documentation
|
|
#+AUTHOR: Fuzzy Clock Contributors
|
|
#+DATE: 2025
|
|
|
|
* Introduction
|
|
|
|
** What is fuzzy-clock.el?
|
|
|
|
Fuzzy Clock is an Emacs package that displays time in increasingly vague and absurd ways.
|
|
|
|
Instead of seeing =14:32=, you could see "Half past two".
|
|
|
|
Or "Afternoon".
|
|
|
|
Or "Tuesday".
|
|
|
|
Or "Middle Fall".
|
|
|
|
Or just "2025" for the entire year.
|
|
|
|
Yes, really.
|
|
|
|
** Why does this exist?
|
|
|
|
Because someone thought "What if my mode-line just said 'Afternoon' for six hours straight?" and decided that was a reasonable idea.
|
|
|
|
Also, the KDE fuzzy clock widget exists, which means this madness has precedent.
|
|
|
|
** Is this useful?
|
|
|
|
Maybe! Some people claim it helps them:
|
|
- Stop obsessing over every passing minute
|
|
- Think in natural language instead of numbers
|
|
- Feel less anxious about time
|
|
- Annoy their coworkers when pair programming
|
|
|
|
But let's be honest: you're probably here because the idea of your mode-line displaying "Late Winter" sounds either delightful or horrifying, and you need to find out which.
|
|
|
|
** Should you keep reading?
|
|
|
|
If you:
|
|
- Think "Early October" is a valid time
|
|
- Want to reduce time anxiety (or increase it dramatically)
|
|
- Enjoy things that are technically functional but philosophically questionable
|
|
- Have ever thought "I wish my clock was less helpful"
|
|
|
|
Then yes, keep reading.
|
|
|
|
* Getting Started
|
|
|
|
Let's get you to a working fuzzy clock as quickly as possible.
|
|
|
|
** Step 1: Load the package
|
|
|
|
#+begin_src emacs-lisp
|
|
;; Assuming you've installed fuzzy-clock.el, load it:
|
|
(require 'fuzzy-clock)
|
|
#+end_src
|
|
|
|
** Step 2: Enable it
|
|
|
|
#+begin_src emacs-lisp
|
|
;; Turn on fuzzy clock mode
|
|
(fuzzy-clock-mode 1)
|
|
#+end_src
|
|
|
|
** What you should see
|
|
|
|
Look at your mode-line (the bar at the bottom of your Emacs window). You should see something like:
|
|
|
|
: Three o'clock
|
|
|
|
Or:
|
|
|
|
: Afternoon
|
|
|
|
Or:
|
|
|
|
: Half past two
|
|
|
|
The exact text depends on what time it is right now.
|
|
|
|
** Did it work?
|
|
|
|
If you see natural language time in your mode-line: *Congratulations!* You have a working fuzzy clock.
|
|
|
|
If you don't see anything, check that ~global-mode-string~ is displayed in your mode-line configuration. Most Emacs configurations include it by default.
|
|
|
|
** Quick experiment
|
|
|
|
Try changing the time on your system clock (or just wait a few minutes). Watch your mode-line update automatically. The default updates every 60 seconds.
|
|
|
|
** Turn it off
|
|
|
|
Don't like it? Turn it off just as easily:
|
|
|
|
#+begin_src emacs-lisp
|
|
(fuzzy-clock-mode 0)
|
|
#+end_src
|
|
|
|
** What's next?
|
|
|
|
You now have fuzzy time in your mode-line. But "Three o'clock" might still be more precise than you want.
|
|
|
|
This is where things get weird.
|
|
|
|
* Understanding Fuzzy Time
|
|
|
|
Or: "How vague do you want to be?"
|
|
|
|
** The Core Concept: Fuzziness Levels
|
|
|
|
Fuzzy Clock has *eleven* different levels of vagueness.
|
|
|
|
At Level 1, you get normal human time like "Quarter past three."
|
|
|
|
At Level 11, your mode-line just says "2025" for twelve months straight.
|
|
|
|
The progression goes from "reasonably fuzzy" to "okay this is getting silly" to "wait, is this even a clock anymore?"
|
|
|
|
But here's the thing: they all actually work. Let's see how ridiculous this gets.
|
|
|
|
** Level 4: Hour (The Default)
|
|
|
|
Let's start with the default level, because it's the easiest to understand.
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq fuzzy-clock-fuzziness 'hour)
|
|
#+end_src
|
|
|
|
At this level, time is rounded to the nearest hour:
|
|
- 14:00 to 14:29 → "Two o'clock"
|
|
- 14:30 to 15:29 → "Three o'clock"
|
|
|
|
Notice the rounding happens at the 30-minute mark. This matches how humans naturally round: "It's about three" when it's 14:32.
|
|
|
|
Special cases:
|
|
- Midnight (00:00-00:29) → "Midnight" (not "Zero o'clock")
|
|
- Noon (12:00-12:29) → "Noon" (not "Twelve o'clock")
|
|
|
|
*Why this is the default:* It strikes a balance. You still have a sense of progression through the day, but you're not watching minutes tick by.
|
|
|
|
** Level 1: Five Minutes (Maximum Precision)
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq fuzzy-clock-fuzziness 'five-minutes)
|
|
#+end_src
|
|
|
|
This is the most precise level. Time is rounded to 5-minute intervals:
|
|
- 14:03 → "Five past two"
|
|
- 14:17 → "Fifteen past two"
|
|
- 14:42 → "Twenty to three"
|
|
|
|
The magic is in the language. Instead of "14:15", you see "Quarter past two". It's still precise, but it's *linguistic* precision, not numeric precision.
|
|
|
|
This level uses natural expressions:
|
|
- 0 minutes → "Three o'clock"
|
|
- 5 minutes past → "Five past three"
|
|
- 15 minutes past → "Quarter past three"
|
|
- 30 minutes past → "Half past three"
|
|
- 15 minutes before → "Quarter to four"
|
|
- 5 minutes before → "Five to four"
|
|
|
|
*When to use this:* When you need precision but prefer natural language. Good for people who like the KDE fuzzy clock at its most precise setting.
|
|
|
|
** Level 2: Fifteen Minutes
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq fuzzy-clock-fuzziness 'fifteen-minutes)
|
|
#+end_src
|
|
|
|
Time rounds to 15-minute intervals:
|
|
- 14:00-14:06 → "Two o'clock"
|
|
- 14:07-14:22 → "Quarter past two"
|
|
- 14:23-14:37 → "Half past two"
|
|
- 14:38-14:52 → "Quarter to three"
|
|
- 14:53-15:06 → "Three o'clock"
|
|
|
|
This is useful when you want to track time in quarter-hour blocks. Many people schedule their days this way naturally.
|
|
|
|
** Level 3: Half Hour
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq fuzzy-clock-fuzziness 'half-hour)
|
|
#+end_src
|
|
|
|
Time rounds to 30-minute intervals:
|
|
- 14:00-14:14 → "Two o'clock"
|
|
- 14:15-14:44 → "Half past two"
|
|
- 14:45-15:14 → "Three o'clock"
|
|
|
|
Only three possible states per hour: on the hour, half past, or the next hour.
|
|
|
|
*When to use this:* When you want to think in half-hour blocks but still have a sense of time progression.
|
|
|
|
** Level 5: Part of Day (The First Big Jump)
|
|
|
|
Now we make a conceptual leap. Instead of dividing hours, we divide the *day itself*.
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq fuzzy-clock-fuzziness 'part-of-day)
|
|
#+end_src
|
|
|
|
Your mode-line will show one of four states:
|
|
- 06:00-11:59 → "Morning"
|
|
- 12:00-17:59 → "Afternoon"
|
|
- 18:00-21:59 → "Evening"
|
|
- 22:00-05:59 → "Night"
|
|
|
|
This changes how you relate to time. You stop thinking in hours and start thinking in *periods*.
|
|
|
|
"Morning" doesn't tell you if it's 6 AM or 11 AM. That's the point. It tells you the *character* of the time, not its precise position.
|
|
|
|
*When to use this:* When you want to stop micromanaging your time. When you want to think in terms of energy levels (morning energy, afternoon slump, evening wind-down) rather than clock positions.
|
|
|
|
** Level 6: Day of Week
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq fuzzy-clock-fuzziness 'day-of-week)
|
|
#+end_src
|
|
|
|
Your mode-line shows: "Monday", "Tuesday", etc.
|
|
|
|
Now we've zoomed out even further. Hours don't matter. The specific day matters.
|
|
|
|
This is useful when you're thinking about your week as a whole. "It's Tuesday" is more meaningful than "It's 14:32 on Tuesday" when you're planning weekly tasks.
|
|
|
|
** Level 7: Part of Month (Where It Gets Weird)
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq fuzzy-clock-fuzziness 'part-of-month)
|
|
#+end_src
|
|
|
|
Your mode-line shows: "Early October", "Middle October", "Late October"
|
|
|
|
Congratulations, you're now telling time with *vibes*.
|
|
|
|
The month is divided into three phases:
|
|
- Days 1-10: Early
|
|
- Days 11-20: Middle
|
|
- Days 21-end: Late
|
|
|
|
Is "Early October" a valid time? Technically no. Will it annoy people? Absolutely. Does it somehow work? Kind of!
|
|
|
|
*When to use this:* When you want to think in monthly cycles but still pretend you're tracking time. Good for confusing meeting scheduling bots.
|
|
|
|
** Level 8: Month
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq fuzzy-clock-fuzziness 'month)
|
|
#+end_src
|
|
|
|
Your mode-line shows: "January", "October", etc.
|
|
|
|
Useful for thinking about the year as a whole. "It's October" tells you where you are in the annual cycle.
|
|
|
|
** Level 9: Part of Season (Committing to the Bit)
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq fuzzy-clock-fuzziness 'part-of-season)
|
|
#+end_src
|
|
|
|
Your mode-line shows: "Early Fall", "Middle Fall", "Late Fall"
|
|
|
|
We've abandoned all pretense of this being a clock now. This is just vibes all the way down.
|
|
|
|
Each season has three months, and each month represents a phase:
|
|
- First month: Early (December = Early Winter, March = Early Spring, etc.)
|
|
- Second month: Middle (January = Middle Winter, April = Middle Spring, etc.)
|
|
- Third month: Late (February = Late Winter, May = Late Spring, etc.)
|
|
|
|
Your mode-line will say "Middle Fall" for the entirety of October. All of it. Every meeting, every deadline, every "what time is it?" — just "Middle Fall."
|
|
|
|
*When to use this:* When you've given up on punctuality entirely. When you want people to think you're either very zen or very confused.
|
|
|
|
** Level 10: Part of Year (Why Not?)
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq fuzzy-clock-fuzziness 'part-of-year)
|
|
#+end_src
|
|
|
|
Your mode-line shows: "Early 2025", "Middle 2025", "Late 2025"
|
|
|
|
At this point we're not even trying to be useful. The year is divided into:
|
|
- Months 1-4: Early (January through April)
|
|
- Months 5-8: Middle (May through August)
|
|
- Months 9-12: Late (September through December)
|
|
|
|
Your mode-line will say "Early 2025" from January through April. That's four months. One third of the year. With the same time display.
|
|
|
|
This is either deeply calming or deeply unsettling. There is no middle ground.
|
|
|
|
*When to use this:* When someone asks "What time is it?" and you want to answer "Late 2025" with a completely straight face.
|
|
|
|
** Level 11: Year (The Final Boss)
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq fuzzy-clock-fuzziness 'year)
|
|
#+end_src
|
|
|
|
Your mode-line shows: "2025"
|
|
|
|
We did it. We've achieved maximum vagueness. Your clock now displays "2025" for twelve consecutive months.
|
|
|
|
Is this useful? No.
|
|
Is this a clock? Debatable.
|
|
Does it spark joy? Maybe!
|
|
|
|
*When to use this:* When you want to know what year it is but literally nothing else. When you're working on geological timescales. When you've transcended time itself but still need to know if it's a leap year.
|
|
|
|
This exists purely because we could, not because we should.
|
|
|
|
** The Pattern: Or, "How We Justified This"
|
|
|
|
Notice the pattern in these levels:
|
|
|
|
1. Five minutes — Useful
|
|
2. Fifteen minutes — Still useful
|
|
3. Half hour — Getting fuzzy
|
|
4. Hour — The sweet spot
|
|
5. Part of day — Okay, this works
|
|
6. Day of week — Sure, why not
|
|
7. Part of month — Wait what
|
|
8. Month — Back to reasonable
|
|
9. Part of season — *Deeply* questionable
|
|
10. Part of year — Are we okay?
|
|
11. Year — We've gone too far
|
|
|
|
There's actually a pattern here (we swear this wasn't just random):
|
|
|
|
The "part of period" thing (early/middle/late) appears at three scales:
|
|
- Part of month (days 1-10, 11-20, 21+)
|
|
- Part of season (first/second/third month)
|
|
- Part of year (months 1-4, 5-8, 9-12)
|
|
|
|
It's like a fractal, if fractals were made of increasingly absurd time displays.
|
|
|
|
Levels 1-4: Actual time tracking
|
|
Levels 5-6: Time but make it chill
|
|
Levels 7-11: Is this even a clock anymore
|
|
|
|
** Choosing Your Fuzziness Level
|
|
|
|
Here's how to think about it:
|
|
|
|
*Ask yourself:* What's the smallest unit of time that matters for how I want to feel right now?
|
|
|
|
- Need to catch a meeting in 15 minutes? → Use ~five-minutes~ or ~fifteen-minutes~
|
|
- Want to reduce time anxiety? → Use ~hour~ or ~part-of-day~
|
|
- Planning your week? → Use ~day-of-week~
|
|
- Tracking monthly cycles? → Use ~part-of-month~ or ~month~
|
|
- Thinking in seasonal rhythms? → Use ~part-of-season~
|
|
- Working on annual projects? → Use ~part-of-year~ or ~year~
|
|
|
|
You can change this *anytime*. Time is contextual. Your fuzziness should be too.
|
|
|
|
** The Philosophy of Rounding
|
|
|
|
Every fuzzy clock implementation has to make decisions about rounding. Let's understand the philosophy here.
|
|
|
|
*** Hour-level rounding
|
|
|
|
At ~hour~ fuzziness, 14:32 becomes "Three o'clock" because 32 minutes is closer to the *next* hour (15:00) than the current hour (14:00).
|
|
|
|
The rounding point is 30 minutes. This matches human intuition: "It's about three" when it's 14:32.
|
|
|
|
*** Special handling for midnight and noon
|
|
|
|
Midnight and noon are *special moments*. They have names. We say "Midnight" and "Noon", not "Zero o'clock" and "Twelve o'clock".
|
|
|
|
Fuzzy Clock respects this. At levels 1-4, midnight and noon appear as words, not numbers.
|
|
|
|
*** The "past" and "to" logic
|
|
|
|
In English, we say:
|
|
- "Quarter past three" (3:15)
|
|
- "Quarter to four" (3:45)
|
|
|
|
We use "past" for the first half of the hour, "to" for the second half.
|
|
|
|
The switch happens at 30 minutes (half past). This is language-specific, and fuzzy-clock implements the English convention.
|
|
|
|
*** Why these specific boundaries?
|
|
|
|
For five-minute fuzziness:
|
|
- 14:03 → "Five past two"
|
|
- 14:07 → "Five past two"
|
|
|
|
The boundaries are ±2 minutes. Why?
|
|
|
|
Because that's how humans round. If someone asks "What time is it?" at 14:07, you'd say "About five past two", not "Seven past two".
|
|
|
|
The rounding boundaries match *natural linguistic rounding*.
|
|
|
|
** Understanding Update Intervals
|
|
|
|
By default, fuzzy-clock updates every 60 seconds:
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq fuzzy-clock-update-interval 60)
|
|
#+end_src
|
|
|
|
*Why does this matter?*
|
|
|
|
If your fuzziness is set to ~hour~, your mode-line will show "Three o'clock" for a full hour. The 60-second update means the display will change within a minute of when it should.
|
|
|
|
But if your fuzziness is ~year~, updating every 60 seconds is overkill. Years last twelve months. You could update once a day:
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq fuzzy-clock-fuzziness 'year)
|
|
(setq fuzzy-clock-update-interval 86400) ; 24 hours
|
|
#+end_src
|
|
|
|
*Match your update interval to your fuzziness level.*
|
|
|
|
Recommended intervals:
|
|
- ~five-minutes~ → 60 seconds (1 minute)
|
|
- ~fifteen-minutes~ → 300 seconds (5 minutes)
|
|
- ~half-hour~ → 600 seconds (10 minutes)
|
|
- ~hour~ → 600 seconds (10 minutes)
|
|
- ~part-of-day~ → 3600 seconds (1 hour)
|
|
- ~day-of-week~ → 3600 seconds (1 hour)
|
|
- ~part-of-month~ → 86400 seconds (24 hours)
|
|
- ~month~ → 86400 seconds (24 hours)
|
|
- ~part-of-season~ → 86400 seconds (24 hours)
|
|
- ~part-of-year~ → 86400 seconds (24 hours)
|
|
- ~year~ → 86400 seconds (24 hours)
|
|
|
|
Less frequent updates = less CPU usage = more battery life.
|
|
|
|
** Beyond the Mode-line: Other Display Methods
|
|
|
|
The mode-line integration is the main use case, but fuzzy-clock offers two other ways to view fuzzy time.
|
|
|
|
*** One-time display in minibuffer
|
|
|
|
#+begin_src emacs-lisp
|
|
M-x fuzzy-clock-show
|
|
#+end_src
|
|
|
|
This shows the current fuzzy time once in the minibuffer, then disappears.
|
|
|
|
Useful when you have ~fuzzy-clock-mode~ disabled but occasionally want to check fuzzy time.
|
|
|
|
You could bind it to a key:
|
|
|
|
#+begin_src emacs-lisp
|
|
(global-set-key (kbd "C-c t") 'fuzzy-clock-show)
|
|
#+end_src
|
|
|
|
Now ~C-c t~ shows you fuzzy time on demand.
|
|
|
|
*** Dedicated buffer display
|
|
|
|
#+begin_src emacs-lisp
|
|
M-x fuzzy-clock-display-buffer
|
|
#+end_src
|
|
|
|
This creates a buffer called ~*Fuzzy Clock*~ showing the current fuzzy time.
|
|
|
|
The buffer doesn't auto-update. It's a snapshot of fuzzy time at the moment you called the command.
|
|
|
|
*Why would you use this?*
|
|
|
|
Honestly? Probably never. It's there for completeness. The mode-line integration is what you actually want.
|
|
|
|
But if you're building a custom dashboard or information display, you could incorporate this buffer.
|
|
|
|
** Practical Configurations
|
|
|
|
Let's put this all together with some real-world configurations.
|
|
|
|
*** Configuration 1: The Default Experience
|
|
|
|
#+begin_src emacs-lisp
|
|
(require 'fuzzy-clock)
|
|
(setq fuzzy-clock-fuzziness 'hour)
|
|
(setq fuzzy-clock-update-interval 60)
|
|
(fuzzy-clock-mode 1)
|
|
#+end_src
|
|
|
|
This is the recommended starting point. Hour-level fuzziness, updates every minute.
|
|
|
|
*** Configuration 2: Maximum Precision
|
|
|
|
#+begin_src emacs-lisp
|
|
(require 'fuzzy-clock)
|
|
(setq fuzzy-clock-fuzziness 'five-minutes)
|
|
(setq fuzzy-clock-update-interval 60)
|
|
(fuzzy-clock-mode 1)
|
|
#+end_src
|
|
|
|
You want natural language but you need precision. "Quarter past three" instead of "15:15".
|
|
|
|
*** Configuration 3: Deep Focus Mode
|
|
|
|
#+begin_src emacs-lisp
|
|
(require 'fuzzy-clock)
|
|
(setq fuzzy-clock-fuzziness 'part-of-day)
|
|
(setq fuzzy-clock-update-interval 3600) ; Update once per hour
|
|
(fuzzy-clock-mode 1)
|
|
#+end_src
|
|
|
|
You want to eliminate time anxiety. "Afternoon" is all you need to know. Updates once per hour to save CPU.
|
|
|
|
*** Configuration 4: Weekly Planning Mode
|
|
|
|
#+begin_src emacs-lisp
|
|
(require 'fuzzy-clock)
|
|
(setq fuzzy-clock-fuzziness 'day-of-week)
|
|
(setq fuzzy-clock-update-interval 3600)
|
|
(fuzzy-clock-mode 1)
|
|
#+end_src
|
|
|
|
You're thinking in weekly cycles. "Tuesday" is more useful than "14:32 on Tuesday".
|
|
|
|
*** Configuration 5: Context-Aware Switching
|
|
|
|
#+begin_src emacs-lisp
|
|
(require 'fuzzy-clock)
|
|
|
|
;; Default: hour fuzziness
|
|
(setq fuzzy-clock-fuzziness 'hour)
|
|
(fuzzy-clock-mode 1)
|
|
|
|
;; Define quick-switch functions
|
|
(defun my-fuzzy-clock-focus-mode ()
|
|
"Switch to part-of-day fuzziness for deep focus."
|
|
(interactive)
|
|
(setq fuzzy-clock-fuzziness 'part-of-day)
|
|
(setq fuzzy-clock-update-interval 3600)
|
|
(message "Fuzzy clock: Focus mode (part-of-day)"))
|
|
|
|
(defun my-fuzzy-clock-precise-mode ()
|
|
"Switch to five-minute fuzziness for meetings."
|
|
(interactive)
|
|
(setq fuzzy-clock-fuzziness 'five-minutes)
|
|
(setq fuzzy-clock-update-interval 60)
|
|
(message "Fuzzy clock: Precise mode (five-minutes)"))
|
|
|
|
(defun my-fuzzy-clock-default-mode ()
|
|
"Reset to default hour fuzziness."
|
|
(interactive)
|
|
(setq fuzzy-clock-fuzziness 'hour)
|
|
(setq fuzzy-clock-update-interval 60)
|
|
(message "Fuzzy clock: Default mode (hour)"))
|
|
|
|
;; Bind to keys
|
|
(global-set-key (kbd "C-c t f") 'my-fuzzy-clock-focus-mode)
|
|
(global-set-key (kbd "C-c t p") 'my-fuzzy-clock-precise-mode)
|
|
(global-set-key (kbd "C-c t d") 'my-fuzzy-clock-default-mode)
|
|
#+end_src
|
|
|
|
Now you can switch fuzziness levels based on context:
|
|
- ~C-c t f~ → Focus mode (part-of-day)
|
|
- ~C-c t p~ → Precise mode (five-minutes)
|
|
- ~C-c t d~ → Default mode (hour)
|
|
|
|
** Advanced Topic: Wait, Is This Actually Deep?
|
|
|
|
Okay, look. We've been joking around, but there's something here.
|
|
|
|
Digital time (14:32:47) is weirdly precise for how humans actually think. Nobody says "Let's meet at fourteen thirty-two." We say "around half past two" or "afternoon."
|
|
|
|
When you use fuzzy time, you're acknowledging that most of the time, you don't actually need to know it's 14:32. You need to know it's "afternoon" or "about three."
|
|
|
|
Does this reduce time anxiety? Maybe!
|
|
Does it help you focus? Possibly!
|
|
Will it make you late to meetings? Absolutely not, you have a phone.
|
|
|
|
The real magic is that "Afternoon" doesn't change for six hours. You stop checking your mode-line every thirty seconds because it literally won't tell you anything new.
|
|
|
|
This is either:
|
|
- A feature that helps you focus
|
|
- A bug that makes the package useless
|
|
- Both simultaneously (Schrödinger's clock)
|
|
|
|
Use at your own risk. Results may include:
|
|
- Reduced time anxiety
|
|
- Increased confusion
|
|
- Coworkers asking why your Emacs says "Middle Fall"
|
|
- Accidentally missing meetings (use a real clock for those)
|
|
|
|
** What You've Learned
|
|
|
|
You now understand:
|
|
|
|
1. How to make your Emacs tell time in increasingly questionable ways
|
|
2. That there are 11 levels of fuzziness, and only like 6 of them are reasonable
|
|
3. That "Middle Fall" is technically a time if you squint hard enough
|
|
4. How to configure your mode-line to confuse everyone around you
|
|
5. That this might actually help with focus, or it might just be silly, or both
|
|
|
|
You're now equipped to use fuzzy-clock. Whether you *should* use it is between you and your sense of judgment.
|
|
|
|
Good luck explaining "Early 2025" to your pair programming partner.
|
|
|
|
* Reference
|
|
|
|
This section is for quick lookup when you know what you're looking for.
|
|
|
|
** Installation
|
|
|
|
*** Via package manager
|
|
|
|
Not yet published to MELPA. Manual installation required.
|
|
|
|
*** Manual installation
|
|
|
|
1. Clone the repository or download ~fuzzy-clock.el~
|
|
2. Add to your ~load-path~:
|
|
|
|
#+begin_src emacs-lisp
|
|
(add-to-list 'load-path "/path/to/fuzzy-clock.el")
|
|
(require 'fuzzy-clock)
|
|
#+end_src
|
|
|
|
** Commands
|
|
|
|
| Command | Description |
|
|
|--------------------------------+------------------------------------------------|
|
|
| ~fuzzy-clock-mode~ | Toggle global fuzzy clock mode (mode-line) |
|
|
| ~fuzzy-clock-show~ | Display fuzzy time once in minibuffer |
|
|
| ~fuzzy-clock-display-buffer~ | Display fuzzy time in dedicated buffer |
|
|
|
|
** Customization Variables
|
|
|
|
| Variable | Type | Default | Description |
|
|
|--------------------------------+---------+---------+---------------------------------------|
|
|
| ~fuzzy-clock-fuzziness~ | symbol | ~'hour~ | Fuzziness level (see below) |
|
|
| ~fuzzy-clock-update-interval~ | integer | ~60~ | Seconds between updates |
|
|
|
|
** Fuzziness Levels
|
|
|
|
| Symbol | Description | Example Output |
|
|
|--------------------+--------------------------------+---------------------------|
|
|
| ~'five-minutes~ | Rounds to 5-minute intervals | "Quarter past three" |
|
|
| ~'fifteen-minutes~ | Rounds to 15-minute intervals | "Half past three" |
|
|
| ~'half-hour~ | Rounds to 30-minute intervals | "Three o'clock" |
|
|
| ~'hour~ | Rounds to hour | "Three o'clock" |
|
|
| ~'part-of-day~ | Morning/Afternoon/Evening/Night| "Afternoon" |
|
|
| ~'day-of-week~ | Monday through Sunday | "Tuesday" |
|
|
| ~'part-of-month~ | Part of month (early/mid/late) | "Early October" |
|
|
| ~'month~ | Month name | "October" |
|
|
| ~'part-of-season~ | Part of season (early/mid/late)| "Middle Fall" |
|
|
| ~'part-of-year~ | Part of year (early/mid/late) | "Late 2025" |
|
|
| ~'year~ | Year number | "2025" |
|
|
|
|
** Functions
|
|
|
|
*** User-Facing Functions
|
|
|
|
**** ~(fuzzy-clock-mode &optional ARG)~
|
|
|
|
Global minor mode to display fuzzy time in mode-line.
|
|
|
|
With prefix ARG, enable if positive, disable if zero or negative.
|
|
|
|
When enabled:
|
|
- Adds fuzzy time to ~global-mode-string~
|
|
- Starts update timer
|
|
- Updates every ~fuzzy-clock-update-interval~ seconds
|
|
|
|
When disabled:
|
|
- Removes from ~global-mode-string~
|
|
- Cancels timer
|
|
|
|
**** ~(fuzzy-clock-show)~
|
|
|
|
Display current fuzzy time in minibuffer.
|
|
|
|
Interactive command. One-time display, does not update.
|
|
|
|
**** ~(fuzzy-clock-display-buffer)~
|
|
|
|
Display current fuzzy time in dedicated buffer.
|
|
|
|
Creates or switches to ~*Fuzzy Clock*~ buffer.
|
|
Snapshot at time of call, does not auto-update.
|
|
|
|
*** Internal Functions
|
|
|
|
**** ~(fuzzy-clock-format-time FUZZINESS HOUR MINUTE &optional DAY MONTH YEAR DOW DST UTCOFF)~
|
|
|
|
Format time as fuzzy string based on FUZZINESS level.
|
|
|
|
Required arguments:
|
|
- ~FUZZINESS~: Symbol indicating fuzziness level
|
|
- ~HOUR~: Hour (0-23)
|
|
- ~MINUTE~: Minute (0-59)
|
|
|
|
Optional arguments (required for some fuzziness levels):
|
|
- ~DAY~: Day of month (1-31)
|
|
- ~MONTH~: Month (1-12)
|
|
- ~YEAR~: Year (e.g., 2025)
|
|
- ~DOW~: Day of week (0=Sunday, 6=Saturday)
|
|
- ~DST~: Daylight saving time flag
|
|
- ~UTCOFF~: UTC offset
|
|
|
|
Returns: String representation of fuzzy time.
|
|
|
|
**** ~(fuzzy-clock-format-season MONTH)~
|
|
|
|
Format season based on MONTH (1-12).
|
|
|
|
Returns: "Winter", "Spring", "Summer", or "Fall"
|
|
|
|
**** ~(fuzzy-clock--hour-to-word HOUR)~
|
|
|
|
Convert HOUR (0-23) to word form in 12-hour format.
|
|
|
|
Examples:
|
|
- 0 or 12 → "Twelve"
|
|
- 3 or 15 → "Three"
|
|
- 23 → "Eleven"
|
|
|
|
Returns: Capitalized hour word
|
|
|
|
**** ~(fuzzy-clock-update)~
|
|
|
|
Internal function. Updates ~fuzzy-clock-string~ with current time.
|
|
|
|
Called automatically by timer. Do not call directly.
|
|
|
|
** Variables
|
|
|
|
*** ~fuzzy-clock-string~
|
|
|
|
String displayed in mode-line showing fuzzy time.
|
|
|
|
This variable is marked as ~risky-local-variable~ to allow evaluation in mode-line.
|
|
Do not modify directly. Updated by ~fuzzy-clock-update~.
|
|
|
|
*** ~fuzzy-clock-timer~
|
|
|
|
Timer object for updating fuzzy clock.
|
|
|
|
Do not modify directly. Managed by ~fuzzy-clock-mode~.
|
|
|
|
** Rounding Behavior Reference
|
|
|
|
*** Five-Minute Fuzziness
|
|
|
|
| Minute Range | Rounded To | Display Example |
|
|
|--------------+------------+---------------------------|
|
|
| 0-2 | 0 | "Three o'clock" |
|
|
| 3-7 | 5 | "Five past three" |
|
|
| 8-12 | 10 | "Ten past three" |
|
|
| 13-17 | 15 | "Quarter past three" |
|
|
| 18-22 | 20 | "Twenty past three" |
|
|
| 23-27 | 25 | "Twenty five past three" |
|
|
| 28-32 | 30 | "Half past three" |
|
|
| 33-37 | 35 | "Twenty five to four" |
|
|
| 38-42 | 40 | "Twenty to four" |
|
|
| 43-47 | 45 | "Quarter to four" |
|
|
| 48-52 | 50 | "Ten to four" |
|
|
| 53-57 | 55 | "Five to four" |
|
|
| 58-59 | 60 (→next) | "Four o'clock" |
|
|
|
|
*** Fifteen-Minute Fuzziness
|
|
|
|
| Minute Range | Rounded To | Display Example |
|
|
|--------------+------------+----------------------|
|
|
| 0-6 | 0 | "Three o'clock" |
|
|
| 7-22 | 15 | "Quarter past three" |
|
|
| 23-37 | 30 | "Half past three" |
|
|
| 38-52 | 45 | "Quarter to four" |
|
|
| 53-59 | 60 (→next) | "Four o'clock" |
|
|
|
|
*** Half-Hour Fuzziness
|
|
|
|
| Minute Range | Rounded To | Display Example |
|
|
|--------------+------------+------------------|
|
|
| 0-14 | 0 | "Three o'clock" |
|
|
| 15-44 | 30 | "Half past three"|
|
|
| 45-59 | 60 (→next) | "Four o'clock" |
|
|
|
|
*** Hour Fuzziness
|
|
|
|
| Minute Range | Rounded To | Display Example |
|
|
|--------------+------------+-----------------|
|
|
| 0-29 | 0 | "Three o'clock" |
|
|
| 30-59 | 60 (→next) | "Four o'clock" |
|
|
|
|
*** Part-of-Day Fuzziness
|
|
|
|
| Hour Range | Display |
|
|
|------------|-------------|
|
|
| 6-11 | "Morning" |
|
|
| 12-17 | "Afternoon" |
|
|
| 18-21 | "Evening" |
|
|
| 22-5 | "Night" |
|
|
|
|
*** Part-of-Month Mapping
|
|
|
|
| Day Range | Part | Display Example |
|
|
|-----------|----------|-------------------|
|
|
| 1-10 | Early | "Early October" |
|
|
| 11-20 | Middle | "Middle October" |
|
|
| 21-31 | Late | "Late October" |
|
|
|
|
*** Part-of-Season Mapping
|
|
|
|
| Month in Season | Part | Winter Example | Spring Example | Summer Example | Fall Example |
|
|
|-----------------|--------|-------------------|-------------------|-------------------|-------------------|
|
|
| First month | Early | "Early Winter" | "Early Spring" | "Early Summer" | "Early Fall" |
|
|
| Second month | Middle | "Middle Winter" | "Middle Spring" | "Middle Summer" | "Middle Fall" |
|
|
| Third month | Late | "Late Winter" | "Late Spring" | "Late Summer" | "Late Fall" |
|
|
|
|
Seasons are defined as:
|
|
- Winter: December (Early), January (Middle), February (Late)
|
|
- Spring: March (Early), April (Middle), May (Late)
|
|
- Summer: June (Early), July (Middle), August (Late)
|
|
- Fall: September (Early), October (Middle), November (Late)
|
|
|
|
*** Part-of-Year Mapping
|
|
|
|
| Month Range | Part | Display Example |
|
|
|-------------|--------|-----------------|
|
|
| 1-4 | Early | "Early 2025" |
|
|
| 5-8 | Middle | "Middle 2025" |
|
|
| 9-12 | Late | "Late 2025" |
|
|
|
|
** Requirements
|
|
|
|
- Emacs 24.4 or later
|
|
- No external dependencies
|
|
|
|
** Known Limitations
|
|
|
|
1. Language support: Currently English only
|
|
2. Season definitions: Northern Hemisphere (December-February = Winter)
|
|
3. 12-hour format only: No 24-hour word format
|
|
4. Mode-line integration only: No header-line or tab-bar support
|
|
|
|
** Troubleshooting
|
|
|
|
*** Fuzzy time doesn't appear in mode-line
|
|
|
|
Check that ~global-mode-string~ is included in your mode-line format:
|
|
|
|
#+begin_src emacs-lisp
|
|
;; Evaluate this to check:
|
|
global-mode-string
|
|
|
|
;; Should include: (:eval fuzzy-clock-string)
|
|
#+end_src
|
|
|
|
If it's missing, your mode-line configuration might be overriding the default.
|
|
|
|
*** Mode-line shows "*invalid*"
|
|
|
|
This happens if ~fuzzy-clock-string~ isn't marked as a risky variable.
|
|
|
|
Fuzzy-clock sets this automatically, but some configurations might block it.
|
|
|
|
Check:
|
|
|
|
#+begin_src emacs-lisp
|
|
(get 'fuzzy-clock-string 'risky-local-variable)
|
|
;; Should return: t
|
|
#+end_src
|
|
|
|
If it returns ~nil~, manually set it:
|
|
|
|
#+begin_src emacs-lisp
|
|
(put 'fuzzy-clock-string 'risky-local-variable t)
|
|
#+end_src
|
|
|
|
*** Fuzzy time doesn't update
|
|
|
|
Check that the timer is running:
|
|
|
|
#+begin_src emacs-lisp
|
|
fuzzy-clock-timer
|
|
;; Should return a timer object like: [t 0 60 60 fuzzy-clock-update nil nil]
|
|
#+end_src
|
|
|
|
If it's ~nil~, the timer isn't running. Try:
|
|
|
|
#+begin_src emacs-lisp
|
|
(fuzzy-clock-mode 0)
|
|
(fuzzy-clock-mode 1)
|
|
#+end_src
|
|
|
|
*** Wrong season displayed (Southern Hemisphere)
|
|
|
|
The season definitions are Northern Hemisphere by default.
|
|
|
|
Current workaround: The season feature isn't customizable yet.
|
|
|
|
Future enhancement: Add customization for hemisphere.
|
|
|
|
** Development
|
|
|
|
*** Running Tests
|
|
|
|
Tests use Buttercup framework via Eldev:
|
|
|
|
#+begin_src sh
|
|
# Install Eldev (if not already installed)
|
|
curl -fsSL https://raw.github.com/doublep/eldev/master/webinstall/github-eldev | sh
|
|
|
|
# Run tests
|
|
eldev test
|
|
#+end_src
|
|
|
|
*** Test Coverage
|
|
|
|
The test suite includes:
|
|
- Rounding behavior tests for all fuzziness levels
|
|
- Part-of-period tests (month, season, year)
|
|
- Mode-line integration tests
|
|
- Special case tests (midnight, noon)
|
|
- Edge case tests (hour wraparound)
|
|
- Display method tests
|
|
- Season helper function tests
|
|
|
|
140 acceptance tests ensure correctness.
|
|
|
|
** Version History
|
|
|
|
*** 0.2.0 (2025)
|
|
|
|
- Refactored granularity progression to use part-of-period pattern
|
|
- Replaced ~'week~ with ~'part-of-month~ (early/middle/late month)
|
|
- Replaced ~'season~ with ~'part-of-season~ (early/middle/late season)
|
|
- Added ~'part-of-year~ (early/middle/late year)
|
|
- Added ~'year~ (year number)
|
|
- Total fuzziness levels increased from 9 to 11
|
|
- Introduced fractal "part of period" pattern across three scales
|
|
- Expanded test suite to 140 acceptance tests
|
|
- Updated documentation to explain new progression pattern
|
|
|
|
*** 0.1.0 (2025)
|
|
|
|
- Initial release
|
|
- 9 fuzziness levels
|
|
- Mode-line integration
|
|
- Minibuffer display
|
|
- Dedicated buffer display
|
|
- Comprehensive test suite
|
|
|
|
** License
|
|
|
|
See LICENSE file in repository.
|
|
|
|
** Contributing
|
|
|
|
Contributions welcome. See CONTRIBUTING file or repository issues.
|
|
|
|
** Credits
|
|
|
|
Inspired by the KDE fuzzy clock widget.
|
|
|
|
** Contact
|
|
|
|
See repository for issue tracker and maintainer contact.
|