Awesome
<h1 align="center">pomo.nvim</h1> <div><h4 align="center"><a href="#setup">Setup</a> ยท <a href="#configuration-options">Configure</a> ยท <a href="#contributing">Contribute</a></h4></div> <div align="center"><a href="https://github.com/epwalsh/pomo.nvim/releases/latest"><img alt="Latest release" src="https://img.shields.io/github/v/release/epwalsh/pomo.nvim?style=for-the-badge&logo=starship&logoColor=D9E0EE&labelColor=302D41&&color=d9b3ff&include_prerelease&sort=semver" /></a> <a href="https://github.com/epwalsh/pomo.nvim/pulse"><img alt="Last commit" src="https://img.shields.io/github/last-commit/epwalsh/pomo.nvim?style=for-the-badge&logo=github&logoColor=D9E0EE&labelColor=302D41&color=9fdf9f"/></a> <a href="https://github.com/neovim/neovim/releases/latest"><img alt="Latest Neovim" src="https://img.shields.io/github/v/release/neovim/neovim?style=for-the-badge&logo=neovim&logoColor=D9E0EE&label=Neovim&labelColor=302D41&color=99d6ff&sort=semver" /></a> <a href="http://www.lua.org/"><img alt="Made with Lua" src="https://img.shields.io/badge/Built%20with%20Lua-grey?style=for-the-badge&logo=lua&logoColor=D9E0EE&label=Lua&labelColor=302D41&color=b3b3ff"></a></div> <hr>A simple, customizable pomodoro timer plugin for Neovim, written in Lua.
In pomo.nvim, most of the functionality is surfaced through the Notifier
instances you configure. A timer can have any number of notifiers, which are essentially callbacks that fire on every tick of the timer (determined by update_interval
) and each significant event, such as when the timer starts, completes, is stopped, or is hidden. pomo.nvim comes with several notifiers out-of-the-box, but it's also easy to create your own.
Features
- ๐ชถ Lightweight and asynchronous
- ๐ป Written in Lua
- โ๏ธ Easily customizable and extendable
- โฑ๏ธ Run multiple concurrent timers and repeat timers, show/hide, pause/resume
- โ Integrate with nvim-notify, lualine, telescope, and more
Commands
-
:TimerStart TIMELIMIT [NAME]
to start a new timer.The time limit can be specified in hours, minutes, seconds, or a combination of those, and shouldn't include any spaces. For example:
:TimerStart 25m Work
to start a timer for 25 minutes called "Work".:TimerStart 10s
to start a timer for 10 seconds.:TimerStart 1h30m
to start a timer for an hour and a half.
pomo.nvim will recognize multiple forms of the time units, such as "m", "min", "minute", or "minutes" for minutes.
-
:TimerStop [TIMERID]
to stop a running timer, e.g.:TimerStop 1
. If no ID is given, the latest timer is stopped. -
:TimerRepeat TIMELIMIT REPETITIONS [NAME]
to start a repeat timer, e.g.:TimerRepeat 10s 2
to repeat a 10 second timer twice. -
:TimerHide [TIMERID]
to hide the notifiers of a running timer, if the notifiers support that. If no ID is given, the latest timer's notifiers are hidden. -
:TimerShow [TIMERID]
the opposite of:TimerHide
. -
:TimerPause [TIMERID]
pause a timer. If no ID is given, the latest timer is paused. -
:TimerResume [TIMERID]
the opposite of:TimerPause
. -
:TimerSession [SESSION_NAME]
to start a predefined Pomodoro session.Example session configuration in your setup:
require("pomo").setup({ sessions = { pomodoro = { { name = "Work", duration = "25m" }, { name = "Short Break", duration = "5m" }, { name = "Work", duration = "25m" }, { name = "Short Break", duration = "5m" }, { name = "Work", duration = "25m" }, { name = "Long Break", duration = "15m" }, }, }, })
To start the above session, use:
:TimerSession pomodoro
.
๐ก Tip: You can pass -1
as the TIMERID
to apply the command to all active timers.
Setup
To setup pomo.nvim you just need to call require("pomo").setup({ ... })
with the desired options. Here are some examples using different plugin managers. The full set of configuration options are listed below.
Using lazy.nvim
return {
"epwalsh/pomo.nvim",
version = "*", -- Recommended, use latest release instead of latest commit
lazy = true,
cmd = { "TimerStart", "TimerRepeat", "TimerSession" },
dependencies = {
-- Optional, but highly recommended if you want to use the "Default" timer
"rcarriga/nvim-notify",
},
opts = {
-- See below for full list of options ๐
},
}
Using packer.nvim
use({
"epwalsh/pomo.nvim",
tag = "*", -- Recommended, use latest release instead of latest commit
requires = {
-- Optional, but highly recommended if you want to use the "Default" timer
"rcarriga/nvim-notify",
},
config = function()
require("pomo").setup({
-- See below for full list of options ๐
})
end,
})
Configuration options
This is a complete list of all of the options that can be passed to require("pomo").setup()
. The values represent reasonable defaults, but please read each option carefully and customize it to your needs:
{
-- How often the notifiers are updated.
update_interval = 1000,
-- Configure the default notifiers to use for each timer.
-- You can also configure different notifiers for timers given specific names, see
-- the 'timers' field below.
notifiers = {
-- The "Default" notifier uses 'vim.notify' and works best when you have 'nvim-notify' installed.
{
name = "Default",
opts = {
-- With 'nvim-notify', when 'sticky = true' you'll have a live timer pop-up
-- continuously displayed. If you only want a pop-up notification when the timer starts
-- and finishes, set this to false.
sticky = true,
-- Configure the display icons:
title_icon = "๓ฑซ",
text_icon = "๓ฐ",
-- Replace the above with these if you don't have a patched font:
-- title_icon = "โณ",
-- text_icon = "โฑ๏ธ",
},
},
-- The "System" notifier sends a system notification when the timer is finished.
-- Available on MacOS and Windows natively and on Linux via the `libnotify-bin` package.
{ name = "System" },
-- You can also define custom notifiers by providing an "init" function instead of a name.
-- See "Defining custom notifiers" below for an example ๐
-- { init = function(timer) ... end }
},
-- Override the notifiers for specific timer names.
timers = {
-- For example, use only the "System" notifier when you create a timer called "Break",
-- e.g. ':TimerStart 2m Break'.
Break = {
{ name = "System" },
},
},
-- You can optionally define custom timer sessions.
sessions = {
-- Example session configuration for a session called "pomodoro".
pomodoro = {
{ name = "Work", duration = "25m" },
{ name = "Short Break", duration = "5m" },
{ name = "Work", duration = "25m" },
{ name = "Short Break", duration = "5m" },
{ name = "Work", duration = "25m" },
{ name = "Long Break", duration = "15m" },
},
},
}
Defining custom notifiers
To define your own notifier you need to create a pomo.Notifier
Lua class along with a factory init
function to construct your notifier. Your Notifier
class needs to have the following methods
Notifier.start(self)
- Called when the timer starts.Notifier.tick(self, time_left)
- Called periodically (e.g. every second) while the timer is active. Thetime_left
argument is the number of seconds left on the timer.Notifier.done(self)
- Called when the timer finishes.Notifier.stop(self)
- Called when the timer is stopped before finishing.
You can also provide optionally Notifier.show(self)
and Notifier.hide(self)
methods to respond to :TimerShow
and :TimerHide
.
The factory init
function takes 1 or 2 arguments, the timer
(a pomo.Timer
) and optionally a table of options from the opts
field in the notifier's config.
For example, here's a simple notifier that just uses print
:
local PrintNotifier = {}
PrintNotifier.new = function(timer, opts)
local self = setmetatable({}, { __index = PrintNotifier })
self.timer = timer
self.hidden = false
self.opts = opts -- not used
return self
end
PrintNotifier.start = function(self)
print(string.format("Starting timer #%d, %s, for %ds", self.timer.id, self.timer.name, self.timer.time_limit))
end
PrintNotifier.tick = function(self, time_left)
if not self.hidden then
print(string.format("Timer #%d, %s, %ds remaining...", self.timer.id, self.timer.name, time_left))
end
end
PrintNotifier.done = function(self)
print(string.format("Timer #%d, %s, complete", self.timer.id, self.timer.name))
end
PrintNotifier.stop = function(self) end
PrintNotifier.show = function(self)
self.hidden = false
end
PrintNotifier.hide = function(self)
self.hidden = true
end
And then in the notifiers
field of your pomo.nvim config, you'd add the following entry:
{ init = PrintNotifier.new, opts = {} }
Integrations
nvim-notify
The "Default" notifier integrates seamlessly with nvim-notify
, you just need to have nvim-notify
installed.
lualine.nvim
pomo.nvim can easily be added to a section in your lualine
. For example, this would extend the defaults for section X to include the next timer to finish (min time remaining):
require("lualine").setup {
sections = {
lualine_x = {
function()
local ok, pomo = pcall(require, "pomo")
if not ok then
return ""
end
local timer = pomo.get_first_to_finish()
if timer == nil then
return ""
end
return "๓ฐ " .. tostring(timer)
end,
"encoding",
"fileformat",
"filetype",
},
},
}
telescope.nvim
Pomo.nvim ships with a telescope extension for managing timers. Here's an example of mapping the keys <leader>pt
to open the telescope picker for timers.
require("telescope").load_extension "pomodori"
vim.keymap.set("n", "<leader>pt", function()
require("telescope").extensions.pomodori.timers()
end, { desc = "Manage Pomodori Timers"})
Contributing
Please see the CONTRIBUTING guide from obsidian.nvim before submitting a pull request, as this repository is set up and managed in the same way.
And if you're feeling especially generous I always appreciate some coffee funds! โค๏ธ