Modify Lualine in Neovim to Show Word Count and Reading Time
Even if you don't properly know Lua you can make modifications by looking at examples and using prior programming knowledge.
A while back I switched from Vim to Neovim with LazyVim. I haven’t written about that experience yet but I have been tweaking my config along the way.
I wanted a way to show the number of total words in text files and the estimated reading time along with adjusting both values if I have an active selection. Even if reading time not perfectly accurate, it’s a good gauge to get a rough idea how long a post will take to read.
I didn’t find a built-in component to display the information I wanted so I began to think, ok, what will be necessary to figure out how to do this? Is this going to be a massive pain or reasonably approachable? What it’s like diving into Lua script without really knowing it?
Here’s what I came up with and how I tackled it:
- Where do I want to display it?
- It can replace the clock which LazyVim shows by default on the bottom right
- Learn and customize how LazyVim displays Lualine sections
- Replace a section of Lualine with custom functionality
- Checked out the documentation on how each section is displayed
- Figure out how to count the words and estimate reading time in text files
- Googling how to do specific things in Lua script
Here’s a minimal version of the file committed up to my dotfiles. It focuses on the word count and reading time stats:
-- .config/nvim/lua/plugins/lualine.lua
local function get_wordcount()
local word_count = 0
if vim.fn.mode():find("[vV]") then
word_count = vim.fn.wordcount().visual_words
else
word_count = vim.fn.wordcount().words
end
return word_count
end
local function wordcount()
local label = "word"
local word_count = get_wordcount()
if word_count > 1 then
label = label .. "s"
end
return word_count .. " " .. label
end
local function readingtime()
-- 200 is about the average words read per minute.
return tostring(math.ceil(get_wordcount() / 200.0)) .. " min"
end
local function is_prose()
return vim.bo.filetype == "markdown" or vim.bo.filetype == "text"
end
return {
{
"nvim-lualine/lualine.nvim",
opts = {
sections = {
-- Disable the default clock and replace it with word stats.
lualine_z = {
{ wordcount, cond = is_prose },
{ readingtime, cond = is_prose },
},
},
},
},
}
The video below goes over the code in more detail.
# Demo Video
Timestamps
- 0:24 – Customize Neovim plugins?
- 1:07 – Replace a Lualine section
- 3:14 – Customize the output text
- 4:17 – Applying it to only text files
- 5:21 – Calculating the estimated reading time
- 6:42 – Get the total or selected word count
- 8:27 – Displaying the word count
- 9:09 – Lua script is pretty approachable
Will you be using this? Let me know below.