11cache = require (" github_nvim.cache" )
2+ local config = require (" github_nvim.config" )
3+ local util = require (" github_nvim.util" )
4+ local gh = require (" github_nvim.gh" )
25-- Safely check if telescope is available
36local function get_telescope ()
47 local ok , telescope = pcall (require , ' telescope' )
1518local cache_ns = " github_nvim.pickers"
1619local cache_key = " github_repos"
1720
18- local function get_github_repos ()
19- cached_result = cache .load (cache_ns , cache_key )
20- if cached_result then
21- print (" cache hit" )
22- return cached_result
23- end
21+ -- Store clone status: key = repo_name, value = "pending" | "success" | "failed"
22+ local clone_status = {}
2423
24+ -- Helper: Get status for a repo
25+ local function get_status (repo )
26+ return clone_status [repo ] or nil
27+ end
28+
29+ -- Helper: Set status
30+ local function set_status (repo , status )
31+ clone_status [repo ] = status
32+ end
33+
34+ local function get_github_repos ()
2535 local handle = io.popen (
26- ' gh repo list -L 200 --json nameWithOwner,description,isPrivate,isFork,isTemplate 2>/dev/null' )
36+ ' gh repo list -L 200 --json nameWithOwner,description,isPrivate,isFork,isTemplate 2>/dev/null' )
2737 local result = handle :read (' *a' )
2838 handle :close ()
2939
@@ -57,10 +67,24 @@ local function get_github_repos()
5767 })
5868 end
5969
70+ return items
71+ end
72+
73+ local function get_github_repos_cached ()
74+ cached_result = cache .load (cache_ns , cache_key )
75+ if cached_result then
76+ print (" cache hit" )
77+ return cached_result
78+ end
79+ local items = get_github_repos ()
6080 print (" cache save" )
6181 cache .save (cache_ns , cache_key , items )
82+ end
6283
63- return items
84+ local my_picker = nil
85+
86+ local function get_current_picker ()
87+ return my_picker
6488end
6589
6690return function ()
@@ -77,19 +101,32 @@ return function()
77101 end
78102
79103 local finder = require (' telescope.finders' ).new_table ({
80- results = get_github_repos (),
104+ results = get_github_repos_cached (),
81105 entry_maker = function (entry )
106+ print (" find..." )
107+ local github_dir = config .defaults .github_dir
108+ local sep = config .defaults .sep
109+ local name = entry .value
110+ local local_path = github_dir .. sep .. name
111+ local local_exists = util .path_exists (local_path ) and true or false
112+ local local_icon = local_exists and " local" or " remote"
113+ local status = get_status (name )
82114 return {
83115 value = entry .value ,
84- display = entry .display ,
116+ display = entry .display .. " " .. local_icon .. ( status and " ... " .. status or " " ) ,
85117 ordinal = entry .value ,
118+ is_private = entry .isPrivate ,
119+ is_fork = entry .isFork ,
120+ is_template = entry .isTemplate ,
121+ local_path = entry .local_path ,
122+ local_exists = entry .local_exists ,
86123 }
87124 end ,
88- -- searcher = conf.fuzzy_finder.new_searcher({}),
125+ -- searcher = conf.fuzzy_finder.new_searcher({}),
89126 searcher = searcher ,
90127 })
91128 local pickers = require (" telescope.pickers" )
92- pickers .new ({}, {
129+ my_picker = pickers .new ({}, {
93130 prompt_title = " Your github repos" ,
94131 finder = finder ,
95132 sorter = conf .generic_sorter (opts ),
@@ -111,15 +148,163 @@ return function()
111148 --
112149 -- return true
113150 -- end,
151+
114152 attach_mappings = function (prompt_bufnr , map )
115153 -- Add mappings
116- map (' i' , ' <CR>' , function ()
117- local selection = require (' telescope.actions.state' ).get_selected_entry ()
118- print (" Selected:" , selection .value )
154+ map (' i' , ' <C-g>' , function ()
155+ local actions = require (' telescope.actions.state' )
156+ local selection = actions .get_selected_entry ()
157+ local local_path = selection .local_path
158+ local local_exists = selection .local_exists
159+
160+ if local_exists then
161+ vim .cmd (" Telescope find_files cwd=" .. local_path )
162+ else
163+ print (" Selected:" , selection .value , " local_path: " , local_path )
164+ end
119165 end )
166+ -- Open in browser
167+ map (" i" , " <C-o>" , function ()
168+ local actions = require (' telescope.actions.state' )
169+ local selection = actions .get_selected_entry ()
170+ local url = " https://github.com/" .. selection .value
171+ util .open_url (url )
172+ end , { desc = " Open in browser" })
173+
174+ -- Copy URL to clipboard
175+ map (" i" , " <C-s>" , function ()
176+ local actions = require (' telescope.actions.state' )
177+ local selection = actions .get_selected_entry ()
178+ local url = " https://github.com/" .. selection .value
179+ vim .fn .setreg (" +" , url ) -- Copy to system clipboard
180+ vim .notify (" Copied: " .. url , vim .log .levels .INFO )
181+ end , { desc = " Copy URL to clipboard" })
182+
183+ -- Clone repo
184+ map (" i" , " <C-p>" , function ()
185+ local actions = require (' telescope.actions.state' )
186+ local selection = actions .get_selected_entry ()
187+ local repo_name = selection .value
188+ -- gh_username = gh.get_github_username()
189+ local dir = vim .fn .input (" Clone to directory: " ,
190+ config .defaults .github_dir .. config .defaults .sep .. repo_name )
191+ set_status (repo_name , " cloning" )
192+
193+
194+ -- Refresh immediately
195+ vim .schedule (function ()
196+ local actions = require (' telescope.actions.state' )
197+ local picker = actions .get_current_picker (prompt_bufnr )
198+ -- print("picker ", vim.inspect(picker))
199+ -- print("picker ", vim.inspect(picker))
200+ if picker and picker .finder .results then
201+ picker .finder .results = vim .tbl_map (function (item )
202+ if item .value == repo_name then
203+ item ._status = " cloning"
204+ item .display = item .display :gsub (" %(.*%)" , " (🔄 Cloning...)" )
205+ end
206+ return item
207+ end , picker .finder .results )
208+ set_status (repo_name , " downloaded" )
209+ picker :refresh ()
210+ end
211+ end )
212+
213+ -- Run async clone
214+ local url = " https://github.com/" .. repo_name
215+ vim .system ({ " git" , " clone" , url , dir }, {
216+ text = true , cwd = user_dir , }, function (result )
217+ vim .schedule (function ()
218+ local actions = require (' telescope.actions.state' )
219+ local picker = actions .get_current_picker (prompt_bufnr )
220+ -- print("picker ", vim.inspect(picker))
221+ if not picker then return end
222+
223+ local updated_results = vim .tbl_map (function (item )
224+ if item .value == repo_name then
225+ if result .code == 0 then
226+ item ._status = " success"
227+ item .display = item .display :gsub (" %(.*%)" , " (✅ Cloned)" )
228+ vim .notify (" ✅ Cloned: " .. dir , vim .log .levels .INFO )
229+ else
230+ item ._status = " failed"
231+ item .display = item .display :gsub (" %(.*%)" , " (❌ Failed)" )
232+ vim .notify (" ❌ Failed to clone: " .. vim .inspect (result ), vim .log .levels .ERROR )
233+ end
234+ end
235+ return item
236+ end , picker .finder .results )
237+
238+ picker .finder .results = updated_results
239+ picker :refresh ()
240+ end )
241+ end )
242+
243+
244+ -- local cmd = "git clone https://github.com/" .. selection.value .. " " .. dir
245+ -- vim.cmd(":silent !" .. cmd)
246+ -- vim.notify("Cloned to: " .. dir)
247+ end , { desc = " Clone repo locally" })
248+
249+ -- Preview README (simple version)
250+ map (" i" , " <C- >" , function ()
251+ local actions = require (' telescope.actions.state' )
252+ local selection = actions .get_selected_entry ()
253+ local url = " https://github.com/" .. selection .value .. " /blob/main/README.md"
254+ util .open_url (url )
255+ end , { desc = " Open README" })
256+
257+ map (" i" , " <C-r>" , function ()
258+ local actions = require (' telescope.actions.state' )
259+ local picker = actions .get_current_picker (prompt_bufnr )
260+ if not picker then return end
261+
262+ -- print("picker ", vim.inspect(picker))
263+
264+ -- Get current query from prompt
265+ local query = vim .api .nvim_buf_get_name (picker .prompt_bufnr ) or " "
266+
267+ -- Set loading prompt
268+ -- picker.set_prompt("🔄 Refreshing...", false)
269+
270+ -- Use your existing get_github_repos() function
271+ vim .defer_fn (function ()
272+ local results = get_github_repos ()
273+
274+ if not results or # results == 0 then
275+ vim .schedule (function ()
276+ local actions = require (' telescope.actions.state' )
277+ vim .notify (" ⚠️ No results returned from GitHub API" , vim .log .levels .WARN )
278+ -- picker.set_prompt("GitHub Repositories")
279+ end )
280+ return
281+ end
282+
283+ -- Save to cache
284+ local cache = require (" github_nvim.cache" )
285+ cache .save (cache_ns , cache_key , results , 60 * 60 * 24 )
286+
287+ -- Update picker UI
288+ vim .schedule (function ()
289+ -- local actions = require('telescope.actions.state')
290+ picker .results = results
291+ picker :refresh ()
292+ -- picker.set_prompt("GitHub Repositories")
293+ vim .notify (" ✅ Refreshed from internet" , vim .log .levels .INFO )
294+ end )
295+ end , 100 ) -- Small delay to avoid flicker
296+ end , { desc = " force refresh repos" })
297+
298+ -- Optional: Add 'select' as default
299+ -- actions.select_default:replace(function()
300+ -- local selection = actions.get_selected_entry()
301+ -- print("Selected:", selection.value)
302+ -- actions.close(prompt_bufnr)
303+ -- end)
120304 return true
121305 end ,
122- }):find ()
306+ })
307+ my_picker :find ()
123308end
124309
125310-- Main picker function
0 commit comments