{"id":51121524,"url":"https://github.com/jamylak/cplug.nvim","last_synced_at":"2026-06-25T03:01:06.560Z","repository":{"id":351274597,"uuid":"1201039201","full_name":"jamylak/cplug.nvim","owner":"jamylak","description":"\u003cleader\u003ec to compile and debug, CMake utilities and other helpful defaults","archived":false,"fork":false,"pushed_at":"2026-05-24T23:52:25.000Z","size":640,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-25T01:34:34.742Z","etag":null,"topics":["cmake","debug","neovim","nvim","plugin","vim"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jamylak.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-04T06:00:34.000Z","updated_at":"2026-05-24T23:52:30.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jamylak/cplug.nvim","commit_stats":null,"previous_names":["jamylak/cplug.nvim"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jamylak/cplug.nvim","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamylak%2Fcplug.nvim","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamylak%2Fcplug.nvim/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamylak%2Fcplug.nvim/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamylak%2Fcplug.nvim/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jamylak","download_url":"https://codeload.github.com/jamylak/cplug.nvim/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamylak%2Fcplug.nvim/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34757355,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-25T02:00:05.521Z","response_time":101,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cmake","debug","neovim","nvim","plugin","vim"],"created_at":"2026-06-25T03:01:05.237Z","updated_at":"2026-06-25T03:01:06.537Z","avatar_url":"https://github.com/jamylak.png","language":"Lua","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cplug.nvim\n\n## 🚧 Work In Progress\n\nThis plugin is still a work in progress and is still being tested.\n\n`cplug.nvim` aims to make `\u003cleader\u003ec` the compile-and-debug entrypoint for projects.\n\nIt started as C debug, CMake, and related C/C++ tooling inside my older `jamylak/nvimconf` setup.\nThe goal here is to pull that work out into a cleaner reusable plugin in its own repo, so the debug workflow can stay separate and easier to maintain.\n\n![screenshot1.png](assets/screenshot1.png)\n\nThis project currently has:\n\n- a public `setup()` API\n- a `:CPlugCompileDebug` user command\n- a `:CPlugAttach` user command\n- a `:CPlugGenerateAttach` user command\n- a `:CPlugCMakeConfigure` user command\n- a `:CPlugCMakeBuildOnce` user command\n- a `:CPlugCMakeBuildAndRun` user command\n- a `:CPlugCMakeRun` user command\n- optional default keymaps\n- a `:checkhealth cplug` healthcheck\n- a core orchestration pipeline for detect -\u003e optional scaffold -\u003e build -\u003e launch resolution\n- a shared backend contract for future language implementations\n- shared `.vscode/launch.json` resolution in the main pipeline\n- a CMake backend for existing, source-only, and empty C/C++ projects\n- an existing-project Cargo backend for Rust\n- a minimal Python backend for existing projects\n- `nvim-dap` / `nvim-dap-ui` startup from the resolved launch config\n- automatic common DAP adapter registration for generated C/C++/Rust LLDB and Python debugpy configs\n- automatic `nvim-dap-disasm` wiring for the default low-level UI when it is installed\n- optional default DAP stepping and breakpoint keymaps\n\nThe remaining work is language expansion and adapter-specific polish.\n\nCurrent backend scope:\n\n- C/C++ detection for existing `CMakeLists.txt` projects, automatic scaffolding for source-only repos, and empty-repo bootstrapping into a minimal C++ project by default\n- missing C/C++ `launch.json` generation from built CMake executables\n- Rust detection for existing `Cargo.toml` projects with debug builds in `target/debug`\n- missing Rust `launch.json` generation from the first Cargo binary target\n- Python detection for existing projects via `pyproject.toml`, `requirements.txt`, or discovered `*.py` files in common source layouts\n- Python launch generation with interpreter defaults from `.venv`, `venv`, `python3`, or `python`\n- automatic Python debug environment bootstrapping with `debugpy`\n- attach config generation for Python and native process attach flows\n- debug launch resolution through `.vscode/launch.json`\n- no Python scaffolding yet\n\n## Setup\n\n```lua\nrequire(\"cplug\").setup()\n```\n\nDisable the built-in keymaps if you want to own lazy-loading or mappings yourself:\n\n```lua\nrequire(\"cplug\").setup({\n  default_keymaps = false,\n})\n```\n\nCustomize the built-in keymaps per action. Each entry accepts a single lhs, a\nlist of lhs values for aliases, or `false` to skip that action entirely:\n\n```lua\nrequire(\"cplug\").setup({\n  keymaps = {\n    compile_debug = { \"\u003cleader\u003ec\", \"\u003cleader\u003egj\" },\n    continue = { \"\u003cleader\u003egc\", \"\u003cleader\u003e\u003cleader\u003ec\" },\n    restart = false,\n  },\n})\n```\n\nSelect a specific VS Code launch configuration by name:\n\n```lua\nrequire(\"cplug\").setup({\n  launch = {\n    configuration = \"Debug current file\",\n  },\n})\n```\n\nControl how cplug chooses among compatible launch configurations:\n\n```lua\nrequire(\"cplug\").setup({\n  launch = {\n    select = \"auto\", -- \"auto\" | \"first\" | \"picker\"\n  },\n})\n```\n\n`launch.json` is generated automatically by default. To change that policy:\n\n```lua\nrequire(\"cplug\").setup({\n  launch = {\n    on_missing = \"prompt\", -- or \"never\"\n  },\n})\n```\n\nControl automatic project scaffolding:\n\n```lua\nrequire(\"cplug\").setup({\n  scaffold = {\n    on_missing = \"always\",\n  },\n  c_family = {\n    empty_project_language = \"cpp\",\n  },\n})\n```\n\nDisable automatic `dap-ui` opening:\n\n```lua\nrequire(\"cplug\").setup({\n  dap = {\n    open_ui = false,\n  },\n})\n```\n\nPick a default managed DAP UI layout:\n\n```lua\nrequire(\"cplug\").setup({\n  dap = {\n    layout = \"code_repl\",\n  },\n})\n```\n\nLet cplug own the default `dapui` layout setup explicitly:\n\n```lua\nrequire(\"cplug\").setup({\n  dap = {\n    manage_ui_layout = true,\n  },\n})\n```\n\nDisable the default disassembly pane in low-level debug layouts:\n\n```lua\nrequire(\"cplug\").setup({\n  dap = {\n    disassembly = {\n      enabled = false,\n    },\n  },\n})\n```\n\nIf you disable cplug-managed UI layouts, you own the `dapui` layout and must\nadd `disassembly` yourself if you still want that pane:\n\n```lua\nrequire(\"cplug\").setup({\n  dap = {\n    manage_ui_layout = false,\n    disassembly = {\n      enabled = true,\n    },\n  },\n})\n\nrequire(\"dapui\").setup({\n  layouts = {\n    {\n      elements = {\n        { id = \"scopes\", size = 0.25 },\n        { id = \"breakpoints\", size = 0.25 },\n        { id = \"stacks\", size = 0.25 },\n        { id = \"watches\", size = 0.25 },\n      },\n      position = \"left\",\n      size = 40,\n    },\n    {\n      elements = {\n        { id = \"disassembly\", size = 0.7 },\n        { id = \"repl\", size = 0.3 },\n      },\n      position = \"bottom\",\n      size = 16,\n    },\n  },\n})\n```\n\nOverride the default CMake build directory:\n\n```lua\nrequire(\"cplug\").setup({\n  c_family = {\n    build_dir = \"build\",\n  },\n})\n```\n\nSkip `.clang-format` generation during C/C++ scaffolding:\n\n```lua\nrequire(\"cplug\").setup({\n  c_family = {\n    generate_clang_format = false,\n  },\n})\n```\n\nDefault scaffolded C/C++ templates can seed `CPLUG_WARNINGS_AS_ERRORS`:\n\n```lua\nrequire(\"cplug\").setup({\n  c_family = {\n    warnings_as_errors = true,\n  },\n})\n```\n\nBootstrap Git during C/C++ scaffolding:\n\n```lua\nrequire(\"cplug\").setup({\n  c_family = {\n    bootstrap_git = false,\n  },\n})\n```\n\nKeep the `:CPlugCMakeBuildOnce` terminal open after a successful build:\n\n```lua\nrequire(\"cplug\").setup({\n  c_family = {\n    keep_build_terminal_open = true,\n  },\n})\n```\n\nKeep the `:CPlugCMakeConfigure` terminal open after a successful configure:\n\n```lua\nrequire(\"cplug\").setup({\n  c_family = {\n    keep_configure_terminal_open = true,\n  },\n})\n```\n\nOverride the Python interpreter used in generated launch configs:\n\n```lua\nrequire(\"cplug\").setup({\n  python = {\n    interpreter = \"/path/to/python\",\n  },\n})\n```\n\nBy default, Python projects get a local `.venv` with `debugpy` when no usable\nproject environment exists. cplug prefers `uv` for this and falls back to\n`python -m venv` plus `pip`. Configure the `uv` invocation if your environment\nneeds specific transport or index behavior:\n\n```lua\nrequire(\"cplug\").setup({\n  python = {\n    console = \"internalConsole\",\n    redirect_output = true,\n    uv = {\n      native_tls = true,\n      extra_args = { \"--index-url\", \"https://example.invalid/simple\" },\n      env = {\n        UV_NATIVE_TLS = \"true\",\n      },\n    },\n  },\n})\n```\n\nDefault keymaps:\n\n- `\u003cleader\u003ec` compile and debug\n- `\u003cleader\u003egj` compile and debug\n- `\u003cleader\u003egg` toggle debug UI\n- `\u003cleader\u003egl` pick debug UI layout\n- `\u003cleader\u003egc` continue\n- `\u003cleader\u003egx` terminate\n- `\u003cleader\u003egn` step over\n- `\u003cleader\u003egi` step into\n- `\u003cleader\u003ego` step out\n- `\u003cleader\u003egb` toggle breakpoint\n- `\u003cleader\u003egr` run to cursor\n- `\u003cleader\u003egq` restart\n- `\u003cleader\u003ege` evaluate expression\n\n## lazy.nvim\n\n```lua\n{\n  \"jamylak/cplug.nvim\",\n  dependencies = {\n    \"mfussenegger/nvim-dap\",\n    \"nvim-neotest/nvim-nio\",\n    \"rcarriga/nvim-dap-ui\",\n    \"Jorenar/nvim-dap-disasm\",\n  },\n  keys = {\n    {\n      \"\u003cleader\u003ec\",\n      function()\n        require(\"cplug\").compile_and_debug()\n      end,\n      desc = \"Compile and debug\",\n    },\n  },\n  config = function()\n    require(\"cplug\").setup({\n      default_keymaps = false,\n    })\n  end,\n}\n```\n\n## Health\n\nRun:\n\n```vim\n:checkhealth cplug\n```\n\nThe healthcheck warns when `nvim-dap`, `nvim-dap-ui`, or `nvim-dap-disasm` are missing from `runtimepath`.\n\n## Tests\n\nRun the current regression scripts with:\n\n```sh\nmake test\n```\n\nTry the plugin locally against a toy or empty C++ project with:\n\n```sh\nsh scripts/run-cpp-demo.sh toy\nsh scripts/run-cpp-demo.sh empty\n```\n\nThe demo runner sets `\u003cleader\u003e` to `\u003cSpace\u003e`, enables automatic project and\nlaunch scaffolding, and will also add local `nvim-dap`, `nvim-dap-ui`, and\n`nvim-dap-disasm` installations plus an LLDB adapter when they are already\navailable on your machine. That lets you use `\u003cSpace\u003ec`, `\u003cSpace\u003egj`, and the\ndefault `\u003cSpace\u003eg...` debug mappings directly in the demo session, including\n`\u003cSpace\u003egl` for the layout picker.\n\nThe demo also exposes `:CPlugAttach` and `:CPlugGenerateAttach` so you can try\nattach flows after starting a local process yourself.\n\nFor a repeatable attach demo, use the dedicated `target` and `editor` scripts:\n\n```sh\nsh scripts/demo/python-attach-target.sh\nsh scripts/demo/python-attach-editor.sh\n\nsh scripts/demo/cpp-attach-target.sh\nsh scripts/demo/cpp-attach-editor.sh\n```\n\nThe `target` script starts something attachable. The `editor` script opens\nNeovim in the matching demo project. Then run `:CPlugAttach` inside Neovim.\n\n## DAP Startup\n\nOnce a backend and launch config are resolved, cplug passes the selected configuration to `nvim-dap` and opens `nvim-dap-ui` by default. cplug manages named `dapui` layout presets unless you set `dap.manage_ui_layout = false`.\n\nBy default `dap.layout = \"auto\"`:\n\n- non-low-level adapters use the `standard` layout\n- low-level adapters use the `native` layout\n\nAvailable managed presets:\n\n- `standard`\n- `native`\n- `code_repl`\n- `stack_focus`\n- `repl_only`\n\nYou can switch layouts at runtime with `:CPlugLayout` or the default\n`\u003cleader\u003egl` keymap. `:CPlugLayout` with no argument opens a built-in floating\npicker with fuzzy filtering.\nLow-level sessions use the disassembly pane in the `native` layout when\n`Jorenar/nvim-dap-disasm` is installed; disable that with\n`dap.disassembly.enabled = false`.\n\n## DAP Keymaps\n\nWhen `default_keymaps = true`, cplug also registers a small set of DAP action mappings:\n\n- `compile and debug` on `\u003cleader\u003ec` and `\u003cleader\u003egj`\n- `toggle debug UI` on `\u003cleader\u003egg`\n- `pick debug UI layout` on `\u003cleader\u003egl`\n- `continue` on `\u003cleader\u003egc`\n- `terminate` on `\u003cleader\u003egx`\n- `step over` on `\u003cleader\u003egn`\n- `step into` on `\u003cleader\u003egi`\n- `step out` on `\u003cleader\u003ego`\n- `toggle breakpoint` on `\u003cleader\u003egb`\n- `run to cursor` on `\u003cleader\u003egr`\n- `restart` on `\u003cleader\u003egq`\n- `evaluate expression` on `\u003cleader\u003ege`\n\nIf you want extra convenience bindings without fully opting out, set\n`keymaps.\u003caction\u003e` to a list of lhs values. If you want complete control, set\n`default_keymaps = false` and define your own mappings outside the plugin.\n\n## Launch Configs\n\nThe shared launch layer expects `.vscode/launch.json` by default, can select a named configuration via `opts.launch.configuration`, and can handle missing files with `opts.launch.on_missing`:\n\n- `\"prompt\"` prompts before generating a backend-specific launch file\n- `\"always\"` generates automatically and is the default\n- `\"never\"` returns an error\n\nGenerated launch files are written as pretty multi-line JSON. By default,\n`dap.auto_adapter = \"auto\"` also registers the common generated adapters when\npossible: `lldb` from `lldb-dap`, `codelldb`, or `lldb-vscode`, and `python`\nthrough the resolved interpreter running `debugpy.adapter`. For Python, cplug\nalso ensures `debugpy` is installed in the project env unless\n`python.bootstrap_debugpy = false` or you set an explicit `python.interpreter`.\nSet `dap.auto_adapter = \"none\"` if you want to own adapter registration\nyourself.\n\nProject scaffolding uses `opts.scaffold.on_missing` with the same modes, and\ndefaults to `\"always\"` so `\u003cleader\u003ec` will generate missing C/C++ project\nfiles automatically.\n\n`:CPlugAttach` uses the same `launch.on_missing` policy, but resolves attach\nconfigurations first and can auto-generate an attach config when the backend\nprovides one and `.vscode/launch.json` is missing.\n\n`:CPlugGenerateAttach` writes or updates an attach configuration for the\ncurrent backend without starting DAP. Existing launch entries are preserved\nunless a generated attach configuration replaces one with the same name.\n\n## Attach\n\nRun:\n\n```vim\n:CPlugAttach\n```\n\nThis detects the current backend, resolves the selected attach configuration,\nand starts `nvim-dap` without entering cplug's build or scaffold path.\n\nRun:\n\n```vim\n:CPlugGenerateAttach\n```\n\nThis writes a backend-appropriate attach configuration into\n`.vscode/launch.json` without starting a debug session.\n\nCurrent attach templates:\n\n- Python: `debugpy`-style server attach on `127.0.0.1:5678`\n- C/C++ and Rust: LLDB process attach using `${command:pickProcess}`\n\n## CMake Configure\n\nRun:\n\n```vim\n:CPlugCMakeConfigure\n```\n\nThis reuses the CMake backend detection and scaffolding flow, then runs a Debug configure step into the configured build directory without starting DAP.\nIt opens the configure step in a terminal split, keeps failures visible, and closes the terminal automatically when configuration succeeds unless `c_family.keep_configure_terminal_open = true`.\n\n## CMake Build Once\n\nRun:\n\n```vim\n:CPlugCMakeBuildOnce\n```\n\nThis reuses the same CMake detection and scaffolding flow, then performs a one-off Debug build into the configured build directory without starting DAP.\nIt opens the build in a terminal split, keeps failures visible, and closes the terminal automatically when the build succeeds unless `c_family.keep_build_terminal_open = true`.\n\n## CMake Build And Run\n\nRun:\n\n```vim\n:CPlugCMakeBuildAndRun\n```\n\nThis reuses the same CMake detection and scaffolding flow, performs a Debug build, and runs the first built executable without starting DAP.\nIt now runs the build in a terminal first, then starts the executable in a second terminal only after the build succeeds.\n\n## CMake Run\n\nRun:\n\n```vim\n:CPlugCMakeRun\n```\n\nThis runs the first built executable from the configured CMake build directory without rebuilding first.\nIt opens the executable in a terminal split, focuses that window, and enters insert mode so live output stays visible while the process runs.\n\n## Layout Picker\n\nRun:\n\n```vim\n:CPlugLayout\n```\n\nWith no argument, this opens the managed DAP layout picker through\nthe built-in floating picker. Start typing to fuzzy-filter the available\nlayouts, then press `\u003cCR\u003e` to switch.\n\nYou can also set a layout directly:\n\n```vim\n:CPlugLayout code_repl\n:CPlugLayout native\n:CPlugLayout auto\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjamylak%2Fcplug.nvim","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjamylak%2Fcplug.nvim","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjamylak%2Fcplug.nvim/lists"}