Skip to content

Commit

Permalink
Merge pull request #12 from ptdewey/dev
Browse files Browse the repository at this point in the history
feat/refactor: add report filtering options, internal rpc args rework
  • Loading branch information
ptdewey authored Oct 20, 2024
2 parents 1c219bd + 3bc65c8 commit 4c87f25
Show file tree
Hide file tree
Showing 11 changed files with 364 additions and 102 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,4 @@ luac.out

## Extras
remote/pendulum-nvim
.luarc.json
57 changes: 47 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Pendulum was created to offer a privacy-focused alternative to cloud-based time
- Automatic Time Tracking: Logs time spent in each file along with the workding directory, file type, project name, and git branch if available.
- Activity Detection: Detects user activity based on cursor movements (on a timer) and buffer switches.
- Customizable Timeout: Configurable timeout to define user inactivity.
- Event Logging**: Tracks buffer events and idle periods, writing these to a CSV log for later analysis.
- Event Logging: Tracks buffer events and idle periods, writing these to a CSV log for later analysis.
- Report Generation: Generate reports from the log file to quickly view how time was spent on various projects (requires Go installed).

## Installation
Expand All @@ -25,6 +25,7 @@ Install Pendulum using your favorite package manager:
#### With Report Generation (Requires Go)

With lazy.nvim

```lua
{
"ptdewey/pendulum-nvim",
Expand All @@ -37,6 +38,7 @@ With lazy.nvim
#### Without Report Generation

With lazy.nvim

```lua
{
"ptdewey/pendulum-nvim",
Expand All @@ -52,13 +54,15 @@ With lazy.nvim

Pendulum can be customized with several options. Here is a table with configurable options:

| Option | Description | Default |
|---------------|---------------------------------------------------|--------------------------------|
| `log_file` | Path to the CSV file where logs should be written | `$HOME/pendulum-log.csv` |
| `timeout_len` | Length of time in seconds to determine inactivity | `180` |
| `timer_len` | Interval in seconds at which to check activity | `120` |
| `gen_reports` | Generate reports from the log file | `true` |
| `top_n` | Number of top entries to include in the report | `5` |
| Option | Description | Default |
|-----------------------------|---------------------------------------------------------|--------------------------|
| `log_file` | Path to the CSV file where logs should be written | `$HOME/pendulum-log.csv` |
| `timeout_len` | Length of time in seconds to determine inactivity | `180` |
| `timer_len` | Interval in seconds at which to check activity | `120` |
| `gen_reports` | Generate reports from the log file | `true` |
| `top_n` | Number of top entries to include in the report | `5` |
| `report_section_excludes` | Additional filters to be applied to each report section | `{}` |
| `report_excludes` | Show/Hide report sections. e.g `branch`, `directory`, `file`, `filetype`, `project` | `{}` |

Example configuration with custom options:

Expand All @@ -69,9 +73,40 @@ require('pendulum').setup({
timer_len = 60, -- 1 minute
gen_reports = true, -- Enable report generation (requires Go)
top_n = 10, -- Include top 10 entries in the report
report_section_excludes = {
"branch", -- Hide `branch` section of the report
-- Other options includes:
-- "directory",
-- "filetype",
-- "file",
-- "project",
},
report_excludes = {
filetype = {
-- This table controls what to be excluded from `filetype` section
"neo-tree", -- Exclude neo-tree filetype
},
file = {
-- This table controls what to be excluded from `file` section
"test.py", -- Exclude any test.py
".*.go", -- Exclude all Go files
}
project = {
-- This table controls what to be excluded from `project` section
"unknown_project" -- Exclude unknown (non-git) projects
},
directory = {
-- This table controls what to be excluded from `directory` section
},
branch = {
-- This table controls what to be excluded from `branch` section
},
},
})
```

**Note**: You can use regex to express the matching patterns within `report_excludes`.

## Usage

Once configured, Pendulum runs automatically in the background. It logs each specified event into the CSV file, which includes timestamps, file names, project names (from Git), and activity states.
Expand All @@ -92,7 +127,6 @@ To rebuild the Pendulum binary and generate reports, use the following commands:
The :PendulumRebuild command recompiles the Go binary, and the :Pendulum command generates the report based on the current log file.
I recommend rebuilding the binary after the plugin is updated.


If you do not want to install Go, report generation can be disabled by changing the `gen_reports` option to `false`. Disabling reports will cause the `Pendulum` and `PendulumRebuild` commands to not be created since they are exclusively used for the reports feature.

```lua
Expand All @@ -104,11 +138,14 @@ config = function()
end,
```

The report contents are customizable and section items or entire sections can be excluded from the report if desired. (See `report_excludes` and `report_section_excludes` options in setup)

## Future Ideas

These are some potential future ideas that would make for welcome contributions for anyone interested.

- Logging to SQLite database (optionally)
- Telescope integration
- Get stats for specified project, filetype, etc. (Could work well with Telescope)

- Nicer looking popup with custom highlight groups
- Alternative version of popup that uses a terminal buffer and [bubbletea](https://github.com/charmbracelet/bubbletea) (using the table component)
6 changes: 3 additions & 3 deletions lua/pendulum/handlers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -99,19 +99,19 @@ function M.setup(opts)
update_activity()

-- create autocommand group
vim.api.nvim_create_augroup("ActivityTracker", { clear = true })
vim.api.nvim_create_augroup("Pendulum", { clear = true })

-- define autocmd to update last active time
vim.api.nvim_create_autocmd({ "CursorMoved", "CursorMovedI" }, {
group = "ActivityTracker",
group = "Pendulum",
callback = function()
update_activity()
end,
})

-- define autocmd for logging events
vim.api.nvim_create_autocmd({ "BufEnter", "VimLeave" }, {
group = "ActivityTracker",
group = "Pendulum",
callback = function()
log_activity(true, opts)
end,
Expand Down
8 changes: 8 additions & 0 deletions lua/pendulum/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ local default_opts = {
timer_len = 120,
gen_reports = true,
top_n = 5,
report_excludes = {
branch = {},
directory = {},
file = {},
filetype = {},
project = {},
},
report_section_excludes = {},
}

---set up plugin autocommands with user options
Expand Down
26 changes: 19 additions & 7 deletions lua/pendulum/remote.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,30 @@ end

--- create plugin user commands to build binary and show report
local function setup_pendulum_commands()
vim.api.nvim_create_user_command("Pendulum", function()
vim.api.nvim_create_user_command("Pendulum", function(args)
chan = ensure_job()
if not chan or chan == 0 then
print("Error: Invalid channel")
return
end
local args =
{ options.log_file, "" .. options.timer_len, "" .. options.top_n }
local success, result = pcall(vim.fn.rpcrequest, chan, "pendulum", args)

local time_range = args.args or "all"

local command_args = {
log_file = options.log_file,
timer_len = options.timer_len,
top_n = options.top_n,
time_range = time_range,
report_excludes = options.report_excludes,
report_section_excludes = options.report_section_excludes,
}

local success, result =
pcall(vim.fn.rpcrequest, chan, "pendulum", command_args)
if not success then
print("RPC request failed: " .. result)
end
end, { nargs = 0 })
end, { nargs = "?" })

vim.api.nvim_create_user_command("PendulumRebuild", function()
print("Rebuilding Pendulum binary with Go...")
Expand All @@ -81,14 +92,14 @@ local function setup_pendulum_commands()
end, { nargs = 0 })
end



--- report generation setup (requires go)
---@param opts table
function M.setup(opts)
options.log_file = opts.log_file
options.timer_len = opts.timer_len
options.top_n = opts.top_n or 5
options.report_excludes = opts.report_excludes
options.report_section_excludes = opts.report_section_excludes

-- get plugin install path
plugin_path = debug.getinfo(1).source:sub(2):match("(.*/).*/.*/")
Expand Down Expand Up @@ -120,6 +131,7 @@ function M.setup(opts)
.. bin_path
.. ", attempting to compile with Go..."
)

local result =
os.execute("cd " .. plugin_path .. "remote" .. " && go build")
if result == 0 then
Expand Down
Loading

0 comments on commit 4c87f25

Please sign in to comment.