From d3806b3d3fef6eb7e044e59ab75335b1678d961d Mon Sep 17 00:00:00 2001 From: Harrison Cramer Date: Wed, 15 Nov 2023 20:24:45 -0500 Subject: [PATCH 01/14] Add info sidebar --- lua/gitlab/actions/summary.lua | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/lua/gitlab/actions/summary.lua b/lua/gitlab/actions/summary.lua index 4c8046c9..e3dfae8b 100644 --- a/lua/gitlab/actions/summary.lua +++ b/lua/gitlab/actions/summary.lua @@ -23,7 +23,7 @@ M.summary = function() return end - local layout, title_popup, description_popup = M.create_layout() + local layout, title_popup, description_popup, info_popup = M.create_layout() M.layout = layout M.layout_buf = layout.bufnr @@ -34,6 +34,7 @@ M.summary = function() M.layout_visible = false end + vim.api.nvim_set_current_win(description_popup.winid) local currentBuffer = vim.api.nvim_get_current_buf() local title = state.INFO.title local description = state.INFO.description @@ -84,7 +85,18 @@ local top_popup = { }, } -local bottom_popup = { +local left_popup = { + buf_options = { + filetype = "markdown", + }, + enter = true, + focusable = true, + border = { + style = "rounded", + }, +} + +local right_popup = { buf_options = { filetype = "markdown", }, @@ -98,27 +110,31 @@ local bottom_popup = { M.create_layout = function() local title_popup = Popup(top_popup) M.title_bufnr = title_popup.bufnr - local description_popup = Popup(bottom_popup) + local description_popup = Popup(left_popup) M.description_bufnr = description_popup.bufnr + local info_popup = Popup(right_popup) local layout = Layout( { - position = "50%", + position = "45%", relative = "editor", size = { - width = "90%", - height = "70%", + width = "92%", + height = "80%", }, }, Layout.Box({ Layout.Box(title_popup, { size = { height = 3 } }), - Layout.Box(description_popup, { size = "100%" }), + Layout.Box({ + Layout.Box(info_popup, { size = "25%" }), + Layout.Box(description_popup, { size = "75%" }), + }, { dir = "row", size = "100%" }), }, { dir = "col" }) ) layout:mount() - return layout, title_popup, description_popup + return layout, title_popup, description_popup, info_popup end return M From ff40cdb7554dc2e3534c54b5f3889a8f8a273b00 Mon Sep 17 00:00:00 2001 From: Harrison Cramer Date: Wed, 15 Nov 2023 21:13:17 -0500 Subject: [PATCH 02/14] =?UTF-8?q?Built=20datetime=20function,=20thanks=20C?= =?UTF-8?q?hatGPT=20=F0=9F=A5=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lua/gitlab/actions/summary.lua | 25 ++++++++++---- lua/gitlab/utils/init.lua | 62 ++++++++++++++++++++++++++++------ 2 files changed, 70 insertions(+), 17 deletions(-) diff --git a/lua/gitlab/actions/summary.lua b/lua/gitlab/actions/summary.lua index e3dfae8b..077fd41f 100644 --- a/lua/gitlab/actions/summary.lua +++ b/lua/gitlab/actions/summary.lua @@ -34,20 +34,20 @@ M.summary = function() M.layout_visible = false end - vim.api.nvim_set_current_win(description_popup.winid) - local currentBuffer = vim.api.nvim_get_current_buf() local title = state.INFO.title local description = state.INFO.description - local lines = {} + local info_lines = M.build_info_lines() + local description_lines = {} for line in description:gmatch("[^\n]+") do - table.insert(lines, line) - table.insert(lines, "") + table.insert(description_lines, line) + table.insert(description_lines, "") end vim.schedule(function() - vim.api.nvim_buf_set_lines(currentBuffer, 0, -1, false, lines) + vim.api.nvim_buf_set_lines(description_popup.bufnr, 0, -1, false, description_lines) vim.api.nvim_buf_set_lines(title_popup.bufnr, 0, -1, false, { title }) + vim.api.nvim_buf_set_lines(info_popup.bufnr, 0, -1, false, info_lines) state.set_popup_keymaps( description_popup, M.edit_summary, @@ -58,6 +58,19 @@ M.summary = function() end) end + +M.build_info_lines = function() + local info = state.INFO + return { + "Author: " .. info.author.name, + "Created At: " .. u.format_to_local(info.created_at), + "Merge Status: " .. info.detailed_merge_status, + "Draft: " .. (info.draft and "Yes" or "No"), + "Has Conflicts: " .. (info.has_conflicts and "Yes" or "No"), + "Assignees: " .. u.make_readable_list(info.assignees, "name"), + } +end + -- This function will PUT the new description to the Go server M.edit_summary = function() local description = u.get_buffer_text(M.description_bufnr) diff --git a/lua/gitlab/utils/init.lua b/lua/gitlab/utils/init.lua index abb3f01f..e707adcc 100644 --- a/lua/gitlab/utils/init.lua +++ b/lua/gitlab/utils/init.lua @@ -1,11 +1,11 @@ -local Job = require("plenary.job") -local M = {} +local Job = require("plenary.job") +local M = {} -M.notify = function(msg, lvl) +M.notify = function(msg, lvl) vim.notify("gitlab.nvim: " .. msg, lvl) end -M.get_colors_for_group = function(group) +M.get_colors_for_group = function(group) local normal_fg = vim.fn.synIDattr(vim.fn.synIDtrans((vim.fn.hlID(group))), "fg") local normal_bg = vim.fn.synIDattr(vim.fn.synIDtrans((vim.fn.hlID(group))), "bg") return { fg = normal_fg, bg = normal_bg } @@ -15,14 +15,14 @@ M.get_current_line_number = function() return vim.api.nvim_call_function("line", { "." }) end -M.is_windows = function() +M.is_windows = function() if vim.fn.has("win32") == 1 or vim.fn.has("win32unix") == 1 then return true end return false end -M.P = function(...) +M.P = function(...) local objects = {} for i = 1, select("#", ...) do local v = select(i, ...) @@ -33,21 +33,49 @@ M.P = function(...) return ... end -M.get_buffer_text = function(bufnr) +M.get_buffer_text = function(bufnr) local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false) local text = table.concat(lines, "\n") return text end -M.string_starts = function(str, start) +M.string_starts = function(str, start) return str:sub(1, #start) == start end -M.press_enter = function() +M.press_enter = function() vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("", false, true, true), "n", false) end -M.format_date = function(date_string) +function offset_to_seconds(offset) + local sign, hours, minutes = offset:match("([%+%-])(%d%d)(%d%d)") + print(sign, hours, minutes) + local offsetSeconds = tonumber(hours) * 3600 + tonumber(minutes) * 60 + if sign == "-" then + offsetSeconds = -offsetSeconds + end + return offsetSeconds +end + +M.format_to_local = function(date_string) + local year, month, day, hour, min, sec, _ms, tzOffset = date_string:match("(%d+)-(%d+)-(%d+)T(%d+):(%d+):(%d+).(%d+)Z") + local localTime = os.time({ + year = year, + month = month, + day = day, + hour = hour, + min = min, + sec = sec, + tzOffset = tzOffset, + }) + + local offset = vim.fn.strftime("%z") + local localTimestamp = localTime + offset_to_seconds(offset) + + return os.date("%m/%d/%Y at%l:%M %Z", localTimestamp) +end + +M.format_date = function(date_string) local date_table = os.date("!*t") local year, month, day, hour, min, sec = date_string:match("(%d+)-(%d+)-(%d+)T(%d+):(%d+):(%d+)") local date = os.time({ year = year, month = month, day = day, hour = hour, min = min, sec = sec }) @@ -81,6 +109,18 @@ M.format_date = function(date_string) end end +M.make_readable_list = function(list_of_tables, key) + local res = "" + for i, t in ipairs(list_of_tables) do + res = res .. t[key] + if i < #list_of_tables then + res = res .. ", " + end + end + return res +end + + M.jump_to_file = function(filename, line_number) if line_number == nil then line_number = 1 @@ -140,7 +180,7 @@ M.join = function(tbl, separator) -- Remove the trailing separator if separator ~= "" then - result = result:sub(1, -#separator - 1) + result = result:sub(1, - #separator - 1) end return result From 8eb071516260a5b830f1bd4d5501d39c2bb4a65c Mon Sep 17 00:00:00 2001 From: Harrison Cramer Date: Wed, 15 Nov 2023 21:43:35 -0500 Subject: [PATCH 03/14] Formatting content into description buffer --- lua/gitlab/actions/summary.lua | 50 ++++++++++++++++++++++++++-------- lua/gitlab/state.lua | 12 +++++++- 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/lua/gitlab/actions/summary.lua b/lua/gitlab/actions/summary.lua index 077fd41f..fbf1da48 100644 --- a/lua/gitlab/actions/summary.lua +++ b/lua/gitlab/actions/summary.lua @@ -48,6 +48,8 @@ M.summary = function() vim.api.nvim_buf_set_lines(description_popup.bufnr, 0, -1, false, description_lines) vim.api.nvim_buf_set_lines(title_popup.bufnr, 0, -1, false, { title }) vim.api.nvim_buf_set_lines(info_popup.bufnr, 0, -1, false, info_lines) + vim.api.nvim_set_option_value("modifiable", false, { buf = info_popup.bufnr }) + vim.api.nvim_set_option_value("readonly", false, { buf = info_popup.bufnr }) state.set_popup_keymaps( description_popup, M.edit_summary, @@ -58,17 +60,39 @@ M.summary = function() end) end - M.build_info_lines = function() local info = state.INFO - return { - "Author: " .. info.author.name, - "Created At: " .. u.format_to_local(info.created_at), - "Merge Status: " .. info.detailed_merge_status, - "Draft: " .. (info.draft and "Yes" or "No"), - "Has Conflicts: " .. (info.has_conflicts and "Yes" or "No"), - "Assignees: " .. u.make_readable_list(info.assignees, "name"), + local options = { + author = { title = "Author", content = info.author.name }, + created_at = { title = "Created At", content = u.format_to_local(info.created_at) }, + updated_at = { title = "Updated At", content = u.format_to_local(info.updated_at) }, + merge_status = { title = "Merge Status", content = info.detailed_merge_status }, + draft = { title = "Draft", content = (info.draft and "Yes" or "No") }, + conflicts = { title = "Has Conflicts", content = (info.has_conflicts and "Yes" or "No") }, + assignees = { title = "Assignees", content = u.make_readable_list(info.assignees, "name") }, + branch = { title = "Branch", content = info.source_branch }, } + + local longest_used = "" + for _, v in ipairs(state.settings.info) do + if string.len(v) > string.len(longest_used) then + longest_used = v + end + end + + local function row_offset(row) + local offset = string.len(longest_used) - string.len(row) + return string.rep(" ", offset + 5) + end + + local lines = { "" } + for _, v in ipairs(state.settings.info) do + local row = options[v] + local line = "* " .. row.title .. row_offset(row.title) .. row.content + table.insert(lines, line) + end + + return lines end -- This function will PUT the new description to the Go server @@ -92,9 +116,6 @@ local top_popup = { focusable = true, border = { style = "rounded", - text = { - top = "Merge Request", - }, }, } @@ -106,6 +127,9 @@ local left_popup = { focusable = true, border = { style = "rounded", + text = { + top = "Details", + }, }, } @@ -117,6 +141,9 @@ local right_popup = { focusable = true, border = { style = "rounded", + text = { + top = "Description", + }, }, } @@ -127,6 +154,7 @@ M.create_layout = function() M.description_bufnr = description_popup.bufnr local info_popup = Popup(right_popup) + -- TODO: Build layout depending on screen size local layout = Layout( { position = "45%", diff --git a/lua/gitlab/state.lua b/lua/gitlab/state.lua index 3ded1b2f..fd10369e 100644 --- a/lua/gitlab/state.lua +++ b/lua/gitlab/state.lua @@ -33,6 +33,16 @@ M.settings = { resolved = "✓", unresolved = "", }, + info = { + "author", + "created_at", + "updated_at", + "merge_status", + "draft", + "conflicts", + "assignees", + "branch", + }, discussion_sign_and_diagnostic = { skip_resolved_discussion = false, skip_old_revision_discussion = false, @@ -60,7 +70,7 @@ M.settings = { -- for namespace `gitlab_discussion`. See :h vim.diagnostic.config enabled = true, severity = vim.diagnostic.severity.INFO, - code = nil, -- see :h diagnostic-structure + code = nil, -- see :h diagnostic-structure display_opts = {}, -- this is dirrectly used as opts in vim.diagnostic.set, see :h vim.diagnostic.config. }, pipeline = { From 2ed159abff7dc0eaa9da4011c1a3eef5ae8bf3a2 Mon Sep 17 00:00:00 2001 From: Harrison Cramer Date: Wed, 15 Nov 2023 22:16:18 -0500 Subject: [PATCH 04/14] Adding more layout work --- example.lua | 37 +++++++++++++++++++++++++++ lua/gitlab/actions/summary.lua | 46 +++++++++++++++++++++++----------- lua/gitlab/state.lua | 20 +++++++++------ 3 files changed, 81 insertions(+), 22 deletions(-) create mode 100644 example.lua diff --git a/example.lua b/example.lua new file mode 100644 index 00000000..00cf9a1e --- /dev/null +++ b/example.lua @@ -0,0 +1,37 @@ +local Layout = require("nui.layout") +local Popup = require("nui.popup") + +local opts = { + buf_options = { + filetype = "markdown", + }, + focusable = true, + border = { + style = "rounded", + }, +} + + +local title_popup = Popup(opts) +local description_popup = Popup(opts) +local info_popup = Popup(opts) + +local layout = Layout( + { + position = "50%", + relative = "editor", + size = { + width = "95%", + height = "95%", + }, + }, + Layout.Box({ + Layout.Box(title_popup, { size = { height = 3 } }), + Layout.Box({ + Layout.Box(description_popup, { grow = 1 }), + Layout.Box(info_popup, { size = { height = 15 } }), + }, { dir = "col", size = "100%" }), + }, { dir = "col" }) +) + +layout:mount() diff --git a/lua/gitlab/actions/summary.lua b/lua/gitlab/actions/summary.lua index fbf1da48..2b4772c3 100644 --- a/lua/gitlab/actions/summary.lua +++ b/lua/gitlab/actions/summary.lua @@ -74,7 +74,7 @@ M.build_info_lines = function() } local longest_used = "" - for _, v in ipairs(state.settings.info) do + for _, v in ipairs(state.settings.info.fields) do if string.len(v) > string.len(longest_used) then longest_used = v end @@ -86,7 +86,7 @@ M.build_info_lines = function() end local lines = { "" } - for _, v in ipairs(state.settings.info) do + for _, v in ipairs(state.settings.info.fields) do local row = options[v] local line = "* " .. row.title .. row_offset(row.title) .. row.content table.insert(lines, line) @@ -154,24 +154,42 @@ M.create_layout = function() M.description_bufnr = description_popup.bufnr local info_popup = Popup(right_popup) - -- TODO: Build layout depending on screen size + local internal_layout + if (state.settings.info.enabled) then + if state.settings.info.horizontal then + internal_layout = Layout.Box({ + Layout.Box(title_popup, { size = { height = 3 } }), + Layout.Box({ + Layout.Box(info_popup, { size = "25%" }), + Layout.Box(description_popup, { size = "75%" }), + }, { dir = "row", size = "100%" }), + }, { dir = "col" }) + else + internal_layout = Layout.Box({ + Layout.Box(title_popup, { size = { height = 3 } }), + Layout.Box({ + Layout.Box(description_popup, { size = "75%" }), + Layout.Box(info_popup, { size = "25%" }), + }, { dir = "col", size = "100%" }), + }, { dir = "col" }) + end + else + internal_layout = Layout.Box({ + Layout.Box(title_popup, { size = { height = 3 } }), + Layout.Box(description_popup, { size = "100%" }), + }, { dir = "col" }) + end + local layout = Layout( { - position = "45%", + position = "50%", relative = "editor", size = { - width = "92%", - height = "80%", + width = "95%", + height = "95%", }, }, - Layout.Box({ - Layout.Box(title_popup, { size = { height = 3 } }), - Layout.Box({ - Layout.Box(info_popup, { size = "25%" }), - Layout.Box(description_popup, { size = "75%" }), - }, { dir = "row", size = "100%" }), - }, { dir = "col" }) - ) + internal_layout) layout:mount() diff --git a/lua/gitlab/state.lua b/lua/gitlab/state.lua index fd10369e..ba4b0492 100644 --- a/lua/gitlab/state.lua +++ b/lua/gitlab/state.lua @@ -34,14 +34,18 @@ M.settings = { unresolved = "", }, info = { - "author", - "created_at", - "updated_at", - "merge_status", - "draft", - "conflicts", - "assignees", - "branch", + enabled = true, + horizontal = false, + fields = { + "author", + "created_at", + "updated_at", + "merge_status", + "draft", + "conflicts", + "assignees", + "branch", + } }, discussion_sign_and_diagnostic = { skip_resolved_discussion = false, From 89b51f9ce359083fc8bab7780b3656de8fbce5e4 Mon Sep 17 00:00:00 2001 From: Harrison Cramer Date: Thu, 16 Nov 2023 08:33:25 -0500 Subject: [PATCH 05/14] Added more summary info logic --- lua/gitlab/actions/pipeline.lua | 8 +++++++- lua/gitlab/actions/summary.lua | 31 ++++++++++++++++++++++--------- lua/gitlab/state.lua | 3 ++- lua/gitlab/utils/init.lua | 17 ++++++++--------- 4 files changed, 39 insertions(+), 20 deletions(-) diff --git a/lua/gitlab/actions/pipeline.lua b/lua/gitlab/actions/pipeline.lua index 6ccce65a..451cc046 100644 --- a/lua/gitlab/actions/pipeline.lua +++ b/lua/gitlab/actions/pipeline.lua @@ -20,6 +20,12 @@ local function get_pipeline() return pipeline end +M.get_pipeline_status = function() + local pipeline = get_pipeline() + if pipeline == nil then return nil end + return string.format("%s (%s)", state.settings.pipeline[pipeline.status], pipeline.status) +end + -- The function will render the Pipeline state in a popup M.open = function() local pipeline = get_pipeline() @@ -44,7 +50,7 @@ M.open = function() local lines = {} u.switch_can_edit_buf(bufnr, true) - table.insert(lines, string.format("Status: %s (%s)", state.settings.pipeline[pipeline.status], pipeline.status)) + table.insert(lines, "Status: " .. M.get_pipeline_status()) table.insert(lines, "") table.insert(lines, string.format("Last Run: %s", u.format_date(pipeline.created_at))) table.insert(lines, string.format("Url: %s", pipeline.web_url)) diff --git a/lua/gitlab/actions/summary.lua b/lua/gitlab/actions/summary.lua index 2b4772c3..fb23618e 100644 --- a/lua/gitlab/actions/summary.lua +++ b/lua/gitlab/actions/summary.lua @@ -7,6 +7,8 @@ local job = require("gitlab.job") local u = require("gitlab.utils") local state = require("gitlab.state") local miscellaneous = require("gitlab.actions.miscellaneous") +local pipeline = require("gitlab.actions.pipeline") + local M = { layout_visible = false, layout = nil, @@ -63,32 +65,43 @@ end M.build_info_lines = function() local info = state.INFO local options = { - author = { title = "Author", content = info.author.name }, - created_at = { title = "Created At", content = u.format_to_local(info.created_at) }, - updated_at = { title = "Updated At", content = u.format_to_local(info.updated_at) }, - merge_status = { title = "Merge Status", content = info.detailed_merge_status }, + author = { title = "Author", content = '@' .. info.author.username .. " (" .. info.author.name .. ")" }, + created_at = { title = "Created", content = u.format_to_local(info.created_at) }, + updated_at = { title = "Updated", content = u.format_to_local(info.updated_at) }, + merge_status = { title = "Status", content = info.detailed_merge_status }, draft = { title = "Draft", content = (info.draft and "Yes" or "No") }, - conflicts = { title = "Has Conflicts", content = (info.has_conflicts and "Yes" or "No") }, + conflicts = { title = "Merge Conflicts", content = (info.has_conflicts and "Yes" or "No") }, assignees = { title = "Assignees", content = u.make_readable_list(info.assignees, "name") }, branch = { title = "Branch", content = info.source_branch }, + pipeline = { + title = "Pipeline Status:", + content = function() return pipeline.get_pipeline_status() end + } } local longest_used = "" for _, v in ipairs(state.settings.info.fields) do - if string.len(v) > string.len(longest_used) then - longest_used = v + local title = options[v].title + if string.len(title) > string.len(longest_used) then + longest_used = title end end local function row_offset(row) local offset = string.len(longest_used) - string.len(row) - return string.rep(" ", offset + 5) + return string.rep(" ", offset + 3) end local lines = { "" } for _, v in ipairs(state.settings.info.fields) do local row = options[v] - local line = "* " .. row.title .. row_offset(row.title) .. row.content + local line = "* " .. row.title .. row_offset(row.title) + if type(row.content) == 'function' then + local content = row.content() + if content ~= nil then line = line .. row.content() end + else + line = line .. row.content + end table.insert(lines, line) end diff --git a/lua/gitlab/state.lua b/lua/gitlab/state.lua index ba4b0492..911f35fe 100644 --- a/lua/gitlab/state.lua +++ b/lua/gitlab/state.lua @@ -35,7 +35,7 @@ M.settings = { }, info = { enabled = true, - horizontal = false, + horizontal = true, fields = { "author", "created_at", @@ -45,6 +45,7 @@ M.settings = { "conflicts", "assignees", "branch", + "pipeline", } }, discussion_sign_and_diagnostic = { diff --git a/lua/gitlab/utils/init.lua b/lua/gitlab/utils/init.lua index e707adcc..a2f792d0 100644 --- a/lua/gitlab/utils/init.lua +++ b/lua/gitlab/utils/init.lua @@ -47,17 +47,16 @@ M.press_enter = function() vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("", false, true, true), "n", false) end -function offset_to_seconds(offset) +M.offset_to_seconds = function(offset) local sign, hours, minutes = offset:match("([%+%-])(%d%d)(%d%d)") - print(sign, hours, minutes) - local offsetSeconds = tonumber(hours) * 3600 + tonumber(minutes) * 60 + local offset_in_seconds = tonumber(hours) * 3600 + tonumber(minutes) * 60 if sign == "-" then - offsetSeconds = -offsetSeconds + offset_in_seconds = -offset_in_seconds end - return offsetSeconds + return offset_in_seconds end -M.format_to_local = function(date_string) +M.format_to_local = function(date_string) local year, month, day, hour, min, sec, _ms, tzOffset = date_string:match("(%d+)-(%d+)-(%d+)T(%d+):(%d+):(%d+).(%d+)Z") local localTime = os.time({ year = year, @@ -70,12 +69,12 @@ M.format_to_local = function(date_string) }) local offset = vim.fn.strftime("%z") - local localTimestamp = localTime + offset_to_seconds(offset) + local localTimestamp = localTime + M.offset_to_seconds(offset) return os.date("%m/%d/%Y at%l:%M %Z", localTimestamp) end -M.format_date = function(date_string) +M.format_date = function(date_string) local date_table = os.date("!*t") local year, month, day, hour, min, sec = date_string:match("(%d+)-(%d+)-(%d+)T(%d+):(%d+):(%d+)") local date = os.time({ year = year, month = month, day = day, hour = hour, min = min, sec = sec }) @@ -109,7 +108,7 @@ M.format_date = function(date_string) end end -M.make_readable_list = function(list_of_tables, key) +M.make_readable_list = function(list_of_tables, key) local res = "" for i, t in ipairs(list_of_tables) do res = res .. t[key] From 22558e3418e8e9ceb98e7e48eb2db0e2bc53a23f Mon Sep 17 00:00:00 2001 From: Harrison Cramer Date: Thu, 16 Nov 2023 08:33:36 -0500 Subject: [PATCH 06/14] Formatting --- example.lua | 1 - lua/gitlab/actions/pipeline.lua | 4 +++- lua/gitlab/actions/summary.lua | 32 +++++++++++++++++--------------- lua/gitlab/state.lua | 4 ++-- lua/gitlab/utils/init.lua | 32 ++++++++++++++++---------------- 5 files changed, 38 insertions(+), 35 deletions(-) diff --git a/example.lua b/example.lua index 00cf9a1e..928a2dae 100644 --- a/example.lua +++ b/example.lua @@ -11,7 +11,6 @@ local opts = { }, } - local title_popup = Popup(opts) local description_popup = Popup(opts) local info_popup = Popup(opts) diff --git a/lua/gitlab/actions/pipeline.lua b/lua/gitlab/actions/pipeline.lua index 451cc046..9bbecf0c 100644 --- a/lua/gitlab/actions/pipeline.lua +++ b/lua/gitlab/actions/pipeline.lua @@ -22,7 +22,9 @@ end M.get_pipeline_status = function() local pipeline = get_pipeline() - if pipeline == nil then return nil end + if pipeline == nil then + return nil + end return string.format("%s (%s)", state.settings.pipeline[pipeline.status], pipeline.status) end diff --git a/lua/gitlab/actions/summary.lua b/lua/gitlab/actions/summary.lua index fb23618e..325647fe 100644 --- a/lua/gitlab/actions/summary.lua +++ b/lua/gitlab/actions/summary.lua @@ -65,7 +65,7 @@ end M.build_info_lines = function() local info = state.INFO local options = { - author = { title = "Author", content = '@' .. info.author.username .. " (" .. info.author.name .. ")" }, + author = { title = "Author", content = "@" .. info.author.username .. " (" .. info.author.name .. ")" }, created_at = { title = "Created", content = u.format_to_local(info.created_at) }, updated_at = { title = "Updated", content = u.format_to_local(info.updated_at) }, merge_status = { title = "Status", content = info.detailed_merge_status }, @@ -75,8 +75,10 @@ M.build_info_lines = function() branch = { title = "Branch", content = info.source_branch }, pipeline = { title = "Pipeline Status:", - content = function() return pipeline.get_pipeline_status() end - } + content = function() + return pipeline.get_pipeline_status() + end, + }, } local longest_used = "" @@ -96,9 +98,11 @@ M.build_info_lines = function() for _, v in ipairs(state.settings.info.fields) do local row = options[v] local line = "* " .. row.title .. row_offset(row.title) - if type(row.content) == 'function' then + if type(row.content) == "function" then local content = row.content() - if content ~= nil then line = line .. row.content() end + if content ~= nil then + line = line .. row.content() + end else line = line .. row.content end @@ -168,7 +172,7 @@ M.create_layout = function() local info_popup = Popup(right_popup) local internal_layout - if (state.settings.info.enabled) then + if state.settings.info.enabled then if state.settings.info.horizontal then internal_layout = Layout.Box({ Layout.Box(title_popup, { size = { height = 3 } }), @@ -193,16 +197,14 @@ M.create_layout = function() }, { dir = "col" }) end - local layout = Layout( - { - position = "50%", - relative = "editor", - size = { - width = "95%", - height = "95%", - }, + local layout = Layout({ + position = "50%", + relative = "editor", + size = { + width = "95%", + height = "95%", }, - internal_layout) + }, internal_layout) layout:mount() diff --git a/lua/gitlab/state.lua b/lua/gitlab/state.lua index 911f35fe..2593d8ec 100644 --- a/lua/gitlab/state.lua +++ b/lua/gitlab/state.lua @@ -46,7 +46,7 @@ M.settings = { "assignees", "branch", "pipeline", - } + }, }, discussion_sign_and_diagnostic = { skip_resolved_discussion = false, @@ -75,7 +75,7 @@ M.settings = { -- for namespace `gitlab_discussion`. See :h vim.diagnostic.config enabled = true, severity = vim.diagnostic.severity.INFO, - code = nil, -- see :h diagnostic-structure + code = nil, -- see :h diagnostic-structure display_opts = {}, -- this is dirrectly used as opts in vim.diagnostic.set, see :h vim.diagnostic.config. }, pipeline = { diff --git a/lua/gitlab/utils/init.lua b/lua/gitlab/utils/init.lua index a2f792d0..be56032f 100644 --- a/lua/gitlab/utils/init.lua +++ b/lua/gitlab/utils/init.lua @@ -1,11 +1,11 @@ -local Job = require("plenary.job") -local M = {} +local Job = require("plenary.job") +local M = {} -M.notify = function(msg, lvl) +M.notify = function(msg, lvl) vim.notify("gitlab.nvim: " .. msg, lvl) end -M.get_colors_for_group = function(group) +M.get_colors_for_group = function(group) local normal_fg = vim.fn.synIDattr(vim.fn.synIDtrans((vim.fn.hlID(group))), "fg") local normal_bg = vim.fn.synIDattr(vim.fn.synIDtrans((vim.fn.hlID(group))), "bg") return { fg = normal_fg, bg = normal_bg } @@ -15,14 +15,14 @@ M.get_current_line_number = function() return vim.api.nvim_call_function("line", { "." }) end -M.is_windows = function() +M.is_windows = function() if vim.fn.has("win32") == 1 or vim.fn.has("win32unix") == 1 then return true end return false end -M.P = function(...) +M.P = function(...) local objects = {} for i = 1, select("#", ...) do local v = select(i, ...) @@ -33,21 +33,21 @@ M.P = function(...) return ... end -M.get_buffer_text = function(bufnr) +M.get_buffer_text = function(bufnr) local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false) local text = table.concat(lines, "\n") return text end -M.string_starts = function(str, start) +M.string_starts = function(str, start) return str:sub(1, #start) == start end -M.press_enter = function() +M.press_enter = function() vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("", false, true, true), "n", false) end -M.offset_to_seconds = function(offset) +M.offset_to_seconds = function(offset) local sign, hours, minutes = offset:match("([%+%-])(%d%d)(%d%d)") local offset_in_seconds = tonumber(hours) * 3600 + tonumber(minutes) * 60 if sign == "-" then @@ -56,8 +56,9 @@ M.offset_to_seconds = function(offset) return offset_in_seconds end -M.format_to_local = function(date_string) - local year, month, day, hour, min, sec, _ms, tzOffset = date_string:match("(%d+)-(%d+)-(%d+)T(%d+):(%d+):(%d+).(%d+)Z") +M.format_to_local = function(date_string) + local year, month, day, hour, min, sec, _ms, tzOffset = + date_string:match("(%d+)-(%d+)-(%d+)T(%d+):(%d+):(%d+).(%d+)Z") local localTime = os.time({ year = year, month = month, @@ -74,7 +75,7 @@ M.format_to_local = function(date_string) return os.date("%m/%d/%Y at%l:%M %Z", localTimestamp) end -M.format_date = function(date_string) +M.format_date = function(date_string) local date_table = os.date("!*t") local year, month, day, hour, min, sec = date_string:match("(%d+)-(%d+)-(%d+)T(%d+):(%d+):(%d+)") local date = os.time({ year = year, month = month, day = day, hour = hour, min = min, sec = sec }) @@ -108,7 +109,7 @@ M.format_date = function(date_string) end end -M.make_readable_list = function(list_of_tables, key) +M.make_readable_list = function(list_of_tables, key) local res = "" for i, t in ipairs(list_of_tables) do res = res .. t[key] @@ -119,7 +120,6 @@ M.make_readable_list = function(list_of_tables, key) return res end - M.jump_to_file = function(filename, line_number) if line_number == nil then line_number = 1 @@ -179,7 +179,7 @@ M.join = function(tbl, separator) -- Remove the trailing separator if separator ~= "" then - result = result:sub(1, - #separator - 1) + result = result:sub(1, -#separator - 1) end return result From 5bac90fb39146030cfccedab6edc18e405713776 Mon Sep 17 00:00:00 2001 From: Harrison Cramer Date: Thu, 16 Nov 2023 08:34:02 -0500 Subject: [PATCH 07/14] Removed unused variable --- lua/gitlab/utils/init.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lua/gitlab/utils/init.lua b/lua/gitlab/utils/init.lua index be56032f..8a52bf18 100644 --- a/lua/gitlab/utils/init.lua +++ b/lua/gitlab/utils/init.lua @@ -57,8 +57,7 @@ M.offset_to_seconds = function(offset) end M.format_to_local = function(date_string) - local year, month, day, hour, min, sec, _ms, tzOffset = - date_string:match("(%d+)-(%d+)-(%d+)T(%d+):(%d+):(%d+).(%d+)Z") + local year, month, day, hour, min, sec, _, tzOffset = date_string:match("(%d+)-(%d+)-(%d+)T(%d+):(%d+):(%d+).(%d+)Z") local localTime = os.time({ year = year, month = month, From 501bff5c5d7ca398ca8bf3318dc6e10bafe0a2ca Mon Sep 17 00:00:00 2001 From: Harrison Cramer Date: Thu, 16 Nov 2023 08:58:31 -0500 Subject: [PATCH 08/14] Fixed up layout widths --- lua/gitlab/actions/summary.lua | 56 +++++++++++++++++++--------------- lua/gitlab/state.lua | 2 +- lua/gitlab/utils/init.lua | 10 ++++++ 3 files changed, 42 insertions(+), 26 deletions(-) diff --git a/lua/gitlab/actions/summary.lua b/lua/gitlab/actions/summary.lua index 325647fe..8469519d 100644 --- a/lua/gitlab/actions/summary.lua +++ b/lua/gitlab/actions/summary.lua @@ -25,7 +25,8 @@ M.summary = function() return end - local layout, title_popup, description_popup, info_popup = M.create_layout() + local info_lines = state.settings.info.enabled and M.build_info_lines() or nil + local layout, title_popup, description_popup, info_popup = M.create_layout(info_lines) M.layout = layout M.layout_buf = layout.bufnr @@ -38,7 +39,6 @@ M.summary = function() local title = state.INFO.title local description = state.INFO.description - local info_lines = M.build_info_lines() local description_lines = {} for line in description:gmatch("[^\n]+") do @@ -49,9 +49,13 @@ M.summary = function() vim.schedule(function() vim.api.nvim_buf_set_lines(description_popup.bufnr, 0, -1, false, description_lines) vim.api.nvim_buf_set_lines(title_popup.bufnr, 0, -1, false, { title }) - vim.api.nvim_buf_set_lines(info_popup.bufnr, 0, -1, false, info_lines) - vim.api.nvim_set_option_value("modifiable", false, { buf = info_popup.bufnr }) - vim.api.nvim_set_option_value("readonly", false, { buf = info_popup.bufnr }) + + if info_popup then + vim.api.nvim_buf_set_lines(info_popup.bufnr, 0, -1, false, info_lines) + vim.api.nvim_set_option_value("modifiable", false, { buf = info_popup.bufnr }) + vim.api.nvim_set_option_value("readonly", false, { buf = info_popup.bufnr }) + end + state.set_popup_keymaps( description_popup, M.edit_summary, @@ -59,6 +63,8 @@ M.summary = function() { cb = exit, action_before_close = true } ) state.set_popup_keymaps(title_popup, M.edit_summary, nil, { cb = exit, action_before_close = true }) + + vim.api.nvim_set_current_buf(description_popup.bufnr) end) end @@ -94,7 +100,7 @@ M.build_info_lines = function() return string.rep(" ", offset + 3) end - local lines = { "" } + local lines = {} for _, v in ipairs(state.settings.info.fields) do local row = options[v] local line = "* " .. row.title .. row_offset(row.title) @@ -126,7 +132,7 @@ M.edit_summary = function() end) end -local top_popup = { +local base_popup_settings = { buf_options = { filetype = "markdown", }, @@ -136,11 +142,10 @@ local top_popup = { }, } -local left_popup = { +local details_popup_settings = { buf_options = { filetype = "markdown", }, - enter = true, focusable = true, border = { style = "rounded", @@ -150,7 +155,7 @@ local left_popup = { }, } -local right_popup = { +local description_popup_settings = { buf_options = { filetype = "markdown", }, @@ -164,36 +169,37 @@ local right_popup = { }, } -M.create_layout = function() - local title_popup = Popup(top_popup) +M.create_layout = function(info_lines) + local title_popup = Popup(base_popup_settings) M.title_bufnr = title_popup.bufnr - local description_popup = Popup(left_popup) + local description_popup = Popup(description_popup_settings) M.description_bufnr = description_popup.bufnr - local info_popup = Popup(right_popup) + local details_popup local internal_layout if state.settings.info.enabled then + details_popup = Popup(details_popup_settings) if state.settings.info.horizontal then + local longest_line = u.get_longest_string(info_lines) + print(longest_line) internal_layout = Layout.Box({ - Layout.Box(title_popup, { size = { height = 3 } }), + Layout.Box(title_popup, { size = 3 }), Layout.Box({ - Layout.Box(info_popup, { size = "25%" }), - Layout.Box(description_popup, { size = "75%" }), + Layout.Box(details_popup, { size = longest_line + 3 }), + Layout.Box(description_popup, { grow = 1 }), }, { dir = "row", size = "100%" }), }, { dir = "col" }) else internal_layout = Layout.Box({ - Layout.Box(title_popup, { size = { height = 3 } }), - Layout.Box({ - Layout.Box(description_popup, { size = "75%" }), - Layout.Box(info_popup, { size = "25%" }), - }, { dir = "col", size = "100%" }), + Layout.Box(title_popup, { size = 3 }), + Layout.Box(description_popup, { grow = 1 }), + Layout.Box(details_popup, { size = #info_lines }), }, { dir = "col" }) end else internal_layout = Layout.Box({ - Layout.Box(title_popup, { size = { height = 3 } }), - Layout.Box(description_popup, { size = "100%" }), + Layout.Box(title_popup, { size = 3 }), + Layout.Box(description_popup, { grow = 1 }), }, { dir = "col" }) end @@ -208,7 +214,7 @@ M.create_layout = function() layout:mount() - return layout, title_popup, description_popup, info_popup + return layout, title_popup, description_popup, details_popup end return M diff --git a/lua/gitlab/state.lua b/lua/gitlab/state.lua index 2593d8ec..afe5cd06 100644 --- a/lua/gitlab/state.lua +++ b/lua/gitlab/state.lua @@ -35,7 +35,7 @@ M.settings = { }, info = { enabled = true, - horizontal = true, + horizontal = false, fields = { "author", "created_at", diff --git a/lua/gitlab/utils/init.lua b/lua/gitlab/utils/init.lua index 8a52bf18..3c630239 100644 --- a/lua/gitlab/utils/init.lua +++ b/lua/gitlab/utils/init.lua @@ -343,6 +343,16 @@ M.reverse = function(list) return rev end +M.get_longest_string = function(list) + local longest = 0 + for _, v in pairs(list) do + if string.len(v) > longest then + longest = string.len(v) + end + end + return longest +end + ---@class Hunk ---@field old_line integer ---@field old_range integer From e7e2781dbd7a2fa75a65141087c116866f83b8f9 Mon Sep 17 00:00:00 2001 From: Harrison Cramer Date: Thu, 16 Nov 2023 09:05:07 -0500 Subject: [PATCH 09/14] Slight refactor for readability --- lua/gitlab/actions/summary.lua | 107 ++++++++++++++++++--------------- 1 file changed, 59 insertions(+), 48 deletions(-) diff --git a/lua/gitlab/actions/summary.lua b/lua/gitlab/actions/summary.lua index 8469519d..ec36dff8 100644 --- a/lua/gitlab/actions/summary.lua +++ b/lua/gitlab/actions/summary.lua @@ -17,7 +17,46 @@ local M = { description_bufnr = nil, } --- The function will render the MR description in a popup +local title_popup_settings = { + buf_options = { + filetype = "markdown", + }, + focusable = true, + border = { + style = "rounded", + }, +} + +local details_popup_settings = { + buf_options = { + filetype = "markdown", + }, + focusable = true, + border = { + style = "rounded", + text = { + top = "Details", + }, + }, +} + +local description_popup_settings = { + buf_options = { + filetype = "markdown", + }, + enter = true, + focusable = true, + border = { + style = "rounded", + text = { + top = "Description", + }, + }, +} + +-- The function will render a popup containing the MR title and MR description, and optionally, +-- any additional metadata that the user wants. The title and description are editable and +-- can be changed via the local action keybinding, which also closes the popup M.summary = function() if M.layout_visible then M.layout:unmount() @@ -25,7 +64,10 @@ M.summary = function() return end + local title = state.INFO.title + local description_lines = M.build_description_lines() local info_lines = state.settings.info.enabled and M.build_info_lines() or nil + local layout, title_popup, description_popup, info_popup = M.create_layout(info_lines) M.layout = layout @@ -37,15 +79,6 @@ M.summary = function() M.layout_visible = false end - local title = state.INFO.title - local description = state.INFO.description - local description_lines = {} - - for line in description:gmatch("[^\n]+") do - table.insert(description_lines, line) - table.insert(description_lines, "") - end - vim.schedule(function() vim.api.nvim_buf_set_lines(description_popup.bufnr, 0, -1, false, description_lines) vim.api.nvim_buf_set_lines(title_popup.bufnr, 0, -1, false, { title }) @@ -68,6 +101,21 @@ M.summary = function() end) end +-- Builds a lua list of strings that contain the MR description +M.build_description_lines = function() + local description_lines = {} + + local description = state.INFO.description + for line in description:gmatch("[^\n]+") do + table.insert(description_lines, line) + table.insert(description_lines, "") + end + + return description_lines +end + +-- Builds a lua list of strings that contain metadata about the current MR. Only builds the +-- lines that users include in their state.settings.info.fields list. M.build_info_lines = function() local info = state.INFO local options = { @@ -132,45 +180,8 @@ M.edit_summary = function() end) end -local base_popup_settings = { - buf_options = { - filetype = "markdown", - }, - focusable = true, - border = { - style = "rounded", - }, -} - -local details_popup_settings = { - buf_options = { - filetype = "markdown", - }, - focusable = true, - border = { - style = "rounded", - text = { - top = "Details", - }, - }, -} - -local description_popup_settings = { - buf_options = { - filetype = "markdown", - }, - enter = true, - focusable = true, - border = { - style = "rounded", - text = { - top = "Description", - }, - }, -} - M.create_layout = function(info_lines) - local title_popup = Popup(base_popup_settings) + local title_popup = Popup(title_popup_settings) M.title_bufnr = title_popup.bufnr local description_popup = Popup(description_popup_settings) M.description_bufnr = description_popup.bufnr From 0203ba773233e7700ca2c88a8413e18d4ce3d65b Mon Sep 17 00:00:00 2001 From: Harrison Cramer Date: Thu, 16 Nov 2023 09:06:51 -0500 Subject: [PATCH 10/14] Adjusted horizontal height --- lua/gitlab/actions/summary.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/gitlab/actions/summary.lua b/lua/gitlab/actions/summary.lua index ec36dff8..d027f29a 100644 --- a/lua/gitlab/actions/summary.lua +++ b/lua/gitlab/actions/summary.lua @@ -204,7 +204,7 @@ M.create_layout = function(info_lines) internal_layout = Layout.Box({ Layout.Box(title_popup, { size = 3 }), Layout.Box(description_popup, { grow = 1 }), - Layout.Box(details_popup, { size = #info_lines }), + Layout.Box(details_popup, { size = #info_lines + 3 }), }, { dir = "col" }) end else From 858eebca936cbdb86608c59d74c0788131efeb5b Mon Sep 17 00:00:00 2001 From: Harrison Cramer Date: Thu, 16 Nov 2023 09:16:33 -0500 Subject: [PATCH 11/14] Adds missing space --- lua/gitlab/utils/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/gitlab/utils/init.lua b/lua/gitlab/utils/init.lua index 3c630239..063b1106 100644 --- a/lua/gitlab/utils/init.lua +++ b/lua/gitlab/utils/init.lua @@ -71,7 +71,7 @@ M.format_to_local = function(date_string) local offset = vim.fn.strftime("%z") local localTimestamp = localTime + M.offset_to_seconds(offset) - return os.date("%m/%d/%Y at%l:%M %Z", localTimestamp) + return os.date("%m/%d/%Y at %l:%M %Z", localTimestamp) end M.format_date = function(date_string) From e4ad440ed7640277e71aa22ce2d1d6c0e2d00a44 Mon Sep 17 00:00:00 2001 From: Harrison Cramer Date: Thu, 16 Nov 2023 10:01:02 -0500 Subject: [PATCH 12/14] Updates readme --- README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.md b/README.md index d9cda87c..316d5806 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,21 @@ require("gitlab").setup({ resolved = '✓', -- Symbol to show next to resolved discussions unresolved = '✖', -- Symbol to show next to unresolved discussions }, + info = { -- Show additional fields in the summary pane + enabled = true, + horizontal = false, -- Display metadata to the left of the summary rather than underneath + fields = { -- The fields listed here will be displayed, in whatever order you choose + "author", + "created_at", + "updated_at", + "merge_status", + "draft", + "conflicts", + "assignees", + "branch", + "pipeline", + }, + }, discussion_sign_and_diagnostic = { skip_resolved_discussion = false, skip_old_revision_discussion = true, @@ -203,6 +218,8 @@ require("gitlab").summary() After editing the description or title, you may save your changes via the `settings.popup.perform_action` keybinding. +By default this plugin will also show additional metadata about the MR in a separate pane underneath the description. This can be disabled, and these fields can be reordered or removed. Please see the `settings.info` section of the configuration. + ### Reviewing Diffs The `review` action will open a diff of the changes. You can leave comments using the `create_comment` action. In visual mode, add multiline comments with the `create_multiline_comment` command, and add suggested changes with the `create_comment_suggestion` command. From eb8feee7a386b85a61ba07d1f80233f161aab36d Mon Sep 17 00:00:00 2001 From: Harrison Cramer Date: Mon, 20 Nov 2023 18:51:21 -0500 Subject: [PATCH 13/14] Adds tests for date parsing functions --- lua/gitlab/actions/summary.lua | 4 ++-- lua/gitlab/spec/util_spec.lua | 34 ++++++++++++++++++++++++++++++++++ lua/gitlab/utils/init.lua | 10 +++++----- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/lua/gitlab/actions/summary.lua b/lua/gitlab/actions/summary.lua index d027f29a..0852034a 100644 --- a/lua/gitlab/actions/summary.lua +++ b/lua/gitlab/actions/summary.lua @@ -120,8 +120,8 @@ M.build_info_lines = function() local info = state.INFO local options = { author = { title = "Author", content = "@" .. info.author.username .. " (" .. info.author.name .. ")" }, - created_at = { title = "Created", content = u.format_to_local(info.created_at) }, - updated_at = { title = "Updated", content = u.format_to_local(info.updated_at) }, + created_at = { title = "Created", content = u.format_to_local(info.created_at, vim.fn.strftime("%z")) }, + updated_at = { title = "Updated", content = u.format_to_local(info.updated_at, vim.fn.strftime("%z")) }, merge_status = { title = "Status", content = info.detailed_merge_status }, draft = { title = "Draft", content = (info.draft and "Yes" or "No") }, conflicts = { title = "Merge Conflicts", content = (info.has_conflicts and "Yes" or "No") }, diff --git a/lua/gitlab/spec/util_spec.lua b/lua/gitlab/spec/util_spec.lua index 91f3aa38..b741e31c 100644 --- a/lua/gitlab/spec/util_spec.lua +++ b/lua/gitlab/spec/util_spec.lua @@ -178,4 +178,38 @@ describe("utils/init.lua", function() assert.are.same(got, want) end) end) + + describe("offset_to_seconds", function() + local tests = { + est = { '-0500', -18000 }, + pst = { '-0800', -28800 }, + gmt = { '+0000', 0 }, + cet = { '+0100', 360 }, + jst = { '+0900', 32400 }, + ist = { '+0530', 19800 }, + art = { '-0300', -10800 }, + aest = { '+1100', 39600 }, + mmt = { '+0630', 23400 }, + } + + for _, val in ipairs(tests) do + local got = u.offset_to_seconds(val[1]) + local want = val[2] + assert.are.same(got, want) + end + end) + + describe("format_to_local", function() + local tests = { + { '2023-10-28T16:25:09.482Z', '-0500', '10/28/2023 at 11:25' }, + { '2016-11-22T1:25:09.482Z', '-0500', '11/21/2016 at 20:25' }, + { '2016-11-22T1:25:09.482Z', '-0000', '11/22/2016 at 01:25' }, + { '2017-3-22T13:25:09.482Z', '+0700', '03/22/2017 at 20:25' }, + } + for _, val in ipairs(tests) do + local got = u.format_to_local(val[1], val[2]) + local want = val[3] + assert.are.same(got, want) + end + end) end) diff --git a/lua/gitlab/utils/init.lua b/lua/gitlab/utils/init.lua index bbccd09d..cb29a41f 100644 --- a/lua/gitlab/utils/init.lua +++ b/lua/gitlab/utils/init.lua @@ -152,7 +152,7 @@ M.reverse = function(list) end ---Returns the difference between a time offset and UTC time, in seconds ----@param offset string The offset to compare, e.g. -0500 +---@param offset string The offset to compare, e.g. -0500 for EST ---@return number M.offset_to_seconds = function(offset) local sign, hours, minutes = offset:match("([%+%-])(%d%d)(%d%d)") @@ -163,10 +163,11 @@ M.offset_to_seconds = function(offset) return offset_in_seconds end ----Converts a UTC timestamp to a human readable string +---Converts a UTC timestamp and offset to a human readable datestring ---@param date_string string The time stamp +---@param offset string The offset of the user's local time zone, e.g. -0500 for EST ---@return string -M.format_to_local = function(date_string) +M.format_to_local = function(date_string, offset) local year, month, day, hour, min, sec, _, tzOffset = date_string:match("(%d+)-(%d+)-(%d+)T(%d+):(%d+):(%d+).(%d+)Z") local localTime = os.time({ year = year, @@ -178,10 +179,9 @@ M.format_to_local = function(date_string) tzOffset = tzOffset, }) - local offset = vim.fn.strftime("%z") local localTimestamp = localTime + M.offset_to_seconds(offset) - return tostring(os.date("%m/%d/%Y at %l:%M %Z", localTimestamp)) + return tostring(os.date("%m/%d/%Y at %H:%M", localTimestamp)) end -- Returns a comma separated (human readable) list of values from a list of associative tables From 07a4eea6e0dbed0d5472e7cf2e76a170f4139b75 Mon Sep 17 00:00:00 2001 From: Harrison Cramer Date: Mon, 20 Nov 2023 18:51:55 -0500 Subject: [PATCH 14/14] Formatting --- lua/gitlab/spec/util_spec.lua | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/lua/gitlab/spec/util_spec.lua b/lua/gitlab/spec/util_spec.lua index b741e31c..079eff69 100644 --- a/lua/gitlab/spec/util_spec.lua +++ b/lua/gitlab/spec/util_spec.lua @@ -181,15 +181,15 @@ describe("utils/init.lua", function() describe("offset_to_seconds", function() local tests = { - est = { '-0500', -18000 }, - pst = { '-0800', -28800 }, - gmt = { '+0000', 0 }, - cet = { '+0100', 360 }, - jst = { '+0900', 32400 }, - ist = { '+0530', 19800 }, - art = { '-0300', -10800 }, - aest = { '+1100', 39600 }, - mmt = { '+0630', 23400 }, + est = { "-0500", -18000 }, + pst = { "-0800", -28800 }, + gmt = { "+0000", 0 }, + cet = { "+0100", 360 }, + jst = { "+0900", 32400 }, + ist = { "+0530", 19800 }, + art = { "-0300", -10800 }, + aest = { "+1100", 39600 }, + mmt = { "+0630", 23400 }, } for _, val in ipairs(tests) do @@ -201,10 +201,10 @@ describe("utils/init.lua", function() describe("format_to_local", function() local tests = { - { '2023-10-28T16:25:09.482Z', '-0500', '10/28/2023 at 11:25' }, - { '2016-11-22T1:25:09.482Z', '-0500', '11/21/2016 at 20:25' }, - { '2016-11-22T1:25:09.482Z', '-0000', '11/22/2016 at 01:25' }, - { '2017-3-22T13:25:09.482Z', '+0700', '03/22/2017 at 20:25' }, + { "2023-10-28T16:25:09.482Z", "-0500", "10/28/2023 at 11:25" }, + { "2016-11-22T1:25:09.482Z", "-0500", "11/21/2016 at 20:25" }, + { "2016-11-22T1:25:09.482Z", "-0000", "11/22/2016 at 01:25" }, + { "2017-3-22T13:25:09.482Z", "+0700", "03/22/2017 at 20:25" }, } for _, val in ipairs(tests) do local got = u.format_to_local(val[1], val[2])