-
Notifications
You must be signed in to change notification settings - Fork 15
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
Custom statement_range()
LSP message
#85
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
// | ||
// statement_range.rs | ||
// | ||
// Copyright (C) 2023 Posit Software, PBC. All rights reserved. | ||
// | ||
// | ||
|
||
use serde::Deserialize; | ||
use serde::Serialize; | ||
use stdext::unwrap; | ||
use tower_lsp::jsonrpc::Result; | ||
use tower_lsp::lsp_types::Position; | ||
use tower_lsp::lsp_types::Range; | ||
use tower_lsp::lsp_types::VersionedTextDocumentIdentifier; | ||
|
||
use crate::backend_trace; | ||
use crate::lsp::backend::Backend; | ||
use crate::lsp::traits::cursor::TreeCursorExt; | ||
use crate::lsp::traits::point::PointExt; | ||
use crate::lsp::traits::position::PositionExt; | ||
|
||
pub static POSITRON_STATEMENT_RANGE_REQUEST: &'static str = "positron/textDocument/statementRange"; | ||
|
||
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct StatementRangeParams { | ||
/// The document to provide a statement range for. | ||
pub text_document: VersionedTextDocumentIdentifier, | ||
/// The location of the cursor. | ||
pub position: Position, | ||
} | ||
|
||
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct StatementRangeResponse { | ||
/// The document range the statement covers. | ||
pub range: Range, | ||
} | ||
|
||
impl Backend { | ||
pub async fn statement_range( | ||
&self, | ||
params: StatementRangeParams, | ||
) -> Result<Option<StatementRangeResponse>> { | ||
backend_trace!(self, "statement_range({:?})", params); | ||
|
||
let uri = ¶ms.text_document.uri; | ||
let document = unwrap!(self.documents.get_mut(uri), None => { | ||
backend_trace!(self, "statement_range(): No document associated with URI {uri}"); | ||
return Ok(None); | ||
}); | ||
|
||
let position = params.position; | ||
let point = position.as_point(); | ||
|
||
let root = document.ast.root_node(); | ||
let mut cursor = root.walk(); | ||
|
||
if !cursor.goto_first_child_for_point_patched(point) { | ||
// TODO: Uncommenting this causes a compile error??? | ||
// backend_trace!(self, "statement_range(): No child associated with point."); | ||
Comment on lines
+60
to
+61
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kevinushey I think we should talk about this and see if the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems to work above; maybe the macro doesn't handle invocations lacking any arguments? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or perhaps it's because logging here requires a call to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It has something to do with the latter. If i put the message before the creation of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That thing gives C++ template compilation errors a run for its money 💀 We could probably adjust the macro to either avoid the await, or spawn a separate execution context wherein it could be awaited safely and independently from the current call... not sure if you have any strong feelings. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Definitely no strong feelings |
||
return Ok(None); | ||
} | ||
|
||
let node = cursor.node(); | ||
|
||
// Tree-sitter `Point`s | ||
let start_point = node.start_position(); | ||
let end_point = node.end_position(); | ||
|
||
// To LSP `Position`s | ||
let start_position = start_point.as_position(); | ||
let end_position = end_point.as_position(); | ||
|
||
let range = Range { | ||
start: start_position, | ||
end: end_position, | ||
}; | ||
|
||
let response = StatementRangeResponse { range }; | ||
|
||
Ok(Some(response)) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it seem reasonable to do this? Is there anything else I need to do besides this tag?