==============================================================================
Table of Contents                                          *xcodebuild.contents*

Introduction ······················································ |xcodebuild|
Features ················································· |xcodebuild.features|
Requirements ········································· |xcodebuild.requirements|
Highlights ············································· |xcodebuild.highlights|
Key Bindings ············································· |xcodebuild.bindings|
User Commands ············································ |xcodebuild.commands|
Global Variables ································· |xcodebuild.global_variables|
Debugging On iOS 17+ Device ···················· |xcodebuild.integrations.ios17|
Health Check ··············································· |xcodebuild.health|
Actions ··················································· |xcodebuild.actions|
Constants ··············································· |xcodebuild.constants|
Autocommands ········································· |xcodebuild.core.autocmd|
Default Options ······································· |xcodebuild.core.config|
Quickfix List ······································· |xcodebuild.core.quickfix|
Xcodebuild Wrapper ····································· |xcodebuild.core.xcode|
Xcode Logs Parser ······························· |xcodebuild.xcode_logs.parser|
Logs Panel ······································· |xcodebuild.xcode_logs.panel|
Project Configuration ······························ |xcodebuild.project.config|
App Data ·········································· |xcodebuild.project.appdata|
Project Builder ··································· |xcodebuild.project.builder|
Project Manager ··································· |xcodebuild.project.manager|
Project Assets Manager ····························· |xcodebuild.project.assets|
Device ············································ |xcodebuild.platform.device|
Device Proxy ································ |xcodebuild.platform.device_proxy|
macOS Platform Integration ························· |xcodebuild.platform.macos|
Autocommand Events ···························· |xcodebuild.broadcasting.events|
Notifications ·························· |xcodebuild.broadcasting.notifications|
Test Diagnostics ································ |xcodebuild.tests.diagnostics|
Test Enumeration Parser ·················· |xcodebuild.tests.enumeration_parser|
Test Explorer ······································ |xcodebuild.tests.explorer|
Test Provider ······································ |xcodebuild.tests.provider|
Test Runner ·········································· |xcodebuild.tests.runner|
Test Search ·········································· |xcodebuild.tests.search|
Snapshot Tests ···································· |xcodebuild.tests.snapshots|
Xcresult File Parser ························ |xcodebuild.tests.xcresult_parser|
Code Coverage ······························ |xcodebuild.code_coverage.coverage|
Code Coverage Report ························· |xcodebuild.code_coverage.report|
DAP Integration ·································· |xcodebuild.integrations.dap|
Remote Debugger Integration ·········· |xcodebuild.integrations.remote_debugger|
LSP Integration ·································· |xcodebuild.integrations.lsp|
nvim-tree Integration ······················ |xcodebuild.integrations.nvim-tree|
neo-tree.nvim Integration ··················· |xcodebuild.integrations.neo-tree|
oil.nvim Integration ························ |xcodebuild.integrations.oil-nvim|
Quick Test Framework Integration ··············· |xcodebuild.integrations.quick|
xcode-build-server Integration ···· |xcodebuild.integrations.xcode-build-server|
Xcodebuild Workaround ············· |xcodebuild.integrations.xcodebuild-offline|
Pickers ················································ |xcodebuild.ui.pickers|
Picker Actions ·································· |xcodebuild.ui.picker_actions|
Helpers ··················································· |xcodebuild.helpers|
Lua Utils ···················································· |xcodebuild.util|

==============================================================================
Introduction                                                        *xcodebuild*

Xcodebuild.nvim is a plugin designed to let you migrate your app
app development from Xcode to Neovim. It provides all essential actions
for development including building, debugging, and testing.

Make sure to check out Tips & Tricks to improve your development in Neovim:
https://github.com/wojciech-kulik/xcodebuild.nvim/discussions/categories/tips-tricks

Source Code: https://github.com/wojciech-kulik/xcodebuild.nvim


                                                               *xcodebuild.nvim*
                                                             *xcodebuild.config*
                                                            *xcodebuild.options*
M.setup({options})                                            *xcodebuild.setup*
  Setup and initialize xcodebuild.nvim

  Parameters: ~
    {options}  (table|nil)
               All options are optional, below you can see the default values:

  Usage: ~
>lua
    require("xcodebuild").setup({
      restore_on_start = true, -- logs, diagnostics, and marks will be loaded on VimEnter (may affect performance)
      auto_save = true, -- save all buffers before running build or tests (command: silent wa!)
      show_build_progress_bar = true, -- shows [ ...    ] progress bar during build, based on the last duration
      prepare_snapshot_test_previews = true, -- prepares a list with failing snapshot tests
      test_search = {
        file_matching = "filename_lsp", -- one of: filename, lsp, lsp_filename, filename_lsp. Check out README for details
        target_matching = true, -- checks if the test file target matches the one from logs. Try disabling it in case of not showing test results
        lsp_client = "sourcekit", -- name of your LSP for Swift files
        lsp_timeout = 200, -- LSP timeout in milliseconds
      },
      commands = {
        extra_build_args = { "-parallelizeTargets" }, -- extra arguments for `xcodebuild build`
        extra_test_args = { "-parallelizeTargets" }, -- extra arguments for `xcodebuild test`
        project_search_max_depth = 3, -- maxdepth of xcodeproj/xcworkspace search while using configuration wizard
        focus_simulator_on_app_launch = true, -- focus simulator window when app is launched
        keep_device_cache = false, -- keep device cache even if scheme or project file changes
      },
      logs = { -- build & test logs
        auto_open_on_success_tests = false, -- open logs when tests succeeded
        auto_open_on_failed_tests = false, -- open logs when tests failed
        auto_open_on_success_build = false, -- open logs when build succeeded
        auto_open_on_failed_build = true, -- open logs when build failed
        auto_close_on_app_launch = false, -- close logs when app is launched
        auto_close_on_success_build = false, -- close logs when build succeeded (only if auto_open_on_success_build=false)
        auto_focus = true, -- focus logs buffer when opened
        filetype = "", -- file type set for buffer with logs
        open_command = "silent botright 20split {path}", -- command used to open logs panel. You must use {path} variable to load the log file
        logs_formatter = "xcbeautify --disable-colored-output --disable-logging", -- command used to format logs, you can use "" to skip formatting
        only_summary = false, -- if true logs won't be displayed, just xcodebuild.nvim summary
        live_logs = true, -- if true logs will be updated in real-time
        show_warnings = true, -- show warnings in logs summary
        notify = function(message, severity) -- function to show notifications from this module (like "Build Failed")
          vim.notify(message, severity)
        end,
        notify_progress = function(message) -- function to show live progress (like during tests)
          vim.cmd("echo '" .. message .. "'")
        end,
      },
      console_logs = {
        enabled = true, -- enable console logs in dap-ui
        format_line = function(line) -- format each line of logs
          return line
        end,
        filter_line = function(line) -- filter each line of logs
          return true
        end,
      },
      marks = {
        show_signs = true, -- show each test result on the side bar
        success_sign = "✔", -- passed test icon
        failure_sign = "✖", -- failed test icon
        show_test_duration = true, -- show each test duration next to its declaration
        show_diagnostics = true, -- add test failures to diagnostics
      },
      quickfix = {
        show_errors_on_quickfixlist = true, -- add build/test errors to quickfix list
        show_warnings_on_quickfixlist = true, -- add build warnings to quickfix list
      },
      test_explorer = {
        enabled = true, -- enable Test Explorer
        auto_open = true, -- open Test Explorer when tests are started
        auto_focus = true, -- focus Test Explorer when opened
        open_command = "botright 42vsplit Test Explorer", -- command used to open Test Explorer, must create a buffer with "Test Explorer" name
        open_expanded = true, -- open Test Explorer with expanded classes
        success_sign = "✔", -- passed test icon
        failure_sign = "✖", -- failed test icon
        progress_sign = "…", -- progress icon (only used when animate_status=false)
        disabled_sign = "⏸", -- disabled test icon
        partial_execution_sign = "‐", -- icon for a class or target when only some tests were executed
        not_executed_sign = " ", -- not executed or partially executed test icon
        show_disabled_tests = false, -- show disabled tests
        animate_status = true, -- animate status while running tests
        cursor_follows_tests = true, -- moves cursor to the last test executed
      },
      code_coverage = {
        enabled = false, -- generate code coverage report and show marks
        file_pattern = "*.swift", -- coverage will be shown in files matching this pattern
        -- configuration of line coverage presentation:
        covered_sign = "",
        partially_covered_sign = "┃",
        not_covered_sign = "┃",
        not_executable_sign = "",
      },
      code_coverage_report = {
        warning_coverage_level = 60,
        error_coverage_level = 30,
        open_expanded = false,
      },
      project_manager = {
        guess_target = true, -- guess target for the new file based on the file path
        find_xcodeproj = false, -- instead of using configured xcodeproj search for xcodeproj closest to targeted file
        should_update_project = function(path) -- path can lead to directory or file
          -- it could be useful if you mix Xcode project with SPM for example
          return true
        end,
        project_for_path = function(path)
          -- you can return a different project for the given {path} (could be directory or file)
          -- ex.: return "/your/path/to/project.xcodeproj"
          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`)
          remote_debugger_port = 65123, -- port used by remote debugger (passed to pymobiledevice3)
        },
        xcodebuild_offline = {
          enabled = false, -- improves build time (requires configuration, see `:h xcodebuild.xcodebuild-offline`)
        },
        xcode_build_server = {
          enabled = true, -- enable calling "xcode-build-server config" when project config changes
        },
        nvim_tree = {
          enabled = true, -- enable updating Xcode project files when using nvim-tree
        },
        neo_tree = {
          enabled = true, -- enable updating Xcode project files when using neo-tree.nvim
        },
        oil_nvim = {
          enabled = true, -- enable updating Xcode project files when using oil.nvim
        },
        quick = { -- integration with Swift test framework: github.com/Quick/Quick
          enabled = true, -- enable Quick tests support (requires Swift parser for nvim-treesitter)
        },
      },
      highlights = {
        -- you can override here any highlight group used by this plugin
        -- simple color: XcodebuildCoverageReportOk = "#00ff00",
        -- link highlights: XcodebuildCoverageReportOk = "DiagnosticOk",
        -- full customization: XcodebuildCoverageReportOk = { fg = "#00ff00", bold = true },
      },
    })
<


==============================================================================
Features                                                   *xcodebuild.features*

 - Support for iOS, iPadOS, watchOS, tvOS, visionOS, and macOS.
 - Support for Swift Packages (building & testing).
 - Project-based configuration.
 - Project Manager to deal with project files without using Xcode.
 - Assets Manager to manage images, colors, and data assets.
 - Test Explorer to visually present a tree with all tests and results.
 - Built using official command line tools like `xcodebuild` and `xcrun simctl`.
 - Actions to build, run, debug, and test apps on simulators and
   physical devices.
 - Environment variables and run arguments management.
 - Buffer integration with test results
   (code coverage, success & failure marks, duration, extra diagnostics).
 - Code coverage report with customizable levels.
 - Advanced log parser to detect all errors, warnings, and failing tests.
 - `nvim-tree`, `neo-tree.nvim`, and `oil.nvim` integration that automatically
   reflects all file tree operations and updates Xcode project file.
 - `nvim-dap` integration to let you easily build, run, and debug apps.
 - `nvim-dap-ui` integration to show app logs in the console window.
 - `lualine.nvim` integration to show selected device, test plan,
   and other project settings.
 - `swift-snapshot-testing` integration to present diff views for failing snapshot tests.
 - `Quick` integration to show test results for tests written using `Quick` framework.
 - `Swift Testing` integration to show test results for tests written using `Swift Testing` framework.
 - Auto-detection of the target membership for new files.
 - Picker with all available plugin actions.
 - Highly customizable (many config options, auto commands, highlights,
   and user commands).

Availability of features

 |             | Device (iOS <17) | Device (iOS 17+) | via Network (<17 / 17+) | Simulator | MacOS |
 | :---------: | :--------------: | :--------------: | :---------------------: | :-------: | :---: |
 |    build    |        🛠️        |        ✅        |         ❌ / ✅         |    ✅     |  ✅   |
 | (un)install |        🛠️        |        ✅        |         🛠️ / ✅         |    ✅     |  ❌   |
 |   launch    |        🛠️        |        ✅        |         🛠️ / ✅         |    ✅     |  ✅   |
 |  run tests  |        🛠️        |        ✅        |         ❌ / ✅         |    ✅     |  ✅   |
 |    debug    |        🛠️        |       🔐 🛠️      |           ❌            |    ✅     |  ✅   |
 | debug tests |        ❌        |        ❌        |           ❌            |    ✅     |  ✅   |
 |  app logs   |        🪲         |       🪲         |          ❌            |    ✅     |  🪲    |


 🔐 - requires passwordless `sudo` permission to `tools/remote_debugger`
      script (see |xcodebuild.remote-debugger|).

 🛠️ - available if pymobiledevice3 is installed.

 🪲  - available while debugging.


==============================================================================
Requirements                                           *xcodebuild.requirements*

                                                              *xcodebuild.tools*
                                                       *xcodebuild.dependencies*
Neovim environment
 - `Neovim 0.9.5+`
 - `telescope.nvim` to present pickers.
 - `nui.nvim` to present floating code coverage report.
 - `nvim-tree`, `neo-tree.nvim`, or `oil.nvim` to visually manage your project files.
 - `nvim-dap` and `nvim-dap-ui` to debug apps.
 - `nvim-treesitter` + Swift parser to show test results for tests written using `Quick` framework.

External tools
 - `xcbeautify` to format Xcode logs (you can set a different tool or disable formatting in the config).
 - `Xcodeproj` to manage project files within Neovim.
 - `Ruby` to use `Xcodeproj` gem.
 - `pymobiledevice3` to debug on physical devices and/or run apps on devices below iOS 17.
 - `xcode-build-server` to make LSP work properly with xcodeproj/xcworkspace.
 - `codelldb` to debug applications.
 - `ripgrep` to find matching test files while using Swift Testing framework.
 - `Xcode` to build, run, and test apps. Make sure that `xcodebuild` and `xcrun simctl` work correctly. Tested with Xcode 15.

Installation
>bash
  brew install xcode-build-server xcbeautify ruby pipx rg
  gem install xcodeproj
  pipx install pymobiledevice3
<

To quickly install all required tools you can run:
>bash
  cd ~/.local/share/nvim/lazy/xcodebuild.nvim
  make install
<

To debug on physical devices with iOS 17+ you will need to set up `sudo`,
see |xcodebuild.ios17| to learn more.


==============================================================================
Highlights                                               *xcodebuild.highlights*

You can customize the highlights by setting `config.highlights` (see |xcodebuild.config|).
Below you can find all highlight groups used by the plugin.

Test File

 | Highlight Group                   | Description                    |
 | --------------------------------- | ------------------------------ |
 | `XcodebuildTestSuccessSign`         | Test passed sign               |
 | `XcodebuildTestFailureSign`         | Test failed sign               |
 | `XcodebuildTestSuccessDurationSign` | Test duration of a passed test |
 | `XcodebuildTestFailureDurationSign` | Test duration of a failed test |

Test Explorer

 | Highlight Group                            | Description                 |
 | ------------------------------------------ | --------------------------- |
 | `XcodebuildTestExplorerTest`                 | Test name (function)        |
 | `XcodebuildTestExplorerClass`                | Test class                  |
 | `XcodebuildTestExplorerTarget`               | Test target                 |
 | `XcodebuildTestExplorerTestInProgress`       | Test in progress sign       |
 | `XcodebuildTestExplorerTestPassed`           | Test passed sign            |
 | `XcodebuildTestExplorerTestFailed`           | Test failed sign            |
 | `XcodebuildTestExplorerTestDisabled`         | Test disabled sign          |
 | `XcodebuildTestExplorerTestNotExecuted`      | Test not executed sign      |
 | `XcodebuildTestExplorerTestPartialExecution` | Not all tests executed sign |

Code Coverage (inline)

 | Highlight Group                       | Description                          |
 | ------------------------------------- | ------------------------------------ |
 | `XcodebuildCoverageFullSign`            | Covered line - sign                  |
 | `XcodebuildCoverageFullNumber`          | Covered line - line number           |
 | `XcodebuildCoverageFullLine`            | Covered line - code                  |
 | `XcodebuildCoveragePartialSign`         | Partially covered line - sign        |
 | `XcodebuildCoveragePartialNumber`       | Partially covered line - line number |
 | `XcodebuildCoveragePartialLine`         | Partially covered line - code        |
 | `XcodebuildCoverageNoneSign`            | Not covered line - sign              |
 | `XcodebuildCoverageNoneNumber`          | Not covered line - line number       |
 | `XcodebuildCoverageNoneLine`            | Not covered line - code              |
 | `XcodebuildCoverageNotExecutableSign`   | Not executable line - sign           |
 | `XcodebuildCoverageNotExecutableNumber` | Not executable line - line number    |
 | `XcodebuildCoverageNotExecutableLine`   | Not executable line - code           |

Code Coverage (report)

 | Highlight Group                 | Description                                        |
 | ------------------------------- | -------------------------------------------------- |
 | `XcodebuildCoverageReportOk`      | Percentage color when above `warning_coverage_level` |
 | `XcodebuildCoverageReportWarning` | Percentage color when below `warning_coverage_level` |
 | `XcodebuildCoverageReportError`   | Percentage color when below `error_coverage_level`   |


==============================================================================
Key Bindings                                               *xcodebuild.bindings*

                                                        *xcodebuild.keybindings*
                                                               *xcodebuild.keys*
                                                            *xcodebuild.keymaps*
Sample key bindings for the plugin.
>lua
    vim.keymap.set("n", "<leader>X", "<cmd>XcodebuildPicker<cr>", { desc = "Show Xcodebuild Actions" })
    vim.keymap.set("n", "<leader>xf", "<cmd>XcodebuildProjectManager<cr>", { desc = "Show Project Manager Actions" })

    vim.keymap.set("n", "<leader>xb", "<cmd>XcodebuildBuild<cr>", { desc = "Build Project" })
    vim.keymap.set("n", "<leader>xB", "<cmd>XcodebuildBuildForTesting<cr>", { desc = "Build For Testing" })
    vim.keymap.set("n", "<leader>xr", "<cmd>XcodebuildBuildRun<cr>", { desc = "Build & Run Project" })

    vim.keymap.set("n", "<leader>xt", "<cmd>XcodebuildTest<cr>", { desc = "Run Tests" })
    vim.keymap.set("v", "<leader>xt", "<cmd>XcodebuildTestSelected<cr>", { desc = "Run Selected Tests" })
    vim.keymap.set("n", "<leader>xT", "<cmd>XcodebuildTestClass<cr>", { desc = "Run Current Test Class" })
    vim.keymap.set("n", "<leader>x.", "<cmd>XcodebuildTestRepeat<cr>", { desc = "Repeat Last Test Run" })

    vim.keymap.set("n", "<leader>xl", "<cmd>XcodebuildToggleLogs<cr>", { desc = "Toggle Xcodebuild Logs" })
    vim.keymap.set("n", "<leader>xc", "<cmd>XcodebuildToggleCodeCoverage<cr>", { desc = "Toggle Code Coverage" })
    vim.keymap.set("n", "<leader>xC", "<cmd>XcodebuildShowCodeCoverageReport<cr>", { desc = "Show Code Coverage Report" })
    vim.keymap.set("n", "<leader>xe", "<cmd>XcodebuildTestExplorerToggle<cr>", { desc = "Toggle Test Explorer" })
    vim.keymap.set("n", "<leader>xs", "<cmd>XcodebuildFailingSnapshots<cr>", { desc = "Show Failing Snapshots" })

    vim.keymap.set("n", "<leader>xd", "<cmd>XcodebuildSelectDevice<cr>", { desc = "Select Device" })
    vim.keymap.set("n", "<leader>xp", "<cmd>XcodebuildSelectTestPlan<cr>", { desc = "Select Test Plan" })
    vim.keymap.set("n", "<leader>xq", "<cmd>Telescope quickfix<cr>", { desc = "Show QuickFix List" })

    vim.keymap.set("n", "<leader>xx", "<cmd>XcodebuildQuickfixLine<cr>", { desc = "Quickfix Line" })
    vim.keymap.set("n", "<leader>xa", "<cmd>XcodebuildCodeActions<cr>", { desc = "Show Code Actions" })
<
Test Explorer
 - Press `o` to jump to the test implementation
 - Press `t` to run selected tests
 - Press `T` to re-run recently selected tests
 - Press `R` to reload test list
 - Press `[` to jump to the previous failed test
 - Press `]` to jump to the next failed test
 - Press `<cr>` to expand or collapse the current node
 - Press `<tab>` to expand or collapse all classes
 - Press `q` to close the Test Explorer

Logs Panel
 - Press `o` on a failed test in the summary section to jump to the failing location
 - Press `q` to close the panel

Code Coverage Report
 - `enter` or `tab` - expand or collapse the current node
 - `o` - open source file


==============================================================================
User Commands                                              *xcodebuild.commands*

                                                      *xcodebuild.user-commands*
General

 | Command                    | Description                                              |
 | -------------------------- | -------------------------------------------------------- |
 | `XcodebuildSetup`            | Run configuration wizard to select project configuration |
 | `XcodebuildPicker`           | Show picker with all available actions                   |
 | `XcodebuildBuild`            | Build project                                            |
 | `XcodebuildCleanBuild`       | Build project (clean build)                              |
 | `XcodebuildBuildRun`         | Build & run app                                          |
 | `XcodebuildBuildForTesting`  | Build for testing                                        |
 | `XcodebuildRun`              | Run app without building                                 |
 | `XcodebuildCancel`           | Cancel currently running action                          |
 | `XcodebuildCleanDerivedData` | Deletes project's DerivedData                            |
 | `XcodebuildToggleLogs`       | Toggle logs panel                                        |
 | `XcodebuildOpenLogs`         | Open logs panel                                          |
 | `XcodebuildCloseLogs`        | Close logs panel                                         |
 | `XcodebuildOpenInXcode`      | Open project in Xcode                                    |
 | `XcodebuildQuickfixLine`     | Try fixing issues in the current line                    |
 | `XcodebuildCodeActions`      | Show code actions for the current line                   |

Project Manager

 | Command                            | Description                                                |
 | ---------------------------------- | ---------------------------------------------------------- |
 | `XcodebuildProjectManager`           | Show picker with all Project Manager actions               |
 | `XcodebuildAssetsManager`            | Show picker with all Assets Manager actions                |
 | `XcodebuildCreateNewFile`            | Create a new file and add it to target(s)                  |
 | `XcodebuildAddCurrentFile`           | Add the active file to target(s)                           |
 | `XcodebuildRenameCurrentFile`        | Rename the current file                                    |
 | `XcodebuildDeleteCurrentFile`        | Delete the current file                                    |
 | `XcodebuildCreateNewGroup`           | Create a new directory and add it to the project           |
 | `XcodebuildAddCurrentGroup`          | Add the parent directory of the active file to the project |
 | `XcodebuildRenameCurrentGroup`       | Rename the current directory                               |
 | `XcodebuildDeleteCurrentGroup`       | Delete the current directory including all files inside    |
 | `XcodebuildUpdateCurrentFileTargets` | Update target membership of the active file                |
 | `XcodebuildShowCurrentFileTargets`   | Show target membership of the active file                  |

 👉 To add a file to multiple targets use multi-select feature (by default `tab`).

Testing

 | Command                    | Description                               |
 | -------------------------- | ----------------------------------------- |
 | `XcodebuildTest`             | Run tests (whole test plan)               |
 | `XcodebuildTestTarget`       | Run test target (where the cursor is)     |
 | `XcodebuildTestClass`        | Run test class (where the cursor is)      |
 | `XcodebuildTestNearest`      | Run test (where the cursor is)            |
 | `XcodebuildTestSelected`     | Run selected tests (using visual mode)    |
 | `XcodebuildTestFailing`      | Rerun previously failed tests             |
 | `XcodebuildTestRepeat`       | Repeat the last test run                  |
 | `XcodebuildFailingSnapshots` | Show a picker with failing snapshot tests |

Code Coverage

 | Command                          | Description                                |
 | -------------------------------- | ------------------------------------------ |
 | `XcodebuildToggleCodeCoverage`     | Toggle code coverage marks on the side bar |
 | `XcodebuildShowCodeCoverageReport` | Open HTML code coverage report             |
 | `XcodebuildJumpToNextCoverage`     | Jump to next code coverage mark            |
 | `XcodebuildJumpToPrevCoverage`     | Jump to previous code coverage mark        |

Test Explorer

 | Command                                | Description                    |
 | -------------------------------------- | ------------------------------ |
 | `XcodebuildTestExplorerShow`             | Show Test Explorer             |
 | `XcodebuildTestExplorerHide`             | Hide Test Explorer             |
 | `XcodebuildTestExplorerToggle`           | Toggle Test Explorer           |
 | `XcodebuildTestExplorerClear`            | Clears Test Explorer           |
 | `XcodebuildTestExplorerRunSelectedTests` | Run Selected Tests             |
 | `XcodebuildTestExplorerRerunTests`       | Re-run recently selected tests |

Configuration

 | Command                  | Description                         |
 | -------------------------| ----------------------------------- |
 | `XcodebuildSelectScheme`   | Show scheme picker                  |
 | `XcodebuildSelectDevice`   | Show device picker                  |
 | `XcodebuildNextDevice`     | Selects next device                 |
 | `XcodebuildPreviousDevice` | Selects previous device             |
 | `XcodebuildSelectTestPlan` | Show test plan picker               |
 | `XcodebuildShowConfig`     | Print current project configuration |
 | `XcodebuildEditEnvVars`    | Edit environment variables          |
 | `XcodebuildEditRunArgs`    | Edit run arguments                  |
 | `XcodebuildBootSimulator`  | Boot selected simulator             |
 | `XcodebuildInstallApp`     | Install application                 |
 | `XcodebuildUninstallApp`   | Uninstall application               |


==============================================================================
Global Variables                                   *xcodebuild.global_variables*

                                                   *xcodebuild.global-variables*
                                                          *xcodebuild.variables*
                                                            *xcodebuild.lualine*
This plugin provides several global variables that you can use to
integrate with `lualine` or other plugins.

 | Variable                     | Description                                        |
 | ---------------------------- | -------------------------------------------------- |
 | `vim.g.xcodebuild_device_name` | Device name (ex. iPhone 15 Pro)                    |
 | `vim.g.xcodebuild_os`          | OS version (ex. 16.4)                              |
 | `vim.g.xcodebuild_platform`    | Device platform (ex. iPhone Simulator)             |
 | `vim.g.xcodebuild_scheme`      | Selected project scheme (ex. MyApp)                |
 | `vim.g.xcodebuild_test_plan`   | Selected Test Plan (ex. MyAppTests)                |
 | `vim.g.xcodebuild_last_status` | Last build/test status (ex. Build Succeeded [15s]) |


Sample `lualine` integration:
>lua
    local function xcodebuild_device()
      if vim.g.xcodebuild_platform == "macOS" then
        return " macOS"
      end

      local deviceIcon = ""
      if vim.g.xcodebuild_platform:match("watch") then
        deviceIcon = "􀟤"
      elseif vim.g.xcodebuild_platform:match("tv") then
        deviceIcon = "􀡴 "
      elseif vim.g.xcodebuild_platform:match("vision") then
        deviceIcon = "􁎖 "
      end

      if vim.g.xcodebuild_os then
        return deviceIcon .. " " .. vim.g.xcodebuild_device_name .. " (" .. vim.g.xcodebuild_os .. ")"
      end

      return deviceIcon .. " " .. vim.g.xcodebuild_device_name
    end

    ------

    lualine_x = {
      { "' ' .. vim.g.xcodebuild_last_status", color = { fg = "Gray" } },
      { "'󰙨 ' .. vim.g.xcodebuild_test_plan", color = { fg = "#a6e3a1", bg = "#161622" } },
      { xcodebuild_device, color = { fg = "#f9e2af", bg = "#161622" } },
    },
<


==============================================================================
Debugging On iOS 17+ Device                      *xcodebuild.integrations.ios17*

                                                              *xcodebuild.ios17*
                                                    *xcodebuild.remote-debugger*

Since iOS 17, a new secure connection between Mac and mobile devices is
required. Xcodebuild.nvim uses `pymobiledevice3` to establish a special
trusted tunnel that is later used for debugging. However, this operation
requires `sudo`.

Showing a pop-up to enter a password every time you run a debugger would
be quite annoying. That's why the plugin provides a small script
`tools/remote_debugger` that wraps the only two operations requiring
`sudo` (starting a secure tunnel and closing it).

This allows you to configure passwordless access just for this single
file and make it work with xcodebuild.nvim.

⚠️ CAUTION
Giving passwordless `sudo` access to that file, potentially opens a gate for
malicious software that could modify the file and run some evil code using
`root` account. The best way to protect that file is to create a local copy,
change the owner to `root`, and give write permission only to `root`.
The same must be applied to the parent directory. The script below
automatically secures the file.

👉 Enable integration

Update your config with:
>lua
  integrations = {
    pymobiledevice = {
      enabled = true,
    },
  }
<

👉 Run the following command to install & protect the script

>bash
  DEST="$HOME/Library/xcodebuild.nvim" && \
    SOURCE="$HOME/.local/share/nvim/lazy/xcodebuild.nvim/tools/remote_debugger" && \
    ME="$(whoami)" && \
    sudo install -d -m 755 -o root "$DEST" && \
    sudo install -m 755 -o root "$SOURCE" "$DEST" && \
    sudo bash -c "echo \"$ME ALL = (ALL) NOPASSWD: $DEST/remote_debugger\" >> /etc/sudoers"
<

See also: https://github.com/doronz88/pymobiledevice3/blob/master/misc/RemoteXPC.md#trusted-tunnel


                                          *xcodebuild.remote-debugger-migration*

Previous version of xcodebuild.nvim asked you to give sudo permission to:
`$HOME/.local/share/nvim/lazy/xcodebuild.nvim/tools/remote_debugger`

Unfortunately, it's not the best solution, because someone could modify
that file and run some evil code using `root` account.

Therefore, to improve security, please run `sudo visudo -f /etc/sudoers` and
remove previously added line with `remote_debugger` path.

After that, run the script that is presented above to securely install
`pymobiledevice3` integration. See: |xcodebuild.remote-debugger|.

The script installed in a new way will be protected and the modification
of the file will be allowed only for the `root` user.

Please also note that remote debugger config options have been moved to:
`integrations.pymobiledevice`.


==============================================================================
Health Check                                                 *xcodebuild.health*

 This module checks if everything is installed and configured correctly.

M.check()                                              *xcodebuild.health.check*


==============================================================================
Actions                                                     *xcodebuild.actions*

                                                                *xcodebuild.api*
This module is responsible for handling actions that the user can
call programmatically. It is the main entry point to the plugin's API.

The interface should stay relatively stable.

M.open_in_xcode()                             *xcodebuild.actions.open_in_xcode*
  Opens the project in Xcode.


M.open_logs()                                     *xcodebuild.actions.open_logs*
  Opens the logs panel.


M.close_logs()                                   *xcodebuild.actions.close_logs*
  Closes the logs panel.


M.toggle_logs()                                 *xcodebuild.actions.toggle_logs*
  Toggles the logs panel.


M.show_picker()                                 *xcodebuild.actions.show_picker*
  Shows the pickers with all available actions.


M.cancel()                                           *xcodebuild.actions.cancel*
  Cancels all running actions.


M.configure_project()                     *xcodebuild.actions.configure_project*
  Shows configuration wizard.


M.build({callback})                                   *xcodebuild.actions.build*
  Builds the project.

  Parameters: ~
    {callback}  (fun(report:ParsedReport)|nil)


M.clean_build({callback})                       *xcodebuild.actions.clean_build*
  Starts clean build.

  Parameters: ~
    {callback}  (fun(report:ParsedReport)|nil)


M.build_for_testing({callback})           *xcodebuild.actions.build_for_testing*
  Builds the project for testing.

  Parameters: ~
    {callback}  (fun(report:ParsedReport)|nil)


M.build_and_run({callback})                   *xcodebuild.actions.build_and_run*
  Builds and runs the project.

  Parameters: ~
    {callback}  (fun(report:ParsedReport)|nil)


M.clean_derived_data()                   *xcodebuild.actions.clean_derived_data*
  Cleans the derived data.


M.edit_env_vars()                             *xcodebuild.actions.edit_env_vars*
  Opens `env.txt` file in a new tab.


M.edit_run_args()                             *xcodebuild.actions.edit_run_args*
  Opens `run_args.txt` file in a new tab.


M.run({callback})                                       *xcodebuild.actions.run*
  Launches the app.

  Parameters: ~
    {callback}  (function|nil)


M.run_tests()                                     *xcodebuild.actions.run_tests*
  Starts tests.


M.run_target_tests()                       *xcodebuild.actions.run_target_tests*
  Starts tests of the current target.


M.run_class_tests()                         *xcodebuild.actions.run_class_tests*
  Starts tests from the class under the cursor.


M.run_nearest_test()                       *xcodebuild.actions.run_nearest_test*
  Starts the nearest test to the cursor.
  It searches for the test declaration going up.


M.run_selected_tests()                   *xcodebuild.actions.run_selected_tests*
  Starts selected tests.


M.rerun_failed_tests()                   *xcodebuild.actions.rerun_failed_tests*
  Starts tests that failed previously.


M.repeat_last_test_run()               *xcodebuild.actions.repeat_last_test_run*
  Repeats the last test run.


                                *xcodebuild.actions.show_failing_snapshot_tests*
M.show_failing_snapshot_tests()
  Shows a pickers with failing snapshot tests.


M.select_project({callback})                 *xcodebuild.actions.select_project*
  Starts the pickers with project file selection.

  Parameters: ~
    {callback}  (function|nil)


M.select_scheme({callback})                   *xcodebuild.actions.select_scheme*
  Starts the pickers with scheme selection.

  Parameters: ~
    {callback}  (function|nil)


M.select_testplan({callback})               *xcodebuild.actions.select_testplan*
  Starts the pickers with test plan selection.

  Parameters: ~
    {callback}  (fun(testPlan:string)|nil)


M.select_device({callback})                   *xcodebuild.actions.select_device*
  Starts the pickers with device selection.

  Parameters: ~
    {callback}  (function|nil)


M.show_current_config()                 *xcodebuild.actions.show_current_config*
  Sends a notification with the current project settings.


M.install_app({callback})                       *xcodebuild.actions.install_app*
  Installs the app on the device.

  Parameters: ~
    {callback}  (function|nil)


M.uninstall_app({callback})                   *xcodebuild.actions.uninstall_app*
  Uninstalls the app from the device.

  Parameters: ~
    {callback}  (function|nil)


M.boot_simulator({callback})                 *xcodebuild.actions.boot_simulator*
  Boots the simulator.

  Parameters: ~
    {callback}  (function|nil)


M.toggle_code_coverage({isVisible})    *xcodebuild.actions.toggle_code_coverage*
  Toggles the code coverage.

  Parameters: ~
    {isVisible}  (boolean)


                                  *xcodebuild.actions.show_code_coverage_report*
M.show_code_coverage_report()
  Shows the code coverage report.


M.jump_to_next_coverage()             *xcodebuild.actions.jump_to_next_coverage*
  Jumps to the next coverage marker.


                                  *xcodebuild.actions.jump_to_previous_coverage*
M.jump_to_previous_coverage()
  Jumps to the previous coverage marker.


M.test_explorer_clear()                 *xcodebuild.actions.test_explorer_clear*
  Clears the test explorer.


M.test_explorer_show()                   *xcodebuild.actions.test_explorer_show*
  Shows the test explorer.


M.test_explorer_hide()                   *xcodebuild.actions.test_explorer_hide*
  Hides the test explorer.


M.test_explorer_toggle()               *xcodebuild.actions.test_explorer_toggle*
  Toggles the test explorer.


                           *xcodebuild.actions.test_explorer_run_selected_tests*
M.test_explorer_run_selected_tests()
  Runs selected tests.


                                  *xcodebuild.actions.test_explorer_rerun_tests*
M.test_explorer_rerun_tests()
  Runs last executed tests or all if nothing was executed.


M.show_assets_manager()                 *xcodebuild.actions.show_assets_manager*
  Show the Assets Manager.


M.get_project_targets()                 *xcodebuild.actions.get_project_targets*
  Returns project targets.

  Returns: ~
    (string[]|nil)


                                        *xcodebuild.actions.add_file_to_targets*
M.add_file_to_targets({filepath}, {targets})
  Adds a file to the targets.

  Parameters: ~
    {filepath}  (string)
    {targets}   (string[])


M.create_new_file()                         *xcodebuild.actions.create_new_file*
  Creates a new file and updates the project.
  It asks the user to input the name and select targets.


M.add_current_file()                       *xcodebuild.actions.add_current_file*
  Adds the current file to the project.


M.rename_current_file()                 *xcodebuild.actions.rename_current_file*
  Renames the current file.
  It asks the user for a new name.


M.delete_current_file()                 *xcodebuild.actions.delete_current_file*
  Deletes the current file.
  It asks the user to confirm the action.


M.create_new_group()                       *xcodebuild.actions.create_new_group*
  Creates a new group and updates the project.
  It asks the user to input the name.


M.add_current_group()                     *xcodebuild.actions.add_current_group*
  Adds the group to the project.


M.rename_current_group()               *xcodebuild.actions.rename_current_group*
  Renames the current group.
  It asks the user for a new name.


M.delete_current_group()               *xcodebuild.actions.delete_current_group*
  Deletes the current group.
  It asks the user to confirm the action.


                                  *xcodebuild.actions.show_current_file_targets*
M.show_current_file_targets()
  Shows a picker with targets of the current file.


                                *xcodebuild.actions.update_current_file_targets*
M.update_current_file_targets()
  Shows a picker to select the targets for the current file.


                               *xcodebuild.actions.show_project_manager_actions*
M.show_project_manager_actions()
  Shows all available actions for the project manager.


M.quickfix_line()                             *xcodebuild.actions.quickfix_line*
  Automatically fixes the current line if possible.


M.show_code_actions()                     *xcodebuild.actions.show_code_actions*
  Shows the code actions for the current line.


M.run_func_test()                             *xcodebuild.actions.run_func_test*
  @deprecated use `run_nearest_test` instead


M.run_failing_tests()                     *xcodebuild.actions.run_failing_tests*
  @deprecated use `rerun_failed_tests` instead


M.select_next_device()                   *xcodebuild.actions.select_next_device*


                                     *xcodebuild.actions.select_previous_device*
M.select_previous_device()


==============================================================================
Constants                                                 *xcodebuild.constants*

This module contains constants and type definitions that are
used across the plugin.

Buffer                                             *xcodebuild.constants.Buffer*

  Type: ~
    number


Row                                                   *xcodebuild.constants.Row*

  Type: ~
    number


PlatformId                                     *xcodebuild.constants.PlatformId*
  Platform type enum.
  These values match constants emitted by `xcodebuild` commands.

  Variants: ~
    ("iOS")                 physical iOS device (iPhone or iPad)
    ("iOS Simulator")       iOS simulator (iPhone or iPad)
    ("tvOS Simulator")      tvOS simulator (Apple TV)
    ("tvOS")                tvOS device (Apple TV)
    ("watchOS Simulator")   watchOS simulator (Apple Watch)
    ("watchOS")             watchOS device (Apple Watch)
    ("visionOS Simulator")  visionOS simulator (Apple Glasses)
    ("visionOS")            visionOS device (Apple Glasses)
    ("macOS")               macOS


PlatformConstants                       *xcodebuild.constants.PlatformConstants*
  Platform constants.

  Fields: ~
    {IOS_DEVICE}          (PlatformId) physical iOS device (iPhone or iPad)
    {IOS_SIMULATOR}       (PlatformId) iOS simulator (iPhone or iPad)
    {TVOS_SIMULATOR}      (PlatformId) tvOS simulator (Apple TV)
    {TVOS_DEVICE}         (PlatformId) tvOS device (Apple TV)
    {WATCHOS_SIMULATOR}   (PlatformId) watchOS simulator (Apple Watch)
    {WATCHOS_DEVICE}      (PlatformId) watchOS device (Apple Watch)
    {VISIONOS_SIMULATOR}  (PlatformId) visionOS simulator (Apple Glasses)
    {VISIONOS_DEVICE}     (PlatformId) visionOS device (Apple Glasses)
    {MACOS}               (PlatformId) macOS


M.Platform                                       *xcodebuild.constants.Platform*
  Platform type enum.

  Type: ~
    (PlatformConstants)


M.get_sdk({platform})                             *xcodebuild.constants.get_sdk*
  Returns the SDK name for the given platform.

  Parameters: ~
    {platform}  (PlatformId)

  Returns: ~
    (string)


M.is_simulator({platform})                   *xcodebuild.constants.is_simulator*
  Returns whether the given platform is a simulator.

  Parameters: ~
    {platform}  (PlatformId)

  Returns: ~
    (boolean)


M.is_device({platform})                         *xcodebuild.constants.is_device*
  Returns whether the given platform is a device.
  Note: macOS is not considered a device.

  Parameters: ~
    {platform}  (PlatformId)

  Returns: ~
    (boolean)


==============================================================================
Autocommands                                           *xcodebuild.core.autocmd*

This module is responsible for setting up autocommands.
It listens to the following events:
- `VimEnter`: when the user starts Neovim,
- `BufReadPost`: when a buffer is read.

These events are used to refresh marks and diagnostics.

M.setup()                                        *xcodebuild.core.autocmd.setup*
  Setup the autocommands for xcodebuild.nvim


==============================================================================
Default Options                                         *xcodebuild.core.config*

This module is responsible for setting up the configuration options.
It provides a set of default options and a function to override them.

M.setup({options})                                *xcodebuild.core.config.setup*
  Set up the configuration options.

  Parameters: ~
    {options}  (table|nil)

  See: ~
    |xcodebuild.options|


==============================================================================
Quickfix List                                         *xcodebuild.core.quickfix*

This module is responsible for setting up the quickfix list with
errors and warnings.

M.set({report})                                   *xcodebuild.core.quickfix.set*
  Sets the quickfix list based on the given {report}.
  It sets build errors, build warnings, test failures and test errors
  if the corresponding options are enabled.

  Parameters: ~
    {report}  (ParsedReport)

  See: ~
    |xcodebuild.xcode_logs.parser.ParsedReport|


==============================================================================
Xcodebuild Wrapper                                       *xcodebuild.core.xcode*

This module contains the wrapper for the `xcodebuild` tool.

It is used to interact with the Xcode project and perform various actions.

TargetMap                                      *xcodebuild.core.xcode.TargetMap*
  Hash map of targets to list of file paths.

  Type: ~
    table<string,string[]>


XcodeDevice                                  *xcodebuild.core.xcode.XcodeDevice*

  Fields: ~
    {platform}  (string|nil)
    {variant}   (string|nil)
    {arch}      (string|nil)
    {id}        (string|nil)
    {name}      (string|nil)
    {os}        (string|nil)
    {error}     (string|nil)


XcodeProjectInfo                        *xcodebuild.core.xcode.XcodeProjectInfo*

  Fields: ~
    {configs}  (string[])
    {targets}  (string[])
    {schemes}  (string[])


XcodeBuildOptions                      *xcodebuild.core.xcode.XcodeBuildOptions*

  Fields: ~
    {workingDirectory}  (string|nil)
    {buildForTesting}   (boolean|nil)
    {clean}             (boolean|nil)
    {projectFile}       (string|nil)
    {scheme}            (string)
    {destination}       (string)
    {extraBuildArgs}    (string[])
    {on_stdout}         (function)
    {on_stderr}         (fun(_:any,output:string[],_:any))
    {on_exit}           (fun(_:any,code:number,_:any))


XcodeTestOptions                        *xcodebuild.core.xcode.XcodeTestOptions*

  Fields: ~
    {workingDirectory}  (string|nil)
    {withoutBuilding}   (boolean|nil)
    {projectFile}       (string|nil)
    {scheme}            (string)
    {destination}       (string)
    {testPlan}          (string|nil)
    {testsToRun}        (string[]|nil)
    {extraTestArgs}     (string[])
    {on_stdout}         (function)
    {on_stderr}         (fun(_:any,output:string[],_:any))
    {on_exit}           (fun(_:any,code:number,_:any))


                                   *xcodebuild.core.xcode.XcodeEnumerateOptions*
XcodeEnumerateOptions

  Fields: ~
    {workingDirectory}  (string|nil)
    {projectFile}       (string)
    {scheme}            (string)
    {destination}       (string)
    {testPlan}          (string)
    {extraTestArgs}     (string[])


XcodeBuildSettings                    *xcodebuild.core.xcode.XcodeBuildSettings*

  Fields: ~
    {appPath}      (string)
    {productName}  (string)
    {bundleId}     (string)
    {buildDir}     (string|nil)


XcodeScheme                                  *xcodebuild.core.xcode.XcodeScheme*

  Fields: ~
    {name}      (string)
    {filepath}  (string|nil)


                                  *xcodebuild.core.xcode.find_derived_data_path*
M.find_derived_data_path({productName}, {workingDirectory})
  Returns derived data path for Swift Package {productName} that matches the {workingDirectory}.

  Parameters: ~
    {productName}       (string)
    {workingDirectory}  (string)

  Returns: ~
    (string|nil)


                                     *xcodebuild.core.xcode.get_targets_filemap*
M.get_targets_filemap({derivedDataPath})
  Returns a map of targets to list of file paths based on
  the `SwiftFileList` files in the build directory.

  If the build directory is not found, it returns an empty map.

  Parameters: ~
    {derivedDataPath}  (string|nil)

  Returns: ~
    (TargetMap)


                                        *xcodebuild.core.xcode.get_destinations*
M.get_destinations({projectFile}, {scheme}, {workingDirectory}, {callback})
  Returns the list of devices which match project requirements.

  Parameters: ~
    {projectFile}       (string|nil)
    {scheme}            (string)
    {workingDirectory}  (string|nil)
    {callback}          (fun(destinations:XcodeDevice[]))

  Returns: ~
    (number)   job id


                                             *xcodebuild.core.xcode.get_schemes*
M.get_schemes({projectFile}, {workingDirectory}, {callback})
  Returns the list of schemes for the given project.

  Parameters: ~
    {projectFile}       (string|nil)
    {workingDirectory}  (string|nil)
    {callback}          (fun(schemes:string[]))

  Returns: ~
    (number)   job id


                                            *xcodebuild.core.xcode.find_schemes*
M.find_schemes({xcodeprojPath}, {workingDirectory}, {callback})
  Returns the list of schemes for the given project.

  Parameters: ~
    {xcodeprojPath}     (string|nil)
    {workingDirectory}  (string|nil)
    {callback}          (fun(schemes:XcodeScheme[]))

  Returns: ~
    (number|nil)   job id


                                 *xcodebuild.core.xcode.get_project_information*
M.get_project_information({xcodeproj}, {workingDirectory}, {callback})
  Returns the list of project information including schemes, configs, and
  targets for the given {xcodeproj}.

  Parameters: ~
    {xcodeproj}         (string|nil)
    {workingDirectory}  (string|nil)
    {callback}          (fun(settings:XcodeProjectInfo))

  Returns: ~
    (number)   job id


                                           *xcodebuild.core.xcode.get_testplans*
M.get_testplans({projectFile}, {scheme}, {callback})
  Returns the list of test plans for the given project.

  Parameters: ~
    {projectFile}  (string)
    {scheme}       (string)
    {callback}     (fun(testPlans:string[]))

  Returns: ~
    (number)   job id


M.build_project({opts})                    *xcodebuild.core.xcode.build_project*
  Builds the project with the given options.

  Parameters: ~
    {opts}  (XcodeBuildOptions)

  Returns: ~
    (number)   job id


                                      *xcodebuild.core.xcode.get_build_settings*
M.get_build_settings({platform}, {projectFile}, {scheme}, {xcodeprojPath}, {callback})
  Returns the build settings for the given project.

  If one of the settings is not found, it will send an error notification.

  Parameters: ~
    {platform}       (string)
    {projectFile}    (string)
    {scheme}         (string)
    {xcodeprojPath}  (string)
    {callback}       (fun(settings:XcodeBuildSettings))

  Returns: ~
    (number|nil)   job id


                                             *xcodebuild.core.xcode.install_app*
M.install_app({platform}, {destination}, {appPath}, {callback})
  Installs the application on the given platform and destination.

  Parameters: ~
    {platform}     (string)
    {destination}  (string)
    {appPath}      (string)
    {callback}     (function|nil)

  Returns: ~
    (number)   job id


                                   *xcodebuild.core.xcode.install_app_on_device*
M.install_app_on_device({destination}, {appPath}, {callback})
  Installs the application on device.

  Parameters: ~
    {destination}  (string)
    {appPath}      (string)
    {callback}     (function|nil)

  Returns: ~
    (number)   job id


                                *xcodebuild.core.xcode.install_app_on_simulator*
M.install_app_on_simulator({destination}, {appPath}, {bootIfNeeded}, {callback})
  Installs the application on simulator.

  Parameters: ~
    {destination}   (string)
    {appPath}       (string)
    {bootIfNeeded}  (boolean|nil)
    {callback}      (function|nil)

  Returns: ~
    (number)   job id


                                    *xcodebuild.core.xcode.launch_app_on_device*
M.launch_app_on_device({destination}, {bundleId}, {callback})
  Launches the application on device.

  Parameters: ~
    {destination}  (string)
    {bundleId}     (string)
    {callback}     (function|nil)

  Returns: ~
    (number)   job id


                                 *xcodebuild.core.xcode.launch_app_on_simulator*
M.launch_app_on_simulator({destination}, {bundleId}, {waitForDebugger}, {callback})
  Launches the application on simulator.
  It also streams logs to file and DAP console.

  Parameters: ~
    {destination}      (string)
    {bundleId}         (string)
    {waitForDebugger}  (boolean)
    {callback}         (function|nil)

  Returns: ~
    (number)   job id


                                              *xcodebuild.core.xcode.launch_app*
M.launch_app({platform}, {destination}, {bundleId}, {waitForDebugger}, {callback})
  Launches the application on the given platform and destination.

  Parameters: ~
    {platform}         (string)
    {destination}      (string)
    {bundleId}         (string)
    {waitForDebugger}  (boolean)
    {callback}         (function|nil)

  Returns: ~
    (number|nil)   job id


                                          *xcodebuild.core.xcode.boot_simulator*
M.boot_simulator({destination}, {callback})
  Boots the simulator and launches the Simulator app if needed.

  Parameters: ~
    {destination}  (string)
    {callback}     (fun(success:boolean)|nil)

  Returns: ~
    (number)   job id


                            *xcodebuild.core.xcode.uninstall_app_from_simulator*
M.uninstall_app_from_simulator({destination}, {bundleId}, {callback})
  Uninstalls the application from simulator.

  Parameters: ~
    {destination}  (string)
    {bundleId}     (string)
    {callback}     (function|nil)

  Returns: ~
    (number)   job id


                               *xcodebuild.core.xcode.uninstall_app_from_device*
M.uninstall_app_from_device({destination}, {bundleId}, {callback})
  Uninstalls the application from device.

  Parameters: ~
    {destination}  (string)
    {bundleId}     (string)
    {callback}     (function|nil)

  Returns: ~
    (number)   job id


                                           *xcodebuild.core.xcode.uninstall_app*
M.uninstall_app({platform}, {destination}, {bundleId}, {callback})
  Uninstalls the application on the given platform and destination.

  Parameters: ~
    {platform}     (string)
    {destination}  (string)
    {bundleId}     (string)
    {callback}     (function|nil)

  Returns: ~
    (number)   job id


M.get_app_pid({productName}, {platform})     *xcodebuild.core.xcode.get_app_pid*
  Gets the pid of the application.
  Works only with simulator.

  Parameters: ~
    {productName}  (string)
    {platform}     (PlatformId|nil)

  Returns: ~
    (number|nil)   pid


                                                *xcodebuild.core.xcode.kill_app*
M.kill_app({productName}, {platform}, {callback})
  Kills the application.
  Works only with simulator.

  Parameters: ~
    {productName}  (string)
    {platform}     (PlatformId|nil)
    {callback}     (function|nil)


                                       *xcodebuild.core.xcode.get_code_coverage*
M.get_code_coverage({xctestresultPath}, {filepath}, {callback})
  Gets the code coverage for the given {filepath}.

  Parameters: ~
    {xctestresultPath}  (string)
    {filepath}          (string) # file to check
    {callback}          (fun(coverageData:string[]))

  Returns: ~
    (number)   job id


M.enumerate_tests({opts}, {callback})    *xcodebuild.core.xcode.enumerate_tests*
  Returns the list of tests for the given project.

  Parameters: ~
    {opts}      (XcodeEnumerateOptions)
    {callback}  (fun(tests:XcodeTest[]))

  Returns: ~
    (number)   job id


                             *xcodebuild.core.xcode.export_code_coverage_report*
M.export_code_coverage_report({xcresultPath}, {outputPath}, {callback})
  Exports the code coverage report from the given {xcresultPath}
  to the {outputPath}.
  Reports is exported in the JSON format.

  Parameters: ~
    {xcresultPath}  (string)
    {outputPath}    (string)
    {callback}      (function|nil)

  Returns: ~
    (number)   job id


M.run_tests({opts})                            *xcodebuild.core.xcode.run_tests*
  Runs tests with the given options.

  Parameters: ~
    {opts}  (XcodeTestOptions)

  Returns: ~
    (number)   job id


==============================================================================
Xcode Logs Parser                                 *xcodebuild.xcode_logs.parser*

This module is responsible for processing logs produced by `xcodebuild`
commands. It parses the logs and generates a report with tests
results, errors, and warnings.


ParsedTest                             *xcodebuild.xcode_logs.parser.ParsedTest*

  Fields: ~
    {filepath}        (string|nil) The file path of the test.
    {filename}        (string|nil) The file name of the test.
    {target}          (string|nil) The target name of the test.
                      Could be nil when running autogenerated test plan.
    {class}           (string) The class name of the test.
    {name}            (string) The test name of the test.
    {testResult}      (string) The result of the test (passed|failed).
    {success}         (boolean) If the test passed or failed.
    {lineNumber}      (number|nil) The line number of the test or
                      the place where it failed.
    {time}            (string|nil) The formatted time it took to run the test.
    {message}         (string[]|nil) The error message if the test failed.
    {swiftTestingId}  (string|nil) The id of the test in SwiftTesting.


                                 *xcodebuild.xcode_logs.parser.ParsedBuildError*
ParsedBuildError

  Fields: ~
    {filepath}      (string)
    {filename}      (string)
    {lineNumber}    (number)
    {columnNumber}  (number)
    {message}       (string[])


                          *xcodebuild.xcode_logs.parser.ParsedBuildGenericError*
ParsedBuildGenericError

  Fields: ~
    {source}   (string|nil)
    {message}  (string[])


                                  *xcodebuild.xcode_logs.parser.ParsedTestError*
ParsedTestError

  Fields: ~
    {filepath}    (string)
    {filename}    (string)
    {lineNumber}  (number)
    {message}     (string[])


                               *xcodebuild.xcode_logs.parser.ParsedBuildWarning*
ParsedBuildWarning

  Fields: ~
    {filepath}      (string)
    {filename}      (string)
    {lineNumber}    (number)
    {columnNumber}  (number)
    {message}       (string[])


                                     *xcodebuild.xcode_logs.parser.ParsedReport*
ParsedReport

  Fields: ~
    {output}            (string[]) The original logs output.
    {tests}             (table<string,ParsedTest[]>)
                        Tests report.
                        The key is `Target:Class` or `Class` if target
                        is not available.
    {testsCount}        (number) The total number of executed tests.
    {failedTestsCount}  (number) The total number of failed tests.
    {buildErrors}       (ParsedBuildError[]|ParsedBuildGenericError[])
                        The list of build errors.
                        It will be injected into LSP diagnostics and
                        quickfix list.
    {buildWarnings}     (ParsedBuildWarning[])
                        The list of build warnings.
                        It will be injected into LSP diagnostics and
                        quickfix list.
    {testErrors}        (ParsedTestError[])
                        The list of errors that occurred during tests
                        but not in test functions. It could be for
                        example some crash like force-unwrapping.
                        It will be injected into LSP diagnostics and
                        quickfix list.
    {usesSwiftTesting}  (boolean|nil)
    {xcresultFilepath}  (string|nil) The path to the xcresult file.


M.clear()                                   *xcodebuild.xcode_logs.parser.clear*
  Clears the parser state.


M.parse_logs({logLines})               *xcodebuild.xcode_logs.parser.parse_logs*
  Parses Xcode logs and generates the report with tests results,
  errors, and warnings.

  Returns partial report based on currently processed logs.
  Calling it multiple times appends the logs to the report, and
  returns the updated report.

  To process new logs, call `clear` before calling this function.

  Parameters: ~
    {logLines}  (string[]) Xcode log lines.

  Returns: ~
    (ParsedReport)


==============================================================================
Logs Panel                                         *xcodebuild.xcode_logs.panel*

                                                               *xcodebuild.logs*
This module contains the logs panel related functions.

Key bindings:
 - Press `o` on a failed test in the summary section to jump to the failing location
 - Press `q` to close the panel


M.clear()                                    *xcodebuild.xcode_logs.panel.clear*
  Clears the logs buffer.


                                  *xcodebuild.xcode_logs.panel.append_log_lines*
M.append_log_lines({lines}, {format})
  Appends {lines} to the logs buffer.

  Parameters: ~
    {lines}   (string[])
    {format}  (boolean|nil) default = true


                                          *xcodebuild.xcode_logs.panel.set_logs*
M.set_logs({report}, {isTesting}, {callback})
  Processes {report} and shows logs in the panel.
  It also writes the logs to the file.
  {callback} is called after the processing is finished.

  Parameters: ~
    {report}     (ParsedReport)
    {isTesting}  (boolean)
    {callback}   (function)

  See: ~
    |xcodebuild.xcode_logs.parser.ParsedReport|


M.open_logs({scrollToBottom})            *xcodebuild.xcode_logs.panel.open_logs*
  Opens the logs panel.

  Parameters: ~
    {scrollToBottom}  (boolean)


M.close_logs()                          *xcodebuild.xcode_logs.panel.close_logs*
  Closes the logs panel.


M.toggle_logs()                        *xcodebuild.xcode_logs.panel.toggle_logs*
  Toggles the logs panel.


M.setup_buffer({bufnr})               *xcodebuild.xcode_logs.panel.setup_buffer*
  Sets up the logs buffer.

  Parameters: ~
    {bufnr}  (number)


==============================================================================
Project Configuration                                *xcodebuild.project.config*

This module is responsible for managing the project settings.

Settings are saved in a JSON file located at `.nvim/xcodebuild/settings.json`.
This way each project can have its own settings.
It's important to open Neovim in the root directory of the project,
so the settings can be loaded.

                                     *xcodebuild.project.config.ProjectSettings*
ProjectSettings

  Fields: ~
    {deviceName}        (string|nil) device name (ex. "iPhone 12")
    {os}                (string|nil) OS version (ex. "14.5")
    {platform}          (PlatformId|nil) platform (ex. "iOS")
    {projectFile}       (string|nil) project file path (ex. "path/to/Project.xcodeproj")
    {scheme}            (string|nil) scheme name (ex. "MyApp")
    {destination}       (string|nil) destination (ex. "28B52DAA-BC2F-410B-A5BE-F485A3AFB0BC")
    {bundleId}          (string|nil) bundle identifier (ex. "com.mycompany.myapp")
    {appPath}           (string|nil) app path (ex. "path/to/MyApp.app")
    {buildDir}          (string|nil) buildDir (ex. "/path/to/DerivedData/app-abc123/Build/Products")
    {productName}       (string|nil) product name (ex. "MyApp")
    {testPlan}          (string|nil) test plan name (ex. "MyAppTests")
    {xcodeproj}         (string|nil) xcodeproj file path (ex. "path/to/Project.xcodeproj")
    {swiftPackage}      (string|nil) Swift Package file path (ex. "path/to/Package.swift")
    {workingDirectory}  (string|nil) parent directory of the project file
    {lastBuildTime}     (number|nil) last build time in seconds
    {showCoverage}      (boolean|nil) if the inline code coverage should be shown


DeviceCache                              *xcodebuild.project.config.DeviceCache*

  Fields: ~
    {scheme}       (string|nil)
    {projectFile}  (string|nil)
    {devices}      (XcodeDevice[]|nil)


M.settings                                  *xcodebuild.project.config.settings*
  Current project settings.

  Type: ~
    (ProjectSettings)


M.device_cache                          *xcodebuild.project.config.device_cache*
  Cached devices.

  Type: ~
    (DeviceCache|nil)


M.load_settings()                      *xcodebuild.project.config.load_settings*
  Loads the settings from the JSON file at `.nvim/xcodebuild/settings.json`.
  It also updates the global variables with the current settings.


M.save_settings()                      *xcodebuild.project.config.save_settings*
  Saves the settings to the JSON file at `.nvim/xcodebuild/settings.json`.
  It also updates the global variables with the current settings.


                               *xcodebuild.project.config.is_device_cache_valid*
M.is_device_cache_valid()
  Checks if device cache is valid.

  Returns: ~
    (boolean)


                                 *xcodebuild.project.config.update_device_cache*
M.update_device_cache({devices})
  Updates the device cache.

  Parameters: ~
    {devices}  (XcodeDevice[])


                                   *xcodebuild.project.config.save_device_cache*
M.save_device_cache()
  Saves the device cache to the JSON file at `.nvim/xcodebuild/devices.json`.


                                   *xcodebuild.project.config.load_device_cache*
M.load_device_cache()
  Loads the device cache from the JSON file at `.nvim/xcodebuild/devices.json`.


                                   *xcodebuild.project.config.is_spm_configured*
M.is_spm_configured()
  Checks if SPM project is configured.

  Returns: ~
    (boolean)


                               *xcodebuild.project.config.is_library_configured*
M.is_library_configured()
  Checks if Xcode static library is configured.

  Returns: ~
    (boolean)


                                   *xcodebuild.project.config.is_app_configured*
M.is_app_configured()
  Checks if Xcode app project is configured.

  Returns: ~
    (boolean)


M.is_configured()                      *xcodebuild.project.config.is_configured*
  Checks if project is configured.

  Returns: ~
    (boolean)


                                     *xcodebuild.project.config.update_settings*
M.update_settings({opts}, {callback})
  Updates the settings (`appPath`, `productName`, and `bundleId`) based on
  the current project.
  Calls `xcodebuild` commands to get the build settings.

  Parameters: ~
    {opts}      ({skipIfSamePlatform:boolean}) the options table
    {callback}  (function|nil) the callback function to be called after
                the settings are updated.


                                     *xcodebuild.project.config.set_destination*
M.set_destination({destination})
  Sets the selected destination.

  Parameters: ~
    {destination}  (XcodeDevice)


                                   *xcodebuild.project.config.configure_project*
M.configure_project()
  Starts configuration wizard to set up the project settings.


==============================================================================
App Data                                            *xcodebuild.project.appdata*

This module provides functionality to manage the project
data stored in `.nvim/xcodebuild` folder, such as logs,
reports, snapshots, coverage, and settings.

It also provides paths to the tools used by the plugin.

All data is stored in the current working directory in
the `.nvim/xcodebuild` folder. That's why it's important
to always run the plugin from the root of the project.

AppData                                     *xcodebuild.project.appdata.AppData*

  Fields: ~
    {report}                    (ParsedReport|table) # The last test report (can be empty).
    {appdir}                    (string) # The path to the `.nvim/xcodebuild` folder.
    {app_logs_filename}         (string) # The name of the app logs file.
    {app_logs_filepath}         (string) # The path to the app logs file.
    {original_logs_filename}    (string) # The name of the original logs file.
    {original_logs_filepath}    (string) # The path to the original logs file.
    {build_logs_filename}       (string) # The name of the build logs file.
    {build_logs_filepath}       (string) # The path to the build logs file.
    {report_filename}           (string) # The name of the report file.
    {report_filepath}           (string) # The path to the report file.
    {tests_filename}            (string) # The name of the tests file.
    {tests_filepath}            (string) # The path to the tests file.
    {snapshots_dir}             (string) # The path to the snapshots directory.
    {coverage_report_filepath}  (string) # The path to the coverage report file.
    {test_explorer_filepath}    (string) # The path to the test explorer file.
    {breakpoints_filepath}      (string) # The path to the breakpoints file.
    {GETSNAPSHOTS_TOOL}         (string) # The name of the getsnapshots tool.
    {PROJECT_HELPER_TOOL}       (string) # The name of the project helper tool.


M.tool_path({name})                       *xcodebuild.project.appdata.tool_path*
  Returns the path to the tool with the given {name}.

  Parameters: ~
    {name}  (string)

  Returns: ~
    (string)


                                     *xcodebuild.project.appdata.create_app_dir*
M.create_app_dir()
  Creates the `.nvim/xcodebuild` folder if it doesn't exist.


                                *xcodebuild.project.appdata.initialize_env_vars*
M.initialize_env_vars()
  Initializes the `.nvim/xcodebuild/env.txt` file.


                                *xcodebuild.project.appdata.initialize_run_args*
M.initialize_run_args()
  Initializes the `.nvim/xcodebuild/run_args.txt` file.


M.read_run_args()                     *xcodebuild.project.appdata.read_run_args*
  Reads the run arguments from disk.

  Returns: ~
    (string[]|nil)


M.read_env_vars()                     *xcodebuild.project.appdata.read_env_vars*
  Reads the environment variables from disk.

  Returns: ~
    (table<string,string>|nil)


                                 *xcodebuild.project.appdata.read_original_logs*
M.read_original_logs()
  Reads the original Xcode logs.

  Returns: ~
    (string[])


                                *xcodebuild.project.appdata.write_original_logs*
M.write_original_logs({data})
  Writes the original Xcode logs to disk.

  Parameters: ~
    {data}  (string[])


M.read_report()                         *xcodebuild.project.appdata.read_report*
  Reads the last test report from disk.

  Returns: ~
    (ParsedReport|nil)


M.write_report({report})               *xcodebuild.project.appdata.write_report*
  Writes the given {report} to disk.

  Parameters: ~
    {report}  (ParsedReport)


                                    *xcodebuild.project.appdata.read_build_logs*
M.read_build_logs()
  Reads the build logs from disk.
  These logs contain also the summary prepared by this
  plugin.

  Returns: ~
    (string[])


                                   *xcodebuild.project.appdata.write_build_logs*
M.write_build_logs({data})
  Writes the build logs to disk.
  These logs contain also the summary prepared by this
  plugin.

  Parameters: ~
    {data}  (string[])


                                   *xcodebuild.project.appdata.load_last_report*
M.load_last_report()
  Loads the last test report from disk and updates the
  quickfix list and the diagnostics.
  Sets `M.report`.


                                     *xcodebuild.project.appdata.clear_app_logs*
M.clear_app_logs()
  Clears the app logs and DAP console.


                                    *xcodebuild.project.appdata.append_app_logs*
M.append_app_logs({output})
  Appends the given {output} to the app logs file and
  updates the DAP console.

  Parameters: ~
    {output}  (string[])


                           *xcodebuild.project.appdata.write_test_explorer_data*
M.write_test_explorer_data({report})
  Writes Test Explorer data to disk.

  Parameters: ~
    {report}  (TestExplorerNode[])


                            *xcodebuild.project.appdata.read_test_explorer_data*
M.read_test_explorer_data()
  Reads Test Explorer data from disk.

  Returns: ~
    (TestExplorerNode[]|nil)


==============================================================================
Project Builder                                     *xcodebuild.project.builder*

This module contains the functionality to build the project.

It interacts with multiple modules to build the project
and present the results.

It also sends notifications and events to the user.

                                  *xcodebuild.project.builder.build_and_run_app*
M.build_and_run_app({waitForDebugger}, {callback})
  Builds and runs the app on device or simulator.

  Parameters: ~
    {waitForDebugger}  (boolean)
    {callback}         (function|nil)

  See: ~
    |xcodebuild.platform.device.run_app|
    |xcodebuild.project.builder.build_project|


M.build_project({opts}, {callback})   *xcodebuild.project.builder.build_project*
  Builds the project.
  Sets quickfix list, logs, and sends notifications.

  Parameters: ~
    {opts}      (table|nil)
                * {buildForTesting} (boolean|nil)
                * {doNotShowSuccess} (boolean|nil)
                  if should send the notification
                * {clean} (boolean|nil) runs clean build
    {callback}  (function|nil)

  See: ~
    |xcodebuild.core.xcode.build_project|


                                 *xcodebuild.project.builder.clean_derived_data*
M.clean_derived_data()
  Cleans the `DerivedData` folder.
  It will ask for confirmation before deleting it.


==============================================================================
Project Manager                                     *xcodebuild.project.manager*

                                                    *xcodebuild.project-manager*
This module is responsible for managing the project files and groups.

It uses the `xcodeproj` tool to update the Xcode project file.

In general, all functions that take paths as arguments, they don't
change files on disk. These without arguments are interactive and
perform changes on disk too.

All actions send notifications to the user.

Additionally, the `Project Manager` will try predicting targets for newly created files based on their location.
If you prefer to select targets manually, you can always disable it in the configuration using
`project_manager.guess_target`.

See: https://github.com/CocoaPods/Xcodeproj

                                    *xcodebuild.project.manager.create_new_file*
M.create_new_file()
  Creates a new file in the project and on disk.
  It asks for the file name and creates it in the current directory.
  It also asks the user to select targets.


                                *xcodebuild.project.manager.add_file_to_targets*
M.add_file_to_targets({filepath}, {targets})
  Adds the file to the selected targets.
  The group from {filepath} must exist in the project.

  Parameters: ~
    {filepath}  (string)
    {targets}   (string[])


                                *xcodebuild.project.manager.get_project_targets*
M.get_project_targets()
  Returns all project targets.

  Returns: ~
    (string[]|nil)


                                           *xcodebuild.project.manager.add_file*
M.add_file({filepath}, {callback}, {opts})
  Adds the file to project.
  Asks the user to select the targets or tries to guess them.

  If {opts.createGroups} is `true`, all groups from {filepath} will be created if needed.

  Calls the {callback} after the file has been added to the targets or the user has canceled the action.

  Parameters: ~
    {filepath}  (string)
    {callback}  (function|nil)
    {opts}      ({createGroups:boolean}|nil)


                                   *xcodebuild.project.manager.add_current_file*
M.add_current_file()
  Adds the current file to the selected targets.
  Ask the user to select the targets.
  All groups will be added to the project if they are not already there.


                                          *xcodebuild.project.manager.move_file*
M.move_file({oldFilePath}, {newFilePath})
  Moves the file to the new path in the project.
  The group from {newFilePath} must exist in the project.

  Parameters: ~
    {oldFilePath}  (string)
    {newFilePath}  (string)


                                        *xcodebuild.project.manager.rename_file*
M.rename_file({oldFilePath}, {newFilePath})
  Renames the file in the project.

  Parameters: ~
    {oldFilePath}  (string)
    {newFilePath}  (string)


                                *xcodebuild.project.manager.rename_current_file*
M.rename_current_file()
  Renames the current file in the project and on disk.
  Asks the user for the new file name.


M.delete_file({filepath})               *xcodebuild.project.manager.delete_file*
  Deletes the file from the project.

  Parameters: ~
    {filepath}  (string)


                                *xcodebuild.project.manager.delete_current_file*
M.delete_current_file()
  Deletes the current file from the project and disk.
  Asks the user for confirmation.


                                   *xcodebuild.project.manager.create_new_group*
M.create_new_group()
  Creates a new group in the project and on disk.
  Asks the user for the group name.


M.add_group({path})                       *xcodebuild.project.manager.add_group*
  Adds the group to the project.

  Parameters: ~
    {path}  (string)


                                  *xcodebuild.project.manager.add_current_group*
M.add_current_group()
  Adds the current group to the project.


                                       *xcodebuild.project.manager.rename_group*
M.rename_group({oldGroupPath}, {newGroupPath})
  Renames the group in the project.

  Parameters: ~
    {oldGroupPath}  (string)
    {newGroupPath}  (string)


                               *xcodebuild.project.manager.rename_current_group*
M.rename_current_group()
  Renames the current group in the project and on disk.
  Asks the user for the new group name.


                               *xcodebuild.project.manager.move_or_rename_group*
M.move_or_rename_group({oldGroupPath}, {newGroupPath})
  Moves or renames the group in the project.
  If the parent path is different, it moves the group.
  If the parent path is the same, it renames the group.
  The parent group of {newGroupPath} must exist.

  Parameters: ~
    {oldGroupPath}  (string)
    {newGroupPath}  (string)


M.delete_group()                       *xcodebuild.project.manager.delete_group*
  Deletes the group from the project.


                               *xcodebuild.project.manager.delete_current_group*
M.delete_current_group()
  Deletes the current group from the project and disk.
  Asks the user for confirmation.


                        *xcodebuild.project.manager.update_current_file_targets*
M.update_current_file_targets()
  Updates the file targets in the project.
  Asks the user to select the targets.


M.guess_target({groupPath})            *xcodebuild.project.manager.guess_target*
  Finds the first existing group in the project for the provided {groupPath}
  and tries to list targets for the first Swift file it encounters there or in subgroups.

  If it fails, it repeats the process one more time for the parent group.

  Note: This method could be inaccurate. However, it's good enough heuristic for most cases.
  If needed, you can always manually select the targets.

  Parameters: ~
    {groupPath}  (string)

  Returns: ~
    (string[]|nil)


                          *xcodebuild.project.manager.show_current_file_targets*
M.show_current_file_targets()
  Shows the targets for the current file.


                                 *xcodebuild.project.manager.show_action_picker*
M.show_action_picker()
  Shows the action picker with all available actions.


==============================================================================
Project Assets Manager                               *xcodebuild.project.assets*

This module contains the functionality to manage Xcode project assets.

It allows to add, delete, and browse assets in the project.
Supported asset types are: images, colors, and data.

                                        *xcodebuild.project.assets.create_image*
M.create_image({filename}, {path}, {template})
  Creates a new image set.

  Parameters: ~
    {filename}  (string)
    {path}      (string)
    {template}  (boolean) renderings as template


M.create_data({filename}, {path})        *xcodebuild.project.assets.create_data*
  Creates a new data set.

  Parameters: ~
    {filename}  (string)
    {path}      (string)


M.create_color({name}, {color}, {path}) *xcodebuild.project.assets.create_color*
  Creates a new color set.

  Parameters: ~
    {name}   (string) color name
    {color}  (string) color in hex format, e.g. #FF0000
    {path}   (string)


                                *xcodebuild.project.assets.delete_folder_picker*
M.delete_folder_picker()
  Shows a picker to delete a folder.


                             *xcodebuild.project.assets.create_new_asset_picker*
M.create_new_asset_picker()
  Shows a wizard to create a new asset.


                                   *xcodebuild.project.assets.show_asset_picker*
M.show_asset_picker({reveal})
  Shows a picker with all the assets in the project.
  Opens the asset in Finder or Quick Look.

  Parameters: ~
    {reveal}  (boolean) reveal in Finder


                                 *xcodebuild.project.assets.delete_asset_picker*
M.delete_asset_picker()
  Shows a picker to delete an asset.


                                 *xcodebuild.project.assets.show_assets_manager*
M.show_assets_manager()
  Shows the Assets Manager with all available actions.


==============================================================================
Device                                              *xcodebuild.platform.device*

This module contains the functionality to interact with devices
and simulators.

It is used to install, uninstall, and run the application.
You can also boot the simulator and kill the application using this module.

M.kill_app({callback})                     *xcodebuild.platform.device.kill_app*
  Kills the application on device, simulator, or macOS.

  Parameters: ~
    {callback}  (function|nil)


M.run_app({waitForDebugger}, {callback})    *xcodebuild.platform.device.run_app*
  Runs the application on device, simulator, or macOS.

  Parameters: ~
    {waitForDebugger}  (boolean)
    {callback}         (function|nil)


                                     *xcodebuild.platform.device.boot_simulator*
M.boot_simulator({callback})
  Boots the simulator.

  Parameters: ~
    {callback}  (function|nil)


M.install_app({callback})               *xcodebuild.platform.device.install_app*
  Installs the application on device or simulator.
  Does not support macOS.

  Parameters: ~
    {callback}  (function|nil)


M.uninstall_app({callback})           *xcodebuild.platform.device.uninstall_app*
  Uninstalls the application from device or simulator.
  Does not support macOS.

  Parameters: ~
    {callback}  (function|nil)


==============================================================================
Device Proxy                                  *xcodebuild.platform.device_proxy*

This module contains the functionality to interact with physical devices
using the `pymobiledevice3` tool.

It allows to install, uninstall, run, kill applications, list connected
devices, and start the debugger.

This module is used for interactions with physical devices with iOS
below version 17 and with all physical devices to start debugger.
For other devices, the |xcodebuild.core.xcode| module is used.

The tool can be installed by:
>bash
    python3 -m pip install -U pymobiledevice
<

See:
  https://github.com/wojciech-kulik/xcodebuild.nvim/wiki/Features#-availability
  https://github.com/wojciech-kulik/xcodebuild.nvim/wiki/Integrations#-debugging-on-ios-17
  https://github.com/doronz88/pymobiledevice3

Device                                 *xcodebuild.platform.device_proxy.Device*

  Fields: ~
    {id}        (string)
    {name}      (string)
    {os}        (string)
    {platform}  (PlatformId)


                                   *xcodebuild.platform.device_proxy.is_enabled*
M.is_enabled()
  Checks if the `pymobiledevice` integration is enabled and the tool is installed.

  Returns: ~
    (boolean)


                                 *xcodebuild.platform.device_proxy.is_installed*
M.is_installed()
  Checks if the `pymobiledevice3` tool is installed.

  Returns: ~
    (boolean)


                        *xcodebuild.platform.device_proxy.validate_installation*
M.validate_installation()
  Validates if the `pymobiledevice3` tool is installed.
  If not, it sends an error notification.

  Returns: ~
    (boolean)


                                   *xcodebuild.platform.device_proxy.should_use*
M.should_use()
  Checks if the `pymobiledevice3` tool is installed and
  if it should be used. The tools is used only for physical devices
  with iOS below 17. If the iOS version is unknown, it tries to fetch it
  and returns false.

  This function is intended to check if the tool should be used
  for actions like install, uninstall, and run the application.

  This tool should be always used for debugging if it's installed.

  Returns: ~
    (boolean)


                                  *xcodebuild.platform.device_proxy.install_app*
M.install_app({destination}, {appPath}, {callback})
  Installs the application on the device.

  Parameters: ~
    {destination}  (string) # device id
    {appPath}      (string) # device path to the app
    {callback}     (function|nil)

  Returns: ~
    (number)   job id


                                *xcodebuild.platform.device_proxy.uninstall_app*
M.uninstall_app({destination}, {bundleId}, {callback})
  Uninstalls the application with the provided bundle id.

  Parameters: ~
    {destination}  (string) # device id
    {bundleId}     (string)
    {callback}     (function|nil)

  Returns: ~
    (number)   job id


                                   *xcodebuild.platform.device_proxy.launch_app*
M.launch_app({destination}, {bundleId}, {callback})
  Launches the application with the provided bundle id.

  Parameters: ~
    {destination}  (string) # device id
    {bundleId}     (string)
    {callback}     (function|nil)

  Returns: ~
    (number)   job id


                                     *xcodebuild.platform.device_proxy.kill_app*
M.kill_app({appName}, {callback})
  Kills the application with the provided name.

  Parameters: ~
    {appName}   (string)
    {callback}  (function|nil)

  Returns: ~
    (number)   job id


                        *xcodebuild.platform.device_proxy.get_connected_devices*
M.get_connected_devices({callback})
  Returns the list of connected devices.

  Parameters: ~
    {callback}  (fun(devices:Device[])|nil)

  Returns: ~
    (number)   job id


                                *xcodebuild.platform.device_proxy.find_app_path*
M.find_app_path({destination}, {bundleId})
  Returns the path to the application on the device.

  Parameters: ~
    {destination}  (string) # device id
    {bundleId}     (string)

  Returns: ~
    (string|nil)   app path


                          *xcodebuild.platform.device_proxy.start_secure_server*
M.start_secure_server({destination}, {rsd})
  Starts the secure server.
  It is used on devices with iOS 17 and above.

  Returns the command to connect to the device using `codelldb`.

  Parameters: ~
    {destination}  (string) # device id
    {rsd}          (string) # rsd parameter

  Returns: ~
    (string|nil)   connection command


                                 *xcodebuild.platform.device_proxy.start_server*
M.start_server({destination}, {port}, {callback})
  Starts the server.
  It is used on devices with iOS below 17.

  The callback returns {connection_string} that can be used to connect
  to the device using `codelldb`.

  This process must be alive during the debugging session.
  Later, it can be closed with `vim.fn.jobstop({job_id})`.

  Parameters: ~
    {destination}  (string) # device id
    {port}         (number)
    {callback}     (fun(connection_string:string)|nil)

  Returns: ~
    (number)   job id


                         *xcodebuild.platform.device_proxy.create_secure_tunnel*
M.create_secure_tunnel({destination}, {callback})
  Creates a secure tunnel with the device.
  It is used on devices with iOS 17 and above.

  Next with the received {rsd} parameter, the server can be started
  with the `start_secure_server` function.

  This process must be alive during the debugging session.
  Later, it can be closed with the `close_secure_tunnel` function.

  It can't be stopped with `vim.fn.jobstop(job_id)` because it's
  running with `sudo`.

  Requires passwordless `sudo` for the `remote_debugger` tool.

  Parameters: ~
    {destination}  (string) # device id
    {callback}     (fun(rsd:string)|nil)

  Returns: ~
    (number|nil)   job id


                          *xcodebuild.platform.device_proxy.close_secure_tunnel*
M.close_secure_tunnel()
  Closes the secure tunnel with the device.

  Requires passwordless `sudo` for the `remote_debugger` tool.


==============================================================================
macOS Platform Integration                           *xcodebuild.platform.macos*

This module is responsible for the integration of macOS platform with `nvim-dap`.

M.launch_app({appPath}, {callback})       *xcodebuild.platform.macos.launch_app*
  Simply starts the application on macOS.

  Parameters: ~
    {appPath}   (string)
    {callback}  (function|nil)

  Returns: ~
    (number)   job id


                                    *xcodebuild.platform.macos.launch_and_debug*
M.launch_and_debug({appPath}, {callback})
  Starts the application on macOS and starts the debugger.

  Parameters: ~
    {appPath}   (string)
    {callback}  (function|nil)

  Returns: ~
    (number|nil)   job id


==============================================================================
Autocommand Events                              *xcodebuild.broadcasting.events*

                                                             *xcodebuild.events*
This module is responsible for broadcasting events about the build and
tests status. It also updates some global variables to be used in the UI.

You can customize integration with xcodebuild.nvim plugin by subscribing to notifications.

Example:
>lua
    vim.api.nvim_create_autocmd("User", {
      pattern = "XcodebuildTestsFinished",
      callback = function(event)
        print("Tests finished (passed: "
            .. event.data.passedCount
            .. ", failed: "
            .. event.data.failedCount
            .. ")"
        )
      end,
    })
<
All available autocommand patterns:

 | Pattern                          |
 | -------------------------------- |
 | `XcodebuildBuildStarted`           |
 | `XcodebuildBuildStatus`            |
 | `XcodebuildBuildFinished`          |
 | `XcodebuildTestsStarted`           |
 | `XcodebuildTestsStatus`            |
 | `XcodebuildTestsFinished`          |
 | `XcodebuildApplicationLaunched`    |
 | `XcodebuildActionCancelled`        |
 | `XcodebuildProjectSettingsUpdated` |
 | `XcodebuildTestExplorerToggled`    |
 | `XcodebuildCoverageToggled`        |
 | `XcodebuildCoverageReportToggled`  |
 | `XcodebuildLogsToggled`            |

For payload details of each event, see the respective function.


                                  *xcodebuild.broadcasting.events.build_started*
M.build_started({forTesting})
  Notifies that the build has been started.
  It triggers the `XcodebuildBuildStarted` autocommand and clears the
  global variable `xcodebuild_last_status`.

  Parameters: ~
    {forTesting}  (boolean) if the build is for testing.


                                   *xcodebuild.broadcasting.events.build_status*
M.build_status({forTesting}, {progress}, {duration})
  Notifies about the build progress.
  It triggers the `XcodebuildBuildStatus` autocommand and updates global
  variable `xcodebuild_last_status`.

  Set {progress} to nil when the expected duration is unknown.

  Parameters: ~
    {forTesting}  (boolean) if the build is for testing.
    {progress}    (number|nil) the progress percentage (0-100).
    {duration}    (number) the duration of the build in seconds.


                                 *xcodebuild.broadcasting.events.build_finished*
M.build_finished({forTesting}, {success}, {cancelled}, {errors})
  Notifies that the build has been finished.
  It triggers the `XcodebuildBuildFinished` autocommand and updates global
  variable `xcodebuild_last_status`.

  Parameters: ~
    {forTesting}  (boolean) if the build is for testing.
    {success}     (boolean) if the build was successful.
    {cancelled}   (boolean) if the build was cancelled.
    {errors}      (ParsedBuildError[]|ParsedBuildGenericError[]) build errors.


                                  *xcodebuild.broadcasting.events.tests_started*
M.tests_started()
  Notifies that tests have been started.
  It triggers the `XcodebuildTestsStarted` autocommand and clears the
  global variable `xcodebuild_last_status`.


                                   *xcodebuild.broadcasting.events.tests_status*
M.tests_status({passedCount}, {failedCount})
  Notifies about tests progress.
  It triggers the `XcodebuildTestsStatus` autocommand and updates global
  variable `xcodebuild_last_status`.

  Parameters: ~
    {passedCount}  (number) the number of passed tests.
    {failedCount}  (number) the number of failed tests.


                                 *xcodebuild.broadcasting.events.tests_finished*
M.tests_finished({passedCount}, {failedCount}, {cancelled})
  Notifies that tests have been finished.
  It triggers the `XcodebuildTestsFinished` autocommand and updates global
  variable `xcodebuild_last_status`.

  Parameters: ~
    {passedCount}  (number) the number of passed tests.
    {failedCount}  (number) the number of failed tests.
    {cancelled}    (boolean) if tests were cancelled.


                           *xcodebuild.broadcasting.events.application_launched*
M.application_launched()
  Notifies that the application has been launched.
  It triggers the `XcodebuildApplicationLaunched` autocommand.


                               *xcodebuild.broadcasting.events.action_cancelled*
M.action_cancelled()
  Notifies that the last action has been cancelled.
  It triggers the `XcodebuildActionCancelled` autocommand.


                       *xcodebuild.broadcasting.events.project_settings_updated*
M.project_settings_updated({settings})
  Notifies that the project settings have been updated.
  It triggers the `XcodebuildProjectSettingsUpdated` autocommand.

  Parameters: ~
    {settings}  (ProjectSettings) the updated settings.


                          *xcodebuild.broadcasting.events.toggled_test_explorer*
M.toggled_test_explorer({visible}, {bufnr}, {winnr})
  Notifies that the test explorer has been toggled.
  It triggers the `XcodebuildTestExplorerToggled` autocommand.

  Parameters: ~
    {visible}  (boolean) if the test explorer is visible.
    {bufnr}    (number|nil) the buffer number with the test explorer.
    {winnr}    (number|nil) the window number with the test explorer.


                          *xcodebuild.broadcasting.events.toggled_code_coverage*
M.toggled_code_coverage({visible})
  Notifies that the code coverage has been toggled.
  It triggers the `XcodebuildCoverageToggled` autocommand.

  Parameters: ~
    {visible}  (boolean) if the code coverage is visible.


                   *xcodebuild.broadcasting.events.toggled_code_coverage_report*
M.toggled_code_coverage_report({visible}, {bufnr}, {winnr})
  Notifies that the code coverage report has been toggled.
  It triggers the `XcodebuildCoverageReportToggled` autocommand.

  Parameters: ~
    {visible}  (boolean) if the code coverage report is visible.
    {bufnr}    (number|nil) the buffer number with the report.
    {winnr}    (number|nil) the window number with the report.


                                   *xcodebuild.broadcasting.events.toggled_logs*
M.toggled_logs({visible}, {bufnr}, {winnr})
  Notifies that the logs have been toggled.
  It triggers the `XcodebuildLogsToggled` autocommand.

  Parameters: ~
    {visible}  (boolean) if the logs are visible.
    {bufnr}    (number|nil) the buffer number with logs.
    {winnr}    (number|nil) the window number with logs.


==============================================================================
Notifications                            *xcodebuild.broadcasting.notifications*

                                                      *xcodebuild.notifications*
This module is responsible for sending notifications to the user.

All notifications are sent via |xcodebuild.core.config.options.logs| functions:
- `notify({message}, {severity})`
- `notify_progress({message})`

This way the user can customize the notifications and the progress bar.

They can also be disabled or integrated with other plugins like `fidget.nvim`.


                       *xcodebuild.broadcasting.notifications.start_build_timer*
M.start_build_timer({buildForTesting})
  Starts the build timer.

  Parameters: ~
    {buildForTesting}  (boolean) if the build is for testing.

  Returns: ~
    (number)   the id of the current build


                        *xcodebuild.broadcasting.notifications.stop_build_timer*
M.stop_build_timer()
  Stops the build timer if exists.


                     *xcodebuild.broadcasting.notifications.send_build_finished*
M.send_build_finished({report}, {id}, {isCancelled}, {opts})
  Sends a message that the build is finished.

  Parameters: ~
    {report}       (ParsedReport) the build report.
    {id}           (number) the id of the current build.
    {isCancelled}  (boolean) if the build was cancelled.
    {opts}         (table|nil) additional options.
                   * {doNotShowSuccess} (boolean|nil)
                     if true, the success message will not be sent.


                      *xcodebuild.broadcasting.notifications.send_tests_started*
M.send_tests_started()
  Sends a message that tests have been started.


                     *xcodebuild.broadcasting.notifications.show_tests_progress*
M.show_tests_progress({report})
  Sends a message that tests are in progress.
  Notifies about the progress of tests.

  Parameters: ~
    {report}  (ParsedReport) the test report.


                     *xcodebuild.broadcasting.notifications.send_tests_finished*
M.send_tests_finished({report}, {isCancelled})
  Sends a message that tests have been finished.
  Notifies also about the result of tests.

  Parameters: ~
    {report}       (ParsedReport) the test report.
    {isCancelled}  (boolean) if tests were cancelled.


                   *xcodebuild.broadcasting.notifications.send_project_settings*
M.send_project_settings({settings})
  Sends the project settings.

  Parameters: ~
    {settings}  (ProjectSettings) the project settings.


                                    *xcodebuild.broadcasting.notifications.send*
M.send({message}, {severity})
  Forwards the notification to the callback from the config.

  Parameters: ~
    {message}   (string) the message to send.
    {severity}  (number|nil) the severity of the message.

  See: ~
    |vim.log.levels|


                              *xcodebuild.broadcasting.notifications.send_error*
M.send_error({message})
  Forwards the notification to the callback from the config.

  Parameters: ~
    {message}  (string) the message to send.


                            *xcodebuild.broadcasting.notifications.send_warning*
M.send_warning({message})
  Forwards the notification to the callback from the config.

  Parameters: ~
    {message}  (string) the message to send.


                           *xcodebuild.broadcasting.notifications.send_progress*
M.send_progress({message})
  Forwards the notification to the callback from the config.

  Parameters: ~
    {message}  (string) the message to send.


==============================================================================
Test Diagnostics                                  *xcodebuild.tests.diagnostics*

This module is responsible for handling diagnostics and marks for test files.

                              *xcodebuild.tests.diagnostics.refresh_test_buffer*
M.refresh_test_buffer({bufnr}, {report})
  Refreshes the diagnostics and marks for the given buffer.

  Parameters: ~
    {bufnr}   (number)
    {report}  (ParsedReport)

  See: ~
    |xcodebuild.xcode_logs.parser.ParsedReport|


                      *xcodebuild.tests.diagnostics.refresh_test_buffer_by_name*
M.refresh_test_buffer_by_name({name}, {report})
  Refreshes diagnostics and marks for the test buffer with the given name.

  It implements a debounce mechanism to avoid refreshing
  the same buffer multiple times.The window is 1 second.

  Note: this function will affect the buffer after 1 second.
  To refresh the buffer instantly use `refresh_test_buffer`.


  Parameters: ~
    {name}    (string)
    {report}  (ParsedReport)


                         *xcodebuild.tests.diagnostics.refresh_all_test_buffers*
M.refresh_all_test_buffers({report})
  Refreshes diagnostics and marks for all test buffers.

  Parameters: ~
    {report}  (ParsedReport)

  See: ~
    |xcodebuild.xcode_logs.parser.ParsedReport|


M.clear()                                   *xcodebuild.tests.diagnostics.clear*
  Clears marks and diagnostics.


M.clear_marks()                       *xcodebuild.tests.diagnostics.clear_marks*
  Clears marks.


M.setup()                                   *xcodebuild.tests.diagnostics.setup*
  Set up highlights for tests.


==============================================================================
Test Enumeration Parser                    *xcodebuild.tests.enumeration_parser*

This module contains the parser for the:
`xcodebuild enumerate-tests` command results.

See |xcodebuild.core.xcode.enumerate_tests| for more details.

                                 *xcodebuild.tests.enumeration_parser.XcodeTest*
XcodeTest

  Fields: ~
    {id}       (string)
    {target}   (string)
    {class}    (string)
    {name}     (string)
    {enabled}  (boolean)


                                     *xcodebuild.tests.enumeration_parser.parse*
M.parse({filepath})
  Parses the test enumeration results from `xcodebuild` command.

  Parameters: ~
    {filepath}  (string)

  Returns: ~
    (XcodeTest[])

  See: ~
    |xcodebuild.core.xcode.enumerate_tests|


==============================================================================
Test Explorer                                        *xcodebuild.tests.explorer*

                                                      *xcodebuild.test-explorer*
This module contains the Test Explorer functionality.

The Test Explorer is a UI that shows the status of tests
and allows the user to run, repeat, and open tests.

Tests are presented as a tree structure with targets,
classes, and tests.

Key mappings:
 - Press `o` to jump to the test implementation
 - Press `t` to run selected tests
 - Press `T` to re-run recently selected tests
 - Press `R` to reload test list
 - Press `X` to clear test list
 - Press `[` to jump to the previous failed test
 - Press `]` to jump to the next failed test
 - Press `<cr>` to expand or collapse the current node
 - Press `<tab>` to expand or collapse all classes
 - Press `g?` to show all key mappings
 - Press `q` to close the Test Explorer


                              *xcodebuild.tests.explorer.TestExplorerNodeStatus*
TestExplorerNodeStatus
  Report node status.

  Variants: ~
    ("not_executed")
    ("partial_execution")
    ("passed")
    ("running")
    ("passed")
    ("failed")
    ("disabled")


                                *xcodebuild.tests.explorer.TestExplorerNodeKind*
TestExplorerNodeKind
  Report node type.

  Variants: ~
    ("target")
    ("class")
    ("test")


                                    *xcodebuild.tests.explorer.TestExplorerNode*
TestExplorerNode

  Fields: ~
    {id}              (string)
    {swiftTestingId}  (string|nil)
    {kind}            (TestExplorerNodeKind)
    {status}          (TestExplorerNodeStatus)
    {name}            (string)
    {hidden}          (boolean)
    {filepath}        (string|nil)
    {lineNumber}      (number|nil)
    {classes}         (TestExplorerNode[]|nil)
    {tests}           (TestExplorerNode[]|nil)


M.report                                      *xcodebuild.tests.explorer.report*
  Tree structure with tests report.

  It's a list of targets, each target has a list of classes,
  and each class has a list of tests.


  Type: ~
    (TestExplorerNode[])


                                  *xcodebuild.tests.explorer.toggle_all_classes*
M.toggle_all_classes()
  Collapses or expands all classes.


                                 *xcodebuild.tests.explorer.toggle_current_node*
M.toggle_current_node()
  Collapses or expands the current node.


                                  *xcodebuild.tests.explorer.open_selected_test*
M.open_selected_test()
  Opens the selected test or class under the cursor.
  It navigates to the previous window to avoid
  navigation in Test Explorer window.


M.start_tests({selectedTests})           *xcodebuild.tests.explorer.start_tests*
  Changes status to `running` for all test ids from
  {selectedTests}. If {selectedTests} is nil, then
  all enabled tests will be marked as `running`.

  Parameters: ~
    {selectedTests}  (string[]|nil) test ids


M.finish_tests()                        *xcodebuild.tests.explorer.finish_tests*
  Stops the animation and changes the status of `running`
  tests to `not_executed`.


                                  *xcodebuild.tests.explorer.update_test_status*
M.update_test_status({testId}, {status}, {opts})
  Updates the status of the test with the provided {testId}.
  It also updates parent nodes.

  Parameters: ~
    {testId}  (string)
    {status}  (TestExplorerNodeStatus)
    {opts}    ({filepath:string|nil,lineNumber:number|nil,swiftTestingId:string|nil})


                                 *xcodebuild.tests.explorer.jump_to_failed_test*
M.jump_to_failed_test({next})
  Jumps to the next or previous failed test on the list.

  Parameters: ~
    {next}  (boolean)


                                     *xcodebuild.tests.explorer.repeat_last_run*
M.repeat_last_run()
  Repeats the last executed tests or runs all tests.


                                  *xcodebuild.tests.explorer.run_selected_tests*
M.run_selected_tests()
  Runs the selected tests (in visual-mode).


M.clear({showInfoMessage})                     *xcodebuild.tests.explorer.clear*
  Clears the Test Explorer buffer.

  Parameters: ~
    {showInfoMessage}  (boolean|nil) default: true


M.toggle()                                    *xcodebuild.tests.explorer.toggle*
  Toggles the Test Explorer window.


M.hide()                                        *xcodebuild.tests.explorer.hide*
  Hides the Test Explorer window.


M.show()                                        *xcodebuild.tests.explorer.show*
  Shows the Test Explorer window.


M.load_tests({tests})                     *xcodebuild.tests.explorer.load_tests*
  Loads tests and generates the report.

  Parameters: ~
    {tests}  (XcodeTest[])


M.show_help()                              *xcodebuild.tests.explorer.show_help*
  Shows the help with mappings.


M.setup()                                      *xcodebuild.tests.explorer.setup*
  Sets up the Test Explorer. Loads last report if available.


==============================================================================
Test Provider                                        *xcodebuild.tests.provider*

This module contains the functionality to find tests
based on the provided options.

It is used by the |xcodebuild.tests.runner| module.

                                 *xcodebuild.tests.provider.TestProviderOptions*
TestProviderOptions

  Fields: ~
    {selectedTests}  (boolean|nil)
    {currentTest}    (boolean|nil)
    {failingTests}   (boolean|nil)


                                    *xcodebuild.tests.provider.TestProviderTest*
TestProviderTest

  Fields: ~
    {name}      (string)
    {class}     (string)
    {filepath}  (string|nil)


M.find_tests({opts})                      *xcodebuild.tests.provider.find_tests*
  Finds tests based on the provided {opts}.
  Returns a tuple with the test class found in the buffer
  and a list of tests.

  Set `opts.selectedTests` to true to find all selected tests.
  Set `opts.currentTest` to true to find the current test.
  Set `opts.failingTests` to true to find all failing tests
  across the project.

  Parameters: ~
    {opts}  (TestProviderOptions)

  Returns: ~
    (string|nil)           className
    (TestProviderTest[])   tests


==============================================================================
Test Runner                                            *xcodebuild.tests.runner*

This module contains the functionality to run tests.

It interacts with multiple modules to build, run, and
present test results.

M.reload_tests()                          *xcodebuild.tests.runner.reload_tests*
  Builds application, enumerates tests, and loads
  them into the Test Explorer.


M.run_tests({testsToRun})                    *xcodebuild.tests.runner.run_tests*
  Runs the provided {testsToRun} and shows the Test Explorer.
  If {testsToRun} is nil, it runs all tests.

  This is a core function to run tests. It coordinates
  the build, test run, and the presentation of the results.

  It sets logs, diagnostics, quickfix list, coverage,
  snapshot previews, and Test Explorer.

  Parameters: ~
    {testsToRun}  (string[]|nil) test ids


                                     *xcodebuild.tests.runner.TestRunnerOptions*
TestRunnerOptions

  Fields: ~
    {doNotBuild}     (boolean|nil)
    {currentTarget}  (boolean|nil)
    {currentClass}   (boolean|nil)
    {currentTest}    (boolean|nil)
    {selectedTests}  (boolean|nil)
    {failingTests}   (boolean|nil)


                                    *xcodebuild.tests.runner.run_selected_tests*
M.run_selected_tests({opts})
  Runs only selected tests based on {opts}.
  If target is not found for the current buffer,
  it additionally triggers build for testing.

  Parameters: ~
    {opts}  (TestRunnerOptions)


                                  *xcodebuild.tests.runner.repeat_last_test_run*
M.repeat_last_test_run()
  Repeats the last test run.


                           *xcodebuild.tests.runner.show_failing_snapshot_tests*
M.show_failing_snapshot_tests()
  Shows a picker with failing snapshot tests.


==============================================================================
Test Search                                            *xcodebuild.tests.search*

This module is responsible for providing test locations,
target names, symbol file paths, and keys for hash maps.

It uses LSP and file name matching to find results.

LSPResult                                    *xcodebuild.tests.search.LSPResult*
  0 - LSP request succeeded (doesn't mean that there is a match)
  1 - LSP request timed out

  Type: ~
    number


M.targetsFilesMap                      *xcodebuild.tests.search.targetsFilesMap*
  Hash map with all targets and their files.

  Type: ~
    (TargetMap)


M.clear()                                        *xcodebuild.tests.search.clear*
  Clears the LSP cache and the array with all Swift files.
  Doesn't clear the targets map (`M.targetsFilesMap`).


M.load_targets_map()                  *xcodebuild.tests.search.load_targets_map*
  Loads the targets map based on the build folder.
  Sets `M.targetsFilesMap`.


M.get_test_key({target}, {class})         *xcodebuild.tests.search.get_test_key*
  Returns the test key based on the {target} and {class}.
  Returns `Target:Class` or `:Class` if {target} is empty.
  It also can return only `Class` if target matching is
  disabled in config.

  Parameters: ~
    {target}  (string|nil)
    {class}   (string|nil)

  Returns: ~
    (string|nil)


                                 *xcodebuild.tests.search.get_test_key_for_file*
M.get_test_key_for_file({filepath}, {class})
  The same as `get_test_key` but it uses the
  {filepath} to find the target first.

  Parameters: ~
    {filepath}  (string)
    {class}     (string|nil)

  Returns: ~
    (string|nil)


                                  *xcodebuild.tests.search.find_target_for_file*
M.find_target_for_file({filepath})
  Finds the target for {filepath} based on the map created
  from the build folder (`M.targetsFilesMap`).

  Parameters: ~
    {filepath}  (string)

  Returns: ~
    (string|nil)


                                         *xcodebuild.tests.search.find_filepath*
M.find_filepath({targetName}, {className})
  Finds the file path based on the {targetName} and {className}.
  It uses the configuration to decide the strategy,
  it could be LSP or filename matching, or both.

  Parameters: ~
    {targetName}  (string)
    {className}   (string)

  Returns: ~
    (string|nil)   filepath


                             *xcodebuild.tests.search.find_filepath_by_filename*
M.find_filepath_by_filename({filename})
  Finds the file path based on the {filename}.

  Parameters: ~
    {filename}  (string|nil)

  Returns: ~
    (string|nil)   filepath


==============================================================================
Snapshot Tests                                      *xcodebuild.tests.snapshots*

This module is responsible for saving and retrieving
previews of failing snapshot tests.

It uses the `getsnapshots` tool to create diffs.

                             *xcodebuild.tests.snapshots.save_failing_snapshots*
M.save_failing_snapshots({xcresultFilepath}, {callback})
  Extracts the failing snapshot tests from the provided
  {xcresultFilepath} and creates diff images in the
  `failing-snapshots` directory.

  It uses the external CLI tool located in `tools/getsnapshots`.

  Parameters: ~
    {xcresultFilepath}  (string)
    {callback}          (function|nil)


                              *xcodebuild.tests.snapshots.get_failing_snapshots*
M.get_failing_snapshots()
  Returns a list of sorted file paths with snapshot diffs.

  Returns: ~
    (string[])


                                   *xcodebuild.tests.snapshots.delete_snapshots*
M.delete_snapshots()
  Deletes the `failing-snapshots` directory.


==============================================================================
Xcresult File Parser                          *xcodebuild.tests.xcresult_parser*

This module is responsible for processing `xcresult` file
and filling the report with the test data.

Normally, processing logs from `xcodebuild` is enough to get
the test data. However, when running tests using Swift Testing
framework, some details like target name are missing.


                           *xcodebuild.tests.xcresult_parser.fill_xcresult_data*
M.fill_xcresult_data({report})
  Fills the report with the data from the `xcresult` file.

  Parameters: ~
    {report}  (ParsedReport)

  Returns: ~
    (boolean)  if the report was updated, false otherwise.


==============================================================================
Code Coverage                                *xcodebuild.code_coverage.coverage*

                                                      *xcodebuild.code-coverage*
This module is responsible for showing the code coverage in the editor.

M.setup()                              *xcodebuild.code_coverage.coverage.setup*
  Sets up the code coverage signs and highlights.


                  *xcodebuild.code_coverage.coverage.is_code_coverage_available*
M.is_code_coverage_available()
  Checks if the code coverage report is available.

  Returns: ~
    (boolean)


                         *xcodebuild.code_coverage.coverage.refresh_all_buffers*
M.refresh_all_buffers()
  Refreshes the code coverage for all buffers matching `file_pattern` from the config.


                       *xcodebuild.code_coverage.coverage.jump_to_next_coverage*
M.jump_to_next_coverage()
  Jumps to the next coverage sign.


                   *xcodebuild.code_coverage.coverage.jump_to_previous_coverage*
M.jump_to_previous_coverage()
  Jumps to the previous coverage sign.


                             *xcodebuild.code_coverage.coverage.export_coverage*
M.export_coverage({xcresultFilepath}, {callback})
  Exports the code coverage from the xcresult file.

  Parameters: ~
    {xcresultFilepath}  (string)
    {callback}          (function|nil)


                        *xcodebuild.code_coverage.coverage.toggle_code_coverage*
M.toggle_code_coverage({isVisible})
  Toggles the code coverage visibility in all buffers.
  First, the code coverage must be exported using |export_coverage| function.

  Parameters: ~
    {isVisible}  (boolean|nil)


                               *xcodebuild.code_coverage.coverage.show_coverage*
M.show_coverage({bufnr})
  Shows the code coverage in the given buffer.
  First, the code coverage must be exported using |export_coverage| function.

  Parameters: ~
    {bufnr}  (number)


                                 *xcodebuild.code_coverage.coverage.show_report*
M.show_report()
  Shows the code coverage report in a floating window.
  First, the code coverage must be exported using |export_coverage| function.


==============================================================================
Code Coverage Report                           *xcodebuild.code_coverage.report*

                                               *xcodebuild.code-coverage-report*
This module is responsible for showing the code coverage report in a floating window.
It relies on `nui.nvim` plugin to create the floating window.

Key bindings:
 - `enter` or `tab` - expand or collapse the current node
 - `o` - open source file


                           *xcodebuild.code_coverage.report.is_report_available*
M.is_report_available()
  Checks if the coverage report file exists.

  Returns: ~
    (boolean)


M.open()                                  *xcodebuild.code_coverage.report.open*
  Opens the code coverage report in a floating window.


M.setup()                                *xcodebuild.code_coverage.report.setup*
  Sets up the highlight groups for the code coverage report.


==============================================================================
DAP Integration                                    *xcodebuild.integrations.dap*

                                                                *xcodebuild.dap*
This module is responsible for the integration with `nvim-dap` plugin.

It provides functions to start the debugger and to manage its state.

To configure `nvim-dap` for development:

  1. Download `codelldb` VS Code plugin from: https://github.com/vadimcn/codelldb/releases
     For macOS use darwin version. Just unzip vsix file and set paths below.
  2. Install also `nvim-dap-ui` for a nice GUI to debug.
  3. Make sure to enable console window from `nvim-dap-ui` to see simulator logs.

Sample `nvim-dap` configuration:
>lua
    return {
      "mfussenegger/nvim-dap",
      dependencies = {
        "wojciech-kulik/xcodebuild.nvim"
      },
      config = function()
        local xcodebuild = require("xcodebuild.integrations.dap")
        -- SAMPLE PATH, change it to your local codelldb path
        local codelldbPath = "/YOUR_PATH/codelldb-aarch64-darwin/extension/adapter/codelldb"

        xcodebuild.setup(codelldbPath)

        vim.keymap.set("n", "<leader>dd", xcodebuild.build_and_debug, { desc = "Build & Debug" })
        vim.keymap.set("n", "<leader>dr", xcodebuild.debug_without_build, { desc = "Debug Without Building" })
        vim.keymap.set("n", "<leader>dt", xcodebuild.debug_tests, { desc = "Debug Tests" })
        vim.keymap.set("n", "<leader>dT", xcodebuild.debug_class_tests, { desc = "Debug Class Tests" })
        vim.keymap.set("n", "<leader>b", xcodebuild.toggle_breakpoint, { desc = "Toggle Breakpoint" })
        vim.keymap.set("n", "<leader>B", xcodebuild.toggle_message_breakpoint, { desc = "Toggle Message Breakpoint" })
        vim.keymap.set("n", "<leader>dx", xcodebuild.terminate_session, { desc = "Terminate Debugger" })
      end,
    }
<

See:
  https://github.com/mfussenegger/nvim-dap
  https://github.com/rcarriga/nvim-dap-ui
  https://github.com/vadimcn/codelldb


                                   *xcodebuild.integrations.dap.build_and_debug*
M.build_and_debug({callback})
  Builds, installs and runs the project. Also, it starts the debugger.

  Parameters: ~
    {callback}  (function|nil)


                               *xcodebuild.integrations.dap.debug_without_build*
M.debug_without_build({callback})
  It only installs the app and starts the debugger without building
  the project.

  Parameters: ~
    {callback}  (function|nil)


                         *xcodebuild.integrations.dap.attach_debugger_for_tests*
M.attach_debugger_for_tests()
  Attaches the debugger to the running application when tests are starting.

  Tests are controlled by `xcodebuild` tool, so we can't request waiting
  for the debugger to attach. Instead, we listen to the
  `XcodebuildTestsStatus` to start the debugger.

  When `XcodebuildTestsFinished` or `XcodebuildActionCancelled` is received,
  we terminate the debugger session.
  If build failed, we stop waiting for events.


M.debug_tests()                        *xcodebuild.integrations.dap.debug_tests*
  Starts the debugger and runs all tests.


                                *xcodebuild.integrations.dap.debug_target_tests*
M.debug_target_tests()
  Starts the debugger and runs all tests in the target.


                                 *xcodebuild.integrations.dap.debug_class_tests*
M.debug_class_tests()
  Starts the debugger and runs all tests in the class.


                                   *xcodebuild.integrations.dap.debug_func_test*
M.debug_func_test()
  Starts the debugger and runs the current test.


                              *xcodebuild.integrations.dap.debug_selected_tests*
M.debug_selected_tests()
  Starts the debugger and runs the selected tests.


                               *xcodebuild.integrations.dap.debug_failing_tests*
M.debug_failing_tests()
  Starts the debugger and re-runs the failing tests.


                                  *xcodebuild.integrations.dap.get_program_path*
M.get_program_path()
  Returns path to the built application.

  Returns: ~
    (string)


M.wait_for_pid()                      *xcodebuild.integrations.dap.wait_for_pid*
  Waits for the application to start and returns its PID.

  Returns: ~
    (thread|nil)   coroutine with pid


                                     *xcodebuild.integrations.dap.clear_console*
M.clear_console()
  Clears the DAP console buffer.


                                    *xcodebuild.integrations.dap.update_console*
M.update_console({output}, {append})
  Updates the DAP console buffer with the given output.
  It also automatically scrolls to the last line if
  the cursor is in a different window or if the cursor
  is not on the last line.

  Parameters: ~
    {output}  (string[])
    {append}  (boolean|nil) # if true, appends the output to the last line


                           *xcodebuild.integrations.dap.get_swift_configuration*
M.get_swift_configuration()
  Returns the `coodelldb` configuration for `nvim-dap`.

  Returns: ~
    (table[])

  Usage: ~
>lua
    require("dap").configurations.swift = require("xcodebuild.integrations.dap").get_swift_configuration()
<


                              *xcodebuild.integrations.dap.get_codelldb_adapter*
M.get_codelldb_adapter({codelldbPath}, {lldbPath}, {port})
  Returns the `codelldb` adapter for `nvim-dap`.

  Examples:
    {codelldbPath} - `/your/path/to/codelldb-aarch64-darwin/extension/adapter/codelldb`
    {lldbPath} - (default) `/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/LLDB`

  Parameters: ~
    {codelldbPath}  (string)
    {lldbPath}      (string|nil)
    {port}          (number|nil)

  Returns: ~
    (table)

  Usage: ~
>lua
    require("dap").adapters.codelldb = require("xcodebuild.integrations.dap")
      .get_codelldb_adapter("path/to/codelldb")
<


                                  *xcodebuild.integrations.dap.save_breakpoints*
M.save_breakpoints()
  Saves breakpoints to `.nvim/xcodebuild/breakpoints.json` file.


                                  *xcodebuild.integrations.dap.load_breakpoints*
M.load_breakpoints({bufnr})
  Loads breakpoints from `.nvim/xcodebuild/breakpoints.json` file and sets them
  in {bufnr} or in all loaded buffers if {bufnr} is nil.

  Parameters: ~
    {bufnr}  (number|nil)


                                 *xcodebuild.integrations.dap.toggle_breakpoint*
M.toggle_breakpoint()
  Toggles a breakpoint in the current line and saves breakpoints to disk.


                         *xcodebuild.integrations.dap.toggle_message_breakpoint*
M.toggle_message_breakpoint()
  Toggles a breakpoint with a log message in the current line and saves breakpoints to disk.
  To print a variable, wrap it with {}: `{myObject.myProperty}`.


                                 *xcodebuild.integrations.dap.terminate_session*
M.terminate_session()
  Terminates the debugger session, cancels the current action, and closes the `nvim-dap-ui`.


M.get_actions()                        *xcodebuild.integrations.dap.get_actions*
  Returns a list of actions with names for the `nvim-dap` plugin.
  @return table<{name:string,action:function}>


                                             *xcodebuild.integrations.dap.setup*
M.setup({codelldbPath}, {loadBreakpoints})
  Sets up the adapter and configuration for the `nvim-dap` plugin.
  {codelldbPath} - path to the `codelldb` binary.

  Sample {codelldbPath} - `/your/path/to/codelldb-aarch64-darwin/extension/adapter/codelldb`
  {loadBreakpoints} - if true or nil, sets up an autocmd to load breakpoints when a Swift file is opened.

  Parameters: ~
    {codelldbPath}     (string)
    {loadBreakpoints}  (boolean|nil) default: true


==============================================================================
Remote Debugger Integration            *xcodebuild.integrations.remote_debugger*

This module is responsible for the integration of `phymobiledevice3`
debug session with `nvim-dap`. It enables debugging on physical devices.

The module listens to `nvim-dap` events and starts the remote debugger.

See |xcodebuild.requirements|


                    *xcodebuild.integrations.remote_debugger.RemoteDebuggerMode*
RemoteDebuggerMode
   1 - Legacy mode (iOS <17)
   2 - Secured mode (iOS 17+)

  Type: ~
    number


                                  *xcodebuild.integrations.remote_debugger.mode*
M.mode
  The current mode of the remote debugger.

  Type: ~
    (RemoteDebuggerMode)


                              *xcodebuild.integrations.remote_debugger.set_mode*
M.set_mode({mode})
  Sets the mode of the remote debugger.
  Use `M.LEGACY_MODE` or `M.SECURED_MODE`.

  Parameters: ~
    {mode}  (RemoteDebuggerMode)


                 *xcodebuild.integrations.remote_debugger.start_remote_debugger*
M.start_remote_debugger({callback})
  Starts the remote debugger based on the mode.

  Parameters: ~
    {callback}  (function|nil)


                  *xcodebuild.integrations.remote_debugger.stop_remote_debugger*
M.stop_remote_debugger()
  Stops the remote debugger based on the mode.


==============================================================================
LSP Integration                                    *xcodebuild.integrations.lsp*

This module is responsible for the integration with LSP.
It provides functions, which fix issues with code actions in Swift.

`sourcekit-lsp` requires from the provided range to match exactly the issue
location. Neovim by default sends the current cursor position. Because of
that, code actions won't appear unless you put the cursor in the right place.

Functions from this module find the diagnostic for the current line and
send the correct range to the LSP server.

                                     *xcodebuild.integrations.lsp.quickfix_line*
M.quickfix_line()
  Calls code action for the current line.
  If one code action is available, it will apply the fix.
  If more than one code action is available, it will show the list.
  If no code action is available, nothing will happen.


M.code_actions()                      *xcodebuild.integrations.lsp.code_actions*
  Shows code actions for the current line.
  If no code action is available, nothing will happen.


                             *xcodebuild.integrations.lsp.restart_sourcekit_lsp*
M.restart_sourcekit_lsp()
  Restarts the `sourcekit-lsp` client.


==============================================================================
nvim-tree Integration                        *xcodebuild.integrations.nvim-tree*

This module is responsible for the integration with `nvim-tree`.
It listens to `nvim-tree` events and updates the project file accordingly.

The integration is enabled only if the current working directory
contains the project configuration (|xcodebuild.project.config|).

You can always disable the integration in the |xcodebuild.config|.

This feature requires `Xcodeproj` to be installed (|xcodebuild.requirements|).

See:
  |xcodebuild.project-manager|
  https://github.com/nvim-tree/nvim-tree.lua
  https://github.com/wojciech-kulik/xcodebuild.nvim/wiki/Integrations#-file-tree-integration


M.setup()                              *xcodebuild.integrations.nvim-tree.setup*
  Sets up the integration with `nvim-tree`.
  It subscribes to `nvim-tree` events.

  See: ~
    |xcodebuild.project-manager|


==============================================================================
neo-tree.nvim Integration                     *xcodebuild.integrations.neo-tree*

This module is responsible for the integration with `neo-tree.nvim`.
It listens to `neo-tree` events and updates the project file accordingly.

The integration is enabled only if the current working directory
contains the project configuration (|xcodebuild.project.config|).

You can always disable the integration in the |xcodebuild.config|.

This feature requires `Xcodeproj` to be installed (|xcodebuild.requirements|).

See:
  |xcodebuild.project-manager|
  https://github.com/nvim-neo-tree/neo-tree.nvim
  https://github.com/wojciech-kulik/xcodebuild.nvim/wiki/Integrations#-file-tree-integration


M.setup()                               *xcodebuild.integrations.neo-tree.setup*
  Sets up the integration with `neo-tree`.
  It subscribes to `neo-tree` events.

  See: ~
    |xcodebuild.project-manager|


==============================================================================
oil.nvim Integration                          *xcodebuild.integrations.oil-nvim*

This module is responsible for the integration with `oil.nvim`.
It listens to `oil.nvim` events and updates the project file accordingly.

The integration is enabled only if the current working directory
contains the project configuration (|xcodebuild.project.config|).

You can always disable the integration in the |xcodebuild.config|.

This feature requires `Xcodeproj` to be installed (|xcodebuild.requirements|).

See:
  |xcodebuild.project-manager|
  https://github.com/stevearc/oil.nvim
  https://github.com/wojciech-kulik/xcodebuild.nvim/wiki/Integrations#-file-tree-integration


M.setup()                               *xcodebuild.integrations.oil-nvim.setup*
  Sets up the integration with `oil.nvim`.
  It subscribes to `oil.nvim` events.

  See: ~
    |xcodebuild.project-manager|


==============================================================================
Quick Test Framework Integration                 *xcodebuild.integrations.quick*

This module is responsible for parsing tests written using `Quick` framework.

It provides functions to get a list of `Quick` tests and their locations.

Note: it requires the Swift parser to be installed (using `nvim-treesitter`).

See: https://github.com/Quick/Quick


QuickTest                              *xcodebuild.integrations.quick.QuickTest*

  Fields: ~
    {id}   (string) test id (matching xcodebuild test name)
    {row}  (number) 1-based row number


                                    *xcodebuild.integrations.quick.TestTreeNode*
TestTreeNode

  Fields: ~
    {id}        (string) node type
    {testId}    (string|nil) test id (matching xcodebuild test name)
    {name}      (string) group name
    {row}       (number) 0-based row number
    {endRow}    (number) 0-based row number
    {parent}    (TestTreeNode|nil)
    {children}  (TestTreeNode[])


                           *xcodebuild.integrations.quick.build_quick_test_tree*
M.build_quick_test_tree({bufnr})
  Builds a tree of tests based on the given buffer.

  The result is a tree structure where each node represents a group of tests.

  The first node is always the root node, it doesn't represent any test group.
  Iterate through the `children` property to get the top-level test groups.


  Parameters: ~
    {bufnr}  (number)

  Returns: ~
    (TestTreeNode|nil)


                                *xcodebuild.integrations.quick.find_quick_tests*
M.find_quick_tests({bufnr})
  Returns a list of tests and their locations.

  The result is a table where keys are test ids and values are `QuickTest` objects.

  Each test represents a single test case (e.g. `it` block).


  Parameters: ~
    {bufnr}  (number)

  Returns: ~
    (table<string,QuickTest>|nil)


                            *xcodebuild.integrations.quick.contains_quick_tests*
M.contains_quick_tests({bufnr})
  Returns whether the given buffer contains Quick tests.

  It checks if the buffer contains a subclass of `QuickSpec` or
  if there is `import Quick`.

  Parameters: ~
    {bufnr}  (number)

  Returns: ~
    (boolean)


                       *xcodebuild.integrations.quick.is_swift_parser_installed*
M.is_swift_parser_installed()
  Returns whether the Swift parser is installed.

  It caches the result for future calls.

  Returns: ~
    (boolean)


M.is_enabled()                        *xcodebuild.integrations.quick.is_enabled*
  Returns whether the Quick integration is enabled.

  Returns: ~
    (boolean)


==============================================================================
xcode-build-server Integration      *xcodebuild.integrations.xcode-build-server*

This module is responsible for the integration with xcode-build-server.

See: https://github.com/SolaWing/xcode-build-server


                       *xcodebuild.integrations.xcode-build-server.is_installed*
M.is_installed()
  Returns whether the xcode-build-server is installed.

  Returns: ~
    (boolean)


                         *xcodebuild.integrations.xcode-build-server.is_enabled*
M.is_enabled()
  Returns whether the integration is enabled.

  Returns: ~
    (boolean)


                         *xcodebuild.integrations.xcode-build-server.run_config*
M.run_config({projectFile}, {scheme})
  Calls "config" command of xcode-build-server in order to update buildServer.json file.

  Parameters: ~
    {projectFile}  (string)
    {scheme}       (string)

  Returns: ~
    (number)   job id


==============================================================================
Xcodebuild Workaround               *xcodebuild.integrations.xcodebuild-offline*

                                                 *xcodebuild.xcodebuild-offline*

This module provides a workaround for the issue with slow `xcodebuild` command.

The issue is caused by the fact that `xcodebuild` tries to connect to the Apple
servers before building the project, which can take 20 seconds or more.
Usually, those requests are not necessary, but they slow down each build.

This module provides a workaround by mapping Apple servers to localhost in the
`/etc/hosts` file during the build. It is a temporary solution and should be
used with caution.

Keep in mind that disabling access to `developerservices2.apple.com` for
`xcodebuild` may cause some issues with the build process. It will disable
things like registering devices, capabilities, and other network-related
features. Therefore, it's best to use it when you are working just on the
code and don't need updating project settings.

Below you can find three ways to enable the workaround.

1. Manual (script)

Enable workaround:
>bash
  sudo bash -c "echo '127.0.0.1 developerservices2.apple.com' >>/etc/hosts"
<

Disable workaround:
>bash
  sudo sed -i '' '/developerservices2\.apple\.com/d' /etc/hosts
<

2. Manual (network sniffer)

If you use some tool to sniff network traffic like Proxyman or Charles Proxy,
you can block requests to `https://developerservices2.apple.com/*` and
automatically return some error like 999 status code. It will prevent
`xcodebuild` from further calls.

3. Automatic (`xcodebuild.nvim` integration)

In this approach the Apple server will be blocked only when the `xcodebuild`
command (triggered by the plugin) is running. However, it requires a passwordless
`sudo` permission for the script.

⚠️ CAUTION
Giving passwordless `sudo` access to that file, potentially opens a gate for
malicious software that could modify the file and run some evil code using
`root` account. The best way to protect that file is to create a local copy,
change the owner to `root`, and give write permission only to `root`. The same
must be applied to the parent directory. The script below automatically
secures the file.

👉 Enable integration that automatically blocks Apple servers

Update your config with:
>lua
  integrations = {
    xcodebuild_offline = {
      enabled = true,
    },
  }
<

👉 Run the following command to install & protect the script

>bash
  DEST="$HOME/Library/xcodebuild.nvim" && \
    SOURCE="$HOME/.local/share/nvim/lazy/xcodebuild.nvim/tools/xcodebuild_offline" && \
    ME="$(whoami)" && \
    sudo install -d -m 755 -o root "$DEST" && \
    sudo install -m 755 -o root "$SOURCE" "$DEST" && \
    sudo bash -c "echo \"$ME ALL = (ALL) NOPASSWD: $DEST/xcodebuild_offline\" >> /etc/sudoers"
<


More details about this issue can be found here:
https://github.com/wojciech-kulik/xcodebuild.nvim/issues/201#issuecomment-2423828065


                         *xcodebuild.integrations.xcodebuild-offline.is_enabled*
M.is_enabled()
  Returns whether the `xcodebuild` command should be run in offline mode.

  Returns: ~
    (boolean)


             *xcodebuild.integrations.xcodebuild-offline.wrap_command_if_needed*
M.wrap_command_if_needed({command})
  Wraps the `xcodebuild` command with the workaround script if needed.

  Parameters: ~
    {command}  (string[])

  Returns: ~
    (string[])


==============================================================================
Pickers                                                  *xcodebuild.ui.pickers*

                                                            *xcodebuild.pickers*
This module is responsible for showing pickers using Telescope.nvim.

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)
    {device_select_callback}  (function|nil)


M.close()                                          *xcodebuild.ui.pickers.close*
  Closes the active picker.


                                                    *xcodebuild.ui.pickers.show*
M.show({title}, {items}, {callback}, {opts})
  Shows a picker using Telescope.nvim.

  Parameters: ~
    {title}     (string)
    {items}     (string[]|XcodeDevice[])
    {callback}  (function|nil)
    {opts}      (PickerOptions|nil)


                              *xcodebuild.ui.pickers.select_xcodeproj_if_needed*
M.select_xcodeproj_if_needed({callback}, {opts})
  Shows a picker with the available `xcodeproj` files
  if this is not already set in the project settings.
  If the `xcworkspace` is set and there is the corresponding
  `xcodeproj` file with the same name, it will be selected automatically.
  If the project is configured for Swift Package, it returns `nil`.

  Parameters: ~
    {callback}  (fun(xcodeproj:string|nil)|nil)
    {opts}      (PickerOptions|nil)


M.select_xcodeproj({callback}, {opts})  *xcodebuild.ui.pickers.select_xcodeproj*
  Shows a picker with `xcodeproj` files

  Parameters: ~
    {callback}  (fun(xcodeproj:string)|nil)
    {opts}      (PickerOptions|nil)


M.select_project({callback}, {opts})      *xcodebuild.ui.pickers.select_project*
  Shows a picker with `xcworkspace`, `xcodeproj`, and `Package.swift` files.

  Parameters: ~
    {callback}  (fun(projectFile:string)|nil)
    {opts}      (PickerOptions|nil)


M.select_scheme({callback}, {opts})        *xcodebuild.ui.pickers.select_scheme*
  Shows a picker with the available schemes.

  Parameters: ~
    {callback}  (fun(scheme:string)|nil)
    {opts}      (PickerOptions|nil)


M.select_testplan({callback}, {opts})    *xcodebuild.ui.pickers.select_testplan*
  Shows a picker with the available test plans.

  Parameters: ~
    {callback}  (fun(testPlan:string|nil)|nil)
    {opts}      (PickerOptions|nil)

  Returns: ~
    (number|nil)  id


                                      *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: ~
    (number|nil)  id if launched

  See: ~
    |xcodebuild.config|


                            *xcodebuild.ui.pickers.select_failing_snapshot_test*
M.select_failing_snapshot_test()
  Shows a picker with the available failing snapshots.


M.show_all_actions()                    *xcodebuild.ui.pickers.show_all_actions*
  Shows a picker with the available actions.
  If the project is not configured, it will show the configuration wizard.


==============================================================================
Picker Actions                                    *xcodebuild.ui.picker_actions*

This module is responsible for preparing and showing actions for picker based on the project type.

                                 *xcodebuild.ui.picker_actions.show_spm_actions*
M.show_spm_actions()
  Shows available actions for Swift Package project.


                     *xcodebuild.ui.picker_actions.show_library_project_actions*
M.show_library_project_actions()
  Shows available actions for Xcode library project.


                       *xcodebuild.ui.picker_actions.show_xcode_project_actions*
M.show_xcode_project_actions()
  Shows available actions for Xcode project.


==============================================================================
Helpers                                                     *xcodebuild.helpers*

This module contains general helper functions used across the plugin.

|xcodebuild.util| is for general language utils and |xcodebuild.helpers|
are for plugin specific utils.

M.defer_send({text})                             *xcodebuild.helpers.defer_send*
  Sends a notification with a small delay to fix some glitches.

  Parameters: ~
    {text}  (string)


M.cancel_actions()                           *xcodebuild.helpers.cancel_actions*
  Cancels all running actions from all modules.


M.validate_project({opts})                 *xcodebuild.helpers.validate_project*
  Validates if the project is configured.
  It sends an error notification if the project is not configured.

  Parameters: ~
    {opts}  ({requiresXcodeproj:boolean|nil,requiresApp:boolean|nil}|nil)

  Returns: ~
    (boolean)


M.clear_state()                                 *xcodebuild.helpers.clear_state*
  Clears the state before the next build/test action.


M.find_all_swift_files()               *xcodebuild.helpers.find_all_swift_files*
  Finds all swift files in project working directory.
  Returns a map of filename to list of filepaths.

  Returns: ~
    (table<string,string[]>)


M.get_major_os_version()               *xcodebuild.helpers.get_major_os_version*
  Returns the major version of the OS (ex. 17 for 17.1.1).
  It uses the device from the project configuration.

  Returns: ~
    (number|nil)


                                             *xcodebuild.helpers.buf_set_option*
M.buf_set_option({bufnr}, {name}, {value})
  Wraps any nvim_buf_set_option() call to ensure forward compatibility.
  The function is required because nvim_buf_set_option() was deprecated in nvim-0.10.

  Parameters: ~
    {bufnr}  (number)
    {name}   (string)
    {value}  (any)


                                             *xcodebuild.helpers.win_set_option*
M.win_set_option({winnr}, {name}, {value})
  Wraps any nvim_win_set_option() call to ensure forward compatibility.
  The function is required because nvim_win_set_option() was deprecated in nvim-0.10.

  Parameters: ~
    {winnr}  (number)
    {name}   (string)
    {value}  (any)


                                     *xcodebuild.helpers.update_readonly_buffer*
M.update_readonly_buffer({bufnr}, {updateFoo})
  Enables `modifiable` and updates the buffer using {updateFoo}.
  After the operation, it restores the `modifiable` to `false`.

  Parameters: ~
    {bufnr}      (number|nil)
    {updateFoo}  (function)


==============================================================================
Lua Utils                                                      *xcodebuild.util*

This module contains general lua helper functions used across the plugin.

|xcodebuild.util| is for general language utils and |xcodebuild.helpers|
are for plugin specific utils.

M.get_hl_without_italic({name})          *xcodebuild.util.get_hl_without_italic*
  Gets modified highlight without italic.

  Parameters: ~
    {name}  (string)

  Returns: ~
    (table)


M.get_modified_hl({name}, {opts})              *xcodebuild.util.get_modified_hl*
  Read highlight and return the modified version.

  Parameters: ~
    {name}  (string)
    {opts}  (table)

  Returns: ~
    (table|nil)   definition


M.shallow_copy({orig})                            *xcodebuild.util.shallow_copy*
  Creates a shallow copy of a table.
  If the table contains other tables, it will only copy the references.

  Parameters: ~
    {orig}  (any)

  Returns: ~
    (any)


M.is_empty({table})                                   *xcodebuild.util.is_empty*
  Checks if a table is empty or nil.

  Parameters: ~
    {table}  (table|nil)

  Returns: ~
    (boolean)


M.is_not_empty({table})                           *xcodebuild.util.is_not_empty*
  Checks if a table is NOT empty and NOT nil.

  Parameters: ~
    {table}  (table|nil)

  Returns: ~
    (boolean)


M.get_buffers({opts})                              *xcodebuild.util.get_buffers*
  Gets all buffers in the current neovim instance.
  If {opts.returnNotLoaded} is true, it will
  return all buffers, including the ones that are not loaded.

  Parameters: ~
    {opts}  (table|nil)
            * {returnNotLoaded} (boolean)

  Returns: ~
    (number[])


M.file_exists({name})                              *xcodebuild.util.file_exists*
  Checks if a file exists.

  Parameters: ~
    {name}  (string)

  Returns: ~
    (boolean)


M.dir_exists({path})                                *xcodebuild.util.dir_exists*
  Checks if a directory exists.

  Parameters: ~
    {path}  (string)

  Returns: ~
    (boolean)


                                           *xcodebuild.util.get_buf_by_filename*
M.get_buf_by_filename({filename}, {opts})
  Gets a buffer by its filename.
  If `opts.returnNotLoaded` is true, it will
  return all buffers, including the ones that are not loaded.

  Parameters: ~
    {filename}  (string)
    {opts}      (table|nil) * {returnNotLoaded} (boolean)


M.get_buf_by_name({name})                      *xcodebuild.util.get_buf_by_name*
  Gets a buffer by its name.
  Returns also buffers that are not loaded.

  Parameters: ~
    {name}  (string)

  Returns: ~
    (number|nil)


M.get_buf_by_filetype({filetype})          *xcodebuild.util.get_buf_by_filetype*
  Gets a buffer by its filetype.
  Returns also buffers that are not loaded.

  Parameters: ~
    {filetype}  (string)

  Returns: ~
    (number|nil)


                                     *xcodebuild.util.get_bufs_by_matching_name*
M.get_bufs_by_matching_name({pattern})
  Gets all buffers that match a pattern.

  Parameters: ~
    {pattern}  (string)

  Returns: ~
    ({bufnr:number,file:string}[])


M.focus_buffer({bufnr})                           *xcodebuild.util.focus_buffer*
  Focuses a buffer by its buffer number.
  If the buffer's window is not found, it will return false.

  Parameters: ~
    {bufnr}  (number)

  Returns: ~
    (boolean)


M.get_filename({filepath})                        *xcodebuild.util.get_filename*
  Gets the filename from a filepath.

  Parameters: ~
    {filepath}  (string)

  Returns: ~
    (string)


M.shell({cmd})                                           *xcodebuild.util.shell*
  Runs a shell command and returns the output as a list of strings.

  Parameters: ~
    {cmd}  (string|string[])

  Returns: ~
    (string[])


M.shellAsync({cmd}, {callback})                     *xcodebuild.util.shellAsync*
  Runs a shell command asynchronously.

  Parameters: ~
    {cmd}       (string|string[])
    {callback}  (function|nil)


M.is_fd_installed()                            *xcodebuild.util.is_fd_installed*
  Checks if fd is installed on the system.

  Returns: ~
    (boolean)


M.merge_array({lhs}, {rhs})                        *xcodebuild.util.merge_array*
  Merges two arrays into a new one.

  Parameters: ~
    {lhs}  (any[])
    {rhs}  (any[])

  Returns: ~
    (any[])


M.skip_nil({array})                                   *xcodebuild.util.skip_nil*
  Returns a new array without nil values.

  Parameters: ~
    {array}  (any[])

  Returns: ~
    (any[])


M.trim({str})                                             *xcodebuild.util.trim*
  Trims whitespace from the beginning and end of a string.

  Parameters: ~
    {str}  (string)

  Returns: ~
    (string)


M.select({tab}, {selector})                             *xcodebuild.util.select*
  Maps an array based on a {selector} function.

  Parameters: ~
    {tab}       (any[])
    {selector}  (fun(value:any):any)

  Returns: ~
    (any[])


M.filter({tab}, {predicate})                            *xcodebuild.util.filter*
  Filters an array based on a {predicate} function.

  Parameters: ~
    {tab}        (any[])
    {predicate}  (fun(value:any):boolean)

  Returns: ~
    (any[])


M.has_suffix({text}, {suffix})                      *xcodebuild.util.has_suffix*
  Checks if a string ends with a suffix.

  Parameters: ~
    {text}    (string)
    {suffix}  (string)

  Returns: ~
    (boolean)


M.has_prefix({text}, {prefix})                      *xcodebuild.util.has_prefix*
  Checks if a string starts with a prefix.

  Parameters: ~
    {text}    (string)
    {prefix}  (string)

  Returns: ~
    (boolean)


M.contains({array}, {value})                          *xcodebuild.util.contains*
  Checks if an array contains a value.

  Parameters: ~
    {array}  (any[]|nil)
    {value}  (any)


M.find({array}, {predicate})                              *xcodebuild.util.find*
  Finds the first value in an array that matches a predicate.

  Parameters: ~
    {array}      (any[])
    {predicate}  (fun(value:any):boolean)

  Returns: ~
    (any)


M.call({callback})                                        *xcodebuild.util.call*
  Calls {callback} with arguments if {callback} is not nil.
  Returns the result of the function call.

  Parameters: ~
    {callback}  (function|nil) @vararg any

  Returns: ~
    (any)


M.indexOf({array}, {value})                            *xcodebuild.util.indexOf*
  Finds the index of a value in an array.

  Parameters: ~
    {array}  (any[])
    {value}  (any)

  Returns: ~
    (number|nil)


M.indexOfPredicate({array}, {predicate})      *xcodebuild.util.indexOfPredicate*
  Finds the index of a value that
  matches a predicate in an array.

  Parameters: ~
    {array}      (any[])
    {predicate}  (fun(value:any):boolean)

  Returns: ~
    (number|nil)


M.readfile({filepath})                                *xcodebuild.util.readfile*
  Reads file content and returns it as a list of lines.
  If the file does not exist, it will return false and an empty list.

  Parameters: ~
    {filepath}  (string) @return boolean, string[] # success: boolean, lines: string[]


vim:tw=78:ts=8:noet:ft=help:norl:
