Skip to content

Commit 17e4a7f

Browse files
committed
feat: implementing filters
1 parent d4faf00 commit 17e4a7f

File tree

4 files changed

+138
-9
lines changed

4 files changed

+138
-9
lines changed

lua/ledger/config.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ local M = {}
33
--- @class ledger.Tui
44
--- @field enabled boolean
55
--- @field sections table<string, ledger.TuiSection>
6+
--- @field open_in_tab boolean
67

78
--- @class ledger.TuiFilter
89
--- @field flag string
@@ -171,6 +172,7 @@ local function get_default_config()
171172
},
172173
tui = {
173174
enabled = true,
175+
open_in_tab = true,
174176
sections = {
175177
["Show Balance"] = {
176178
command = "ledger --strict -f main.ledger bal",

lua/ledger/tui/init.lua

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,20 @@ LedgerTui.__index = LedgerTui
1515
local instance
1616

1717
function LedgerTui:setup()
18+
local config = require("ledger.config").get()
19+
1820
if self.running then
1921
print("ledger.nvim already has the tui open")
2022
return
2123
end
2224

2325
logger:info("initializing tui view")
2426
self.running = true
27+
28+
if config.tui.open_in_tab then
29+
vim.cmd("tabnew")
30+
end
31+
2532
self.layout:setup_windows()
2633
self.layout:setup_aucmds()
2734
self.reports:populate_reports()
@@ -30,7 +37,12 @@ end
3037

3138
function LedgerTui:shutdown()
3239
self.layout:restore_window_options()
33-
print("shutting down")
40+
self.layout:close_buffer(self.layout.reports_buf)
41+
self.layout:close_buffer(self.layout.help_buf)
42+
self.layout:close_buffer(self.layout.hint_buf)
43+
self.layout:close_buffer(self.layout.output_buf)
44+
self.layout:close_buffer(self.layout.filters_buf)
45+
self.running = false
3446
end
3547

3648
function LedgerTui:set_keymaps()

lua/ledger/tui/layout.lua

Lines changed: 84 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ local HL_GROUPS = {
1414
--- @field previous_signcolumn "no" | "yes"
1515
--- @field output_buf integer
1616
--- @field filters_buf integer
17+
--- @field applied_filters_buf integer
1718
--- @field reports_buf integer
1819
--- @field hint_buf integer
1920
--- @field help_buf integer
@@ -50,21 +51,33 @@ function LedgerTuiLayout.set_buffer_options()
5051
vim.bo.swapfile = false
5152
end
5253

54+
--- @param buffer integer
55+
function LedgerTuiLayout:close_buffer(buffer)
56+
if buffer == nil then
57+
return
58+
end
59+
60+
if vim.api.nvim_buf_is_valid(buffer) then
61+
vim.api.nvim_buf_delete(buffer, { force = true })
62+
end
63+
end
64+
5365
--- sets up all the windows for the tui layout, which consists
5466
--- of three buffers, one for the reports, one for the output
5567
--- and one for working with filters, which is supposed to look
5668
--- something like this:
5769
---
5870
--- ┌───┬───────────┬───┐
59-
--- │ │ │
60-
--- │ R │ O │ F │
61-
--- │ │ │
71+
--- │ │ │ F
72+
--- │ R │ O ├───┤
73+
--- │ │ │ A
6274
--- ├───┴───────────┴───┤
6375
--- │ HINT │
6476
--- └───────────────────┘
6577
--- R: Reports pane
6678
--- O: Outputs pane
6779
--- F: Filters pane
80+
--- A: Applied Filters pane
6881
function LedgerTuiLayout:setup_windows()
6982
vim.cmd("split")
7083
local hint_buf = vim.api.nvim_create_buf(false, true)
@@ -92,6 +105,12 @@ function LedgerTuiLayout:setup_windows()
92105
local filter_width = math.ceil(vim.o.columns * 0.15)
93106

94107
vim.cmd("vertical resize " .. filter_width)
108+
109+
local applied_filters_buf = vim.api.nvim_create_buf(false, true)
110+
vim.api.nvim_set_current_buf(applied_filters_buf)
111+
self.set_buffer_options()
112+
self:set_window_options()
113+
vim.cmd("horizontal resize " .. filter_width)
95114
vim.cmd("wincmd h")
96115
vim.cmd("wincmd h")
97116

@@ -105,6 +124,7 @@ function LedgerTuiLayout:setup_windows()
105124
vim.defer_fn(function()
106125
vim.api.nvim_set_option_value("modifiable", false, { buf = output_buf })
107126
vim.api.nvim_set_option_value("modifiable", false, { buf = filters_buf })
127+
vim.api.nvim_set_option_value("modifiable", false, { buf = applied_filters_buf })
108128
vim.api.nvim_set_option_value("modifiable", false, { buf = reports_buf })
109129
end, 100)
110130

@@ -113,6 +133,7 @@ function LedgerTuiLayout:setup_windows()
113133
self.output_buf = output_buf
114134
self.filters_buf = filters_buf
115135
self.reports_buf = reports_buf
136+
self.applied_filters_buf = applied_filters_buf
116137
self:setup_keymaps()
117138
end
118139

@@ -373,6 +394,57 @@ local function open_filter_input_popup()
373394

374395
vim.api.nvim_open_win(hint_buf, false, win_config(center_y + 3 + 1, center_x, 4, "Summary"))
375396
vim.api.nvim_open_win(input_buf, true, win_config(center_y, center_x, 1))
397+
398+
vim.api.nvim_create_autocmd({ "BufLeave" }, {
399+
group = layout.augroup,
400+
buffer = input_buf,
401+
callback = function()
402+
if vim.api.nvim_buf_is_valid(hint_buf) then
403+
vim.api.nvim_buf_delete(hint_buf, { force = true })
404+
end
405+
if vim.api.nvim_buf_is_valid(input_buf) then
406+
vim.api.nvim_buf_delete(input_buf, { force = true })
407+
end
408+
end,
409+
})
410+
411+
vim.api.nvim_buf_set_option(input_buf, "buftype", "acwrite")
412+
vim.api.nvim_buf_set_option(input_buf, "bufhidden", "wipe")
413+
vim.api.nvim_buf_set_option(input_buf, "swapfile", false)
414+
vim.api.nvim_buf_set_name(input_buf, "InputBuffer")
415+
416+
vim.api.nvim_create_autocmd({ "BufWriteCmd" }, {
417+
buffer = input_buf,
418+
callback = function()
419+
local lines = vim.api.nvim_buf_get_lines(input_buf, 0, -1, false)
420+
421+
if #lines > 0 then
422+
local reports = require("ledger.tui.reports").get()
423+
local layout = require("ledger.tui.layout").get()
424+
425+
local input = lines[1]
426+
if reports.filters[report_name] == nil then
427+
reports.filters[report_name] = { active = {} }
428+
end
429+
reports.filters[report_name].active[filter_name] = {
430+
flag = filter.flag,
431+
value = input,
432+
}
433+
logger:info("applying filter '" .. filter_name .. "' with input '" .. input .. "'")
434+
layout.focus_reports()
435+
reports:maybe_run_command()
436+
reports:populate_filters()
437+
layout:update_hint()
438+
end
439+
440+
if vim.api.nvim_buf_is_valid(input_buf) then
441+
vim.api.nvim_buf_delete(input_buf, { force = true })
442+
end
443+
if vim.api.nvim_buf_is_valid(hint_buf) then
444+
vim.api.nvim_buf_delete(hint_buf, { force = true })
445+
end
446+
end,
447+
})
376448
end
377449

378450
local function dismiss_hint()
@@ -382,8 +454,10 @@ local function dismiss_hint()
382454
vim.api.nvim_set_current_buf(layout.reports_buf)
383455
end
384456

385-
vim.api.nvim_buf_delete(layout.hint_buf, {})
386-
layout.hint_buf = -1
457+
if vim.api.nvim_buf_is_valid(layout.hint_buf) then
458+
vim.api.nvim_buf_delete(layout.hint_buf, {})
459+
layout.hint_buf = -1
460+
end
387461
end
388462

389463
local function focus_reports()
@@ -406,6 +480,10 @@ local function focus_reports()
406480
end
407481
end
408482

483+
function LedgerTuiLayout:focus_reports()
484+
focus_reports()
485+
end
486+
409487
local function focus_filters()
410488
local layout = require("ledger.tui.layout").get()
411489

@@ -445,6 +523,7 @@ function LedgerTuiLayout:setup_keymaps()
445523
set_buffer_maps(self.output_buf)
446524
set_buffer_maps(self.filters_buf)
447525
set_buffer_maps(self.hint_buf)
526+
-- set_buffer_maps(self.applied_filters_buf)
448527

449528
vim.api.nvim_buf_create_user_command(self.filters_buf, "OpenFilterInput", open_filter_input_popup, {})
450529
vim.api.nvim_buf_set_keymap(self.filters_buf, "n", "<CR>", ":OpenFilterInput<CR>", {})

lua/ledger/tui/reports.lua

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,16 @@ local logger = require("ledger.logger").get()
33

44
local M = {}
55

6+
--- @class ledger.TuiReportEntryFilter
7+
--- @field flag string
8+
--- @field value string
9+
10+
--- @class ledger.TuiReportEntry
11+
--- @field active table<string, ledger.TuiReportEntryFilter>
12+
613
--- @class ledger.TuiReports
714
--- @field layout ledger.TuiLayout
15+
--- @field filters table<string, ledger.TuiReportEntry>
816
local LedgerReports = {}
917
LedgerReports.__index = LedgerReports
1018

@@ -30,6 +38,17 @@ function LedgerReports:populate_filters()
3038
return
3139
end
3240
end
41+
42+
if self.filters[current_report] ~= nil then
43+
local filters = {}
44+
45+
for name, filter in pairs(self.filters[current_report].active) do
46+
local formatted = name .. " (" .. filter.flag .. ") " .. filter.value
47+
table.insert(filters, formatted)
48+
end
49+
50+
-- self.layout.set_buffer_content(self.layout.applied_filters_buf, filters)
51+
end
3352
end
3453

3554
function LedgerReports:populate_reports()
@@ -63,6 +82,21 @@ function LedgerReports:maybe_get_current_report()
6382
return true, row_content[1]
6483
end
6584

85+
--- @param name string
86+
--- @param command ledger.TuiSection
87+
--- @return string
88+
function LedgerReports:apply_filters(name, command)
89+
local command_string = command.command
90+
91+
if self.filters[name] then
92+
for _, filter in pairs(self.filters[name].active) do
93+
command_string = command_string .. " " .. filter.flag .. " " .. filter.value
94+
end
95+
end
96+
97+
return command_string
98+
end
99+
66100
function LedgerReports:maybe_run_command()
67101
local ok, current_report = self:maybe_get_current_report()
68102
if not ok then
@@ -72,9 +106,11 @@ function LedgerReports:maybe_run_command()
72106
for name, command in pairs(config.tui.sections) do
73107
if name == current_report then
74108
local cwd = require("ledger.files").cwd()
75-
logger:info('running command "' .. command.command)
76109

77-
local ok, pid = pcall(vim.system, vim.split(command.command, " "), { cwd = cwd })
110+
local command = self:apply_filters(name, command)
111+
logger:info('running command "' .. command)
112+
113+
local ok, pid = pcall(vim.system, vim.split(command, " "), { cwd = cwd })
78114
if not ok then
79115
logger:error("failed to run command")
80116
error("failed to run command")
@@ -89,7 +125,6 @@ function LedgerReports:maybe_run_command()
89125

90126
local output_splitted = vim.split(output, "\n")
91127
self.layout.set_buffer_content(self.layout.output_buf, output_splitted)
92-
93128
return
94129
end
95130
end
@@ -101,6 +136,7 @@ function M.setup(layout)
101136
if not instance then
102137
instance = setmetatable({
103138
layout = layout,
139+
filters = {},
104140
}, LedgerReports)
105141
end
106142
return instance

0 commit comments

Comments
 (0)