Skip to main content

cosh_tools/lsp/
types.rs

1//! Input and output types shared by all `lsp` tools.
2
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5
6/// Parameters for `lsp_diagnostics`.
7#[derive(Clone, Debug, Default, Deserialize, JsonSchema)]
8pub struct DiagnosticsInput {
9    /// File to scope diagnostics to. Omitted: every tracked file in the
10    /// workspace. The file is opened on its language server if needed.
11    pub file_path: Option<String>,
12    /// Minimum severity to report: `"errors"`, `"warnings"` (errors +
13    /// warnings), or `"all"`. Default `"all"`.
14    pub severity: Option<String>,
15    /// Maximum number of formatted lines. Default 50.
16    pub max_items: Option<u32>,
17    /// Milliseconds to wait for diagnostics to settle after opening/refreshing
18    /// the file. Default 5000.
19    pub settle_ms: Option<u32>,
20}
21
22/// Result of `lsp_diagnostics`.
23#[derive(Clone, Debug, Serialize, JsonSchema)]
24pub struct DiagnosticsOutput {
25    /// Model-ready rendering: one diagnostic per line, ordered by severity
26    /// then position, deduplicated across servers, capped with an explicit
27    /// `… and N more` marker.
28    pub formatted: String,
29    /// Number of rendered lines (excluding any truncation marker).
30    pub count: usize,
31    /// Whether the store was quiet before rendering (`true` = fresh data;
32    /// `false` = the settle budget elapsed mid-churn and results may be stale).
33    pub settled: bool,
34}
35
36/// One-based position inside a file, as the model counts lines.
37#[derive(Debug, Clone, Copy, Deserialize, JsonSchema)]
38pub struct Position1 {
39    /// 1-based line number.
40    pub line: u32,
41    /// 1-based character/column offset.
42    pub character: u32,
43}
44
45/// Parameters shared by `lsp_definitions` and `lsp_references`.
46///
47/// Addressing is hybrid: give `position`, or just `symbol` and the engine
48/// locates its first whole-word occurrence in the file.
49#[derive(Clone, Debug, Deserialize, JsonSchema)]
50pub struct LocationInput {
51    /// File to query.
52    pub file_path: String,
53    /// Target position (1-based). Provide this OR `symbol`.
54    pub position: Option<Position1>,
55    /// Symbol name to locate in the file (first whole-word match). Used when
56    /// `position` is omitted.
57    pub symbol: Option<String>,
58}
59
60/// Parameters for `lsp_definitions`.
61#[derive(Clone, Debug, Deserialize, JsonSchema)]
62pub struct DefinitionsInput {
63    #[serde(flatten)]
64    pub location: LocationInput,
65}
66
67/// Parameters for `lsp_references`.
68#[derive(Clone, Debug, Deserialize, JsonSchema)]
69pub struct ReferencesInput {
70    #[serde(flatten)]
71    pub location: LocationInput,
72    /// Include the declaration itself among the references. Default true.
73    pub include_declaration: Option<bool>,
74    /// Maximum number of references returned. Default 100.
75    pub max_items: Option<u32>,
76}
77
78/// A resolved definition/reference target.
79#[derive(Clone, Debug, Serialize, JsonSchema)]
80pub struct LocationEntry {
81    /// File path (absolute).
82    pub path: String,
83    /// 1-based line of the target start.
84    pub line: u32,
85    /// 1-based character of the target start.
86    pub character: u32,
87    /// The source line's text, trimmed (context aid).
88    pub text: String,
89}
90
91/// Result of `lsp_definitions`.
92#[derive(Clone, Debug, Serialize, JsonSchema)]
93pub struct DefinitionsOutput {
94    pub definitions: Vec<LocationEntry>,
95    /// Model-ready rendering, one entry per line.
96    pub formatted: String,
97}
98
99/// References grouped by file.
100#[derive(Clone, Debug, Serialize, JsonSchema)]
101pub struct ReferenceFile {
102    pub path: String,
103    /// 1-based positions of each reference in this file.
104    pub locations: Vec<(u32, u32)>,
105}
106
107/// Result of `lsp_references`.
108#[derive(Clone, Debug, Serialize, JsonSchema)]
109pub struct ReferencesOutput {
110    pub total: usize,
111    pub files: Vec<ReferenceFile>,
112    /// Model-ready rendering grouped by file.
113    pub formatted: String,
114}
115
116/// Parameters for `lsp_symbols`.
117#[derive(Clone, Debug, Deserialize, JsonSchema)]
118pub struct SymbolsInput {
119    /// File whose document symbols are listed.
120    pub file_path: String,
121    /// Substring filter on symbol names (case-insensitive). Omitted: return
122    /// everything.
123    pub query: Option<String>,
124    /// Maximum number of symbols returned. Default 200.
125    pub max_items: Option<u32>,
126}
127
128/// One document symbol.
129#[derive(Clone, Debug, Serialize, JsonSchema)]
130pub struct SymbolEntry {
131    pub name: String,
132    /// LSP symbol kind rendered as text (`function`, `struct`, …).
133    pub kind: String,
134    /// 1-based definition position.
135    pub line: u32,
136    pub character: u32,
137    /// Enclosing symbol from the hierarchy walk (e.g. the impl or parent fn).
138    pub container: Option<String>,
139}
140
141/// Result of `lsp_symbols`.
142#[derive(Clone, Debug, Serialize, JsonSchema)]
143pub struct SymbolsOutput {
144    pub symbols: Vec<SymbolEntry>,
145    /// Model-ready indented tree preserving hierarchy.
146    pub formatted: String,
147}
148
149/// Parameters for `lsp_restart`.
150#[derive(Clone, Debug, Deserialize, JsonSchema)]
151pub struct RestartInput {
152    /// Restart only the server(s) serving this file. Omitted: restart every
153    /// running server in the workspace.
154    pub file_path: Option<String>,
155}
156
157/// Result of `lsp_restart`.
158#[derive(Clone, Debug, Serialize, JsonSchema)]
159pub struct RestartOutput {
160    /// Server names that were stopped (they respawn lazily on next touch;
161    /// files touched during restart are re-opened immediately).
162    pub restarted: Vec<String>,
163}
164
165// ---------------------------------------------------------------------------
166// Rename
167// ---------------------------------------------------------------------------
168
169/// Parameters for `lsp_rename`.
170///
171/// Two-phase by default: without `confirm` the tool returns the rename PLAN
172/// (files + edit counts + preview) and changes nothing. Re-call with
173/// `confirm: true` to apply.
174#[derive(Clone, Debug, Deserialize, JsonSchema)]
175pub struct RenameInput {
176    /// File containing the symbol to rename.
177    pub file_path: String,
178    /// Target position (1-based). Provide this OR `symbol`.
179    pub position: Option<Position1>,
180    /// Symbol name to locate in the file (first whole-word match).
181    pub symbol: Option<String>,
182    /// The new name.
183    pub new_name: String,
184    /// Apply the plan. Default false (dry-run).
185    pub confirm: Option<bool>,
186}
187
188/// One file touched by a rename plan.
189#[derive(Clone, Debug, Serialize, JsonSchema)]
190pub struct RenameFilePlan {
191    pub path: String,
192    /// Number of edits inside this file.
193    pub edits: usize,
194    /// First replacements (`L{line} → {new}`), capped at 3. Empty on applied
195    /// output.
196    pub preview: Vec<String>,
197}
198
199/// Result of `lsp_rename`.
200#[derive(Debug, Serialize, JsonSchema)]
201pub struct RenameOutput {
202    /// `true` when edits were written to disk.
203    pub applied: bool,
204    pub files: Vec<RenameFilePlan>,
205    pub total_edits: usize,
206    pub formatted: String,
207}
208
209// ---------------------------------------------------------------------------
210// Hover
211// ---------------------------------------------------------------------------
212
213/// Parameters for `lsp_hover`. Same hybrid addressing as definitions.
214#[derive(Clone, Debug, Deserialize, JsonSchema)]
215pub struct HoverInput {
216    pub file_path: String,
217    pub position: Option<Position1>,
218    pub symbol: Option<String>,
219}
220
221/// Result of `lsp_hover`.
222#[derive(Debug, Serialize, JsonSchema)]
223pub struct HoverOutput {
224    /// Rendered hover contents (markdown when the server provides it).
225    pub formatted: String,
226}
227
228// ---------------------------------------------------------------------------
229// Workspace symbols
230// ---------------------------------------------------------------------------
231
232/// Parameters for `lsp_workspace_symbols`.
233#[derive(Clone, Debug, Deserialize, JsonSchema)]
234pub struct WorkspaceSymbolsInput {
235    /// Substring query matched against symbol names. Empty = all symbols.
236    pub query: Option<String>,
237    /// Maximum symbols returned. Default 100.
238    pub max_items: Option<u32>,
239}
240
241/// One workspace-wide symbol hit.
242#[derive(Debug, Serialize, JsonSchema)]
243pub struct WorkspaceSymbolEntry {
244    pub name: String,
245    pub kind: String,
246    pub path: String,
247    pub line: u32,
248    pub character: u32,
249}
250
251/// Result of `lsp_workspace_symbols`.
252#[derive(Debug, Serialize, JsonSchema)]
253pub struct WorkspaceSymbolsOutput {
254    pub symbols: Vec<WorkspaceSymbolEntry>,
255    pub total: usize,
256    pub formatted: String,
257}
258
259// ---------------------------------------------------------------------------
260// Call hierarchy
261// ---------------------------------------------------------------------------
262
263/// Parameters for `lsp_call_hierarchy`.
264#[derive(Clone, Debug, Deserialize, JsonSchema)]
265pub struct CallHierarchyInput {
266    pub file_path: String,
267    pub position: Option<Position1>,
268    pub symbol: Option<String>,
269    /// `"outgoing"` (what this calls) or `"incoming"` (what calls this).
270    /// Default `"outgoing"`.
271    pub direction: Option<String>,
272    /// Maximum calls returned. Default 50.
273    pub max_items: Option<u32>,
274}
275
276/// One call relationship.
277#[derive(Debug, Serialize, JsonSchema)]
278pub struct CallEntry {
279    /// Callee name for outgoing; caller name for incoming.
280    pub name: String,
281    pub kind: String,
282    pub path: String,
283    pub line: u32,
284    pub character: u32,
285    /// Call-site positions inside the caller (incoming only).
286    pub sites: Vec<(u32, u32)>,
287}
288
289/// Result of `lsp_call_hierarchy`.
290#[derive(Debug, Serialize, JsonSchema)]
291pub struct CallHierarchyOutput {
292    pub direction: String,
293    pub calls: Vec<CallEntry>,
294    pub formatted: String,
295}
296
297// ---------------------------------------------------------------------------
298// Code actions
299// ---------------------------------------------------------------------------
300
301/// Parameters for `lsp_code_actions`.
302#[derive(Clone, Debug, Deserialize, JsonSchema)]
303pub struct CodeActionsInput {
304    /// File containing the diagnostic/error.
305    pub file_path: String,
306    /// 1-based line where the problem is.
307    pub line: u32,
308    /// Apply the Nth action's edit instead of listing. Default: list only.
309    pub apply_index: Option<usize>,
310}
311
312/// One available code action.
313#[derive(Debug, Serialize, JsonSchema)]
314pub struct CodeActionEntry {
315    pub index: usize,
316    /// Human-readable title from the server (e.g. "Import `HashMap`").
317    pub title: String,
318    /// Action kind (`quickfix`, `refactor`, `source`…).
319    pub kind: Option<String>,
320    /// Whether this action carries file edits (vs just a command).
321    pub has_edit: bool,
322    /// Files the edit touches.
323    pub files: Vec<String>,
324}
325
326/// Result of `lsp_code_actions`.
327#[derive(Debug, Serialize, JsonSchema)]
328pub struct CodeActionsOutput {
329    /// `true` when an action was applied to disk.
330    pub applied: bool,
331    pub actions: Vec<CodeActionEntry>,
332    pub formatted: String,
333}