Skip to content

Commit

Permalink
docs: add type hints (#49)
Browse files Browse the repository at this point in the history
* feat(parsers): move all parsers to their own submodule (#43)

BREAKING CHANGE: Parser modules have been moved

Add `check` functions to all parser modules

* fix: Termux compatible `is_readable_directory` function (#42)

* feat(util): use test command to check directory

* fix: use single quotes in util/file.lua

* feat(util): add type hints and documentation, remove old function

* feat(parsers): move all parsers to their own submodule (#43)

BREAKING CHANGE: Parser modules have been moved

Add `check` functions to all parser modules

* feat(util): use old "readable directory" method when not in Termux

* docs: start adding type definitions

* feat: continue adding types

* docs: add even more types

* docs: change TODO lines to work with todo-comments.nvim

[todo-comments.nvim](https://music.youtube.com/watch?v=4LZjhJ-hfjc&si=KjafjlUP6rh3cOGt)

---------

Co-authored-by: Eamon <eamon.b.school@gmail.com>
  • Loading branch information
Agent-E11 and Eamon authored Jul 18, 2024
1 parent 0e4575f commit f51e230
Show file tree
Hide file tree
Showing 13 changed files with 117 additions and 47 deletions.
41 changes: 30 additions & 11 deletions lua/battery/battery.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,41 @@ local config = require('battery.config')
local parsers = require('battery.parsers')
local icons = require('battery.icons')

-- TODO check for icons and if not available fallback to text
-- TODO allow user to select no icons
-- TODO maybe autodetect icons?
-- TODO: check for icons and if not available fallback to text
-- TODO: allow user to select no icons
-- TODO: maybe autodetect icons?

local log = L.new({ plugin = 'battery' })

-- TODO maybe store the update time here?
-- TODO: maybe store the update time here?

---@class BatteryStatus
---@field percent_charge_remaining? integer
---@field battery_count? integer
---@field ac_power? boolean
---@field method? string
local battery_status = {
percent_charge_remaining = nil,
battery_count = nil,
ac_power = nil,
method = nil,
percent_charge_remaining = nil,
}

-- Gets the last updated battery information
-- TODO may add the ability to ask for it to be updated right now
---Gets the last updated battery information
---TODO: may add the ability to ask for it to be updated right now
---@return BatteryStatus
function M.get_battery_status()
return battery_status
end

-- This maps to a timer sequence number in the utils module so the user
-- can reload the battery module and we can detect the old job is still running.
---This maps to a timer sequence number in the utils module so the user
---can reload the battery module and we can detect the old job is still running.
---@type integer?
local timer = nil

---Select the battery info job to run based on platform and what programs
---are available
---@return (fun(battery_status: table): any)?
---@return (fun(battery_status: BatteryStatus): any)?
---@return string?
local function select_job()
for method, parser_module in pairs(parsers.parsers) do
Expand All @@ -46,7 +54,8 @@ local function select_job()
return nil, nil
end

-- This is used for the health check
---This is used for the health check
---@return string?
function M.get_method()
local method = battery_status.method
if method == nil then
Expand Down Expand Up @@ -100,6 +109,7 @@ local function start_timer()
log.debug('start timer seq no ' .. timer)
end

---@param user_opts Config
function M.setup(user_opts)
config.from_user_opts(user_opts)

Expand All @@ -113,6 +123,7 @@ function M.setup(user_opts)
start_timer()
end

---@return string
function M.get_status_line()
if battery_status.battery_count == nil then
return icons.specific.unknown
Expand All @@ -126,6 +137,14 @@ function M.get_status_line()
else
local ac_power = battery_status.ac_power
local battery_percent = battery_status.percent_charge_remaining
if not battery_percent then
log.error(
'battery_status.percent_charge_remaining is nil, \
there is probably something wrong with the current \
parser implementation.'
)
battery_percent = 100
end

local plug_icon = ''
if ac_power and config.current.show_plugged_icon then
Expand Down
15 changes: 13 additions & 2 deletions lua/battery/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,20 @@

local M = {}

-- Some future options
---@class Config
---@field update_rate_seconds integer
---@field show_status_when_no_battery boolean
---@field show_plugged_icon boolean
---@field show_unplugged_icon boolean
---@field show_percent boolean
---@field vertical_icons boolean
---@field multiple_battery_selection MultipleBatterySelection

-- TODO: Some future options
-- vertical_icons (if false show horizontal)
-- show_charging_battery_icons

---@type Config
local default_config = {
update_rate_seconds = 30,
show_status_when_no_battery = true,
Expand All @@ -18,7 +28,8 @@ local default_config = {

M.current = default_config

M.from_user_opts = function(user_opts)
---@param user_opts Config
function M.from_user_opts(user_opts)
M.current = user_opts and vim.tbl_deep_extend('force', default_config, user_opts) or default_config
end

Expand Down
1 change: 1 addition & 0 deletions lua/battery/health.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ local error = vim.health.error or vim.health.report_error

local B = require('battery.battery')

---@return boolean
local function check_method()
return B.get_method() ~= nil
end
Expand Down
5 changes: 4 additions & 1 deletion lua/battery/icons.lua
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ M.specific = {

---Convert percentage charge to icon given a table of icons
---and max charge for that icon

---@param p integer
---@param icon_table IconSet
---@return string
Expand All @@ -104,10 +103,14 @@ function M.icon_for_percentage(p, icon_table)
return '!'
end

---@param p integer
---@return string
function M.discharging_battery_icon_for_percent(p)
return M.icon_for_percentage(p, M.sets.plain)
end

---@param p integer
---@return string
function M.horizontal_battery_icon_for_percent(p)
return M.icon_for_percentage(p, M.sets.horizontal)
end
Expand Down
24 changes: 14 additions & 10 deletions lua/battery/parsers/acpi.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ local BC = require('util.chooser')
local config = require('battery.config')
local log = L.new({ plugin = 'battery' })

-- TODO would be nice to unit test the parser
-- TODO: would be nice to unit test the parser
--[[ Sample output:
Without ac power connected you see...
Expand All @@ -23,13 +23,15 @@ Battery 0: Charging, 47%, 01:09:53 until charged
]]
--

-- Parse the response from the battery info job and update
-- the battery status
-- To fix this issue I have removed the average battery calculation
-- and instead will report the first battery found. Users are finding
-- that their peripheral batteries are included by acpi which makes
-- the plugin useless.
-- https://github.com/justinhj/battery.nvim/issues/12
---Parse the response from the battery info job and update
---the battery status
---To fix this issue I have removed the average battery calculation
---and instead will report the first battery found. Users are finding
---that their peripheral batteries are included by acpi which makes
---the plugin useless.
---https://github.com/justinhj/battery.nvim/issues/12
---@param result string[]
---@param battery_status BatteryStatus
local function parse_acpi_battery_info(result, battery_status)
local count = 0
local ac_power = nil
Expand Down Expand Up @@ -65,8 +67,10 @@ local function parse_acpi_battery_info(result, battery_status)
end
end

-- Create a plenary job to get the battery info
-- battery_status is a table to store the results in
---Create a plenary job to get the battery info
---battery_status is a table to store the results in
---@param battery_status BatteryStatus
---@return unknown # Plenary job
function M.get_battery_info_job(battery_status)
return J:new({
command = 'acpi',
Expand Down
4 changes: 3 additions & 1 deletion lua/battery/parsers/init.lua
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
local M = {}

---@module 'battery.battery'

---@class ParserModule
---@field check fun(): boolean
---@field get_battery_info_job fun(battery_status: table): any
---@field get_battery_info_job fun(battery_status: BatteryStatus): any

---@type table<string, ParserModule>
M.parsers = {
Expand Down
14 changes: 9 additions & 5 deletions lua/battery/parsers/pmset.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ local get_battery_info_pmset_args = {
'ps',
}

-- TODO would be nice to unit test the parser
-- TODO: would be nice to unit test the parser
--[[ Sample output:
Without ac power connected you see...
Expand All @@ -26,8 +26,10 @@ Now drawing from 'AC Power'
]]
--

-- Parse the response from the battery info job and update
-- the battery status
---Parse the response from the battery info job and update
---the battery status
---@param result string[]
---@param battery_status BatteryStatus
local function parse_pmset_battery_info(result, battery_status)
local count = 0
local charge_total = 0
Expand Down Expand Up @@ -61,8 +63,10 @@ local function parse_pmset_battery_info(result, battery_status)
end
end

-- Create a plenary job to get the battery info
-- battery_status is a table to store the results in
---Create a plenary job to get the battery info
---battery_status is a table to store the results in
---@param battery_status BatteryStatus
---@return unknown # Plenary job
function M.get_battery_info_job(battery_status)
return J:new({
command = 'pmset',
Expand Down
12 changes: 8 additions & 4 deletions lua/battery/parsers/powershell.lua
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ local get_battery_info_powershell_command = {
Select-Object -Property EstimatedChargeRemaining,BatteryStatus)',
}

-- Parse the response json from the battery info job and update
-- the battery status
---Parse the response json from the battery info job and update
---the battery status
---@param result string[]
---@param battery_status BatteryStatus
local function parse_powershell_battery_info(result, battery_status)
-- Decode the json response into a list of batteries
local batteries = vim.json.decode(table.concat(result, ''))
Expand Down Expand Up @@ -68,8 +70,10 @@ local function parse_powershell_battery_info(result, battery_status)
end
end

-- Create a plenary job to get the battery info
-- battery_status is a table to store the results in
---Create a plenary job to get the battery info
---battery_status is a table to store the results in
---@param battery_status BatteryStatus
---@return unknown # Plenary job
function M.get_battery_info_job(battery_status)
return J:new({
command = 'powershell',
Expand Down
8 changes: 6 additions & 2 deletions lua/battery/parsers/powersupply.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ local status_to_ac_power = {
['unknown'] = false, -- We don't know, so assume false
}

-- Parse the response from the battery info job and update
-- the battery status
---Parse the response from the battery info job and update
---the battery status
---@param battery_paths string[]
---@param battery_status BatteryStatus
local function parse_powersupply_battery_info(battery_paths, battery_status)
local path_count = #battery_paths
local battery_count = 0
Expand Down Expand Up @@ -62,6 +64,8 @@ local function parse_powersupply_battery_info(battery_paths, battery_status)
end
end

---@param battery_status BatteryStatus
---@return unknown # Plenary job
function M.get_battery_info_job(battery_status)
return J:new({
-- Find symbolic links in /sys/class/power_supply that start with BAT
Expand Down
8 changes: 6 additions & 2 deletions lua/battery/parsers/termux-api.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ local L = require('plenary.log')

local log = L.new({ plugin = 'battery' })

---@param result string[]
---@param battery_status BatteryStatus
local function parse_termux_battery_info(result, battery_status)
local status = vim.json.decode(table.concat(result, ''))
log.debug(vim.inspect(status))
Expand All @@ -16,8 +18,10 @@ local function parse_termux_battery_info(result, battery_status)
log.debug(vim.inspect(battery_status))
end

-- Create a plenary job to get the battery info
-- battery_status is a table to store the results in
---Create a plenary job to get the battery info
---battery_status is a table to store the results in
---@param battery_status BatteryStatus
---@return unknown # Plenary job
function M.get_battery_info_job(battery_status)
return J:new({
command = 'termux-battery-status',
Expand Down
28 changes: 20 additions & 8 deletions lua/util/chooser.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
-- Handles choosing a battery from an array based on config options
local M = {}

---@param t number[]
---@return number
local function average(t)
local sum = 0
for _, v in pairs(t) do
Expand All @@ -10,14 +12,24 @@ local function average(t)
return sum / #t
end

-- Given a an array of battery percentages and a selection config
-- return the one that should be displayed
-- Valid values for multiple_battery_selection are
-- "max" or "maximum" chooses the largest one
-- 1,2,3 .. chooses the nth battery found (defaulting to the last found if there are not enough)
-- "avg" or "average" returns the average
-- invalid or nil config will default to 1, the first found battery
-- Given an empty list will return 0
---@alias MultipleBatterySelection
---| 'max'
---| 'maximum'
---| 'avg'
---| 'average'
---| integer

---Given an array of battery percentages and a selection config
---return the one that should be displayed
---Valid values for multiple_battery_selection are
--- "max" or "maximum" chooses the largest one
--- 1,2,3 .. chooses the nth battery found (defaulting to the last found if there are not enough)
--- "avg" or "average" returns the average.
---Invalid or nil config will default to 1, the first found battery.
---Given an empty list will return 0
---@param battery_percents integer[]
---@param multiple_battery_selection MultipleBatterySelection
---@return integer
function M.battery_chooser(battery_percents, multiple_battery_selection)
if type(battery_percents) ~= 'table' or battery_percents[1] == nil then
return 0
Expand Down
2 changes: 2 additions & 0 deletions lua/util/timers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ local M = {}

local timer_seq_num = 0

---@return integer
function M.get_current()
return timer_seq_num
end

---@return integer
function M.get_next()
timer_seq_num = timer_seq_num + 1
return timer_seq_num
Expand Down
2 changes: 1 addition & 1 deletion test/spec/battery_plugin/battery_spec.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
require('matcher_combinators.luassert')

describe('battery', function()
-- TODO test suite
-- TODO: test suite
end)

0 comments on commit f51e230

Please sign in to comment.