Skip to content
Merged
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
2 changes: 1 addition & 1 deletion src/lsp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ impl LanguageServer for ProtoLanguageServer {
};

let content = self.state.get_content(&uri);
let identifier = tree.get_actionable_node_text_at_position(&pos, content.as_bytes());
let identifier = tree.get_hoverable_node_text_at_position(&pos, content.as_bytes());
let current_package_name = tree.get_package_name(content.as_bytes());

let Some(identifier) = identifier else {
Expand Down
10 changes: 10 additions & 0 deletions src/parser/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ impl ParsedTree {
.map(|n| n.utf8_text(content.as_ref()).expect("utf-8 parse error"))
}

pub fn get_hoverable_node_text_at_position<'a>(
&'a self,
pos: &Position,
content: &'a [u8],
) -> Option<&'a str> {
let n = self.get_node_at_position(pos)?;
self.get_actionable_node_text_at_position(pos, content)
.or(Some(n.kind()))
}

pub fn get_ancestor_nodes_at_position<'a>(&'a self, pos: &Position) -> Vec<Node<'a>> {
let Some(mut n) = self.get_actionable_node_at_position(pos) else {
return vec![];
Expand Down
108 changes: 108 additions & 0 deletions src/workspace/hover.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,118 @@
use std::{collections::HashMap, sync::LazyLock};

use async_lsp::lsp_types::MarkedString;

use crate::{
formatter::ProtoFormatter, state::ProtoLanguageState, utils::split_identifier_package,
};


static BUITIN_DOCS: LazyLock<HashMap<&'static str, &'static str>> = LazyLock::new(|| {
HashMap::from([
(
"int32",
r#"A 32-bit integer (varint encoding)

Values of this type range between `-2147483648` and `2147483647`.
Beware that negative values are encoded as five bytes on the wire!"#,
),
(
"int64",
r#"A 64-bit integer (varint encoding)

Values of this type range between `-9223372036854775808` and `9223372036854775807`.
Beware that negative values are encoded as ten bytes on the wire!"#,
),
(
"uint32",
r#"A 32-bit unsigned integer (varint encoding)

Values of this type range between `0` and `4294967295`."#,
),
(
"uint64",
r#"A 64-bit unsigned integer (varint encoding)

Values of this type range between `0` and `18446744073709551615`."#,
),
(
"sint32",
r#"A 32-bit integer (ZigZag encoding)

Values of this type range between `-2147483648` and `2147483647`."#,
),
(
"sint64",
r#"A 64-bit integer (ZigZag encoding)

Values of this type range between `-9223372036854775808` and `9223372036854775807`."#,
),
(
"fixed32",
r#"A 32-bit unsigned integer (4-byte encoding)

Values of this type range between `0` and `4294967295`."#,
),
(
"fixed64",
r#"A 64-bit unsigned integer (8-byte encoding)

Values of this type range between `0` and `18446744073709551615`."#,
),
(
"sfixed32",
r#"A 32-bit integer (4-byte encoding)

Values of this type range between `-2147483648` and `2147483647`."#,
),
(
"sfixed64",
r#"A 64-bit integer (8-byte encoding)

Values of this type range between `-9223372036854775808` and `9223372036854775807`."#,
),
(
"float",
"A single-precision floating point number (IEEE-745.2008 binary32).",
),
(
"double",
"A double-precision floating point number (IEEE-745.2008 binary64).",
),
(
"string",
r#"A string of text.

Stores at most 4GB of text. Intended to be UTF-8 encoded Unicode; use `bytes` if you need other encodings."#,
),
(
"bytes",
r#"A blob of arbitrary bytes.

Stores at most 4GB of binary data. Encoded as base64 in JSON."#,
),
(
"bool",
r#"A Boolean value: `true` or `false`.

Encoded as a single byte: `0x00` or `0xff` (all non-zero bytes decode to `true`)."#,
),
(
"default",
r#"A magic option that specifies the field's default value.

Unlike every other option on a field, this does not have a corresponding field in
`google.protobuf.FieldOptions`; it is implemented by compiler magic."#,
),
])
});

impl<F: ProtoFormatter> ProtoLanguageState<F> {
pub fn hover(&self, curr_package: &str, identifier: &str) -> Vec<MarkedString> {
if let Some(docs) = BUITIN_DOCS.get(identifier) {
return vec![MarkedString::String(docs.to_string())];
}

let (mut package, identifier) = split_identifier_package(identifier);
if package.is_empty() {
package = curr_package;
Expand Down Expand Up @@ -42,6 +149,7 @@ mod test {
state.upsert_file(&c_uri, c.to_owned());

assert_yaml_snapshot!(state.hover("com.workspace", "Author"));
assert_yaml_snapshot!(state.hover("com.workspace", "int64"));
assert_yaml_snapshot!(state.hover("com.workspace", "Author.Address"));
assert_yaml_snapshot!(state.hover("com.workspace", "com.utility.Foobar.Baz"));
assert_yaml_snapshot!(state.hover("com.utility", "Baz"));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
source: src/workspace/hover.rs
expression: "state.hover(\"com.library\", \"Author.Address\")"
expression: "state.hover(\"com.workspace\", \"int64\")"
snapshot_kind: text
---
- Address is a Address
- "A 64-bit integer (varint encoding)\n\nValues of this type range between `-9223372036854775808` and `9223372036854775807`.\nBeware that negative values are encoded as ten bytes on the wire!"
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
source: src/workspace/hover.rs
expression: "state.hover(\"com.library\", \"com.utility.Foobar.Baz\")"
expression: "state.hover(\"com.workspace\", \"Author.Address\")"
snapshot_kind: text
---
- What is baz?
- Address is a Address
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
source: src/workspace/hover.rs
expression: "state.hover(\"com.utility\", \"Baz\")"
snapshot_kind: text
---
- What is baz?
Loading