{"id":13496051,"url":"https://github.com/giann/croissant","last_synced_at":"2025-04-05T13:09:44.803Z","repository":{"id":83813172,"uuid":"171019128","full_name":"giann/croissant","owner":"giann","description":"🥐 A Lua REPL and debugger","archived":false,"fork":false,"pushed_at":"2024-07-18T06:12:05.000Z","size":605,"stargazers_count":423,"open_issues_count":8,"forks_count":10,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-03-29T12:11:09.506Z","etag":null,"topics":["cli","commandline","debugger","lua","repl"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/giann.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","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},"funding":{"github":["giann"]}},"created_at":"2019-02-16T15:33:28.000Z","updated_at":"2025-03-22T14:29:54.000Z","dependencies_parsed_at":"2024-07-18T08:11:42.217Z","dependency_job_id":null,"html_url":"https://github.com/giann/croissant","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giann%2Fcroissant","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giann%2Fcroissant/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giann%2Fcroissant/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/giann%2Fcroissant/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/giann","download_url":"https://codeload.github.com/giann/croissant/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247339158,"owners_count":20923014,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["cli","commandline","debugger","lua","repl"],"created_at":"2024-07-31T19:01:41.549Z","updated_at":"2025-04-05T13:09:44.696Z","avatar_url":"https://github.com/giann.png","language":"Lua","readme":"\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://github.com/giann/croissant/raw/master/assets/logo.png\" alt=\"croissant\" width=\"304\" height=\"304\"\u003e\n\u003c/p\u003e\n\n# Croissant\n🥐 A Lua REPL and debugger implemented in Lua\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://github.com/giann/croissant/raw/master/assets/repl.gif\" alt=\"croissant\"\u003e\n\u003c/p\u003e\n\n**Note:** Croissant is in active development.\n\nCroissant is based on [sirocco](https://github.com/giann/sirocco).\n\n## Features\n\n- Syntax highlighting\n- Code parsed as you type\n- Persistent history\n- Multiline\n- Formatted returned values\n- Basic auto-completion\n- Contextual help (`C-h` or `M-h` on an identifier)\n- Debugger\n\n### Planned\n\n- Customization: keybinding, theme, etc.\n\n## Installation\n\nRequirements:\n- Lua 5.1/JIT/5.2/5.3 (needs more testing for \u003c 5.3 though)\n- luarocks \u003e= 3.0 (_Note: `hererocks -rlatest` will install 2.4, you need to specify it with `-r3.0`_)\n\n```bash\nluarocks install croissant\n```\n\n## Usage\n\n```bash\n# Make sure lua/luarocks binaries are in your $PATH (~/.luarocks/bin)\ncroissant [-h] [\u003cinput\u003e] [\u003carguments\u003e] [-d [\u003cdebugger\u003e] ...]\n```\n\n- `\u003cinput\u003e`: a lua file to run or debug. If not provided, croissant will run the REPL.\n- `\u003carguments\u003e`: arguments to pass to the `\u003cinput\u003e` script\n- `--debugger -d --break -b [file.lua:line] ...`: runs croissant in debugger mode and optionally sets breakpoints\n- `--help -h`: shows help message\n\n## Debugger\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://github.com/giann/croissant/raw/master/assets/debugger.gif\" alt=\"croissant\"\u003e\n\u003c/p\u003e\n\n### Using the cli\n\n```bash\ncroissant filetodebug.lua -d\n```\n\nThis will start croissant in debugger mode. You can then add some breakpoints with the `breakpoint` command and start your script with the `run` command.\n\n### In your code\n\nAlternatively, you can require the debugger in your script where you want to break:\n\n```bash\nrequire \"croissant.debugger\"()\n```\n\n### Commands\n\nCroissant looks at the first word of your entry and runs any command it matches. It'll otherwise runs the entry as Lua code in the current frame context. If empty, croissant executes the previous repeatable command.\n\n- **`help [\u003ccommand\u003e]`**: prints general help or help about specified command\n- **`run`**: starts your script\n- **`args \u003cargument\u003e ...`**: set arguments to pass to your script\n- **`watch \u003cexpression\u003e`**: breaks when evaluated Lua `expression` changes value\n- **`breakpoint \u003cwhere\u003e [\u003cwhen\u003e]`**: add a new breakpoint at `\u003cwhere\u003e` (can be line number in current file, `file.lua:line` or a function name) if `\u003cwhen\u003e` (lua code evaluated in the breakpoint context) is true or absent\n- **`condition \u003c#id\u003e \u003cwhen\u003e`**: change breaking condition of breakpoint `#id`\n- **`delete \u003c#id\u003e`**: delete breakpoint or watchpoint `#id`\n- **`enable \u003c#id\u003e`**: enable breakpoint or watchpoint `#id`\n- **`disable \u003c#id\u003e`**: disable breakpoint or watchpoint `#id`\n- **`display \u003cexpression\u003e`**: display evalued Lua `expression` each time the program stops\n- **`undisplay \u003c#id\u003e`**: dlete display `#id`\n- **`clear`**: deletes all breakpoints, watchpoints and displays\n- **`info \u003cwhat\u003e`**:\n    + `breakpoints`: list breakpoints and watchpoints\n    + `locals`: list locals of the current frame\n    + `displays`: list displays\n- **`step`** (repeatable): step in the code\n- **`next`** (repeatable): step in the code going over any function call\n- **`finish`** (repeatable): will break after leaving the current function\n- **`up`** (repeatable): go up one frame\n- **`down`** (repeatable): go down one frame\n- **`continue`** (repeatable): continue until hitting a breakpoint. If no breakpoint are specified, clears debug hooks\n- **`eval \u003ccode\u003e`**: runs `code` (useful to disambiguate from debugger commands)\n- **`depth \u003cdepthLimit\u003e \u003citemsLimit\u003e`**: set depth limit and number of items when pretty printing values\n- **`exit`**: quit\n- **`where [\u003crows\u003e]`**: prints `\u003crows\u003e` or `conf.whereRows` rows around the current line. Is ran for you each time you step in the code or change frame context\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://github.com/giann/croissant/raw/master/assets/debugger-where.png\" alt=\"where command\"\u003e\n\u003c/p\u003e\n\n- **`trace`**: prints current stack trace and highlights current frame.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://github.com/giann/croissant/raw/master/assets/debugger-trace.png\" alt=\"where trace\"\u003e\n\u003c/p\u003e\n\n## Caveats\n\n- Pretty printing values can be expensive in CPU and memory: avoid dumping either large of deeply nested tables. You can play with the `dump.depthLimit` and `dump.itemsLimit` value in your `~/.croissantrc` or the `depth` command to avoid exploring to far down in complex tables.\n- The debugger will slow your program down. Croissant will try and clear hooks whenever possible but if you know you won't hit anymore breakpoints, do a `clear` before doing `continue`.\n- A breakpoint on a function name will not work if the function is not called by its name in your code. Example:\n\n```lua\nlocal function stopMe()\n    -- ...\nend\n\nlocal function call(fn)\n    fn()\nend\n\ncall(stopMe)\n```\n\n## Configuration\n\nYou can customize some aspect of croissant by writing a `~/.croissantrc` lua file. Here are the default values than you can overwrite:\n\n```lua\nreturn {\n    -- Default prompt\n    prompt = \"→ \",\n    -- Prompt used when editing multiple lines of code\n    continuationPrompt = \".... \",\n\n    -- Maximum amount of remembered lines\n    -- Croissant manages two history file: one for the repl (~/.croissant_history),\n    -- one for the debugger (~/.croissant_debugger_history)\n    historyLimit = 1000,\n\n    -- How many rows `where` should print around the current line\n    whereRows = 4,\n\n    -- Syntax highlighting colors\n    -- Available colors are: black, red, green, yellow, blue, magenta, cyan, white.\n    -- They can also be combined with modifiers: bright, dim, underscore, blink, reverse, hidden\n    syntaxColors = {\n        constant   = { \"bright\", \"yellow\" },\n        string     = { \"green\" },\n        comment    = { \"dim\", \"cyan\" },\n        number     = { \"yellow\" },\n        operator   = { \"yellow\" },\n        keywords   = { \"bright\", \"magenta\" },\n        identifier = { \"blue\" },\n    },\n\n    dump = {\n        -- Nesting limit at which croissant will stop when pretty printing a table\n        depthLimit = 5,\n        -- If a table has more items than itemsLimit, will stop there and print ellipsis\n        itemsLimit = 30\n    }\n}\n```\n\n## Löve 2D\n\nRead and understand the [**Caveats**](#caveats) section.\n\n```bash\nluarocks install croissant --tree mygame/lua_modules\n```\n\nTell Löve to search in `lua_modules`:\n\n```lua\nlove.filesystem.setRequirePath(\n    love.filesystem.getRequirePath()\n        .. \";lua_modules/share/lua/5.1/?/init.lua\"\n        .. \";lua_modules/share/lua/5.1/?.lua\"\n)\n\nlove.filesystem.setCRequirePath(\n    love.filesystem.getCRequirePath()\n    .. \";lua_modules/lib/lua/5.1/?.so\"\n)\n```\n\nRequire `croissant.debugger` where you want to break:\n\n```lua\nrequire \"croissant.debugger\"()\n```\n","funding_links":["https://github.com/sponsors/giann"],"categories":["Lua"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgiann%2Fcroissant","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgiann%2Fcroissant","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgiann%2Fcroissant/lists"}