Skip to content

Commit 41bae5b

Browse files
authored
Fix wrong tag offset in agenda (#444)
closes #433
1 parent f959358 commit 41bae5b

File tree

6 files changed

+60
-47
lines changed

6 files changed

+60
-47
lines changed

lua/orgmode/agenda/init.lua

Lines changed: 23 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -25,49 +25,54 @@ function Agenda:new(opts)
2525
views = {},
2626
content = {},
2727
highlights = {},
28+
win_width = utils.winwidth(),
2829
}
2930
setmetatable(data, self)
3031
self.__index = self
3132
return data
3233
end
3334

34-
function Agenda:agenda(opts)
35-
local view = AgendaView:new(vim.tbl_deep_extend('force', opts or {}, {
35+
---@param View table
36+
---@param opts? table
37+
function Agenda:open_agenda_view(View, opts)
38+
self:open_window()
39+
self.win_width = utils.winwidth()
40+
local view = View:new(vim.tbl_deep_extend('force', opts or {}, {
3641
filters = self.filters,
42+
win_width = self.win_width,
3743
})):build()
3844
self.views = { view }
3945
return self:_render()
4046
end
4147

48+
function Agenda:agenda(opts)
49+
self:open_agenda_view(AgendaView, opts)
50+
end
51+
4252
-- TODO: Introduce searching ALL/DONE
4353
function Agenda:todos()
44-
local view = AgendaTodosView:new({ filters = self.filters }):build()
45-
self.views = { view }
46-
return self:_render()
54+
self:open_agenda_view(AgendaTodosView)
4755
end
4856

4957
function Agenda:search()
50-
local view = AgendaSearchView:new({ filters = self.filters }):build()
51-
self.views = { view }
52-
return self:_render()
58+
self:open_agenda_view(AgendaSearchView)
5359
end
5460

5561
function Agenda:tags(opts)
56-
local view = AgendaTagsView:new(vim.tbl_deep_extend('force', opts or {}, {
57-
filters = self.filters,
58-
})):build()
59-
self.views = { view }
60-
return self:_render()
62+
self:open_agenda_view(AgendaTagsView, opts)
6163
end
6264

6365
function Agenda:tags_todo()
6466
return self:tags({ todo_only = true })
6567
end
6668

69+
---@return number|nil window id
6770
function Agenda:open_window()
68-
local opened = self:is_opened()
69-
if opened then
70-
return opened
71+
-- if an agenda window is already open, return it
72+
for _, win in ipairs(vim.api.nvim_list_wins()) do
73+
if vim.api.nvim_buf_get_option(vim.api.nvim_win_get_buf(win), 'filetype') == 'orgagenda' then
74+
return win
75+
end
7176
end
7277

7378
utils.open_window('orgagenda', math.max(34, config.org_agenda_min_height), config.win_split_mode)
@@ -131,11 +136,8 @@ function Agenda:_render(skip_rebuild)
131136
utils.concat(self.highlights, view.highlights)
132137
end
133138
end
134-
local opened = self:is_opened()
135-
if not opened then
136-
opened = self:open_window()
137-
end
138-
vim.cmd(vim.fn.win_id2win(opened) .. 'wincmd w')
139+
local win = self:open_window()
140+
vim.cmd(vim.fn.win_id2win(win) .. 'wincmd w')
139141
if vim.w.org_window_split_mode == 'horizontal' then
140142
local win_height = math.max(math.min(34, #self.content), config.org_agenda_min_height)
141143
if vim.w.org_window_pos and vim.deep_equal(vim.fn.win_screenpos(0), vim.w.org_window_pos) then
@@ -180,15 +182,6 @@ function Agenda:redo(preserve_cursor_pos)
180182
end))
181183
end
182184

183-
function Agenda:is_opened()
184-
for _, win in ipairs(vim.api.nvim_list_wins()) do
185-
if vim.api.nvim_buf_get_option(vim.api.nvim_win_get_buf(win), 'filetype') == 'orgagenda' then
186-
return win
187-
end
188-
end
189-
return false
190-
end
191-
192185
function Agenda:advance_span(direction)
193186
return self:_call_view_and_render('advance_span', direction, vim.v.count1)
194187
end

lua/orgmode/agenda/views/agenda.lua

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ end
6464
---@field start_day string
6565
---@field header string
6666
---@field filters AgendaFilter
67+
---@field win_width number
6768
local AgendaView = {}
6869

6970
function AgendaView:new(opts)
@@ -81,7 +82,9 @@ function AgendaView:new(opts)
8182
start_on_weekday = opts.org_agenda_start_on_weekday or config.org_agenda_start_on_weekday,
8283
start_day = opts.org_agenda_start_day or config.org_agenda_start_day,
8384
header = opts.org_agenda_overriding_header,
85+
win_width = opts.win_width or utils.winwidth(),
8486
}
87+
8588
setmetatable(data, self)
8689
self.__index = self
8790
data:_set_date_range()
@@ -199,8 +202,13 @@ function AgendaView:build()
199202
local category_len = math.max(11, (longest_items.category + 1))
200203
local date_len = math.min(11, longest_items.label)
201204

205+
-- print(win_width)
206+
202207
for _, agenda_item in ipairs(agenda_items) do
203-
table.insert(content, AgendaView.build_agenda_item_content(agenda_item, category_len, date_len, #content))
208+
table.insert(
209+
content,
210+
AgendaView.build_agenda_item_content(agenda_item, category_len, date_len, #content, self.win_width)
211+
)
204212
end
205213
end
206214

@@ -267,7 +275,7 @@ end
267275

268276
---@param agenda_item AgendaItem
269277
---@return table
270-
function AgendaView.build_agenda_item_content(agenda_item, longest_category, longest_date, line_nr)
278+
function AgendaView.build_agenda_item_content(agenda_item, longest_category, longest_date, line_nr, win_width)
271279
local headline = agenda_item.headline
272280
local category = ' ' .. utils.pad_right(string.format('%s:', headline:get_category()), longest_category)
273281
local date = agenda_item.label
@@ -282,10 +290,9 @@ function AgendaView.build_agenda_item_content(agenda_item, longest_category, lon
282290
todo_keyword = todo_padding .. todo_keyword
283291
local line = string.format('%s%s%s %s', category, date, todo_keyword, headline.title)
284292
local todo_keyword_pos = string.format('%s%s%s', category, date, todo_padding):len()
285-
local winwidth = utils.winwidth()
286293
if #headline.tags > 0 then
287294
local tags_string = headline:tags_to_string()
288-
local padding_length = math.max(1, winwidth - vim.api.nvim_strwidth(line) - vim.api.nvim_strwidth(tags_string))
295+
local padding_length = math.max(1, win_width - vim.api.nvim_strwidth(line) - vim.api.nvim_strwidth(tags_string))
289296
local indent = string.rep(' ', padding_length)
290297
line = string.format('%s%s%s', line, indent, tags_string)
291298
end

lua/orgmode/agenda/views/search.lua

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ local AgendaFilter = require('orgmode.agenda.filter')
22
local AgendaTodosView = require('orgmode.agenda.views.todos')
33
local Files = require('orgmode.parser.files')
44
local Range = require('orgmode.parser.range')
5+
local utils = require('orgmode.utils')
56

67
---@class AgendaSearchView
78
---@field items table[]
@@ -10,6 +11,7 @@ local Range = require('orgmode.parser.range')
1011
---@field header string
1112
---@field search string
1213
---@field filters AgendaFilter
14+
---@field win_width number
1315
local AgendaSearchView = {}
1416

1517
function AgendaSearchView:new(opts)
@@ -21,6 +23,7 @@ function AgendaSearchView:new(opts)
2123
search = opts.search or '',
2224
filters = opts.filters or AgendaFilter:new(),
2325
header = opts.org_agenda_overriding_header,
26+
win_width = opts.win_width or utils.winwidth(),
2427
}
2528

2629
setmetatable(data, self)
@@ -51,7 +54,7 @@ function AgendaSearchView:build()
5154
}
5255

5356
self.active_view = 'search'
54-
AgendaTodosView.generate_view(self.items, self.content, self.filters)
57+
AgendaTodosView.generate_view(self.items, self.content, self.filters, self.win_width)
5558
return self
5659
end
5760

lua/orgmode/agenda/views/tags.lua

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ local utils = require('orgmode.utils')
1313
---@field search string
1414
---@field filters AgendaFilter
1515
---@field todo_only boolean
16+
---@field win_width number
1617
local AgendaTagsView = {}
1718

1819
function AgendaTagsView:new(opts)
@@ -25,6 +26,7 @@ function AgendaTagsView:new(opts)
2526
todo_only = opts.todo_only or false,
2627
filters = opts.filters or AgendaFilter:new(),
2728
header = opts.org_agenda_overriding_header,
29+
win_width = opts.win_width or utils.winwidth(),
2830
}
2931

3032
setmetatable(data, self)
@@ -59,7 +61,7 @@ function AgendaTagsView:build()
5961
}
6062

6163
self.active_view = self.todo_only and 'tags_todo' or 'tags'
62-
AgendaTodosView.generate_view(self.items, self.content, self.filters)
64+
AgendaTodosView.generate_view(self.items, self.content, self.filters, self.win_width)
6365

6466
return self
6567
end

lua/orgmode/agenda/views/todos.lua

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ end
2222
---@field header string
2323
---@field search string
2424
---@field filters AgendaFilter
25+
---@field win_width number
2526
local AgendaTodosView = {}
2627

2728
function AgendaTodosView:new(opts)
@@ -33,6 +34,7 @@ function AgendaTodosView:new(opts)
3334
search = opts.search or '',
3435
filters = opts.filters or AgendaFilter:new(),
3536
header = opts.org_agenda_overriding_header,
37+
win_width = opts.win_width or utils.winwidth(),
3638
}
3739

3840
setmetatable(data, self)
@@ -53,11 +55,11 @@ function AgendaTodosView:build()
5355
self.content = { { line_content = 'Global list of TODO items of type: ALL' } }
5456
self.highlights = {}
5557
self.active_view = 'todos'
56-
self.generate_view(self.items, self.content, self.filters)
58+
self.generate_view(self.items, self.content, self.filters, self.win_width)
5759
return self
5860
end
5961

60-
function AgendaTodosView.generate_view(items, content, filters)
62+
function AgendaTodosView.generate_view(items, content, filters, win_width)
6163
items = sort_todos(items)
6264
local offset = #content
6365
local longest_category = utils.reduce(items, function(acc, todo)
@@ -66,22 +68,21 @@ function AgendaTodosView.generate_view(items, content, filters)
6668

6769
for i, headline in ipairs(items) do
6870
if filters:matches(headline) then
69-
table.insert(content, AgendaTodosView.generate_todo_item(headline, longest_category, i + offset))
71+
table.insert(content, AgendaTodosView.generate_todo_item(headline, longest_category, i + offset, win_width))
7072
end
7173
end
7274

7375
return { items = items, content = content }
7476
end
7577

76-
function AgendaTodosView.generate_todo_item(headline, longest_category, line_nr)
78+
function AgendaTodosView.generate_todo_item(headline, longest_category, line_nr, win_width)
7779
local category = ' ' .. utils.pad_right(string.format('%s:', headline:get_category()), longest_category + 1)
7880
local todo_keyword = headline.todo_keyword.value
7981
local todo_keyword_padding = todo_keyword ~= '' and ' ' or ''
8082
local line = string.format(' %s%s%s %s', category, todo_keyword_padding, todo_keyword, headline.title)
81-
local winwidth = utils.winwidth()
8283
if #headline.tags > 0 then
8384
local tags_string = headline:tags_to_string()
84-
local padding_length = math.max(1, winwidth - vim.api.nvim_strwidth(line) - vim.api.nvim_strwidth(tags_string))
85+
local padding_length = math.max(1, win_width - vim.api.nvim_strwidth(line) - vim.api.nvim_strwidth(tags_string))
8586
local indent = string.rep(' ', padding_length)
8687
line = string.format('%s%s%s', line, indent, tags_string)
8788
end

lua/orgmode/utils/init.lua

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -476,12 +476,19 @@ end
476476
function utils.winwidth(winnr)
477477
winnr = winnr or 0
478478
local winwidth = vim.api.nvim_win_get_width(winnr)
479-
local window_numbers = vim.api.nvim_win_get_option(winnr, 'number')
480-
local window_relnumbers = vim.api.nvim_win_get_option(winnr, 'relativenumber')
481-
if window_numbers or window_relnumbers then
482-
winwidth = winwidth - vim.wo.numberwidth
479+
480+
local win_id
481+
if winnr == 0 then -- use current window
482+
win_id = vim.fn.win_getid()
483+
else
484+
win_id = vim.fn.win_getid(winnr)
483485
end
484-
return winwidth
486+
487+
local wininfo = vim.fn.getwininfo(win_id)[1]
488+
-- this encapsulates both signcolumn & numbercolumn (:h wininfo)
489+
local gutter_width = wininfo and wininfo.textoff or 0
490+
491+
return winwidth - gutter_width
485492
end
486493

487494
---@param name string

0 commit comments

Comments
 (0)