Language servers
Language servers give the Zide editor eight things: errors and warnings inline as you work, type and signature information on hover, completions, parameter hints while you fill in a call, go to definition, peek definition, find references, and a document outline. They exist so that reviewing code in Zide doesn’t send you to another editor to answer “where else is this called?” or “did that edit break the build?”.
Zide installs and runs these servers for you. You do not need to configure anything before opening a file.
What you get in the editor
Inline diagnostics. Errors and warnings tint the affected line number and underline the code. Errors use a bold red number with a subtle chip, warnings an amber chip, and informational diagnostics a blue number. Hover an underline to read the full message. Diagnostics are shown for the file you are looking at.
Symbol information. Rest the pointer on a symbol to see its type and documentation in a panel, with a caret pointing at the symbol it describes. The panel is purely informational. It holds no buttons, because reaching one would mean moving the pointer, and moving the pointer dismisses the panel.
Go to definition. Hold Ctrl (Windows/Linux) or Command (macOS) and click a symbol, or right-click it and choose Go to Definition. A resolvable symbol is underlined while you hold the modifier. The target opens in its own content tab, positioned at the definition, and that tab becomes active. If that file is already open, its existing tab is the one you land in rather than a second copy of it.
Peek definition. Right-click a symbol and choose Peek Definition. The definition opens as a read-only panel inside the file you are already reading, wedged in below the line you clicked. Nothing else moves: the active tab does not change, the caret stays where it was, and the panel takes no focus, so you can keep typing.
Completions. As you type, the server offers the names that are actually in scope, with each one’s kind, its type, and its documentation. See Completions below.
Parameter hints. While you fill in a call’s arguments, the signature appears above the caret with the parameter you are on picked out. See Parameter hints below.
Find references. Right-click a symbol and choose Find References. The results open in Find in Files Symbol mode, in the side panel beside the code. Selecting a row opens that file’s own tab at the exact line and column the server reported. See Finding every use of a symbol below.
There is no dedicated keyboard shortcut for Peek. Ctrl/Command+Click is contextual: inside the code editor it follows a symbol definition, while links and selectable lists keep their existing behavior elsewhere in Zide. Every symbol action also remains available from the right-click menu.
Go to Definition or Peek Definition?
They answer two different questions, which is why both are offered and why they always appear together, a symbol that can be navigated to can always be previewed.
- Go to Definition means take me there. You intend to work in the definition, so you get a real tab and your place in the current file is a thing you will come back to.
- Peek Definition means what is it? You want to read a signature or check a body without leaving the line you are on. When you are done, the panel closes and there is nothing to navigate back from.
Reading is the far more common of the two, so Peek is usually the one you want.
Working in the Peek panel
The panel shows the definition line highlighted with a few lines above it and rather more below, because a definition is read downwards.
When the server returns more than one definition, an overload set, a trait method and its implementations, the panel adds a list of every result with its path and line, and previews one at a time. Click a result, or use the up and down arrow keys, to preview another. Press Enter, double-click a result, or use the Open in New Tab button in the panel header to open the selected definition in a content tab.
Peek closes when you press Escape, click outside it, move the caret, invoke Peek somewhere else, or open a definition in a tab. Escape and clicking outside the editor put you back exactly where Peek found you, with the same caret and scroll position.
The panel’s text cannot be selected. That is what keeps focus in the source editor, which is what keeps the caret and the arrow keys working; if you want to copy from a definition, open it.
The right-click menu on a symbol
Each entry appears only when there is something behind it, so nothing in the menu is ever a no-op:
- Go to Definition: when the server resolved one.
- Peek Definition: under exactly the same condition as Go to Definition. The two are never offered separately.
- Find References: when the server supports finding references. Unlike the entries around it, this one is not pre-resolved: references are the expensive query, and asking speculatively on every right-click would slow the menu down for the one action that is already the slowest. A search that finds nothing says so in Find in Files Symbol mode.
- Show Symbol Information: when the server has something to say. Always offered, including when the hover panel is switched off, so this is the reliable route to it. Keywords like
importpass for words but carry no information, so they get no entry. - Copy Error Message: when you right-click a diagnostic. Copies the message together with its code, the reporting server, and the file and line, because the two places people paste an error are a search box and a bug report and both want that context.
- Copy Symbol Information and Copy Symbol.
Copying is in the menu rather than on the panel for the same reason the panel has no buttons: a hover panel’s text cannot be selected, since the pointer movement needed to reach it closes it.
A file whose language has no server behaves exactly as it did before: no gutter markers, no errors, nothing to dismiss.
Completions
Suggestions appear as you type an identifier, and after the characters the server asks to be told about, a . in most languages, a :: in Rust, a < in HTML.
Each suggestion carries an icon for its kind and its type or signature beside the name. A panel next to the list holds the highlighted suggestion’s documentation; it is fetched only for the suggestion you are looking at, so a list of several hundred candidates costs one request rather than several hundred. Turn the panel off with Show documentation with completions if you would rather keep the list compact.
Keyboard. Up and Down move through the list, Tab or Enter accepts, and Escape dismisses it. Ctrl+Space (Cmd+Space on macOS) asks for suggestions at any point, including in the middle of a word and when automatic suggestions are switched off. Tab still indents, and still moves between snippet fields, when there is no suggestion to accept.
Ordering is the server’s, among the candidates that match what you have typed. Zide filters and highlights the match itself, so rdts finds read_to_string, and lets the server break the ties, because which of several equally good matches you most likely meant is a question only the server can answer.
Some things worth knowing:
- A suggestion can bring an import with it. Accepting a name that isn’t in scope yet adds its
importoruseline at the top of the file, in the same step. Some servers only work that line out after you accept, so it can land a moment later. Zide applies it only when it belongs above the line you are completing on and the file hasn’t otherwise changed in the meantime, an import placed by a line number that has since moved is worse than one you add yourself. - A function arrives with its arguments. Accepting a function or method in Rust, TypeScript, or JavaScript fills in its parameters as fields you tab between. Python does not, pyright has no equivalent, so a Python completion inserts the name alone.
- Snippets are applied, not pasted. A suggestion that comes with placeholders, a function call with its arguments filled in as fields you tab between, inserts them as fields. Snippet features Zide cannot apply are degraded rather than shown literally: a choice becomes its first option, and an editor variable Zide does not provide inserts nothing rather than its own name.
- A completion never eats what you have already typed. The replacement always ends at the caret, whatever range the server computed before your last keystroke.
- Very large result sets are capped. A server asked for every symbol in a large workspace can return tens of thousands; Zide keeps the server’s own best thousand and re-asks as you narrow, so the list converges on the real answer rather than staying a lucky prefix.
- A slow or crashed server never blocks typing. Suggestions that arrive after you have moved on are discarded, not applied.
Parameter hints
Type a call’s opening bracket and the signature appears above the caret, with the parameter you are currently filling in picked out. It follows you across commas, and it disappears when the call closes, when you press Escape, or when the caret leaves. Ctrl+Shift+Space (Cmd+Shift+Space on macOS) brings it back at any point inside a call.
When the server offers several overloads, the panel says which one it is showing, such as Signature 2 of 4, and follows the server as you type arguments that narrow the choice.
While parameter hints are showing, the hover panel stays out of the way. Both want the space above the caret, and the panel you are actively typing into wins over one the pointer happened to rest on. Rest the pointer on a symbol after the call closes and the hover panel behaves as it always does.
While a server starts
Language servers are not instant. rust-analyzer on a large crate takes a noticeable moment to launch and longer to finish indexing, and until it has, there is nothing to hover and nothing to complete. Zide reports that in two places, deliberately split.
The editor’s status bar carries short, file-scoped messages in a slot of its own:
| Message | Meaning |
|---|---|
| Starting server | Opening this file needed a server that wasn’t running yet |
| Installing server | Its server is downloading |
| Phase… nn% | The server says it is still working. Servers name their own phases, rust-analyzer reports Fetching, then Indexing, then priming caches, and each counts from zero, so the figure restarting is the next phase starting rather than progress lost. Falls back to Indexing… when a server names nothing |
| Language features ready | It is up. Disappears after three seconds |
| Language features unavailable | Its server failed. The footer has the detail and the fix |
Each message carries the same icon as the footer language-servers indicator, because that control is where its actions live. The controls beside the slot never move as messages come and go, and on a narrow editor the full message is available as a tooltip.
Everything else stays quiet. A server that was already running produces no message at all, a file opening normally is not news, and an indicator that permanently reports that nothing is wrong is one you stop reading. Indexing… appears only when the server itself says it is busy; Zide never infers it from diagnostics being slow, which is indistinguishable from a file with no problems in it. A file whose language has no server says nothing either; its status slot’s tooltip reads No language server configured.
The footer indicator owns everything durable: installs in progress, missing toolchains, and failures, together with the Install, Retry, and View logs actions that resolve them. Those actions live there and only there, so there is never a question of which copy is the real one. See The footer indicator below.
Switching files, tabs, or panes immediately shows the newly active file’s own status. A failure in one project is never reported against a file in another.
Hover in the diff
The diff is where a change actually gets reviewed, so symbol information is available there too, the same panel, the same dwell, the same content. Rest the pointer on a symbol in a diff and its type appears.
It is deliberately available on one side only: the current file.
- In a side-by-side diff, that is the right panel.
- In a unified diff, that is the added and unchanged lines, the ones that exist in the file as it is now.
- Removed lines never answer. A language server describes the document it has, which is the current one; asking it about text that has been deleted would return information about whatever now occupies that position and present it as though it described the deleted line.
For the same reason, hover is only offered when the right side really is the file on disk, a working-tree diff. A diff between two commits, or between HEAD and the index, renders content from git that the server has never seen, so it stays quiet rather than answering confidently about the wrong text.
Switching Show symbol information on hover off in settings turns this off along with the editor’s panel.
Finding every use of a symbol
Find in Files has two modes that answer the same question from different directions. Text matches spelling across files. Symbol asks the language server which uses are actually the same symbol, so a local variable called id does not drag in every other id in the project. Open Symbol mode and click Choose Symbol… to pick from the active file’s language-server outline, or invoke Find References directly on an editor symbol. Text mode remains available for every repository.
The query bar names the current symbol and provides Clear. The list groups results by file, with a count per file and each use as its own row showing its line number and source preview. Selecting a row reuses the normal file destination and positions it at that character. Middle-click opens a fresh background tab; the row’s context menu offers Open and Open in New Tab. Arrow keys move through the list and Enter opens the highlighted row; dragging a row into a pane opens the file there. Press R to run the search again after you have changed the code.
Some deliberate limits:
- Results outside the folder you opened are dropped. A reference in a dependency’s source is a real reference, but it is not part of the project you are reviewing, and Zide does not present files you did not open as if they were.
- Duplicates collapse. A server that reports the same use twice produces one row, because two rows that navigate to the same character are not two results.
- Very large result sets are capped, and the list says how many were left out. Find references on a name like
Stringin a large workspace returns tens of thousands of uses; rendering all of them is not a feature.
The activity remembers the Text and Symbol queries across a restart, but not their results, re-running against the code as it is now is more useful than restoring a stale snapshot.
If a server does not implement find references, the menu entry does not appear for files it handles.
The document outline
The outline button in the editor toolbar opens a popover listing the document’s structure as a tree, headings in Markdown, classes with their methods, or modules with their functions. Code symbols include their kind and, where a language server supplies one, their signature. Use the pin in the header to keep that same outline beside the editor. The pinned presentation is an app-wide preference, so it follows you between file tabs.
The popover starts closed and closes after you select a symbol; the pinned panel stays open. Each tab keeps its own branches, selected symbol, and scroll position while it is open. Selecting a symbol moves the cursor to its name, not the first line of its body, in the editor you are already in. It never opens a second copy of the file.
Keyboard: Up and Down move through the visible rows without navigating, Right expands a branch, Left collapses it or steps out to its parent, Home and End jump to the ends, and Enter takes you to the selected symbol.
The outline reloads after you save, and again once typing settles. A reload keeps every branch that still exists open; a symbol you deleted takes its expansion with it.
This is a different thing from the toolbar’s Go to Symbol dropdown next to it. Go to Symbol is an instant, flat list. The outline adds hierarchy: it uses Markdown headings, asks the language server for richer code structure when available, and falls back to Zide’s local syntax understanding for supported source files. The outline button remains available for every editable file; when Zide cannot build a useful outline, the popover explains that plainly.
Supported languages
Zide ships a curated set, the servers that can be installed reliably without you first assembling a toolchain.
| Language | Server |
|---|---|
| Rust | rust-analyzer |
| TypeScript / JavaScript | typescript-language-server + typescript |
| Python | pyright |
| Go | gopls |
| C# | csharp-ls |
| Web (JSON, CSS, HTML) | vscode-langservers-extracted |
| Bash | bash-language-server |
The Web row is one install that provides three servers, so JSON, CSS, and HTML are covered together. TypeScript and JavaScript likewise share one install, which pulls in typescript as well as the language server, because the server drives the tsserver that ships inside it.
Toolchain requirements
Most of these need something already on your machine:
- TypeScript/JavaScript, Python, Web, and Bash are distributed through npm, so they need Node.js. This is why installing a Python server asks for Node.
- Go is installed by the Go toolchain itself (
go install golang.org/x/tools/gopls@latest), so it needs Go. - C# is installed by the .NET SDK’s tool manager (
dotnet tool install --global csharp-ls), so it needs the .NET SDK, version 10 or later. The .NET runtime on its own is not enough, and neither is an older SDK: Zide installs a pinned csharp-ls, and that release needs .NET 10. An older SDK is reported as its own state rather than as “missing”, because the fix is an upgrade, not an install.
Rust needs nothing, rust-analyzer is a direct download.
The Toolchains detected strip on the settings page shows which of these are present.
Syntax highlighting is a separate thing and never waits on any of this. A .cs file is highlighted as C# whether or not csharp-ls is installed, and on a machine with no .NET SDK at all, the same is true of every language Zide highlights.
Which project a C# server is given
For most languages Zide hands the server the nearest enclosing project directory, using markers like .git, Cargo.toml, or package.json.
C# is resolved from its solution instead. Zide looks up from the file for the nearest .sln or .slnx and hands the server that directory, because a project opened outside its solution loses every reference into the other projects in it, which is most of what go to definition is for. Only when there is no solution anywhere above the file does Zide fall back to the directory holding its .csproj, and then to the ordinary marker search.
The search never rises above the folder you opened as a Project Tab, or above the repository root, a solution belonging to some parent checkout is out of reach by design.
How servers get installed
By default, opening a file installs that language’s server in the background the first time you need it. Progress appears in the language servers indicator in the footer.
Zide makes one automatic attempt per language per session, whatever the outcome. It does not keep trying: an install that did not produce a working server will not produce one on the second run either, and a background job that retries itself is a job that can spin forever. After that attempt, the settings row is where you take over. Install and Retry both ask again, and both re-enable the automatic path for that row.
For the rows that install through a toolchain, C# and Go, this happens only when that toolchain is already on your machine. With no .NET SDK, opening a .cs file does nothing at all rather than failing: there is no install to run yet. The C# row in settings is where that is stated, and it says Needs .NET SDK. Install the SDK, press Re-check, and the next .cs file you open installs the server.
If a server is already on your machine, Zide uses it rather than downloading another copy. It looks in your project’s node_modules/.bin, then on PATH, then in the usual toolchain directories.
You can turn automatic installation off in Settings → Editor → Language Servers and install each language explicitly instead.
Settings
Settings → Editor → Language Servers is a global page. Every control on it applies to every project you open, there is no per-project scope here. Its sibling page, Editor → Style, holds font, word wrap, and indentation.
- Servers
- Enable language servers: the master switch. Turning it off stops every running server and clears diagnostics from the editor.
- Install servers automatically: whether opening a file installs its server.
- Maximum Server Count: how many may run together before the least recently used one stops. See Why servers stop on their own for when to raise it.
- In the editor
- Show symbol information on hover: whether resting the pointer on a symbol opens the panel. With this off, the panel is still available from the right-click menu; only the automatic appearance stops.
- Suggest completions: whether the server’s completions are offered at all.
- Suggest while typing: whether they appear as you type, rather than only when you ask. With this off, Ctrl+Space still works; only the interruption stops. Unavailable while completions are switched off entirely.
- Show documentation with completions: whether a panel opens beside the list with the highlighted suggestion’s documentation.
- Show parameter hints in calls: whether a call’s signature appears while you fill in its arguments.
- Toolchains detected: whether Node, npm, Go, and the .NET SDK are present, with a Re-check button for after you install one. A toolchain that is there but too old shows the version it found and what is needed (
.NET SDK 9.0.305 · needs 10 or later) rather than reading as absent. - Languages: one row per language, each with a status and its actions.
Each row states machine-wide truth: whether the server is installed at all. Which binary a particular project ended up using is shown in the footer panel instead, because that answer can differ per project.
Reading a language row
The status column says where the row stands:
| Status | Meaning |
|---|---|
| Ready | A server resolves right now, installed by Zide, or already on your machine |
| Installing | Download or toolchain install in progress |
| Failed | The last install attempt failed. The row carries the reason |
| Needs toolchain | Not installed, and the toolchain that installs it is missing |
| Needs toolchain version | The toolchain is installed but too old, for example Needs .NET SDK 10 or later |
| Not installed | Not installed, and Zide can install it for you |
A toolchain row (C#, Go) behaves a little differently, because Zide does not own those installs. It offers Install while the server is missing and Update once it is there, and it offers no Uninstall: the toolchain installed it, and the toolchain removes it (dotnet tool uninstall --global csharp-ls, or deleting the binary from ~/go/bin). Update runs the toolchain’s own update command and fetches a newer server if one exists.
Under the package name, a row says where its server came from, Installed by Zide with its version, or Already on this machine. A row satisfied by a server you already had offers Install Zide copy rather than Install, since nothing is broken; installed rows offer Reinstall and Uninstall.
When an install fails
An install can fail whether you started it or opening a file did. It surfaces in three places at once, and never as a toast:
- The footer indicator turns red, and its panel names the row that failed.
- The console (source Language Servers) carries the failure with the real error text, once per install however it was started.
- The settings row shows that error inline with a Retry button.
The reason is kept for the rest of the session, so a settings page opened after a background install failed still shows what went wrong rather than a bare Failed. Restarting Zide clears it and the row is judged on what is actually installed.
The row shows the actual error and a Retry button. Common causes:
- npm not found: install Node.js, then use Re-check on the toolchains strip.
- No network: retry when you’re back online.
- Permission denied: Zide installs into its own application data directory; this usually means a security tool is holding the files. Retry.
- The SDK is too old: the row names the version found and the version needed, with a download link. Install the newer SDK, press Re-check, then Retry.
An install is only reported as done once every server it is supposed to produce has been verified and Zide can resolve it. The Web row installs three servers, and all three are checked; a row can never say “Installed by Zide” and “Not installed” at the same time.
A failed install is not retried automatically until you click Retry or Install, so a broken connection doesn’t cause repeated downloads.
The footer indicator
The language servers icon in the footer carries the current state:
| Colour | Meaning |
|---|---|
| Plain | Nothing needs you, whether servers are running or not |
| Amber | Installing |
| Red | A server or an install failed |
Colour here means “look at me” and nothing else. Servers running normally is the resting state of a working feature, so it gets no tint, a permanently coloured icon reporting that nothing is wrong is an icon you stop reading. The running count is in the icon’s tooltip.
Click it to open the Running now panel, which lists each running server with:
- the project it is serving, and the language
- the resolved binary: exactly which executable this project is using, and where it came from
- resident memory and uptime
- a Logs button
Logs opens that server’s captured output beneath the row. It stays open until you close it and follows new output as it arrives, holding your scroll position if you have scrolled up to read something. A copy button puts the whole log on the clipboard. This is the place to look when a server is running and yet producing nothing.
Why servers stop on their own
Language servers are expensive. A rust-analyzer working on a large project can hold several gigabytes, and Zide is built for having many projects, often with several worktrees of the same repository open at once.
So Zide manages them:
- A server with no activity for 20 minutes shuts down. Opening a file starts it again.
- At most four servers run at once by default. When a fifth is needed, the least recently used one stops.
- Closing a file tells its server to release that file. Closing a project stops every server for it.
- Quitting Zide stops all of them.
A server disappearing from the Running now panel is therefore expected behaviour rather than a fault. The gear in the panel’s top right opens these settings.
When to raise the limit
A server is started per project and language, not per file, so the size of a project does not affect the count. One enormous repository in one language is one server no matter how many files you open.
Four suits a few worktrees of one repository plus a second project, which is what it was chosen for. Two situations go past it:
- Monorepos. A project boundary is the nearest
package.json,Cargo.toml,go.mod, or solution above the file, so every package is its own project. Five packages of TypeScript is five servers. - Many worktrees. Three worktrees of one repository is three servers before you open anything else.
Past the limit, servers evict each other, and a re-opened file restarts its server from cold and re-indexes. If the Running now panel keeps showing servers you did not expect to have stopped, raise Maximum Server Count.
Raise it with the memory in mind: a language server on a large project can hold several gigabytes, which is the reason there is a limit rather than none. Lowering the number never stops a running server; it takes effect the next time one starts.
Troubleshooting
No diagnostics in a Rust file. rust-analyzer’s real diagnostics come from cargo check, which runs on save. Save the file. While you type, only syntax-level problems appear.
No diagnostics in a TypeScript file. These arrive as you type. If nothing appears at all, check that the row shows Ready in settings and that the file is inside a project with a tsconfig.json or package.json.
“Needs Go” on the Go row. gopls ships with the Go toolchain. Install Go, then press Re-check.
“Needs .NET SDK 10 or later” on the C# row. The SDK is installed, but it is older than the pinned csharp-ls needs. Install .NET 10 or newer, press Re-check, then Install on the row. Without this check the install runs and fails with a message from NuGet about a settings file (DotnetToolSettings.xml), which describes a package problem that does not exist.
“Needs .NET SDK” on the C# row. csharp-ls is a .NET global tool, so the SDK has to be there before Zide can install it. Installing the .NET runtime alone is not enough, the strip reads the SDK version. Install the SDK, then press Re-check, and either press Install on the row or just open a .cs file. You do not need to restart Zide: the SDK installer adds itself to PATH, which Zide only reads at startup, so Zide also looks in the standard install locations directly (C:\Program Files\dotnet, /usr/local/share/dotnet, /usr/share/dotnet, ~/.dotnet).
Zide can’t find a .NET SDK that is definitely installed. If it lives somewhere non-standard, a side-by-side layout, or a container image, set DOTNET_ROOT to that directory and restart Zide. That variable is read at startup, so a restart is needed for this one.
“Tool ‘csharp-ls’ is already installed” when installing C#. The tool is on your machine already, and the row should read Ready rather than offering an install. Zide finds global .NET tools on PATH and in ~/.dotnet/tools; if the row still says otherwise, csharp-ls was installed somewhere else, and putting that directory on PATH and restarting Zide will find it.
No diagnostics in a C# file. csharp-ls loads the solution or project it is given and reports nothing until it has finished, a large solution takes a while on first open. If nothing ever appears, open Logs in the Running now panel: a server that found no solution or project to load says so there. Check that the file really is inside a project referenced by the solution above it.
A server installed under Zide 0.7.0 does nothing. Zide 0.7.0 recorded the wrong thing as the pointer to a completed npm install, so the TypeScript/JavaScript, Python, Web, and Bash servers installed successfully and then could not be found afterwards. Zide repairs those installs by itself on the next run; there is nothing to reinstall and nothing to clean up.
The row says the install worked, but nothing happens in the editor. The install command reported success and Zide still cannot find a server to run. This is most likely on Windows: dotnet tool install --global and go install write to a directory they add to the system PATH, and Zide read PATH when it started. Zide looks in those directories directly, so this should be rare, but if it happens, restarting Zide picks up the new PATH. Zide reports this case as a failed install rather than a successful one, because from where you are sitting it is one.
The C# row says Ready but the Running now panel says nothing is running. csharp-ls loads projects through MSBuild, so it has to be able to find the .NET SDK itself, not just be installed. Zide passes the SDK location to every server it starts, so this should not happen; if it does, press Logs on the row, or start Zide from a terminal where dotnet --version works.
A server keeps failing. Open the Running now panel and press Logs on its row to see what it actually printed. Zide restarts a crashed server a few times before marking it failed; the console (source Language Servers) carries the detail as well.
No symbol panel on hover. Check Show symbol information on hover in Settings → Editor → Language Servers. Whatever that setting says, right-click the symbol and choose Show Symbol Information. If parameter hints are showing, the hover panel deliberately stays down until the call closes.
No completions. Press Ctrl+Space (Cmd+Space on macOS): if suggestions appear, Suggest while typing is off rather than anything being broken. If nothing appears at all, check the status slot in the editor’s status bar, a server that is still starting or indexing has nothing to suggest yet, and check Suggest completions in Settings → Editor → Language Servers. Not every server implements completion; one that doesn’t offers none, and no empty popup appears.
No parameter hints. They appear inside a call, after its opening bracket, and only for servers that implement signature help. Press Ctrl+Shift+Space (Cmd+Shift+Space on macOS) inside a call to ask for them directly.
The status slot says “features unavailable”. That file’s server failed. Click the language servers indicator in the footer, find the row for this project, and press Logs to see what it printed. The Retry and Install actions are there too, the status slot deliberately carries none of its own.
Nothing works after turning something off. Check that Enable language servers is on in Settings → Editor → Language Servers.