Skip to content

Commit

Permalink
feat: M-a shortcut to add a new device without resetting cache (#255)
Browse files Browse the repository at this point in the history
  • Loading branch information
wojciech-kulik authored Nov 23, 2024
1 parent 026c447 commit ab1bd22
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 24 deletions.
27 changes: 20 additions & 7 deletions doc/xcodebuild.txt
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,15 @@ M.setup({options}) *xcodebuild.setup*
return nil
end,
},
device_picker = {
mappings = {
move_up_device = "<M-y>", -- move device up in the list
move_down_device = "<M-e>", -- move device down in the list
add_device = "<M-a>", -- add device to cache
delete_device = "<M-d>", -- delete device from cache
refresh_devices = "<C-r>", -- refresh devices list
},
},
integrations = {
pymobiledevice = {
enabled = true, -- enable pymobiledevice integration (requires configuration, see: `:h xcodebuild.remote-debugger`)
Expand Down Expand Up @@ -4020,21 +4029,23 @@ Pickers *xcodebuild.ui.pickers*
*xcodebuild.pickers*
This module is responsible for showing pickers using Telescope.nvim.

Available shortcuts:
Device picker shortcuts:
<C-r> - Refresh the picker results
<M-y> - Move the selected item up
<M-e> - Move the selected item down
<M-x> - Remove the selected item
<M-a> - Add a new device


PickerOptions *xcodebuild.ui.pickers.PickerOptions*

Fields: ~
{on_refresh} (function|nil)
{multiselect} (boolean|nil)
{modifiable} (boolean|nil)
{auto_select} (boolean|nil)
{close_on_select} (boolean|nil)
{on_refresh} (function|nil)
{multiselect} (boolean|nil)
{modifiable} (boolean|nil)
{auto_select} (boolean|nil)
{close_on_select} (boolean|nil)
{device_select_callback} (function|nil)


*xcodebuild.ui.pickers.show*
Expand Down Expand Up @@ -4096,12 +4107,14 @@ M.select_testplan({callback}, {opts}) *xcodebuild.ui.pickers.select_testplan*
(number|nil) id


M.select_destination({callback}, {opts})*xcodebuild.ui.pickers.select_destination*
*xcodebuild.ui.pickers.select_destination*
M.select_destination({callback}, {addMode}, {opts})
Shows a picker with the available devices.
It returns devices from cache if available.

Parameters: ~
{callback} (fun(destination:Device[])|nil)
{addMode} (boolean|nil) if true, it will add the selected device to the cache
{opts} (PickerOptions|nil)

Returns: ~
Expand Down
2 changes: 1 addition & 1 deletion lua/xcodebuild/actions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ function M.select_device(callback)
helpers.cancel_actions()
pickers.select_destination(function()
update_settings({ skipIfSamePlatform = true }, callback)
end, { close_on_select = true })
end, false, { close_on_select = true })
end

---Sends a notification with the current project settings.
Expand Down
9 changes: 9 additions & 0 deletions lua/xcodebuild/core/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,15 @@ local defaults = {
return nil
end,
},
device_picker = {
mappings = {
move_up_device = "<M-y>", -- move device up in the list
move_down_device = "<M-e>", -- move device down in the list
add_device = "<M-a>", -- add device to cache
delete_device = "<M-d>", -- delete device from cache
refresh_devices = "<C-r>", -- refresh devices list
},
},
integrations = {
pymobiledevice = {
enabled = true, -- enable pymobiledevice integration (requires configuration, see: `:h xcodebuild.remote-debugger`)
Expand Down
9 changes: 9 additions & 0 deletions lua/xcodebuild/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,15 @@ end
--- return nil
--- end,
--- },
--- device_picker = {
--- mappings = {
--- move_up_device = "<M-y>", -- move device up in the list
--- move_down_device = "<M-e>", -- move device down in the list
--- add_device = "<M-a>", -- add device to cache
--- delete_device = "<M-d>", -- delete device from cache
--- refresh_devices = "<C-r>", -- refresh devices list
--- },
--- },
--- integrations = {
--- pymobiledevice = {
--- enabled = true, -- enable pymobiledevice integration (requires configuration, see: `:h xcodebuild.remote-debugger`)
Expand Down
2 changes: 1 addition & 1 deletion lua/xcodebuild/project/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ function M.configure_project()
end, { close_on_select = true, auto_select = true })

M.update_settings({})
end)
end, false)
end, { auto_select = true }) -- scheme
end)
end)
Expand Down
64 changes: 49 additions & 15 deletions lua/xcodebuild/ui/pickers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
---@brief [[
---This module is responsible for showing pickers using Telescope.nvim.
---
---Available shortcuts:
---Device picker shortcuts:
---<C-r> - Refresh the picker results
---<M-y> - Move the selected item up
---<M-e> - Move the selected item down
---<M-x> - Remove the selected item
---<M-a> - Add a new device
---
---@brief ]]

Expand All @@ -17,6 +18,7 @@
---@field modifiable boolean|nil
---@field auto_select boolean|nil
---@field close_on_select boolean|nil
---@field device_select_callback function|nil

local util = require("xcodebuild.util")
local notifications = require("xcodebuild.broadcasting.notifications")
Expand Down Expand Up @@ -210,7 +212,10 @@ local function swap_entries(entries, index1, index2)
end

---Sets the picker actions for moving and deleting items.
local function set_picker_actions(bufnr)
---@param bufnr number
---@param opts PickerOptions|nil
local function set_picker_actions(bufnr, opts)
local mappings = require("xcodebuild.core.config").options.device_picker.mappings
local actionState = require("telescope.actions.state")
local get_entries = function()
if not activePicker then
Expand All @@ -225,7 +230,7 @@ local function set_picker_actions(bufnr)
return entries
end

vim.keymap.set({ "n", "i" }, "<M-y>", function()
vim.keymap.set({ "n", "i" }, mappings.move_up_device, function()
if actionState.get_current_line() ~= "" then
return
end
Expand All @@ -251,7 +256,7 @@ local function set_picker_actions(bufnr)
end
end, { buffer = bufnr })

vim.keymap.set({ "n", "i" }, "<M-e>", function()
vim.keymap.set({ "n", "i" }, mappings.move_down_device, function()
if actionState.get_current_line() ~= "" then
return
end
Expand All @@ -278,7 +283,7 @@ local function set_picker_actions(bufnr)
end
end, { buffer = bufnr })

vim.keymap.set({ "n", "i" }, "<M-d>", function()
vim.keymap.set({ "n", "i" }, mappings.delete_device, function()
if activePicker and actionState.get_selected_entry() then
activePicker:delete_selection(function(selection)
local index = util.indexOfPredicate(projectConfig.device_cache.devices, function(device)
Expand All @@ -290,6 +295,12 @@ local function set_picker_actions(bufnr)
end)
end
end, { buffer = bufnr })

vim.keymap.set({ "n", "i" }, mappings.add_device, function()
M.select_destination(function()
M.select_destination((opts or {}).device_select_callback, false, opts)
end, true, { close_on_select = false, multiselect = true })
end, { buffer = bufnr })
end

---Shows a picker using Telescope.nvim.
Expand All @@ -298,6 +309,8 @@ end
---@param callback function|nil
---@param opts PickerOptions|nil
function M.show(title, items, callback, opts)
local mappings = require("xcodebuild.core.config").options.device_picker.mappings

if currentJobId then
vim.fn.jobstop(currentJobId)
currentJobId = nil
Expand All @@ -315,14 +328,14 @@ function M.show(title, items, callback, opts)
file_ignore_patterns = {},
attach_mappings = function(prompt_bufnr, _)
if opts.on_refresh ~= nil then
vim.keymap.set({ "n", "i" }, "<C-r>", function()
vim.keymap.set({ "n", "i" }, mappings.refresh_devices, function()
start_telescope_spinner()
opts.on_refresh()
end, { silent = true, buffer = prompt_bufnr })
end

if opts.modifiable then
set_picker_actions(prompt_bufnr)
set_picker_actions(prompt_bufnr, opts)
end

telescopeActions.select_default:replace(function()
Expand Down Expand Up @@ -595,10 +608,11 @@ end
---Shows a picker with the available devices.
---It returns devices from cache if available.
---@param callback fun(destination: Device[])|nil
---@param addMode boolean|nil if true, it will add the selected device to the cache
---@param opts PickerOptions|nil
---@return number|nil job id if launched
---@see xcodebuild.config
function M.select_destination(callback, opts)
function M.select_destination(callback, addMode, opts)
opts = opts or {}

local projectFile = projectConfig.settings.projectFile
Expand All @@ -607,7 +621,7 @@ function M.select_destination(callback, opts)
local workingDirectory = projectConfig.settings.workingDirectory
local results = {}

if projectConfig.is_device_cache_valid() then
if not addMode and projectConfig.is_device_cache_valid() then
results = projectConfig.device_cache.devices or {}
projectConfig.update_device_cache(results)
end
Expand All @@ -633,6 +647,14 @@ function M.select_destination(callback, opts)
end

local alreadyAdded = {}

if addMode then
local cache = projectConfig.device_cache and projectConfig.device_cache.devices or {}
for _, destination in ipairs(cache) do
alreadyAdded[destination.id] = true
end
end

local filtered = util.filter(destinations, function(table)
if table.id and not alreadyAdded[table.id] then
alreadyAdded[table.id] = true
Expand All @@ -643,7 +665,9 @@ function M.select_destination(callback, opts)
return false
end)

projectConfig.update_device_cache(filtered)
if not addMode then
projectConfig.update_device_cache(filtered)
end
results = filtered
update_results(results)
end)
Expand All @@ -665,11 +689,21 @@ function M.select_destination(callback, opts)
end

opts.on_refresh = getConnectedDevices
opts.modifiable = true

M.show("Select Device", results, function(entry, _)
projectConfig.set_destination(entry.value)
util.call(callback, entry.value)
opts.modifiable = not addMode
opts.device_select_callback = not addMode and callback or nil

M.show(addMode and "Add Device(s)" or "Select Device", results, function(entry, _)
if addMode then
local cache = projectConfig.device_cache.devices or {}
for _, device in ipairs(entry) do
table.insert(cache, device)
end
projectConfig.update_device_cache(cache)
util.call(callback, entry)
else
projectConfig.set_destination(entry.value)
util.call(callback, entry.value)
end
end, opts)

if not hasCachedDevices then
Expand Down

0 comments on commit ab1bd22

Please sign in to comment.