From 5eadb3cce8ab490222d12dfbb5c86372c89a5773 Mon Sep 17 00:00:00 2001 From: pysan3 Date: Sun, 29 Oct 2023 19:13:28 +0900 Subject: [PATCH] fix(calendar): display weekdays based on `nvim_strwidth` --- lua/neorg/core/utils.lua | 17 ++++++++ .../core/ui/calendar/views/monthly.lua | 39 +++++++------------ 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/lua/neorg/core/utils.lua b/lua/neorg/core/utils.lua index eaed5760c..3e4970862 100644 --- a/lua/neorg/core/utils.lua +++ b/lua/neorg/core/utils.lua @@ -206,4 +206,21 @@ function utils.wrap_dotrepeat(event_handler) end end +--- Truncate input str to fit inside the col_limit when displayed. Takes non-ascii chars into account. +---@param str string +---@param col_limit integer #str will be cut so that when displayed, the display length does not exceed limit +---@return string #substring of input str +function utils.truncate_by_cell(str, col_limit) + if str and str:len() == vim.api.nvim_strwidth(str) then + return vim.fn.strcharpart(str, 0, col_limit) + end + local short = vim.fn.strcharpart(str, 0, col_limit) + if vim.api.nvim_strwidth(short) > col_limit then + while vim.api.nvim_strwidth(short) > col_limit do + short = vim.fn.strcharpart(short, 0, vim.fn.strchars(short) - 1) + end + end + return short +end + return utils diff --git a/lua/neorg/modules/core/ui/calendar/views/monthly.lua b/lua/neorg/modules/core/ui/calendar/views/monthly.lua index 00e8454fb..77e94ff8d 100644 --- a/lua/neorg/modules/core/ui/calendar/views/monthly.lua +++ b/lua/neorg/modules/core/ui/calendar/views/monthly.lua @@ -1,5 +1,5 @@ local neorg = require("neorg.core") -local lib, log, modules = neorg.lib, neorg.log, neorg.modules +local lib, log, modules, utils = neorg.lib, neorg.log, neorg.modules, neorg.utils local module = modules.create("core.ui.calendar.views.monthly") @@ -111,9 +111,9 @@ module.private = { day = date.day, }) ) - - -- NOTE(vhyrro): This is just here to make the language server's type annotator happy. - assert(type(month_name) == "string") + ---@cast month_name string + -- local month_length = vim.api.nvim_strwidth(month_name) + local month_length = string.len(month_name) local weekday_banner_id = vim.api.nvim_buf_get_extmark_by_id( ui_info.buffer, @@ -129,8 +129,8 @@ module.private = { 4, weekday_banner_id[2] + math.ceil((weekday_banner_id[3].end_col - weekday_banner_id[2]) / 2) - - math.floor(month_name:len() / 2), - month_name:len(), + - math.floor(month_length / 2), + month_length, { { month_name, "@text.underline" } }, nil, { @@ -148,26 +148,17 @@ module.private = { -- This makes the weekdays retrieved locale dependent (which is what we want). local weekdays = {} local weekdays_string_length = 0 - for i = 1, 7 do - table.insert(weekdays, { - os.date( - "%a", - os.time({ - year = 2000, - month = 5, - day = i, - }) - ):sub(1, 2), - "@text.title", - }) - - if i ~= 7 then - table.insert(weekdays, { " " }) - end - - weekdays_string_length = weekdays_string_length + (i ~= 7 and 4 or 2) + local weekday = os.date("%a", os.time({ year = 2000, month = 5, day = i })) + ---@cast weekday string + local truncated = utils.truncate_by_cell(weekday, 2) + local truncated_length = vim.api.nvim_strwidth(truncated) + weekdays[#weekdays + 1] = { truncated, "@text.title" } + weekdays[#weekdays + 1] = { (" "):rep(4 - truncated_length) } + weekdays_string_length = truncated_length -- remember last day's length end + weekdays[#weekdays] = nil -- delete last padding + weekdays_string_length = weekdays_string_length + 4 * 6 -- This serves as the index of this week banner extmark inside the extmark table local absolute_offset = offset + (offset < 0 and (-offset * 100) or 0)