Feat: Add Basic Lua Test Suite (#115)
This MR adds a Lua test suite to the project, run via busted, and introduces tests for a number of the utility functions. Subsequent work will have to be done to test functions that use the `vim.api` scope and external packages to the plugin.
This commit is contained in:
committed by
GitHub
parent
1abc33d149
commit
88b9196a2e
13
.busted
Normal file
13
.busted
Normal file
@@ -0,0 +1,13 @@
|
||||
return {
|
||||
_all = {
|
||||
pattern = "_spec",
|
||||
lpath = "lua/?.lua;lua/?/init.lua",
|
||||
ROOT = {"lua/gitlab"},
|
||||
},
|
||||
default = {
|
||||
verbose = true
|
||||
},
|
||||
tests = {
|
||||
verbose = true,
|
||||
},
|
||||
}
|
||||
18
.github/workflows/go.yaml
vendored
18
.github/workflows/go.yaml
vendored
@@ -4,7 +4,23 @@ on:
|
||||
branches:
|
||||
- main
|
||||
jobs:
|
||||
build:
|
||||
go_lint:
|
||||
name: Lint Go 💅
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.19'
|
||||
cache: false
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v3
|
||||
with:
|
||||
version: v1.54
|
||||
only-new-issues: true
|
||||
go_test:
|
||||
name: Test Go 🧪
|
||||
needs: [go_lint]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
15
.github/workflows/lua-tests.yaml
vendored
Normal file
15
.github/workflows/lua-tests.yaml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
name: Lua Tests
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Run Busted
|
||||
uses: lunarmodules/busted@v2.2.0
|
||||
# with:
|
||||
# args: --run=api
|
||||
@@ -1,10 +1,11 @@
|
||||
name: Linting and Formatting
|
||||
name: Lua
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
jobs:
|
||||
luacheck:
|
||||
lua_lint:
|
||||
name: Lint Lua 💅
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -13,7 +14,8 @@ jobs:
|
||||
uses: lunarmodules/luacheck@v1
|
||||
with:
|
||||
args: --globals vim --no-max-line-length -- .
|
||||
stylua:
|
||||
lua_format:
|
||||
name: Formatting Lua 💅
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -24,16 +26,12 @@ jobs:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
version: latest
|
||||
args: --check .
|
||||
golangci:
|
||||
lua_test:
|
||||
name: Test Lua 🧪
|
||||
needs: [lua_format,lua_lint]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.19'
|
||||
cache: false
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v3
|
||||
with:
|
||||
version: v1.54
|
||||
only-new-issues: true
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Run Busted
|
||||
uses: lunarmodules/busted@v2.2.0
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,2 +1,5 @@
|
||||
bin
|
||||
.luarc.json
|
||||
/luarocks
|
||||
/lua_modules
|
||||
/.luarocks
|
||||
|
||||
1
logs
1
logs
@@ -1 +0,0 @@
|
||||
[DEBUG] GET https://gitlab.com/api/v4/merge_requests?source_branch=develop&state=opened
|
||||
@@ -892,7 +892,7 @@ end
|
||||
---@param note Note
|
||||
---@return string
|
||||
M.build_note_header = function(note)
|
||||
return "@" .. note.author.username .. " " .. u.format_date(note.created_at)
|
||||
return "@" .. note.author.username .. " " .. u.time_since(note.created_at)
|
||||
end
|
||||
|
||||
M.build_note_body = function(note, resolve_info)
|
||||
@@ -977,7 +977,7 @@ M.add_discussions_to_table = function(items)
|
||||
end
|
||||
|
||||
-- Creates the first node in the discussion, and attaches children
|
||||
local body = u.join_tables(root_text_nodes, discussion_children)
|
||||
local body = u.spread(root_text_nodes, discussion_children)
|
||||
local root_node = NuiTree.Node({
|
||||
text = root_text,
|
||||
is_note = true,
|
||||
|
||||
@@ -46,7 +46,7 @@ M.open = function()
|
||||
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, "")
|
||||
table.insert(lines, string.format("Last Run: %s", u.format_date(pipeline.created_at)))
|
||||
table.insert(lines, string.format("Last Run: %s", u.time_since(pipeline.created_at)))
|
||||
table.insert(lines, string.format("Url: %s", pipeline.web_url))
|
||||
table.insert(lines, string.format("Triggered By: %s", pipeline.source))
|
||||
|
||||
@@ -99,7 +99,7 @@ M.see_logs = function()
|
||||
local bufnr = vim.api.nvim_get_current_buf()
|
||||
local linnr = vim.api.nvim_win_get_cursor(0)[1]
|
||||
local text = u.get_line_content(bufnr, linnr)
|
||||
local last_word = u.get_last_chunk(text)
|
||||
local last_word = u.get_last_word(text)
|
||||
if last_word == nil then
|
||||
u.notify("Cannot find job name", vim.log.levels.ERROR)
|
||||
return
|
||||
|
||||
181
lua/gitlab/spec/util_spec.lua
Normal file
181
lua/gitlab/spec/util_spec.lua
Normal file
@@ -0,0 +1,181 @@
|
||||
describe("utils/init.lua", function()
|
||||
it("Loads package", function()
|
||||
local utils_ok, _ = pcall(require, "gitlab.utils")
|
||||
assert._is_true(utils_ok)
|
||||
end)
|
||||
|
||||
local _, u = pcall(require, "gitlab.utils")
|
||||
describe("extract", function()
|
||||
it("Extracts a single value", function()
|
||||
local t = { { one = 1, two = 2 }, { three = 3, four = 4 } }
|
||||
local got = u.extract(t, "one")
|
||||
local want = { 1 }
|
||||
assert.are.same(want, got)
|
||||
end)
|
||||
it("Returns nothing with empty table", function()
|
||||
local t = {}
|
||||
local got = u.extract(t, "one")
|
||||
local want = {}
|
||||
assert.are.same(want, got)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("get_last_word", function()
|
||||
it("Returns the last word in a sentence", function()
|
||||
local sentence = "Hello world!"
|
||||
local got = u.get_last_word(sentence)
|
||||
local want = "world!"
|
||||
assert.are.same(want, got)
|
||||
end)
|
||||
it("Returns an empty string without text", function()
|
||||
local sentence = ""
|
||||
local got = u.get_last_word(sentence)
|
||||
local want = ""
|
||||
assert.are.same(want, got)
|
||||
end)
|
||||
it("Returns whole string w/out divider", function()
|
||||
local sentence = "Thisdoesnothavebreaks"
|
||||
local got = u.get_last_word(sentence)
|
||||
assert.are.same(sentence, got)
|
||||
end)
|
||||
it("Returns correct word w/ different divider", function()
|
||||
local sentence = "this|uses|a|different|divider"
|
||||
local got = u.get_last_word(sentence, "|")
|
||||
local want = "divider"
|
||||
assert.are.same(want, got)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("format_date", function()
|
||||
local current_date = {
|
||||
day = 19,
|
||||
hour = 22,
|
||||
isdst = false,
|
||||
min = 0,
|
||||
month = 11,
|
||||
sec = 44,
|
||||
wday = 1,
|
||||
yday = 323,
|
||||
year = 2023,
|
||||
}
|
||||
it("Returns days since a valid UTC timestamp", function()
|
||||
local stamp = "2023-11-16T19:52:36.946Z"
|
||||
local got = u.time_since(stamp, current_date)
|
||||
local want = "3 days ago"
|
||||
assert.are.same(want, got)
|
||||
end)
|
||||
|
||||
it("Returns hours since a valid UTC timestamp", function()
|
||||
local stamp = "2023-11-19T19:52:36.946Z"
|
||||
local got = u.time_since(stamp, current_date)
|
||||
local want = "2 hours ago"
|
||||
assert.are.same(want, got)
|
||||
end)
|
||||
it("Returns readable time if > 1 year", function()
|
||||
local stamp = "2011-11-19T19:52:36.946Z"
|
||||
local got = u.time_since(stamp, current_date)
|
||||
local want = "November 19, 2011"
|
||||
assert.are.same(want, got)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("remove_first_value", function()
|
||||
it("Removes the first value correctly", function()
|
||||
local got = u.remove_first_value({ 1, 2 })
|
||||
local want = { 2 }
|
||||
assert.are.same(want, got)
|
||||
end)
|
||||
it("Handles a one-length list", function()
|
||||
local got = u.remove_first_value({ 1 })
|
||||
local want = {}
|
||||
assert.are.same(want, got)
|
||||
end)
|
||||
it("Handles a zero-length list", function()
|
||||
local got = u.remove_first_value({})
|
||||
local want = {}
|
||||
assert.are.same(want, got)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("table_size", function()
|
||||
it("Works for associative tables", function()
|
||||
local got = u.remove_first_value({ 1, 2 })
|
||||
local want = { 2 }
|
||||
assert.are.same(want, got)
|
||||
end)
|
||||
it("Handles a one-length list", function()
|
||||
local got = u.remove_first_value({ 1 })
|
||||
local want = {}
|
||||
assert.are.same(want, got)
|
||||
end)
|
||||
it("Handles a zero-length list", function()
|
||||
local got = u.remove_first_value({})
|
||||
local want = {}
|
||||
assert.are.same(want, got)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("contains", function()
|
||||
it("Finds a value in a list", function()
|
||||
local got = u.contains({ 1, 2 }, 1)
|
||||
assert._is_true(got)
|
||||
end)
|
||||
it("Handles missing values", function()
|
||||
local got = u.contains({ 1, 3, 4 }, 2)
|
||||
assert._is_false(got)
|
||||
end)
|
||||
it("Handles empty lists", function()
|
||||
local got = u.contains({}, 1)
|
||||
assert._is_false(got)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("reverse", function()
|
||||
it("Reverses the values in a list", function()
|
||||
local got = u.reverse({ 1, 2, 3, 4 })
|
||||
local want = { 4, 3, 2, 1 }
|
||||
assert.are.same(got, want)
|
||||
end)
|
||||
it("Handles single value", function()
|
||||
local got = u.reverse({ 1 })
|
||||
local want = { 1 }
|
||||
assert.are.same(got, want)
|
||||
end)
|
||||
it("Handles empty list", function()
|
||||
local got = u.reverse({})
|
||||
local want = {}
|
||||
assert.are.same(got, want)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("spread", function()
|
||||
it("Spreads the values", function()
|
||||
local t1 = { 1, 2, 3 }
|
||||
local t2 = { 4, 5, 6 }
|
||||
local got = u.spread(t1, t2)
|
||||
local want = { 1, 2, 3, 4, 5, 6 }
|
||||
assert.are.same(got, want)
|
||||
end)
|
||||
it("Handles an empty t1 table", function()
|
||||
local t1 = {}
|
||||
local t2 = { 4, 5, 6 }
|
||||
local got = u.spread(t1, t2)
|
||||
local want = { 4, 5, 6 }
|
||||
assert.are.same(got, want)
|
||||
end)
|
||||
it("Handles an empty t2 table", function()
|
||||
local t1 = { 1, 2, 3 }
|
||||
local t2 = {}
|
||||
local got = u.spread(t1, t2)
|
||||
local want = { 1, 2, 3 }
|
||||
assert.are.same(got, want)
|
||||
end)
|
||||
it("Handles both empty tables", function()
|
||||
local t1 = {}
|
||||
local t2 = {}
|
||||
local got = u.spread(t1, t2)
|
||||
local want = {}
|
||||
assert.are.same(got, want)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
@@ -122,7 +122,7 @@ M.merge_settings = function(args)
|
||||
end
|
||||
|
||||
M.print_settings = function()
|
||||
u.P(M.settings)
|
||||
vim.print(M.settings)
|
||||
end
|
||||
|
||||
-- First reads environment variables into the settings module,
|
||||
|
||||
@@ -1,6 +1,156 @@
|
||||
local Job = require("plenary.job")
|
||||
local M = {}
|
||||
|
||||
---Pulls out a list of values matching a given key from an array of tables
|
||||
---@param t table List of tables to search
|
||||
---@param key string Value to search for in the list
|
||||
---@return table List List of values that were extracted
|
||||
M.extract = function(t, key)
|
||||
local resultTable = {}
|
||||
for _, value in ipairs(t) do
|
||||
if value[key] then
|
||||
table.insert(resultTable, value[key])
|
||||
end
|
||||
end
|
||||
return resultTable
|
||||
end
|
||||
|
||||
---Get the last word in a sentence
|
||||
---@param sentence string The string to get the last word from
|
||||
---@param divider string The regex to split the sentence by, defaults to whitespace
|
||||
---@return string
|
||||
M.get_last_word = function(sentence, divider)
|
||||
local words = {}
|
||||
local pattern = string.format("([^%s]+)", divider or " ")
|
||||
for word in sentence:gmatch(pattern) do
|
||||
table.insert(words, word)
|
||||
end
|
||||
return words[#words] or ""
|
||||
end
|
||||
|
||||
---Merges two deeply nested tables together, overriding values from the first with conflicts
|
||||
---@param defaults table The first table
|
||||
---@param overrides table The second table
|
||||
---@return table
|
||||
M.merge = function(defaults, overrides)
|
||||
if type(defaults) == "table" and M.table_size(defaults) == 0 and type(overrides) == "table" then
|
||||
return overrides
|
||||
end
|
||||
return vim.tbl_deep_extend("force", defaults, overrides)
|
||||
end
|
||||
|
||||
---Pluralizes the input word, e.g. "3 cows"
|
||||
---@param num integer The count of the item/word
|
||||
---@param word string The word to pluralize
|
||||
---@return string
|
||||
local function pluralize(num, word)
|
||||
return num .. string.format(" %s", word) .. ((num > 1 or num <= 0) and "s" or "")
|
||||
end
|
||||
|
||||
--- Provides a human readable time since a given ISO date string
|
||||
---@param date_string string -- The ISO time stamp to compare with the current time
|
||||
---@return string
|
||||
M.time_since = function(date_string, current_date_table)
|
||||
local dt = current_date_table or 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 })
|
||||
|
||||
local current_date = os.time({
|
||||
year = dt.year,
|
||||
month = dt.month,
|
||||
day = dt.day,
|
||||
hour = dt.hour,
|
||||
min = dt.min,
|
||||
sec = dt.sec,
|
||||
})
|
||||
|
||||
local time_diff = current_date - date
|
||||
|
||||
if time_diff < 60 then
|
||||
return pluralize(time_diff, "second") .. " ago"
|
||||
elseif time_diff < 3600 then
|
||||
return pluralize(math.floor(time_diff / 60), "minute") .. " ago"
|
||||
elseif time_diff < 86400 then
|
||||
return pluralize(math.floor(time_diff / 3600), "hour") .. " ago"
|
||||
elseif time_diff < 2592000 then
|
||||
return pluralize(math.floor(time_diff / 86400), "day") .. " ago"
|
||||
else
|
||||
local formatted_date = os.date("%B %e, %Y", date)
|
||||
return tostring(formatted_date)
|
||||
end
|
||||
end
|
||||
|
||||
---Removes the first value from a list and returns the new, smaller list
|
||||
---@param tbl table The table
|
||||
---@return table
|
||||
M.remove_first_value = function(tbl)
|
||||
local sliced_list = {}
|
||||
if M.table_size(tbl) <= 1 then
|
||||
return sliced_list
|
||||
end
|
||||
for i = 2, #tbl do
|
||||
table.insert(sliced_list, tbl[i])
|
||||
end
|
||||
|
||||
return sliced_list
|
||||
end
|
||||
|
||||
---Spreads all the values from t2 into t1
|
||||
---@param t1 table The first table (gets the values)
|
||||
---@param t2 table The second table
|
||||
---@return table
|
||||
M.spread = function(t1, t2)
|
||||
for _, value in ipairs(t2) do
|
||||
table.insert(t1, value)
|
||||
end
|
||||
|
||||
return t1
|
||||
end
|
||||
|
||||
---Returns the number of keys or values in a table
|
||||
---@param t table The table to count
|
||||
---@return integer
|
||||
M.table_size = function(t)
|
||||
local count = 0
|
||||
for _ in pairs(t) do
|
||||
count = count + 1
|
||||
end
|
||||
return count
|
||||
end
|
||||
|
||||
---Returns whether a given value is in a list or not
|
||||
---@param list table The list to search
|
||||
---@return boolean
|
||||
M.contains = function(list, search_value)
|
||||
for _, value in pairs(list) do
|
||||
if value == search_value then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
---Trims whitespace from a string
|
||||
---@param s string The string to trim
|
||||
---@return string
|
||||
M.trim = function(s)
|
||||
local res = s:gsub("^%s+", ""):gsub("%s+$", "")
|
||||
return res
|
||||
end
|
||||
|
||||
-- Reverses the order of elements in a list
|
||||
---@param list table The list to reverse
|
||||
---@return table
|
||||
M.reverse = function(list)
|
||||
if #list == 0 then
|
||||
return list
|
||||
end
|
||||
local rev = {}
|
||||
for i = #list, 1, -1 do
|
||||
rev[#rev + 1] = list[i]
|
||||
end
|
||||
return rev
|
||||
end
|
||||
|
||||
M.notify = function(msg, lvl)
|
||||
vim.notify("gitlab.nvim: " .. msg, lvl)
|
||||
end
|
||||
@@ -22,65 +172,12 @@ M.is_windows = function()
|
||||
return false
|
||||
end
|
||||
|
||||
M.P = function(...)
|
||||
local objects = {}
|
||||
for i = 1, select("#", ...) do
|
||||
local v = select(i, ...)
|
||||
table.insert(objects, vim.inspect(v))
|
||||
end
|
||||
|
||||
print(table.concat(objects, "\n"))
|
||||
return ...
|
||||
end
|
||||
|
||||
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)
|
||||
return str:sub(1, #start) == start
|
||||
end
|
||||
|
||||
M.press_enter = function()
|
||||
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("<CR>", false, true, true), "n", false)
|
||||
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 })
|
||||
|
||||
local current_date = os.time({
|
||||
year = date_table.year,
|
||||
month = date_table.month,
|
||||
day = date_table.day,
|
||||
hour = date_table.hour,
|
||||
min = date_table.min,
|
||||
sec = date_table.sec,
|
||||
})
|
||||
|
||||
local time_diff = current_date - date
|
||||
|
||||
local function pluralize(num, word)
|
||||
return num .. string.format(" %s", word) .. (num > 1 and "s" or "") .. " ago"
|
||||
end
|
||||
|
||||
if time_diff < 60 then
|
||||
return pluralize(time_diff, "second")
|
||||
elseif time_diff < 3600 then
|
||||
return pluralize(math.floor(time_diff / 60), "minute")
|
||||
elseif time_diff < 86400 then
|
||||
return pluralize(math.floor(time_diff / 3600), "hour")
|
||||
elseif time_diff < 2592000 then
|
||||
return pluralize(math.floor(time_diff / 86400), "day")
|
||||
else
|
||||
local formatted_date = os.date("%A, %B %e", date)
|
||||
return formatted_date
|
||||
end
|
||||
end
|
||||
|
||||
M.jump_to_file = function(filename, line_number)
|
||||
if line_number == nil then
|
||||
line_number = 1
|
||||
@@ -123,38 +220,6 @@ M.create_popup_state = function(title, width, height)
|
||||
}
|
||||
end
|
||||
|
||||
M.merge = function(defaults, overrides)
|
||||
if type(defaults) == "table" and M.table_size(defaults) == 0 and type(overrides) == "table" then
|
||||
return overrides
|
||||
end
|
||||
return vim.tbl_deep_extend("force", defaults, overrides)
|
||||
end
|
||||
|
||||
M.join = function(tbl, separator)
|
||||
separator = separator or " "
|
||||
|
||||
local result = ""
|
||||
for _, value in pairs(tbl) do
|
||||
result = result .. tostring(value) .. separator
|
||||
end
|
||||
|
||||
-- Remove the trailing separator
|
||||
if separator ~= "" then
|
||||
result = result:sub(1, -#separator - 1)
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
M.remove_first_value = function(tbl)
|
||||
local sliced_table = {}
|
||||
for i = 2, #tbl do
|
||||
table.insert(sliced_table, tbl[i])
|
||||
end
|
||||
|
||||
return sliced_table
|
||||
end
|
||||
|
||||
M.read_file = function(file_path)
|
||||
local file = io.open(file_path, "r")
|
||||
if file == nil then
|
||||
@@ -180,41 +245,6 @@ M.uuid = function()
|
||||
end)
|
||||
end
|
||||
|
||||
M.join_tables = function(table1, table2)
|
||||
for _, value in ipairs(table2) do
|
||||
table.insert(table1, value)
|
||||
end
|
||||
|
||||
return table1
|
||||
end
|
||||
|
||||
M.table_size = function(t)
|
||||
local count = 0
|
||||
for _ in pairs(t) do
|
||||
count = count + 1
|
||||
end
|
||||
return count
|
||||
end
|
||||
|
||||
M.contains = function(array, search_value)
|
||||
for _, value in ipairs(array) do
|
||||
if value == search_value then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
M.extract = function(t, property)
|
||||
local resultTable = {}
|
||||
for _, value in ipairs(t) do
|
||||
if value[property] then
|
||||
table.insert(resultTable, value[property])
|
||||
end
|
||||
end
|
||||
return resultTable
|
||||
end
|
||||
|
||||
M.remove_last_chunk = function(sentence)
|
||||
local words = {}
|
||||
for word in sentence:gmatch("%S+") do
|
||||
@@ -225,26 +255,6 @@ M.remove_last_chunk = function(sentence)
|
||||
return sentence_without_last
|
||||
end
|
||||
|
||||
M.get_first_chunk = function(sentence, divider)
|
||||
local words = {}
|
||||
for word in sentence:gmatch(divider or "%S+") do
|
||||
table.insert(words, word)
|
||||
end
|
||||
return words[1]
|
||||
end
|
||||
|
||||
M.get_last_chunk = function(sentence, divider)
|
||||
local words = {}
|
||||
for word in sentence:gmatch(divider or "%S+") do
|
||||
table.insert(words, word)
|
||||
end
|
||||
return words[#words]
|
||||
end
|
||||
|
||||
M.trim = function(s)
|
||||
return s:gsub("^%s+", ""):gsub("%s+$", "")
|
||||
end
|
||||
|
||||
M.get_line_content = function(bufnr, start)
|
||||
local current_buffer = vim.api.nvim_get_current_buf()
|
||||
local lines = vim.api.nvim_buf_get_lines(bufnr ~= nil and bufnr or current_buffer, start - 1, start, false)
|
||||
@@ -297,14 +307,6 @@ M.list_files_in_folder = function(folder_path)
|
||||
return result
|
||||
end
|
||||
|
||||
M.reverse = function(list)
|
||||
local rev = {}
|
||||
for i = #list, 1, -1 do
|
||||
rev[#rev + 1] = list[i]
|
||||
end
|
||||
return rev
|
||||
end
|
||||
|
||||
---@class Hunk
|
||||
---@field old_line integer
|
||||
---@field old_range integer
|
||||
@@ -318,6 +320,8 @@ end
|
||||
M.parse_hunk_headers = function(file_path, base_branch)
|
||||
local hunks = {}
|
||||
|
||||
local Job = require("plenary.job")
|
||||
|
||||
local diff_job = Job:new({
|
||||
command = "git",
|
||||
args = { "diff", "--minimal", "--unified=0", "--no-color", base_branch, "--", file_path },
|
||||
@@ -430,7 +434,7 @@ M.get_lines_from_hunks = function(hunks, target_line, is_new)
|
||||
end
|
||||
|
||||
---Check if current mode is visual mode
|
||||
---@return boolean true if current mode is visual mode
|
||||
---@return boolean is_visual true if current mode is visual mode
|
||||
M.check_visual_mode = function()
|
||||
local mode = vim.api.nvim_get_mode().mode
|
||||
if mode ~= "v" and mode ~= "V" then
|
||||
@@ -442,7 +446,7 @@ end
|
||||
|
||||
---Return start line and end line of visual selection.
|
||||
---Exists visual mode in order to access marks "<" , ">"
|
||||
---@return integer,integer start line and end line
|
||||
---@return integer start,integer end Start line and end line
|
||||
M.get_visual_selection_boundaries = function()
|
||||
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("<Esc>", false, true, true), "nx", false)
|
||||
local start_line = vim.api.nvim_buf_get_mark(0, "<")[1]
|
||||
|
||||
8
todo.md
8
todo.md
@@ -1,8 +0,0 @@
|
||||
## Todo
|
||||
|
||||
- Screenshot folder in config (where the images will be kept)
|
||||
- Within the Summary view, you can call the add_summary_image() command
|
||||
- This command will open a UI picker to choose the file
|
||||
- When you choose the file, we pass that file path to an API endpoint which uploads
|
||||
the file and returns the JSON in the API here (https://docs.gitlab.com/ee/api/projects.html#upload-a-file)
|
||||
- Then we write that into the Summary buffer at the current cursor
|
||||
Reference in New Issue
Block a user