Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LSP hover empty sometimes after #10122 #12742

Closed
david-crespo opened this issue Jan 31, 2025 · 5 comments
Closed

LSP hover empty sometimes after #10122 #12742

david-crespo opened this issue Jan 31, 2025 · 5 comments
Labels
C-bug Category: This is a bug

Comments

@david-crespo
Copy link
Contributor

Summary

I noticed this on master and was able to narrow it down to #10122. I noticed this with both Rust Analyzer and the Deno and Typescript LSPs.

Bad

Building 9829ac0 from source.

Image

Good

Building 7c907e6 (parent of 9829ac0) from source.

Image

Reproduction Steps

Simply put this in a file with a .ts extension and try to hover on f.

Simple repro file

const f = () => 5

TS language configs

I thought maybe it was caused by having multiple language servers, but it doesn't matter whether I have one or two in there.

[[language]]
name = "typescript"
formatter = { command = "prettierd", args = ["--stdin-filepath", "x.ts"] }
language-servers = [ "typescript-language-server" ]
auto-format = true

I also get it with deno-lsp.

Helix log

This is the log from hx -v. -vv seemed to have a lot of noise that is unlikely to be relevant but I'll be happy to provide it if necessary.

~/.cache/helix/helix.log
2025-01-31T10:19:59.975 helix_lsp::transport [INFO] deno-lsp -> {"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{"general":{"positionEncodings":["utf-8","utf-32","utf-16"]},"textDocument":{"codeAction":{"codeActionLiteralSupport":{"codeActionKind":{"valueSet":["","quickfix","refactor","refactor.extract","refactor.inline","refactor.rewrite","source","source.organizeImports"]}},"dataSupport":true,"disabledSupport":true,"isPreferredSupport":true,"resolveSupport":{"properties":["edit","command"]}},"completion":{"completionItem":{"deprecatedSupport":true,"insertReplaceSupport":true,"resolveSupport":{"properties":["documentation","detail","additionalTextEdits"]},"snippetSupport":true,"tagSupport":{"valueSet":[1]}},"completionItemKind":{}},"formatting":{"dynamicRegistration":false},"hover":{"contentFormat":["markdown"]},"inlayHint":{"dynamicRegistration":false},"publishDiagnostics":{"tagSupport":{"valueSet":[1,2]},"versionSupport":true},"rename":{"dynamicRegistration":false,"honorsChangeAnnotations":false,"prepareSupport":true},"signatureHelp":{"signatureInformation":{"activeParameterSupport":true,"documentationFormat":["markdown"],"parameterInformation":{"labelOffsetSupport":true}}}},"window":{"workDoneProgress":true},"workspace":{"applyEdit":true,"configuration":true,"didChangeConfiguration":{"dynamicRegistration":false},"didChangeWatchedFiles":{"dynamicRegistration":true,"relativePatternSupport":false},"executeCommand":{"dynamicRegistration":false},"fileOperations":{"didRename":true,"willRename":true},"inlayHint":{"refreshSupport":false},"symbol":{"dynamicRegistration":false},"workspaceEdit":{"documentChanges":true,"failureHandling":"abort","normalizesLineEndings":false,"resourceOperations":["create","rename","delete"]},"workspaceFolders":true}},"clientInfo":{"name":"helix","version":"25.01.1 (9829ac0c)"},"processId":30553,"rootPath":"/Users/david/repos/llm-cli","rootUri":"file:///Users/david/repos/llm-cli","workspaceFolders":[{"name":"llm-cli","uri":"file:///Users/david/repos/llm-cli"}]},"id":0}
2025-01-31T10:19:59.989 helix_lsp::transport [ERROR] deno-lsp err <- "Starting Deno language server...\n"
2025-01-31T10:19:59.989 helix_lsp::transport [ERROR] deno-lsp err <- "  version: 2.1.9 (release, aarch64-apple-darwin)\n"
2025-01-31T10:19:59.989 helix_lsp::transport [ERROR] deno-lsp err <- "  executable: /Users/david/.deno/bin/deno\n"
2025-01-31T10:19:59.989 helix_lsp::transport [ERROR] deno-lsp err <- "Connected to \"helix\" 25.01.1 (9829ac0c)\n"
2025-01-31T10:20:00.035 helix_lsp::transport [INFO] deno-lsp <- {"jsonrpc":"2.0","result":{"capabilities":{"textDocumentSync":{"openClose":true,"change":2,"save":{}},"selectionRangeProvider":true,"hoverProvider":true,"completionProvider":{"resolveProvider":true,"triggerCharacters":[".","\"","'","`","/","@","<","#"],"allCommitCharacters":[".",";","("]},"signatureHelpProvider":{"triggerCharacters":[",","(","<"],"retriggerCharacters":[")"]},"definitionProvider":true,"typeDefinitionProvider":true,"implementationProvider":true,"referencesProvider":true,"documentHighlightProvider":true,"documentSymbolProvider":{"label":"Deno"},"workspaceSymbolProvider":true,"codeActionProvider":{"codeActionKinds":["quickfix","refactor","refactor.extract.function","refactor.extract.constant","refactor.extract.type","refactor.extract.interface","refactor.move.newFile","refactor.rewrite.import","refactor.rewrite.export","refactor.rewrite.arrow.braces","refactor.rewrite.parameters.toDestructured","refactor.rewrite.property.generateAccessors"],"resolveProvider":true},"codeLensProvider":{"resolveProvider":true},"documentFormattingProvider":true,"renameProvider":true,"foldingRangeProvider":true,"executeCommandProvider":{"commands":["deno.cache","deno.reloadImportRegistries"]},"workspace":{"workspaceFolders":{"supported":true,"changeNotifications":true}},"callHierarchyProvider":true,"semanticTokensProvider":{"legend":{"tokenTypes":["class","enum","interface","namespace","typeParameter","type","parameter","variable","enumMember","property","function","method"],"tokenModifiers":["declaration","static","async","readonly","defaultLibrary","local"]},"range":true,"full":true},"inlayHintProvider":true,"experimental":{"denoConfigTasks":true,"testingApi":true,"didRefreshDenoConfigurationTreeNotifications":true}},"serverInfo":{"name":"deno-language-server","version":"2.1.9 (release, aarch64-apple-darwin)"}},"id":0}
2025-01-31T10:20:00.035 helix_lsp::transport [INFO] deno-lsp <- {"capabilities":{"callHierarchyProvider":true,"codeActionProvider":{"codeActionKinds":["quickfix","refactor","refactor.extract.function","refactor.extract.constant","refactor.extract.type","refactor.extract.interface","refactor.move.newFile","refactor.rewrite.import","refactor.rewrite.export","refactor.rewrite.arrow.braces","refactor.rewrite.parameters.toDestructured","refactor.rewrite.property.generateAccessors"],"resolveProvider":true},"codeLensProvider":{"resolveProvider":true},"completionProvider":{"allCommitCharacters":[".",";","("],"resolveProvider":true,"triggerCharacters":[".","\"","'","`","/","@","<","#"]},"definitionProvider":true,"documentFormattingProvider":true,"documentHighlightProvider":true,"documentSymbolProvider":{"label":"Deno"},"executeCommandProvider":{"commands":["deno.cache","deno.reloadImportRegistries"]},"experimental":{"denoConfigTasks":true,"didRefreshDenoConfigurationTreeNotifications":true,"testingApi":true},"foldingRangeProvider":true,"hoverProvider":true,"implementationProvider":true,"inlayHintProvider":true,"referencesProvider":true,"renameProvider":true,"selectionRangeProvider":true,"semanticTokensProvider":{"full":true,"legend":{"tokenModifiers":["declaration","static","async","readonly","defaultLibrary","local"],"tokenTypes":["class","enum","interface","namespace","typeParameter","type","parameter","variable","enumMember","property","function","method"]},"range":true},"signatureHelpProvider":{"retriggerCharacters":[")"],"triggerCharacters":[",","(","<"]},"textDocumentSync":{"change":2,"openClose":true,"save":{}},"typeDefinitionProvider":true,"workspace":{"workspaceFolders":{"changeNotifications":true,"supported":true}},"workspaceSymbolProvider":true},"serverInfo":{"name":"deno-language-server","version":"2.1.9 (release, aarch64-apple-darwin)"}}
2025-01-31T10:20:00.035 helix_lsp::transport [INFO] deno-lsp -> {"jsonrpc":"2.0","method":"initialized","params":{}}
2025-01-31T10:20:00.035 helix_lsp::transport [INFO] deno-lsp -> {"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"languageId":"typescript","text":"const f = () => 5\n","uri":"file:///Users/david/repos/llm-cli/test.ts","version":0}}}
2025-01-31T10:20:00.035 helix_lsp::transport [INFO] deno-lsp <- {"jsonrpc":"2.0","method":"workspace/configuration","params":{"items":[{"section":"deno"},{"section":"javascript"},{"section":"typescript"},{"scopeUri":"file:///Users/david/repos/llm-cli","section":"deno"},{"scopeUri":"file:///Users/david/repos/llm-cli","section":"javascript"},{"scopeUri":"file:///Users/david/repos/llm-cli","section":"typescript"}]},"id":0}
2025-01-31T10:20:00.035 helix_lsp::transport [INFO] deno-lsp -> {"jsonrpc":"2.0","result":[null,null,null,null,null,null],"id":0}
2025-01-31T10:20:00.039 helix_lsp::transport [ERROR] deno-lsp err <- "Hit the language server document preload limit of 1000 file system entries. You may want to use the \"deno.enablePaths\" configuration setting to only have Deno partially enable a workspace or increase the limit via \"deno.documentPreloadLimit\". In cases where Deno ends up using too much memory, you may want to lower the limit.\n"
2025-01-31T10:20:00.039 helix_lsp::transport [ERROR] deno-lsp err <- "Refreshing configuration tree...\n"
2025-01-31T10:20:00.039 helix_lsp::transport [ERROR] deno-lsp err <- "  Resolved Deno configuration file: \"file:///Users/david/repos/llm-cli/deno.jsonc\"\n"
2025-01-31T10:20:00.040 helix_lsp::transport [ERROR] deno-lsp err <- "  Resolved .npmrc: \"/Users/david/.npmrc\"\n"
2025-01-31T10:20:00.040 helix_lsp::transport [ERROR] deno-lsp err <- "  Resolved lockfile: \"file:///Users/david/repos/llm-cli/deno.lock\"\n"
2025-01-31T10:20:00.056 helix_lsp::transport [INFO] deno-lsp <- {"jsonrpc":"2.0","method":"deno/didRefreshDenoConfigurationTree","params":{"data":[{"scopeUri":"file:///Users/david/repos/llm-cli/","workspaceRootScopeUri":null,"denoJson":{"uri":"file:///Users/david/repos/llm-cli/deno.jsonc"},"packageJson":null}]}}
2025-01-31T10:20:00.056 helix_term::application [INFO] Ignoring Unhandled notification from Language Server
2025-01-31T10:20:00.058 helix_lsp::transport [INFO] deno-lsp <- {"jsonrpc":"2.0","method":"client/registerCapability","params":{"registrations":[{"id":"workspace/didChangeWatchedFiles","method":"workspace/didChangeWatchedFiles","registerOptions":{"watchers":[{"globPattern":"**/*.{json,jsonc,lock}"}]}}]},"id":1}
2025-01-31T10:20:00.058 helix_lsp::transport [INFO] deno-lsp <- {"jsonrpc":"2.0","method":"deno/didChangeDenoConfiguration","params":{"changes":[{"scopeUri":"file:///Users/david/repos/llm-cli/","fileUri":"file:///Users/david/repos/llm-cli/deno.jsonc","type":"added","configurationType":"denoJson"}]}}
2025-01-31T10:20:00.058 helix_lsp::transport [INFO] deno-lsp -> {"jsonrpc":"2.0","result":null,"id":1}
2025-01-31T10:20:00.059 helix_term::application [INFO] Ignoring Unhandled notification from Language Server
2025-01-31T10:20:00.059 helix_lsp::transport [ERROR] deno-lsp err <- "Server ready.\n"
2025-01-31T10:20:00.059 helix_lsp::transport [INFO] deno-lsp <- {"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"uri":"file:///Users/david/repos/llm-cli/test.ts","diagnostics":[],"version":0}}
2025-01-31T10:20:00.059 helix_lsp::transport [INFO] deno-lsp <- {"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"uri":"file:///Users/david/repos/llm-cli/test.ts","diagnostics":[{"range":{"start":{"line":0,"character":6},"end":{"line":0,"character":7}},"severity":2,"code":"no-unused-vars","source":"deno-lint","message":"`f` is never used\nIf this is intentional, prefix it with an underscore like `_f`"}],"version":0}}
2025-01-31T10:20:00.228 helix_lsp::transport [INFO] deno-lsp <- {"jsonrpc":"2.0","method":"deno/didUpgradeCheck","params":{"upgradeAvailable":null}}
2025-01-31T10:20:00.228 helix_term::application [INFO] Ignoring Unhandled notification from Language Server
2025-01-31T10:20:01.059 helix_lsp::transport [INFO] deno-lsp <- {"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"uri":"file:///Users/david/repos/llm-cli/test.ts","diagnostics":[{"range":{"start":{"line":0,"character":6},"end":{"line":0,"character":7}},"severity":2,"code":"no-unused-vars","source":"deno-lint","message":"`f` is never used\nIf this is intentional, prefix it with an underscore like `_f`"}],"version":0}}
2025-01-31T10:20:01.059 helix_lsp::transport [INFO] deno-lsp <- {"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"uri":"file:///Users/david/repos/llm-cli/test.ts","diagnostics":[{"range":{"start":{"line":0,"character":6},"end":{"line":0,"character":7}},"severity":4,"code":6133,"source":"deno-ts","message":"'f' is declared but its value is never read.","tags":[1]},{"range":{"start":{"line":0,"character":6},"end":{"line":0,"character":7}},"severity":2,"code":"no-unused-vars","source":"deno-lint","message":"`f` is never used\nIf this is intentional, prefix it with an underscore like `_f`"}],"version":0}}
2025-01-31T10:20:01.753 helix_lsp::transport [INFO] deno-lsp -> {"jsonrpc":"2.0","method":"textDocument/hover","params":{"position":{"character":6,"line":0},"textDocument":{"uri":"file:///Users/david/repos/llm-cli/test.ts"}},"id":1}
2025-01-31T10:20:01.801 helix_lsp::transport [INFO] deno-lsp <- {"jsonrpc":"2.0","result":{"contents":[{"language":"typescript","value":"const f: () => number"},""],"range":{"start":{"line":0,"character":6},"end":{"line":0,"character":7}}},"id":1}
2025-01-31T10:20:01.802 helix_lsp::transport [INFO] deno-lsp <- {"contents":[{"language":"typescript","value":"const f: () => number"},""],"range":{"end":{"character":7,"line":0},"start":{"character":6,"line":0}}}
2025-01-31T10:20:03.252 helix_lsp::transport [INFO] deno-lsp -> {"jsonrpc":"2.0","method":"shutdown","id":2}
2025-01-31T10:20:03.253 helix_lsp::transport [ERROR] deno-lsp err <- "shutdown request received, shutting down\n"
2025-01-31T10:20:03.253 helix_lsp::transport [INFO] deno-lsp <- {"jsonrpc":"2.0","result":null,"id":2}
2025-01-31T10:20:03.253 helix_lsp::transport [INFO] deno-lsp <- null
2025-01-31T10:20:03.253 helix_lsp::transport [INFO] deno-lsp -> {"jsonrpc":"2.0","method":"exit"}
2025-01-31T10:20:03.254 helix_lsp::transport [ERROR] deno-lsp err <- "exit notification received, stopping\n"

Platform

macOS

Terminal Emulator

ghostty adf4066b

Installation Method

source

Helix Version

helix 25.01.1 (9829ac0)

@david-crespo david-crespo added the C-bug Category: This is a bug label Jan 31, 2025
@david-crespo
Copy link
Contributor Author

david-crespo commented Jan 31, 2025

I logged contents here:

fn hover_contents_to_string(contents: &lsp::HoverContents) -> String {
fn marked_string_to_markdown(contents: &lsp::MarkedString) -> String {
match contents {
lsp::MarkedString::String(contents) => contents.clone(),
lsp::MarkedString::LanguageString(string) => {
if string.language == "markdown" {
string.value.clone()
} else {
format!("```{}\n{}\n```", string.language, string.value)
}
}
}
}
match contents {
lsp::HoverContents::Scalar(contents) => marked_string_to_markdown(contents),
lsp::HoverContents::Array(contents) => contents
.iter()
.map(marked_string_to_markdown)
.collect::<Vec<_>>()
.join("\n\n"),
lsp::HoverContents::Markup(contents) => contents.value.clone(),
}
}

and got

2025-01-31T10:30:14.451 helix_term::ui::lsp::hover [DEBUG] Array([LanguageString(LanguageString { language: "typescript", value: "const f: () => number" }), String("")])

const f: () => number is in there, so it looks like we're dropping it.

@david-crespo
Copy link
Contributor Author

david-crespo commented Jan 31, 2025

I am seeing the markdown when I log here,

let body = Markdown::new(
hover_contents_to_string(&hover.contents),
self.config_loader.clone(),
);

2025-01-31T10:52:26.543 helix_term::ui::lsp::hover [DEBUG] ```typescript
const f: () => number
```

it's just not rendering properly.

@the-mikedavis
Copy link
Member

Seems to be an issue only when popup-border is set

@david-crespo
Copy link
Contributor Author

I think it's clipping one line too many.

let contents_area = area
.clip_top(if self.hovers.len() > 1 {
HEADER_HEIGHT + SEPARATOR_HEIGHT
} else {
0
})
.clip_bottom(u16::from(cx.editor.popup_border()));
let contents_para = Paragraph::new(&contents)
.wrap(Wrap { trim: false })
.scroll((cx.scroll.unwrap_or_default() as u16, 0));

@david-crespo
Copy link
Contributor Author

Thanks for the quick fix! Not a bad analysis from Mr. Claude:

Image

nikola2501 pushed a commit to nikola2501/helix that referenced this issue Jan 31, 2025
The Hover component is used as the inner contents of a Popup. The Popup
should be doing calculations based on whether popup_borders is
configured and not Hover. This fixes an issue with hover rendering when
the popup border option is enabled for popups.

Fixes helix-editor#12742
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug
Projects
None yet
Development

No branches or pull requests

2 participants