org.nvim

Pomodoro

Stability: experimental (org-extensions-stability)

pomodoro runs the Pomodoro technique on top of the clock, like Emacs org-pomodoro:

require("org").setup({ extensions = { pomodoro = { work = 25 } } })

pomodoro_start (:Org pomodoro) starts a pomodoro on the heading at the cursor: the entry is clocked in and a work minute countdown starts. When it ends, the entry's POMODOROS property goes up by one, the entry is clocked out and a break starts: short_break minutes, or long_break minutes after every long_break_every pomodoros. When the break ends you are told so, and pomodoro_start from anywhere (or from the heading of another entry) starts the next one; with auto_start_work it starts by itself. Starting on another heading while a pomodoro runs moves the session there.

With manual_break (org-pomodoro-manual-break) a pomodoro whose time is up goes on in overtime: the clock keeps running and the statusline counts up (๐Ÿ… +2:10) until pomodoro_start (or skip) ends it, counted, and starts the break.

The running pomodoro is kept in state_file, so a Neovim started while it still runs (or is paused, or in overtime) goes on with it; one that ended in the meantime is dropped, and one another Neovim is running is left to it. The clock is not touched then (see clock.persist, org-clock); after a second setup() in the same Neovim a running pomodoro clocks in again.

Each phase change is announced through the clock's notifier (clock.notification_handler, else vim.notify(), and clock.sound), a desktop notification (osascript, notify-send or a Windows toast, system_notification) and the sound command. A User autocmd OrgPomodoroPhase fires with data = { phase, count, title }, phase being "work", "overtime", "short_break", "long_break" or "ready". require("org.extensions.pomodoro").info() returns the session for other code (a statusline, the sidebar): nil, or { phase, remaining, elapsed, paused, count, title, overtime } (seconds).

Actions, :Org pomodoro [arg] and default keys

  <prefix>zs  pomodoro_start    start (:Org pomodoro or start)
  <prefix>zp  pomodoro_pause    pause, or resume a paused phase (pause,
                                resume); the clock stops while paused
  <prefix>zx  pomodoro_stop     stop the session; the running pomodoro
                                is not counted (org-pomodoro-kill) (stop)
  <prefix>zn  pomodoro_skip     end the phase now: a skipped pomodoro is
                                not counted, a skipped break starts the
                                next pomodoro (skip)
  <prefix>zi  pomodoro_status   show the time left (status)
<Tab> completes the arguments of :Org pomodoro.

Statusline

The time left is added to require("org").statusline() (org-api), after the clock: ๐Ÿ… 24:13 (1) while working, โ˜• 4:59 on a break, โธ ๐Ÿ… 12:00 when paused, ๐Ÿ… +2:10 in overtime and ๐Ÿ… ready (2) between pomodoros; the number counts the pomodoros finished in the session. Set statusline = false to leave it out and place require("org.extensions.pomodoro").statusline() yourself:

-- lualine
table.insert(opts.sections.lualine_x, 1, {
  function() return require("org.extensions.pomodoro").statusline() end,
})

Other extensions can add their own parts to require("org").statusline() through require("org").statusline_components (name -> function).

Options

  work                 minutes of a pomodoro, fractions allowed (25)
  short_break          minutes of a short break (5)
  long_break           minutes of a long break (15)
  long_break_every     a long break after every Nth pomodoro; 0 for
                       never (4)
  auto_start_breaks    start the break when a pomodoro ends (true)
  auto_start_work      start the next pomodoro when a break ends (false)
  manual_break         overtime until pomodoro_start (false)
  clock_out_on_break   clock out during breaks and pauses (true)
  property             property counting finished pomodoros
                       ("POMODOROS"); false for none
  system_notification  desktop notifications (true)
  sound                command run when a phase ends: a shell string or
                       an argv list (false)
  statusline           add the pomodoro to require("org").statusline()
                       (true)
  state_file           where the running pomodoro is kept
                       (stdpath("state")/org/pomodoro.json); false
  icons                { work, short_break, long_break, paused, ready,
                       overtime }

Differences from Emacs org-pomodoro: there is no ticking sound, no org-pomodoro-expiry-time question, and killing a pomodoro keeps its clock time (org-pomodoro-keep-killed-pomodoro-time); Emacs forgets the session when it exits.