Skip to content

Commit 794c22d

Browse files
committed
Add PositionEncodingKind and friends from 3.17
3.17 introduces `PositionEncodingKind` to indicate how positions are encoded (utf-8, utf-16, or utf-32). There are also corresponding fields in the client (`positionEncodings`) and server (`positionEncoding`) capabilities to negotiate which to use.
1 parent e3afaf2 commit 794c22d

File tree

1 file changed

+86
-3
lines changed

1 file changed

+86
-3
lines changed

src/lib.rs

Lines changed: 86 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,9 +230,8 @@ pub type LSPArray = Vec<serde_json::Value>;
230230
pub struct Position {
231231
/// Line position in a document (zero-based).
232232
pub line: u32,
233-
/// Character offset on a line in a document (zero-based). Assuming that
234-
/// the line is represented as a string, the `character` value represents
235-
/// the gap between the `character` and `character + 1`.
233+
/// Character offset on a line in a document (zero-based). The meaning of this
234+
/// offset is determined by the negotiated `PositionEncodingKind`.
236235
///
237236
/// If the character value is greater than the line length it defaults back
238237
/// to the line length.
@@ -295,6 +294,55 @@ pub struct LocationLink {
295294
pub target_selection_range: Range,
296295
}
297296

297+
/// A type indicating how positions are encoded,
298+
/// specifically what column offsets mean.
299+
///
300+
/// @since 3.17.0
301+
#[derive(Debug, Eq, PartialEq, Hash, PartialOrd, Clone, Deserialize, Serialize)]
302+
#[cfg(feature = "proposed")]
303+
pub struct PositionEncodingKind(std::borrow::Cow<'static, str>);
304+
305+
#[cfg(feature = "proposed")]
306+
impl PositionEncodingKind {
307+
/// Character offsets count UTF-8 code units.
308+
pub const UTF8: PositionEncodingKind = PositionEncodingKind::new("utf-8");
309+
310+
/// Character offsets count UTF-16 code units.
311+
///
312+
/// This is the default and must always be supported
313+
/// by servers
314+
pub const UTF16: PositionEncodingKind = PositionEncodingKind::new("utf-16");
315+
316+
/// Character offsets count UTF-32 code units.
317+
///
318+
/// Implementation note: these are the same as Unicode code points,
319+
/// so this `PositionEncodingKind` may also be used for an
320+
/// encoding-agnostic representation of character offsets.
321+
pub const UTF32: PositionEncodingKind = PositionEncodingKind::new("utf-32");
322+
323+
pub const fn new(tag: &'static str) -> Self {
324+
PositionEncodingKind(std::borrow::Cow::Borrowed(tag))
325+
}
326+
327+
pub fn as_str(&self) -> &str {
328+
&self.0
329+
}
330+
}
331+
332+
#[cfg(feature = "proposed")]
333+
impl From<String> for PositionEncodingKind {
334+
fn from(from: String) -> Self {
335+
PositionEncodingKind(std::borrow::Cow::from(from))
336+
}
337+
}
338+
339+
#[cfg(feature = "proposed")]
340+
impl From<&'static str> for PositionEncodingKind {
341+
fn from(from: &'static str) -> Self {
342+
PositionEncodingKind::new(from)
343+
}
344+
}
345+
298346
/// Represents a diagnostic, such as a compiler error or warning.
299347
/// Diagnostic objects are only valid in the scope of a resource.
300348
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
@@ -1524,6 +1572,28 @@ pub struct GeneralClientCapabilities {
15241572
#[cfg(feature = "proposed")]
15251573
#[serde(skip_serializing_if = "Option::is_none")]
15261574
pub stale_request_support: Option<StaleRequestSupportClientCapabilities>,
1575+
1576+
/// The position encodings supported by the client. Client and server
1577+
/// have to agree on the same position encoding to ensure that offsets
1578+
/// (e.g. character position in a line) are interpreted the same on both
1579+
/// side.
1580+
///
1581+
/// To keep the protocol backwards compatible the following applies: if
1582+
/// the value 'utf-16' is missing from the array of position encodings
1583+
/// servers can assume that the client supports UTF-16. UTF-16 is
1584+
/// therefore a mandatory encoding.
1585+
///
1586+
/// If omitted it defaults to ['utf-16'].
1587+
///
1588+
/// Implementation considerations: since the conversion from one encoding
1589+
/// into another requires the content of the file / line the conversion
1590+
/// is best done where the file is read which is usually on the server
1591+
/// side.
1592+
///
1593+
/// @since 3.17.0
1594+
#[cfg(feature = "proposed")]
1595+
#[serde(skip_serializing_if = "Option::is_none")]
1596+
pub position_encodings: Option<Vec<PositionEncodingKind>>,
15271597
}
15281598

15291599
/// Client capability that signals how the client
@@ -1754,6 +1824,19 @@ impl From<bool> for TypeDefinitionProviderCapability {
17541824
#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
17551825
#[serde(rename_all = "camelCase")]
17561826
pub struct ServerCapabilities {
1827+
/// The position encoding the server picked from the encodings offered
1828+
/// by the client via the client capability `general.positionEncodings`.
1829+
///
1830+
/// If the client didn't provide any position encodings the only valid
1831+
/// value that a server can return is 'utf-16'.
1832+
///
1833+
/// If omitted it defaults to 'utf-16'.
1834+
///
1835+
/// @since 3.17.0
1836+
#[serde(skip_serializing_if = "Option::is_none")]
1837+
#[cfg(feature = "proposed")]
1838+
pub position_encoding: Option<PositionEncodingKind>,
1839+
17571840
/// Defines how text documents are synced.
17581841
#[serde(skip_serializing_if = "Option::is_none")]
17591842
pub text_document_sync: Option<TextDocumentSyncCapability>,

0 commit comments

Comments
 (0)