diff --git a/crates/tinymist-query/src/fixtures/on_enter/enum_let.typ b/crates/tinymist-query/src/fixtures/on_enter/enum_let.typ new file mode 100644 index 00000000..0427573f --- /dev/null +++ b/crates/tinymist-query/src/fixtures/on_enter/enum_let.typ @@ -0,0 +1,2 @@ +/* range after 2..10 */ ++ #let f = 1; diff --git a/crates/tinymist-query/src/fixtures/on_enter/enum_let2.typ b/crates/tinymist-query/src/fixtures/on_enter/enum_let2.typ new file mode 100644 index 00000000..2f222bfe --- /dev/null +++ b/crates/tinymist-query/src/fixtures/on_enter/enum_let2.typ @@ -0,0 +1,2 @@ +/* range after 2..10 */ ++ #let f() = 1; diff --git a/crates/tinymist-query/src/fixtures/on_enter/enum_plain.typ b/crates/tinymist-query/src/fixtures/on_enter/enum_plain.typ new file mode 100644 index 00000000..cf75f9f8 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/on_enter/enum_plain.typ @@ -0,0 +1,2 @@ +/* range after 2..7 */ ++ test diff --git a/crates/tinymist-query/src/fixtures/on_enter/enum_plain2.typ b/crates/tinymist-query/src/fixtures/on_enter/enum_plain2.typ new file mode 100644 index 00000000..6eefabd5 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/on_enter/enum_plain2.typ @@ -0,0 +1,2 @@ +/* range after 4..7 */ ++ test diff --git a/crates/tinymist-query/src/fixtures/on_enter/enum_plain3.typ b/crates/tinymist-query/src/fixtures/on_enter/enum_plain3.typ new file mode 100644 index 00000000..c30f75cb --- /dev/null +++ b/crates/tinymist-query/src/fixtures/on_enter/enum_plain3.typ @@ -0,0 +1,2 @@ +/* range after 4..4 */ ++ test diff --git a/crates/tinymist-query/src/fixtures/on_enter/enum_var.typ b/crates/tinymist-query/src/fixtures/on_enter/enum_var.typ new file mode 100644 index 00000000..f37ea228 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/on_enter/enum_var.typ @@ -0,0 +1,3 @@ +#let a = 1; +/* range after 2..10 */ ++ #a test diff --git a/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@enum2.typ.snap b/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@enum2.typ.snap index 7b2022c3..57e0cf5c 100644 --- a/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@enum2.typ.snap +++ b/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@enum2.typ.snap @@ -4,4 +4,9 @@ description: "On Enter on 3..3 */\n+ ||\n)" expression: "JsonRepr::new_redacted(result, &REDACT_LOC)" input_file: crates/tinymist-query/src/fixtures/on_enter/enum2.typ --- -null +[ + { + "newText": "\n+ $0", + "range": "1:2:1:2" + } +] diff --git a/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@enum_let.typ.snap b/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@enum_let.typ.snap new file mode 100644 index 00000000..ac9359c0 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@enum_let.typ.snap @@ -0,0 +1,7 @@ +--- +source: crates/tinymist-query/src/on_enter.rs +description: "On Enter on 2..10 */\n+| #let f |= 1;\n)" +expression: "JsonRepr::new_redacted(result, &REDACT_LOC)" +input_file: crates/tinymist-query/src/fixtures/on_enter/enum_let.typ +--- +null diff --git a/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@enum_let2.typ.snap b/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@enum_let2.typ.snap new file mode 100644 index 00000000..67958907 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@enum_let2.typ.snap @@ -0,0 +1,7 @@ +--- +source: crates/tinymist-query/src/on_enter.rs +description: "On Enter on 2..10 */\n+| #let f(|) = 1;\n)" +expression: "JsonRepr::new_redacted(result, &REDACT_LOC)" +input_file: crates/tinymist-query/src/fixtures/on_enter/enum_let2.typ +--- +null diff --git a/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@enum_plain.typ.snap b/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@enum_plain.typ.snap new file mode 100644 index 00000000..f35bdc17 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@enum_plain.typ.snap @@ -0,0 +1,12 @@ +--- +source: crates/tinymist-query/src/on_enter.rs +description: "On Enter on 2..7 */\n+| test|\n)" +expression: "JsonRepr::new_redacted(result, &REDACT_LOC)" +input_file: crates/tinymist-query/src/fixtures/on_enter/enum_plain.typ +--- +[ + { + "newText": "\n+ $0", + "range": "1:1:1:6" + } +] diff --git a/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@enum_plain2.typ.snap b/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@enum_plain2.typ.snap new file mode 100644 index 00000000..b9428c2f --- /dev/null +++ b/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@enum_plain2.typ.snap @@ -0,0 +1,12 @@ +--- +source: crates/tinymist-query/src/on_enter.rs +description: "On Enter on ..7 */\n+ t|est|\n)" +expression: "JsonRepr::new_redacted(result, &REDACT_LOC)" +input_file: crates/tinymist-query/src/fixtures/on_enter/enum_plain2.typ +--- +[ + { + "newText": "\n+ $0", + "range": "1:3:1:6" + } +] diff --git a/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@enum_plain3.typ.snap b/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@enum_plain3.typ.snap new file mode 100644 index 00000000..491db217 --- /dev/null +++ b/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@enum_plain3.typ.snap @@ -0,0 +1,7 @@ +--- +source: crates/tinymist-query/src/on_enter.rs +description: "On Enter on ..4 */\n+ t||est\n)" +expression: "JsonRepr::new_redacted(result, &REDACT_LOC)" +input_file: crates/tinymist-query/src/fixtures/on_enter/enum_plain3.typ +--- +null diff --git a/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@enum_var.typ.snap b/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@enum_var.typ.snap new file mode 100644 index 00000000..576b14ee --- /dev/null +++ b/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@enum_var.typ.snap @@ -0,0 +1,12 @@ +--- +source: crates/tinymist-query/src/on_enter.rs +description: "On Enter on 2..10 */\n+| #a test|\n)" +expression: "JsonRepr::new_redacted(result, &REDACT_LOC)" +input_file: crates/tinymist-query/src/fixtures/on_enter/enum_var.typ +--- +[ + { + "newText": "\n+ $0", + "range": "2:1:2:9" + } +] diff --git a/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@list2.typ.snap b/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@list2.typ.snap index a8d8c0ec..1e182b07 100644 --- a/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@list2.typ.snap +++ b/crates/tinymist-query/src/fixtures/on_enter/snaps/prepare@list2.typ.snap @@ -4,4 +4,9 @@ description: "On Enter on 3..3 */\n- ||\n)" expression: "JsonRepr::new_redacted(result, &REDACT_LOC)" input_file: crates/tinymist-query/src/fixtures/on_enter/list2.typ --- -null +[ + { + "newText": "\n- $0", + "range": "1:2:1:2" + } +] diff --git a/crates/tinymist-query/src/on_enter.rs b/crates/tinymist-query/src/on_enter.rs index d52a7379..f512876e 100644 --- a/crates/tinymist-query/src/on_enter.rs +++ b/crates/tinymist-query/src/on_enter.rs @@ -25,6 +25,8 @@ pub struct OnEnterRequest { pub path: PathBuf, /// The source code range to request for. pub range: LspRange, + /// Whether to handle list and enum items. + pub handle_list: bool, } impl SyntaxRequest for OnEnterRequest { @@ -54,8 +56,10 @@ impl SyntaxRequest for OnEnterRequest { let case = node_ancestors(&leaf).find_map(|node| match node.kind() { SyntaxKind::LineComment => Some(Cases::LineComment(node.clone())), SyntaxKind::Equation => Some(Cases::Equation(node.clone())), - SyntaxKind::ListItem | SyntaxKind::EnumItem => Some(Cases::ListOrEnum(node.clone())), - SyntaxKind::Space | SyntaxKind::Parbreak => { + SyntaxKind::ListItem | SyntaxKind::EnumItem if self.handle_list => { + Some(Cases::ListOrEnum(node.clone())) + } + SyntaxKind::Space | SyntaxKind::Parbreak if self.handle_list => { let prev_leaf = node.prev_sibling()?; let inter_space = node.offset()..rng.start; @@ -78,13 +82,7 @@ impl SyntaxRequest for OnEnterRequest { match case { Some(Cases::LineComment(node)) => worker.enter_line_doc_comment(node, rng), Some(Cases::Equation(node)) => worker.enter_block_math(node, rng), - Some(Cases::ListOrEnum(node)) => { - let _ = node; - let _ = OnEnterWorker::enter_list_or_enum; - - // worker.enter_list_or_enum(node, rng) - None - } + Some(Cases::ListOrEnum(node)) => worker.enter_list_or_enum(node, rng), _ => None, } } @@ -175,6 +173,15 @@ impl OnEnterWorker<'_> { } fn enter_list_or_enum(&self, node: LinkedNode<'_>, rng: Range) -> Option> { + let rng_end = rng.end; + let node_end = node.range().end; + let in_middle_of_node = rng_end < node_end + && self.source.text()[rng_end..node_end].contains(|c: char| !c.is_whitespace()); + + if in_middle_of_node { + return None; + } + let indent = self.indent_of(node.range().start); let is_list = matches!(node.kind(), SyntaxKind::ListItem); @@ -202,6 +209,7 @@ mod tests { let request = OnEnterRequest { path: path.clone(), range: find_test_range(&source), + handle_list: true, }; let result = request.request(&source, PositionEncoding::Utf16); diff --git a/crates/tinymist/src/config.rs b/crates/tinymist/src/config.rs index f52fa2dc..b1a3f335 100644 --- a/crates/tinymist/src/config.rs +++ b/crates/tinymist/src/config.rs @@ -53,6 +53,7 @@ const CONFIG_ITEMS: &[&str] = &[ "formatterIndentSize", "formatterProseWrap", "hoverPeriscope", + "onEnter", "outputPath", "preview", "projectResolution", @@ -108,8 +109,10 @@ pub struct Config { pub completion: CompletionFeat, /// Tinymist's preview features. pub preview: PreviewFeat, - /// When to trigger the lint checks. + /// Tinymist's lint features. pub lint: LintFeat, + /// Tinymist's on-enter features. + pub on_enter: OnEnterFeat, /// Specifies the cli font options pub font_opts: CompileFontArgs, @@ -329,6 +332,7 @@ impl Config { assign_config!(color_theme := "colorTheme"?: Option); assign_config!(lint := "lint"?: LintFeat); assign_config!(completion := "completion"?: CompletionFeat); + assign_config!(on_enter := "onEnter"?: OnEnterFeat); assign_config!(completion.trigger_suggest := "triggerSuggest"?: bool); assign_config!(completion.trigger_parameter_hints := "triggerParameterHints"?: bool); assign_config!(completion.trigger_suggest_and_parameter_hints := "triggerSuggestAndParameterHints"?: bool); @@ -906,6 +910,13 @@ impl LintFeat { self.when.as_ref().unwrap_or(&TaskWhen::OnSave) } } +/// The lint features. +#[derive(Debug, Default, Clone, Deserialize)] +pub struct OnEnterFeat { + /// Whether to handle list. + #[serde(default, deserialize_with = "deserialize_null_default")] + pub handle_list: bool, +} /// Options for browsing preview. #[derive(Debug, Default, Clone, Deserialize)] diff --git a/crates/tinymist/src/lsp/query.rs b/crates/tinymist/src/lsp/query.rs index 1428d5ab..01a8b88b 100644 --- a/crates/tinymist/src/lsp/query.rs +++ b/crates/tinymist/src/lsp/query.rs @@ -173,7 +173,8 @@ impl ServerState { pub(crate) fn on_enter(&mut self, params: OnEnterParams) -> ScheduleResult { let path = as_path(params.text_document); let range = params.range; - run_query!(self.OnEnter(path, range)) + let handle_list = self.config.on_enter.handle_list; + run_query!(self.OnEnter(path, range, handle_list)) } pub(crate) fn will_rename_files(&mut self, params: RenameFilesParams) -> ScheduleResult {