Skip to content

Commit

Permalink
Merge branch 'master' into checkout-picker
Browse files Browse the repository at this point in the history
  • Loading branch information
wd60622 authored Jan 22, 2025
2 parents e5e3d7c + f75ec17 commit 987aec9
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 13 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,9 @@ require"octo".setup({
close_review_tab = { lhs = "<C-c>", desc = "close review tab" },
toggle_viewed = { lhs = "<localleader><space>", desc = "toggle viewer viewed state" },
},
notification = {
read = { lhs = "<localleader>rn", desc = "mark notification as read" },
},
},
})
```
Expand Down Expand Up @@ -379,6 +382,7 @@ If no command is passed, the argument to `Octo` is treated as a URL from where a
| | close | Close the review window and return to the PR |
| actions | | Lists all available Octo actions |
| search | <query> | Search GitHub for issues and PRs matching the [query](https://docs.github.com/en/search-github/searching-on-github/searching-issues-and-pull-requests) |
| notification | list | Shows current unread notifications |

0. `[repo]`: If repo is not provided, it will be derived from `<cwd>/.git/config`.

Expand Down
11 changes: 11 additions & 0 deletions lua/octo/commands.lua
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,11 @@ function M.setup()
M.remove_project_card()
end,
},
notification = {
list = function()
picker.notifications()
end,
},
}

setmetatable(M.commands.pr, {
Expand All @@ -461,6 +466,12 @@ function M.setup()
end,
})

setmetatable(M.commands.notification, {
__call = function(_)
picker.notifications()
end,
})

local user_defined_commands = config.values.commands
M.commands = merge_tables(M.commands, user_defined_commands)
end
Expand Down
5 changes: 4 additions & 1 deletion lua/octo/config.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
local vim = vim
local M = {}

---@alias OctoMappingsWindow "issue" | "pull_request" | "review_thread" | "submit_win" | "review_diff" | "file_panel" | "repo"
---@alias OctoMappingsWindow "issue" | "pull_request" | "review_thread" | "submit_win" | "review_diff" | "file_panel" | "repo" | "notification"
---@alias OctoMappingsList { [string]: table}
---@alias OctoPickers "telescope" | "fzf-lua"
---@alias OctoSplit "right" | "left"
Expand Down Expand Up @@ -309,6 +309,9 @@ function M.get_default_values()
close_review_tab = { lhs = "<C-c>", desc = "close review tab" },
toggle_viewed = { lhs = "<localleader><space>", desc = "toggle viewer viewed state" },
},
notification = {
read = { lhs = "<localleader>nr", desc = "mark notification as read" },
},
repo = {},
},
}
Expand Down
1 change: 1 addition & 0 deletions lua/octo/pickers/fzf-lua/provider.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ M.picker = {
review_commits = require "octo.pickers.fzf-lua.pickers.review_commits",
search = require "octo.pickers.fzf-lua.pickers.search",
users = require "octo.pickers.fzf-lua.pickers.users",
notifications = M.not_implemented,
milestones = M.not_implemented,
}

Expand Down
60 changes: 60 additions & 0 deletions lua/octo/pickers/telescope/entry_maker.lua
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,66 @@ function M.gen_from_octo_actions(width)
end
end

function M.gen_from_notification()
local make_display = function(entry)
if not entry then
return nil
end

local icons = utils.icons

local columns = {
entry.obj.unread == true and icons.notification[entry.kind].unread or icons.notification[entry.kind].read,
{ "#" .. (entry.obj.subject.url:match "/(%d+)$" or "NA") },
{ string.sub(entry.obj.repository.full_name, 1, 50), "TelescopeResultsNumber" },
{ string.sub(entry.obj.subject.title, 1, 100) },
}

local displayer = entry_display.create {
separator = " ",
items = {
{ width = 2 },
{ width = 6 },
{ width = math.min(#entry.obj.repository.full_name, 50) },
{ width = math.min(#entry.obj.subject.title, 100) },
},
}

return displayer(columns)
end

return function(notification)
if not notification or vim.tbl_isempty(notification) then
return nil
end

notification.kind = (function(type)
if type == "Issue" then
return "issue"
elseif type == "PullRequest" then
return "pull_request"
end
return "unknown"
end)(notification.subject.type)

if notification.kind == "unknown" then
return nil
end
local ref = notification.subject.url:match "/(%d+)$"

return {
value = ref,
ordinal = notification.subject.title .. " " .. notification.repository.full_name .. " " .. ref,
display = make_display,
obj = notification,
repo = notification.repository.full_name,
kind = notification.kind,
thread_id = notification.id,
url = notification.subject.url,
}
end
end

function M.gen_from_issue_templates()
local make_display = function(entry)
if not entry then
Expand Down
64 changes: 64 additions & 0 deletions lua/octo/pickers/telescope/provider.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1182,6 +1182,69 @@ function M.actions(flattened_actions)
:find()
end

--
-- NOTIFICATIONS
--
local function mark_notification_read()
return function(prompt_bufnr)
local current_picker = action_state.get_current_picker(prompt_bufnr)
current_picker:delete_selection(function(selection)
local url = string.format("/notifications/threads/%s", selection.thread_id)
gh.run {
args = { "api", "--method", "PATCH", url },
headers = { "Accept: application/vnd.github.v3.diff" },
cb = function(_, stderr)
if stderr and not utils.is_blank(stderr) then
utils.error(stderr)
return
end
end,
}
end)
end
end

function M.notifications()
local cfg = octo_config.values
local opts = {
preview_title = "",
prompt_title = "Github Notifications",
results_title = "",
}

gh.run {
args = { "api", "--paginate", "/notifications" },
headers = { "Accept: application/vnd.github.v3.diff" },
cb = function(output, stderr)
if stderr and not utils.is_blank(stderr) then
utils.error(stderr)
elseif output then
local resp = vim.fn.json_decode(output)
pickers
.new(opts, {

finder = finders.new_table {
results = resp,
entry_maker = entry_maker.gen_from_notification(),
},
sorter = conf.generic_sorter(opts),
previewer = previewers.issue.new(opts),
attach_mappings = function(_, map)
action_set.select:replace(function(prompt_bufnr, type)
open(type)(prompt_bufnr)
end)
map("i", cfg.picker_config.mappings.open_in_browser.lhs, open_in_browser())
map("i", cfg.picker_config.mappings.copy_url.lhs, copy_url())
map("i", cfg.mappings.notification.read.lhs, mark_notification_read())
return true
end,
})
:find()
end
end,
}
end

--
-- Issue templates
--
Expand Down Expand Up @@ -1377,6 +1440,7 @@ M.picker = {
issue_templates = M.issue_templates,
issues = M.issues,
labels = M.select_label,
notifications = M.notifications,
pending_threads = M.pending_threads,
project_cards = M.select_project_card,
project_cards_v2 = M.not_implemented,
Expand Down
1 change: 1 addition & 0 deletions lua/octo/pickers/vim-clap/provider.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ M.picker = {
issue_templates = M.not_implemented,
issues = M.not_implemented,
labels = M.not_implemented,
notifications = M.not_implemented,
pending_threads = M.not_implemented,
project_cards = M.not_implemented,
project_cards_v2 = M.not_implemented,
Expand Down
34 changes: 22 additions & 12 deletions lua/octo/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1619,7 +1619,7 @@ end
--- @see octo.ui.colors for the available highlight groups

-- Symbols found with "Telescope symbols"
local icons = {
M.icons = {
issue = {
open = { "", "OctoGreen" },
closed = { "", "OctoPurple" },
Expand All @@ -1636,6 +1636,16 @@ local icons = {
answered = { "", "OctoGreen" },
closed = { "", "OctoRed" },
},
notification = {
issue = {
unread = { "", "OctoBlue" },
read = { "", "OctoGrey" },
},
pull_request = {
unread = { "", "OctoBlue" },
read = { "", "OctoGrey" },
},
},
unknown = { "" },
}

Expand All @@ -1650,39 +1660,39 @@ function M.get_icon(entry)
local stateReason = entry.obj.stateReason

if state == "OPEN" then
return icons.issue.open
return M.icons.issue.open
elseif state == "CLOSED" and stateReason == "NOT_PLANNED" then
return icons.issue.not_planned
return M.icons.issue.not_planned
elseif state == "CLOSED" then
return icons.issue.closed
return M.icons.issue.closed
end
elseif kind == "pull_request" then
local state = entry.obj.state
local isDraft = entry.obj.isDraft

if state == "MERGED" then
return icons.pull_request.merged
return M.icons.pull_request.merged
elseif state == "CLOSED" then
return icons.pull_request.closed
return M.icons.pull_request.closed
elseif isDraft then
return icons.pull_request.draft
return M.icons.pull_request.draft
elseif state == "OPEN" then
return icons.pull_request.open
return M.icons.pull_request.open
end
elseif kind == "discussion" then
local closed = entry.obj.closed
local isAnswered = entry.obj.isAnswered

if isAnswered ~= vim.NIL and isAnswered then
return icons.discussion.answered
return M.icons.discussion.answered
elseif not closed then
return icons.discussion.open
return M.icons.discussion.open
else
return icons.discussion.closed
return M.icons.discussion.closed
end
end

return icons.unknown
return M.icons.unknown
end

return M

0 comments on commit 987aec9

Please sign in to comment.