Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Termux compatible is_readable_directory function #42

Merged
merged 8 commits into from
Jul 11, 2024
40 changes: 16 additions & 24 deletions lua/battery/battery.lua
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
local M = {}

local L = require('plenary.log')
local powershell = require('battery.powershell')
local pmset = require('battery.pmset')
local powersupply = require('battery.powersupply')
local acpi = require('battery.acpi')
local config = require('battery.config')
local file = require('util.file')
local parsers = require('battery.parsers')
local icons = require('battery.icons')

-- TODO check for icons and if not available fallback to text
Expand All @@ -33,25 +29,21 @@ end
-- can reload the battery module and we can detect the old job is still running.
local timer = nil

-- Select the battery info job to run based on platform and what programs
-- are available
---Select the battery info job to run based on platform and what programs
---are available
---@return (fun(battery_status: table): any)?
---@return string?
local function select_job()
if vim.fn.has('win32') and vim.fn.executable('powershell') == 1 then
log.debug('windows powershell battery job')
return powershell.get_battery_info_job, 'powershell'
elseif vim.fn.executable('pmset') == 1 then
log.debug('pmset battery job')
return pmset.get_battery_info_job, 'pmset'
elseif file.is_readable_directory('/sys/class/power_supply/') then
log.debug('power_supply battery job')
return powersupply.get_battery_info_job, 'powersupply'
elseif vim.fn.executable('acpi') == 1 then
log.debug('acpi battery job')
return acpi.get_battery_info_job, 'acpi'
else
log.debug('no battery job')
return nil, 'none'
for method, parser_module in pairs(parsers.parsers) do
if parser_module.check() then
log.debug('using '..method..' method')
return parser_module.get_battery_info_job, method
end
end

-- No suitable parser was found.
log.debug('no parser found')
return nil, nil
end

-- This is used for the health check
Expand All @@ -68,7 +60,7 @@ local function timer_loop()
log.debug(timer .. ' is running now')
local job_function, method = select_job()
battery_status.method = method
log.debug('using method ' .. method)
log.debug('using method ' .. (method or 'nil'))

if job_function then
job_function(battery_status):start()
Expand Down Expand Up @@ -98,7 +90,7 @@ local function start_timer()
-- Always call the job immediately before starting the timed loop
local job_function, method = select_job()
battery_status.method = method
log.debug('using method ' .. method)
log.debug('using method: ' .. (method or 'nil'))

if job_function then
job_function(battery_status):start()
Expand Down
6 changes: 6 additions & 0 deletions lua/battery/acpi.lua → lua/battery/parsers/acpi.lua
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,10 @@ function M.get_battery_info_job(battery_status)
})
end

---Check if this parser would work in the current environment
---@return boolean
function M.check()
return vim.fn.executable('acpi') == 1
end

return M
15 changes: 15 additions & 0 deletions lua/battery/parsers/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
local M = {}

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

---@type table<string, ParserModule>
M.parsers = {
powershell = require('battery.parsers.powershell'),
pmset = require('battery.parsers.pmset'),
powersupply = require('battery.parsers.powersupply'),
acpi = require('battery.parsers.acpi'),
}

return M
6 changes: 6 additions & 0 deletions lua/battery/pmset.lua → lua/battery/parsers/pmset.lua
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,10 @@ function M.get_battery_info_job(battery_status)
})
end

---Check if this parser would work in the current environment
---@return boolean
function M.check()
return vim.fn.executable('pmset') == 1
end

return M
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,10 @@ function M.get_battery_info_job(battery_status)
})
end

---Check if this parser would work in the current environment
---@return boolean
function M.check()
return vim.fn.has('win32') and vim.fn.executable('powershell') == 1
end

return M
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ local J = require('plenary.job')
local L = require('plenary.log')
local BC = require('util.chooser')
local config = require('battery.config')
local file = require('util.file')
local log = L.new({ plugin = 'battery' })

-- Convert lowercase status from `/sys/class/power_supply/BAT?/status`
Expand Down Expand Up @@ -84,4 +85,10 @@ function M.get_battery_info_job(battery_status)
})
end

---Check if this parser would work in the current environment
---@return boolean
function M.check()
return file.is_readable_directory('/sys/class/power_supply/')
end

return M
21 changes: 18 additions & 3 deletions lua/util/file.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,24 @@ local M = {}

local bit = require('bit')

function M.is_readable_directory(file)
local s = vim.loop.fs_stat(file)
return s ~= nil and s.type == 'directory' and bit.band(s.mode, 4) == 4
---Check if there is a readable directory at the given file path.
---Warning: the `path` may be substituted onto the command line,
---so the input _must_ be trusted.
---@param path string
---@return boolean
function M.is_readable_directory(path)
if not os.getenv('TERMUX_VERSION') then
-- When not running in Termux
local s = vim.loop.fs_stat(path)
return (
s ~= nil -- File exists
and s.type == 'directory' -- File is a directory
and bit.band(s.mode, 4) == 4 -- File is readable (Minimum permissions: ------r--)
)
else
-- In Termux, use the `test` command
return os.execute('test -d \''..path..'\' && test -r \''..path..'\'') == 0
end
end

return M
Loading