Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/epwalsh/pomo.nvim

:new: :stopwatch: A simple, customizable pomodoro timer for Neovim, written in Lua, with nvim-notify, lualine, and telescope integrations
https://github.com/epwalsh/pomo.nvim

neovim neovim-lua neovim-plugin nvim

Last synced: about 11 hours ago
JSON representation

:new: :stopwatch: A simple, customizable pomodoro timer for Neovim, written in Lua, with nvim-notify, lualine, and telescope integrations

Awesome Lists containing this project

README

        

pomo.nvim



Setup ยท Configure ยท Contribute



Latest release Last commit Latest Neovim Made with Lua


A simple, customizable [pomodoro](https://en.wikipedia.org/wiki/Pomodoro_Technique) timer plugin for Neovim, written in Lua.

[![demo](https://github.com/epwalsh/pomo.nvim/assets/8812459/37e58af1-c8d3-470e-b63f-35b22cd308af)](https://github.com/epwalsh/pomo.nvim/assets/8812459/37e58af1-c8d3-470e-b63f-35b22cd308af)

In **pomo.nvim**, most of the functionality is surfaced through the [`Notifier`](https://github.com/epwalsh/pomo.nvim/blob/main/lua/pomo/notifier.lua) instances you [configure](#configuration-options). A timer can have any number of notifiers, which are essentially callbacks that fire on every tick of the timer (determined by [`update_interval`](#configuration-options)) and each significant event, such as when the timer starts, completes, is stopped, or is hidden. **pomo.nvim** comes with [several notifiers](https://github.com/epwalsh/pomo.nvim/tree/main/lua/pomo/notifiers) out-of-the-box, but it's also easy to [create your own](#defining-custom-notifiers).

## 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](https://github.com/rcarriga/nvim-notify), [lualine](#lualinenvim), [telescope](https://github.com/nvim-telescope/telescope.nvim), 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:

```lua
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](#configuration-options) are listed below.

### Using [`lazy.nvim`](https://github.com/folke/lazy.nvim)

```lua
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`](https://github.com/wbthomason/packer.nvim)

```lua
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:

```lua
{
-- 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`](https://github.com/epwalsh/pomo.nvim/blob/main/lua/pomo/notifier.lua) 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. The `time_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`:

```lua
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:

```lua
{ init = PrintNotifier.new, opts = {} }
```

## Integrations

### [nvim-notify](https://github.com/rcarriga/nvim-notify)

The "Default" notifier integrates seamlessly with `nvim-notify`, you just need to have `nvim-notify` installed.

### [lualine.nvim](https://github.com/nvim-lualine/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):

```lua
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",
},
},
}
```

[![lualine screenshot](https://github.com/epwalsh/pomo.nvim/assets/8812459/ff2beac8-a26f-421a-a5a6-cbeca73bfcf2)](https://github.com/epwalsh/pomo.nvim/assets/8812459/ff2beac8-a26f-421a-a5a6-cbeca73bfcf2)

### [telescope.nvim](https://github.com/nvim-telescope/telescope.nvim)

Pomo.nvim ships with a telescope extension for managing timers. Here's an example of mapping the keys `pt` to open the telescope picker for timers.

```lua
require("telescope").load_extension "pomodori"

vim.keymap.set("n", "pt", function()
require("telescope").extensions.pomodori.timers()
end, { desc = "Manage Pomodori Timers"})
```

## Contributing

Please see the [CONTRIBUTING](https://github.com/epwalsh/obsidian.nvim/blob/main/.github/CONTRIBUTING.md) guide from [obsidian.nvim](https://github.com/epwalsh/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! โค๏ธ

[![BuyMeACoffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-ffdd00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black)](https://www.buymeacoffee.com/epwalsh)