Learn Docker With My Newest Course

Dive into Docker takes you from "What is Docker?" to confidently applying Docker to your own projects. It's packed with best practices and examples. Start Learning Docker →

Modify Lualine in Neovim to Show Word Count and Reading Time

modify-lualine-in-neovim-to-show-word-count-and-reading-time.jpg

Even if you don't properly know Lua you can make modifications by looking at examples and using prior programming knowledge.

Quick Jump:

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
  • 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.

Never Miss a Tip, Trick or Tutorial

Like you, I'm super protective of my inbox, so don't worry about getting spammed. You can expect a few emails per year (at most), and you can 1-click unsubscribe at any time. See what else you'll get too.



Comments