1+ local Actions = require (" snacks.gh.actions" )
12local Api = require (" snacks.gh.api" )
2- local Actions = require (" snacks.gh.actions" ).actions
33
44local M = {}
55
@@ -8,15 +8,15 @@ M.actions = setmetatable({}, {
88if type (k )~= " string" then
99return
1010end
11- if not Actions [k ]then
11+ if not Actions . actions [k ]then
1212return nil
1313end
1414--- @type snacks.picker.Action
1515local action = {
16- desc = Actions [k ].desc ,
16+ desc = Actions . actions [k ].desc ,
1717action = function (picker ,item ,action )
1818--- @diagnostic disable-next-line : param-type-mismatch
19- return Actions [k ].action (item , {
19+ return Actions . actions [k ].action (item , {
2020picker = picker ,
2121items = picker :selected ({fallback = true }),
2222action = action ,
@@ -44,7 +44,7 @@ function M.gh(opts, ctx)
4444end
4545end
4646
47- --- @param opts snacks.picker.Config
47+ --- @param opts snacks.picker.gh.issue. Config
4848--- @type snacks.picker.finder
4949function M .issue (opts ,ctx )
5050return M .gh (
@@ -55,7 +55,7 @@ function M.issue(opts, ctx)
5555 )
5656end
5757
58- --- @param opts snacks.picker.Config
58+ --- @param opts snacks.picker.gh.pr. Config
5959--- @type snacks.picker.finder
6060function M .pr (opts ,ctx )
6161return M .gh (
@@ -66,6 +66,81 @@ function M.pr(opts, ctx)
6666 )
6767end
6868
69+ --- @param opts snacks.picker.gh.actions.Config
70+ --- @type snacks.picker.finder
71+ function M .get_actions (opts ,ctx )
72+ opts = opts or {}
73+ local proc --- @type snacks.spawn.Proc ?
74+ if not opts .item and not opts .number then
75+ proc = Api .current_pr (function (pr )
76+ opts .item = pr
77+ end )
78+ end
79+ --- @async
80+ return function (cb )
81+ if proc then
82+ proc :wait ()
83+ end
84+ local item = opts .item
85+
86+ if not item then
87+ local required = {" type" ," repo" ," number" }
88+ local missing = vim .tbl_filter (function (field )
89+ return opts [field ]== nil
90+ end ,required )--- @type string[]
91+ if # missing > 0 then
92+ Snacks .notify .error ({
93+ " Missing required options for `Snacks.picker.gh_actions()`:" ,
94+ " - `" .. table.concat (missing ," ," ).. " `" ,
95+ " " ,
96+ " Either provide the fields, or run in a git repo with a **current PR**." ,
97+ }, {title = " Snacks Picker GH Actions" })
98+ return
99+ end
100+ item = Api .get ({type = opts .type or " pr" ,repo = opts .repo ,number = opts .number })
101+ proc = Api .view (function (it )
102+ item = it
103+ end ,item )
104+
105+ if proc then
106+ proc :wait ()
107+ end
108+ if not item then
109+ Snacks .notify .error (" snacks.picker.gh.get_actions: Failed to get item" )
110+ return
111+ end
112+ end
113+
114+ local actions = Actions .get_actions (item )
115+ actions .gh_actions = nil -- remove this action
116+ actions .gh_perform_action = nil -- remove this action
117+ local items = {}--- @type snacks.picker.finder.Item[]
118+ for name ,action in pairs (actions )do
119+ --- @class snacks.picker.gh.Action : snacks.picker.finder.Item
120+ items [# items + 1 ]= {
121+ text = Snacks .picker .util .text (action , {" name" ," desc" }),
122+ file = item .uri ,
123+ name = name ,
124+ item = item ,
125+ desc = action .desc or name ,
126+ action = action ,
127+ }
128+ end
129+ table.sort (items ,function (a ,b )
130+ local pa = a .action .priority or 0
131+ local pb = b .action .priority or 0
132+ if pa ~= pb then
133+ return pa > pb
134+ end
135+ return a .desc < b .desc
136+ end )
137+ for i ,it in ipairs (items )do
138+ it .text = (" %d. %s" ):format (i ,it .text )
139+ cb (it )
140+ end
141+ end
142+ end
143+
69144--- @param opts snacks.picker.gh.diff.Config
70145--- @type snacks.picker.finder
71146function M .diff (opts ,ctx )