Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 62 additions & 59 deletions docs/CHANGELOG.md

Large diffs are not rendered by default.

49 changes: 0 additions & 49 deletions docs/todo/laravel.md
Original file line number Diff line number Diff line change
Expand Up @@ -589,55 +589,6 @@ The scanners already enumerate every valid key for go-to-definition. The
items below mostly wire that existing enumeration into three more LSP
endpoints rather than building new analysis.

#### L14. Diagnostics for Laravel string keys

**Impact: High · Effort: Medium**

No Laravel string key is currently validated. A typo in `route('dashbaord')`,
`config('app.naem')`, `env('DB_CONNCTION')`, `__('auth.failedd')`, or
`view('layouts.ap')` produces no warning — the bug surfaces only at runtime.
This is the single highest-value gap, because it catches a class of error
that PHP itself never reports.

Emit a warning when a string argument in a recognised context resolves to no
declaration. The candidate set is the same one the go-to-definition scanners
already build, so the diagnostic is "key not in the collected set." Each
construct reuses its existing scanner:

- `route('name')` → not in collected `->name()` declarations.
- `config('a.b.c')` → not in flattened `config/*.php` keys.
- `env('KEY')` → not in `.env` / `.env.example`.
- `__()`/`trans()`/`trans_choice()` → not in `lang/**` keys.
- `view('a.b')` → no matching file under `resources/views/`.

Pair each with a quick-fix where cheap: "create missing view file,"
"add missing key to `.env` (copy from `.env.example`)" (mirrors the
extension's two quick-fixes). Guard against false positives from genuinely
dynamic keys (e.g. `config($key)` with a variable, or
`route("admin.$section")` interpolation) by only flagging plain string
literals.

#### L15. Completion for Laravel string keys

**Impact: High · Effort: Medium**

Completion exists only for Eloquent relations/columns. Extend it to offer
route names, config keys (dot-notation drill-down), env var names,
translation keys, and view names inside the corresponding string contexts.
The candidate lists are exactly the declaration sets the go-to scanners
already produce; the work is detecting the string-literal cursor context
(the symbol-map already records these as `LaravelStringKey`) and returning
the collected keys as completion items.

#### L16. Hover for Laravel string keys

**Impact: Medium · Effort: Low-Medium**

`SymbolKind::LaravelStringKey` currently returns `None` from hover
(`hover/mod.rs`). Show the resolved target: the config/env/translation
*value*, the route's URI + action, or the view's file path. The data is
already loaded by the go-to scanners; this is formatting it as hover markdown.

#### L17. Additional string contexts without booting

**Impact: Medium · Effort: Medium**
Expand Down
19 changes: 18 additions & 1 deletion src/completion/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,6 @@ impl Backend {
let string_ctx =
crate::completion::comment_position::classify_string_context(&content, position);
use crate::completion::comment_position::StringContext;

// ── Array shape key completion ───────────────────────────
// Runs before `InStringLiteral` suppression because in
// normal code `$arr['` puts the scanner inside a
Expand All @@ -373,6 +372,24 @@ impl Backend {
return Ok(Some(response));
}

// ── Laravel string key completion (route/config/view/trans) ──
// Inside `route('|')`, `config('|')`, `view('|')`, `__('|')`,
// etc., offer matching key names from the project.
// NB: `is_laravel` is extracted to a `let` so the read lock
// on `resolved_class_cache` is dropped before calling
// `try_laravel_string_key_completion`, which may trigger
// `ensure_workspace_indexed` → `update_ast` → write lock.
let is_laravel = self.resolved_class_cache.read().is_laravel();
if is_laravel
&& matches!(
string_ctx,
StringContext::InStringLiteral | StringContext::NotInString
)
&& let Some(response) = self.try_laravel_string_key_completion(&content, position)
{
return Ok(Some(response));
}

// ── Eloquent relation/column string completion ──────────
// Like array shape completion, this triggers inside string
// literals where the cursor is in a method argument position
Expand Down
Loading
Loading