feat(tooling): JetBrains IDE support, LSP navigation, barrel imports, package scripts and hooks

- JetBrains plugin 1.4.0: semantic colours (builtin / vendor / own), template strings,
  brace handling, run configurations and a test console, package.ludic and
  package.lock.ludic editing (completion, docs, app preview, colour previews, asset
  navigation), External Libraries for the runtime and packages, doc pages for built-ins
- ludic-lsp: go to definition for imports, document links, hover with inferred types,
  type definition, signature help with parameters, docs from docs/language
- `import "dir"` resolves a barrel `dir/index.ludic`
- package.ludic `entry`, `script` and `hook before|after <command>`; `ludic <script>`,
  `ludic script`, `ludic scripts`
- `ludic test --verbose` and `--test NAME`; the test runner filters by name

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-16 16:00:28 +03:00
parent da57b20156
commit f92d7f89c6
75 changed files with 46802 additions and 40343 deletions

View file

@ -50,6 +50,37 @@ A consumer project's manifest is the same file, usually with only `require`
lines (the `package`/`version` fields describe a *publishable* package and are
optional for a leaf application).
### The entry program
`entry "src/game.ludic"` names the program `ludic run`, `build` and `bundle` compile
when no file is given. Without it the CLI tries `src/main.ludic`, `main.ludic`, then
the one file under `src/` that declares a `program`.
### Scripts and hooks
```
script "dev" "ludic run --headless" # ludic dev (or: ludic script dev)
script "shots" "tools/shots.sh" # ludic shots a b -> tools/shots.sh 'a' 'b'
hook before build "tools/gen_atlas.sh" # a failing before hook stops the build
hook after bundle "tools/notarize.sh" # after hooks run only when the command succeeded
hook before dev "ludic fmt --check" # a script is an event too
```
A **script** is a named shell command, run from the package root. `ludic <name>` runs
it when no built-in command has that name; `ludic script <name>` always does, and
`ludic scripts` lists them. Arguments after the name are passed on, quoted.
A **hook** runs a command `before` or `after` a built-in command (`build`, `run`,
`test`, `bundle`, `pack`, `clean`, `fmt`, `get`, `add`, `update`, `verify`, `vendor`,
`assets`, `build-lib`) or a script. Hooks of one event run in the order written. A
`before` hook that exits non-zero stops the command with that exit code; `after`
hooks run only when the command succeeded.
Both run through the shell with the toolchain's `bin/` first on `PATH` and
`LUDIC_PACKAGE_ROOT`, `LUDIC_EVENT` (the command or script) and `LUDIC_PHASE`
(`before`, `after` or `run`) set. Inside a quoted value, `\"` is a quote and `\\` a
backslash.
## The lockfile — `package.lock.ludic`
Generated by `ludic get`; do not edit by hand. One line per resolved module, pinning