From 0683f0a20ae1c1ce3e7788e303c468767381e6fd Mon Sep 17 00:00:00 2001 From: Oliver Hechtl Date: Sat, 18 Dec 2021 05:40:34 +0100 Subject: [PATCH 01/95] Add scala syntax highlights (#1278) * add partial scala syntax highlights * ran cargo xtask docgen * updated tree-sitter-scala, fixed highlights * fix comments * move identifier to the end of the highlights * add indents --- book/src/generated/lang-support.md | 1 + helix-syntax/languages/tree-sitter-scala | 2 +- languages.toml | 9 + runtime/queries/scala/highlights.scm | 203 +++++++++++++++++++++++ runtime/queries/scala/indents.toml | 23 +++ runtime/queries/scala/injections.scm | 1 + 6 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 runtime/queries/scala/highlights.scm create mode 100644 runtime/queries/scala/indents.toml create mode 100644 runtime/queries/scala/injections.scm diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 80989e63..b7babd8c 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -31,6 +31,7 @@ | racket | | | | `racket` | | ruby | ✓ | | | `solargraph` | | rust | ✓ | ✓ | ✓ | `rust-analyzer` | +| scala | ✓ | | | `metals` | | svelte | ✓ | | ✓ | `svelteserver` | | toml | ✓ | | | | | tsq | ✓ | | | | diff --git a/helix-syntax/languages/tree-sitter-scala b/helix-syntax/languages/tree-sitter-scala index fb23ed9a..0a3dd53a 160000 --- a/helix-syntax/languages/tree-sitter-scala +++ b/helix-syntax/languages/tree-sitter-scala @@ -1 +1 @@ -Subproject commit fb23ed9a99da012d86b7a5059b9d8928607cce29 +Subproject commit 0a3dd53a7fc4b352a538397d054380aaa28be54c diff --git a/languages.toml b/languages.toml index abb94acf..88882f3e 100644 --- a/languages.toml +++ b/languages.toml @@ -430,3 +430,12 @@ file-types = ["md"] roots = [] indent = { tab-width = 2, unit = " " } + +[[language]] +name = "scala" +scope = "source.scala" +roots = ["build.sbt"] +file-types = ["scala", "sbt"] +comment-token = "//" +indent = { tab-width = 2, unit = " " } +language-server = { command = "metals" } diff --git a/runtime/queries/scala/highlights.scm b/runtime/queries/scala/highlights.scm new file mode 100644 index 00000000..50a6e18a --- /dev/null +++ b/runtime/queries/scala/highlights.scm @@ -0,0 +1,203 @@ +; CREDITS @stumash (stuart.mashaal@gmail.com) + +;; variables + + +((identifier) @variable.builtin + (#match? @variable.builtin "^this$")) + +(interpolation) @none + +; Assume other uppercase names constants. +; NOTE: In order to distinguish constants we highlight +; all the identifiers that are uppercased. But this solution +; is not suitable for all occurrences e.g. it will highlight +; an uppercased method as a constant if used with no params. +; Introducing highlighting for those specific cases, is probably +; best way to resolve the issue. +((identifier) @constant (#match? @constant "^[A-Z]")) + +;; types + +(type_identifier) @type + +(class_definition + name: (identifier) @type) + +(object_definition + name: (identifier) @type) + +(trait_definition + name: (identifier) @type) + +(type_definition + name: (type_identifier) @type) + +; method definition + +(class_definition + body: (template_body + (function_definition + name: (identifier) @function.method))) +(object_definition + body: (template_body + (function_definition + name: (identifier) @function.method))) +(trait_definition + body: (template_body + (function_definition + name: (identifier) @function.method))) + +; imports + +(import_declaration + path: (identifier) @namespace) +((stable_identifier (identifier) @namespace)) + +((import_declaration + path: (identifier) @type) (#match? @type "^[A-Z]")) +((stable_identifier (identifier) @type) (#match? @type "^[A-Z]")) + +((import_selectors (identifier) @type) (#match? @type "^[A-Z]")) + +; method invocation + + +(call_expression + function: (identifier) @function) + +(call_expression + function: (field_expression + field: (identifier) @function.method)) + +((call_expression + function: (identifier) @variable.other.member) + (#match? @variable.other.member "^[A-Z]")) + +(generic_function + function: (identifier) @function) + +( + (identifier) @function.builtin + (#match? @function.builtin "^super$") +) + +; function definitions + +(function_definition + name: (identifier) @function) + +(parameter + name: (identifier) @variable.parameter) + +; expressions + + +(field_expression field: (identifier) @variable.other.member) +(field_expression value: (identifier) @type + (#match? @type "^[A-Z]")) + +(infix_expression operator: (identifier) @operator) +(infix_expression operator: (operator_identifier) @operator) +(infix_type operator: (operator_identifier) @operator) +(infix_type operator: (operator_identifier) @operator) + +; literals +(boolean_literal) @constant.builtin.boolean +(integer_literal) @constant.numeric.integer +(floating_point_literal) @constant.numeric.float + + +(symbol_literal) @string.special.symbol + +[ +(string) +(character_literal) +(interpolated_string_expression) +] @string + +(interpolation "$" @punctuation.special) + +;; keywords + +[ + "abstract" + "case" + "class" + "extends" + "final" + "finally" +;; `forSome` existential types not implemented yet + "implicit" + "lazy" +;; `macro` not implemented yet + "object" + "override" + "package" + "private" + "protected" + "sealed" + "trait" + "type" + "val" + "var" + "with" +] @keyword + +(null_literal) @constant.builtin +(wildcard) @keyword + +;; special keywords + +"new" @keyword.operator + +[ + "else" + "if" + "match" + "try" + "catch" + "throw" +] @keyword.control.conditional + +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket + +[ + "." + "," +] @punctuation.delimiter + +[ + "do" + "for" + "while" + "yield" +] @keyword.control.repeat + +"def" @keyword.function + +[ + "=>" + "<-" + "@" +] @keyword.operator + +"import" @keyword.control.import + +"return" @keyword.control.return + +(comment) @comment + +;; `case` is a conditional keyword in case_block + +(case_block + (case_clause ("case") @keyword.control.conditional)) + +(identifier) @variable \ No newline at end of file diff --git a/runtime/queries/scala/indents.toml b/runtime/queries/scala/indents.toml new file mode 100644 index 00000000..6de54844 --- /dev/null +++ b/runtime/queries/scala/indents.toml @@ -0,0 +1,23 @@ + +indent = [ + "block", + "arguments", + "parameter", + "class_definition", + "trait_definition", + "object_definition", + "function_definition", + "val_definition", + "import_declaration", + "while_expression", + "do_while_expression", + "for_expression", + "try_expression", + "match_expression" +] + +outdent = [ + "}", + "]", + ")" +] diff --git a/runtime/queries/scala/injections.scm b/runtime/queries/scala/injections.scm new file mode 100644 index 00000000..4bb7d675 --- /dev/null +++ b/runtime/queries/scala/injections.scm @@ -0,0 +1 @@ +(comment) @comment From edf3c70c302aef628dc1a63895e2492d34e82507 Mon Sep 17 00:00:00 2001 From: Luke Jones Date: Sat, 18 Dec 2021 17:41:32 +1300 Subject: [PATCH 02/95] Add dart lsp config and queries (#1250) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add language: dart The setup requires that dart be in the users path, such as: ``` export PATH="$HOME/Android/flutter/bin/cache/dart-sdk/bin/:$PATH" ``` Refactor the dart highlights * lang: dart: add indents and locals * lang: dart: corrections to local scope Co-authored-by: Blaž Hrastnik --- .gitmodules | 4 + helix-syntax/languages/tree-sitter-dart | 1 + languages.toml | 12 +- runtime/queries/dart/highlights.scm | 237 ++++++++++++++++++++++++ runtime/queries/dart/indents.toml | 20 ++ runtime/queries/dart/locals.scm | 20 ++ 6 files changed, 293 insertions(+), 1 deletion(-) create mode 160000 helix-syntax/languages/tree-sitter-dart create mode 100644 runtime/queries/dart/highlights.scm create mode 100644 runtime/queries/dart/indents.toml create mode 100644 runtime/queries/dart/locals.scm diff --git a/.gitmodules b/.gitmodules index 9c10846d..4b142adf 100644 --- a/.gitmodules +++ b/.gitmodules @@ -154,3 +154,7 @@ path = helix-syntax/languages/tree-sitter-markdown url = https://github.com/MDeiml/tree-sitter-markdown shallow = true +[submodule "helix-syntax/languages/tree-sitter-dart"] + path = helix-syntax/languages/tree-sitter-dart + url = https://github.com/UserNobody14/tree-sitter-dart.git + shallow = true diff --git a/helix-syntax/languages/tree-sitter-dart b/helix-syntax/languages/tree-sitter-dart new file mode 160000 index 00000000..6a253766 --- /dev/null +++ b/helix-syntax/languages/tree-sitter-dart @@ -0,0 +1 @@ +Subproject commit 6a25376685d1d47968c2cef06d4db8d84a70025e diff --git a/languages.toml b/languages.toml index 88882f3e..5c2bc8bb 100644 --- a/languages.toml +++ b/languages.toml @@ -431,6 +431,16 @@ roots = [] indent = { tab-width = 2, unit = " " } +[[language]] +name = "dart" +scope = "source.dart" +file-types = ["dart"] +roots = ["pubspec.yaml"] +auto-format = true +comment-token = "//" +language-server = { command = "dart", args = ["language-server", "--client-id=helix"] } +indent = { tab-width = 2, unit = " " } + [[language]] name = "scala" scope = "source.scala" @@ -438,4 +448,4 @@ roots = ["build.sbt"] file-types = ["scala", "sbt"] comment-token = "//" indent = { tab-width = 2, unit = " " } -language-server = { command = "metals" } +language-server = { command = "metals" } \ No newline at end of file diff --git a/runtime/queries/dart/highlights.scm b/runtime/queries/dart/highlights.scm new file mode 100644 index 00000000..9f667d6b --- /dev/null +++ b/runtime/queries/dart/highlights.scm @@ -0,0 +1,237 @@ +(dotted_identifier_list) @string + +; Methods +; -------------------- +(super) @function.builtin + +(function_expression_body (identifier) @function.method) +((identifier)(selector (argument_part)) @function.method) + +; Annotations +; -------------------- +(annotation + name: (identifier) @attribute) +(marker_annotation + name: (identifier) @attribute) + +; Types +; -------------------- +(class_definition + name: (identifier) @type) + +(constructor_signature + name: (identifier) @function.method) + +(function_signature + name: (identifier) @function.method) + +(getter_signature + (identifier) @function.builtin) + +(setter_signature + name: (identifier) @function.builtin) + +(enum_declaration + name: (identifier) @type) + +(enum_constant + name: (identifier) @type.builtin) + +(void_type) @type.builtin + +((scoped_identifier + scope: (identifier) @type) + (#match? @type "^[a-zA-Z]")) + +((scoped_identifier + scope: (identifier) @type + name: (identifier) @type) + (#match? @type "^[a-zA-Z]")) + +; the DisabledDrawerButtons in : const DisabledDrawerButtons(history: true), +(type_identifier) @type.builtin + +; Variables +; -------------------- +; the "File" in var file = File(); +((identifier) @namespace + (#match? @namespace "^_?[A-Z].*[a-z]")) ; catch Classes or IClasses not CLASSES + +("Function" @type.builtin) +(inferred_type) @type.builtin + +; properties +(unconditional_assignable_selector + (identifier) @variable.other.member) + +(conditional_assignable_selector + (identifier) @variable.other.member) + +; assignments +; -------------------- +; the "strings" in : strings = "some string" +(assignment_expression + left: (assignable_expression) @variable) + +(this) @variable.builtin + +; Parameters +; -------------------- +(formal_parameter + name: (identifier) @variable) + +(named_argument + (label (identifier) @variable)) + +; Literals +; -------------------- +[ + (hex_integer_literal) + (decimal_integer_literal) + (decimal_floating_point_literal) + ;(octal_integer_literal) + ;(hex_floating_point_literal) +] @constant.numeric.integer + +(symbol_literal) @string.special.symbol +(string_literal) @string + +[ + (const_builtin) + (final_builtin) +] @variable.builtin + +[ + (true) + (false) +] @constant.builtin.boolean + +(null_literal) @constant.builtin + +(comment) @comment.line +(documentation_comment) @comment.block.documentation + +; Tokens +; -------------------- +(template_substitution + "$" @punctuation.special + "{" @punctuation.special + "}" @punctuation.special +) @embedded + +(template_substitution + "$" @punctuation.special + (identifier_dollar_escaped) @variable +) @embedded + +(escape_sequence) @constant.character.escape + +; Punctuation +;--------------------- +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket + +[ + ";" + "." + "," + ":" +] @punctuation.delimiter + +; Operators +;--------------------- +[ + "@" + "?" + "=>" + ".." + "==" + "&&" + "%" + "<" + ">" + "=" + ">=" + "<=" + "||" + (multiplicative_operator) + (increment_operator) + (is_operator) + (prefix_operator) + (equality_operator) + (additive_operator) +] @operator + +; Keywords +; -------------------- +["import" "library" "export"] @keyword.control.import +["do" "while" "continue" "for"] @keyword.control.repeat +["return" "yield"] @keyword.control.return +["as" "in" "is"] @keyword.operator + +[ + "?." + "??" + "if" + "else" + "switch" + "default" + "late" +] @keyword.control.conditional + +[ + "try" + "throw" + "catch" + "finally" + (break_statement) +] @keyword.control.exception + +; Reserved words (cannot be used as identifiers) +[ + (case_builtin) + "abstract" + "async" + "async*" + "await" + "class" + "covariant" + "deferred" + "dynamic" + "enum" + "extends" + "extension" + "external" + "factory" + "Function" + "get" + "implements" + "interface" + "mixin" + "new" + "on" + "operator" + "part" + "required" + "set" + "show" + "static" + "super" + "sync*" + "typedef" + "with" +] @keyword + +; when used as an identifier: +((identifier) @variable.builtin + (#match? @variable.builtin "^(abstract|as|covariant|deferred|dynamic|export|external|factory|Function|get|implements|import|interface|library|operator|mixin|part|set|static|typedef)$")) + +; Error +(ERROR) @error + diff --git a/runtime/queries/dart/indents.toml b/runtime/queries/dart/indents.toml new file mode 100644 index 00000000..5c11e05d --- /dev/null +++ b/runtime/queries/dart/indents.toml @@ -0,0 +1,20 @@ +indent = [ + "class_body", + "function_body", + "function_expression_body", + "declaration", + "initializers", + "switch_block", + "if_statement", + "formal_parameter_list", + "formal_parameter", + "list_literal", + "return_statement", + "arguments" +] + +outdent = [ + "}", + "]", + ")" +] diff --git a/runtime/queries/dart/locals.scm b/runtime/queries/dart/locals.scm new file mode 100644 index 00000000..629838e5 --- /dev/null +++ b/runtime/queries/dart/locals.scm @@ -0,0 +1,20 @@ +; Scopes +;------- + +[ + (block) + (try_statement) + (catch_clause) + (finally_clause) +] @local.scope + +; Definitions +;------------ + +(class_definition + body: (_) @local.definition) + +; References +;------------ + +(identifier) @local.reference From a66833590c7dc87b5e015266bace900d46b98b34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Sat, 18 Dec 2021 13:42:41 +0900 Subject: [PATCH 03/95] cargo xtask docgen --- book/src/generated/lang-support.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index b7babd8c..3255b9af 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -6,6 +6,7 @@ | cmake | ✓ | | | `cmake-language-server` | | cpp | ✓ | | | `clangd` | | css | ✓ | | | | +| dart | ✓ | | ✓ | `dart` | | elixir | ✓ | | | `elixir-ls` | | glsl | ✓ | | ✓ | | | go | ✓ | ✓ | ✓ | `gopls` | @@ -31,7 +32,7 @@ | racket | | | | `racket` | | ruby | ✓ | | | `solargraph` | | rust | ✓ | ✓ | ✓ | `rust-analyzer` | -| scala | ✓ | | | `metals` | +| scala | ✓ | | ✓ | `metals` | | svelte | ✓ | | ✓ | `svelteserver` | | toml | ✓ | | | | | tsq | ✓ | | | | From 02fc52f6d52c91c691dd2b7f9312b81aa20b8cbb Mon Sep 17 00:00:00 2001 From: Kirawi <67773714+kirawi@users.noreply.github.com> Date: Sat, 18 Dec 2021 00:57:49 -0500 Subject: [PATCH 04/95] Apply recent nightly suggestions (#1286) array iterators are now implicit --- helix-core/src/movement.rs | 52 ++++++++++++++++++------------------- helix-term/src/commands.rs | 2 +- helix-term/src/ui/prompt.rs | 2 +- 3 files changed, 27 insertions(+), 29 deletions(-) diff --git a/helix-core/src/movement.rs b/helix-core/src/movement.rs index 01a8f890..47fe6827 100644 --- a/helix-core/src/movement.rs +++ b/helix-core/src/movement.rs @@ -307,8 +307,6 @@ fn reached_target(target: WordMotionTarget, prev_ch: char, next_ch: char) -> boo #[cfg(test)] mod test { - use std::array::{self, IntoIter}; - use ropey::Rope; use super::*; @@ -360,7 +358,7 @@ mod test { ((Direction::Backward, 999usize), (0, 0)), // |This is a simple alphabetic line ]; - for ((direction, amount), coordinates) in IntoIter::new(moves_and_expected_coordinates) { + for ((direction, amount), coordinates) in moves_and_expected_coordinates { range = move_horizontally(slice, range, direction, amount, Movement::Move); assert_eq!(coords_at_pos(slice, range.head), coordinates.into()) } @@ -374,7 +372,7 @@ mod test { let mut range = Range::point(position); - let moves_and_expected_coordinates = IntoIter::new([ + let moves_and_expected_coordinates = [ ((Direction::Forward, 11usize), (1, 1)), // Multiline\nt|ext sample\n... ((Direction::Backward, 1usize), (1, 0)), // Multiline\n|text sample\n... ((Direction::Backward, 5usize), (0, 5)), // Multi|line\ntext sample\n... @@ -384,7 +382,7 @@ mod test { ((Direction::Backward, 0usize), (0, 3)), // Mul|tiline\ntext sample\n... ((Direction::Forward, 999usize), (5, 0)), // ...and whitespaced\n| ((Direction::Forward, 999usize), (5, 0)), // ...and whitespaced\n| - ]); + ]; for ((direction, amount), coordinates) in moves_and_expected_coordinates { range = move_horizontally(slice, range, direction, amount, Movement::Move); @@ -402,11 +400,11 @@ mod test { let mut range = Range::point(position); let original_anchor = range.anchor; - let moves = IntoIter::new([ + let moves = [ (Direction::Forward, 1usize), (Direction::Forward, 5usize), (Direction::Backward, 3usize), - ]); + ]; for (direction, amount) in moves { range = move_horizontally(slice, range, direction, amount, Movement::Extend); @@ -420,7 +418,7 @@ mod test { let slice = text.slice(..); let position = pos_at_coords(slice, (0, 0).into(), true); let mut range = Range::point(position); - let moves_and_expected_coordinates = IntoIter::new([ + let moves_and_expected_coordinates = [ ((Direction::Forward, 1usize), (1, 0)), ((Direction::Forward, 2usize), (3, 0)), ((Direction::Forward, 1usize), (4, 0)), @@ -430,7 +428,7 @@ mod test { ((Direction::Backward, 0usize), (4, 0)), ((Direction::Forward, 5), (5, 0)), ((Direction::Forward, 999usize), (5, 0)), - ]); + ]; for ((direction, amount), coordinates) in moves_and_expected_coordinates { range = move_vertically(slice, range, direction, amount, Movement::Move); @@ -450,7 +448,7 @@ mod test { H, V, } - let moves_and_expected_coordinates = IntoIter::new([ + let moves_and_expected_coordinates = [ // Places cursor at the end of line ((Axis::H, Direction::Forward, 8usize), (0, 8)), // First descent preserves column as the target line is wider @@ -463,7 +461,7 @@ mod test { ((Axis::V, Direction::Backward, 999usize), (0, 8)), ((Axis::V, Direction::Forward, 4usize), (4, 8)), ((Axis::V, Direction::Forward, 999usize), (5, 0)), - ]); + ]; for ((axis, direction, amount), coordinates) in moves_and_expected_coordinates { range = match axis { @@ -489,7 +487,7 @@ mod test { H, V, } - let moves_and_expected_coordinates = IntoIter::new([ + let moves_and_expected_coordinates = [ // Places cursor at the fourth kana. ((Axis::H, Direction::Forward, 4), (0, 4)), // Descent places cursor at the 4th character. @@ -498,7 +496,7 @@ mod test { ((Axis::H, Direction::Backward, 1usize), (1, 3)), // Jumping back up 1 line. ((Axis::V, Direction::Backward, 1usize), (0, 3)), - ]); + ]; for ((axis, direction, amount), coordinates) in moves_and_expected_coordinates { range = match axis { @@ -530,7 +528,7 @@ mod test { #[test] fn test_behaviour_when_moving_to_start_of_next_words() { - let tests = array::IntoIter::new([ + let tests = [ ("Basic forward motion stops at the first space", vec![(1, Range::new(0, 0), Range::new(0, 6))]), (" Starting from a boundary advances the anchor", @@ -604,7 +602,7 @@ mod test { vec![ (1, Range::new(0, 0), Range::new(0, 6)), ]), - ]); + ]; for (sample, scenario) in tests { for (count, begin, expected_end) in scenario.into_iter() { @@ -616,7 +614,7 @@ mod test { #[test] fn test_behaviour_when_moving_to_start_of_next_long_words() { - let tests = array::IntoIter::new([ + let tests = [ ("Basic forward motion stops at the first space", vec![(1, Range::new(0, 0), Range::new(0, 6))]), (" Starting from a boundary advances the anchor", @@ -688,7 +686,7 @@ mod test { vec![ (1, Range::new(0, 0), Range::new(0, 8)), ]), - ]); + ]; for (sample, scenario) in tests { for (count, begin, expected_end) in scenario.into_iter() { @@ -700,7 +698,7 @@ mod test { #[test] fn test_behaviour_when_moving_to_start_of_previous_words() { - let tests = array::IntoIter::new([ + let tests = [ ("Basic backward motion from the middle of a word", vec![(1, Range::new(3, 3), Range::new(4, 0))]), @@ -773,7 +771,7 @@ mod test { vec![ (1, Range::new(0, 6), Range::new(6, 0)), ]), - ]); + ]; for (sample, scenario) in tests { for (count, begin, expected_end) in scenario.into_iter() { @@ -785,7 +783,7 @@ mod test { #[test] fn test_behaviour_when_moving_to_start_of_previous_long_words() { - let tests = array::IntoIter::new([ + let tests = [ ( "Basic backward motion from the middle of a word", vec![(1, Range::new(3, 3), Range::new(4, 0))], @@ -870,7 +868,7 @@ mod test { vec![ (1, Range::new(0, 8), Range::new(8, 0)), ]), - ]); + ]; for (sample, scenario) in tests { for (count, begin, expected_end) in scenario.into_iter() { @@ -882,7 +880,7 @@ mod test { #[test] fn test_behaviour_when_moving_to_end_of_next_words() { - let tests = array::IntoIter::new([ + let tests = [ ("Basic forward motion from the start of a word to the end of it", vec![(1, Range::new(0, 0), Range::new(0, 5))]), ("Basic forward motion from the end of a word to the end of the next", @@ -954,7 +952,7 @@ mod test { vec![ (1, Range::new(0, 0), Range::new(0, 5)), ]), - ]); + ]; for (sample, scenario) in tests { for (count, begin, expected_end) in scenario.into_iter() { @@ -966,7 +964,7 @@ mod test { #[test] fn test_behaviour_when_moving_to_end_of_previous_words() { - let tests = array::IntoIter::new([ + let tests = [ ("Basic backward motion from the middle of a word", vec![(1, Range::new(9, 9), Range::new(10, 5))]), ("Starting from after boundary retreats the anchor", @@ -1036,7 +1034,7 @@ mod test { vec![ (1, Range::new(0, 10), Range::new(10, 4)), ]), - ]); + ]; for (sample, scenario) in tests { for (count, begin, expected_end) in scenario.into_iter() { @@ -1048,7 +1046,7 @@ mod test { #[test] fn test_behaviour_when_moving_to_end_of_next_long_words() { - let tests = array::IntoIter::new([ + let tests = [ ("Basic forward motion from the start of a word to the end of it", vec![(1, Range::new(0, 0), Range::new(0, 5))]), ("Basic forward motion from the end of a word to the end of the next", @@ -1118,7 +1116,7 @@ mod test { vec![ (1, Range::new(0, 0), Range::new(0, 7)), ]), - ]); + ]; for (sample, scenario) in tests { for (count, begin, expected_end) in scenario.into_iter() { diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index cd566720..48dccff2 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -1938,7 +1938,7 @@ fn append_mode(cx: &mut Context) { if !last_range.is_empty() && last_range.head == end { let transaction = Transaction::change( doc.text(), - std::array::IntoIter::new([(end, end, Some(doc.line_ending.as_str().into()))]), + [(end, end, Some(doc.line_ending.as_str().into()))].into_iter(), ); doc.apply(&transaction, view.id); } diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index 07e1b33c..29e0339a 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -127,7 +127,7 @@ impl Prompt { let mut char_position = char_indices .iter() .position(|(idx, _)| *idx == self.cursor) - .unwrap_or_else(|| char_indices.len()); + .unwrap_or(char_indices.len()); for _ in 0..rep { // Skip any non-whitespace characters From f174d27d0d1ab5d981c6902a54035db4ffde839f Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Sat, 18 Dec 2021 22:58:17 +0800 Subject: [PATCH 05/95] Change text for gg to explain gg (#1287) --- book/src/keymap.md | 2 +- helix-term/src/commands.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/book/src/keymap.md b/book/src/keymap.md index f0a2cb30..d84b17b8 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -161,7 +161,7 @@ Jumps to various locations. | Key | Description | Command | | ----- | ----------- | ------- | -| `g` | Go to the start of the file | `goto_file_start` | +| `g` | Go to line number `` else start of file | `goto_file_start` | | `e` | Go to the end of the file | `goto_last_line` | | `f` | Go to files in the selection | `goto_file` | | `h` | Go to the start of the line | `goto_line_start` | diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 48dccff2..28f955eb 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -287,7 +287,7 @@ impl MappableCommand { add_newline_below, "Add newline below", goto_type_definition, "Goto type definition", goto_implementation, "Goto implementation", - goto_file_start, "Goto file start/line", + goto_file_start, "Goto line number else file start", goto_file_end, "Goto file end", goto_file, "Goto files in selection", goto_file_hsplit, "Goto files in selection (hsplit)", From 6d183b2154bdeb8508059d2cb3cf165ac4c67bb6 Mon Sep 17 00:00:00 2001 From: Sebastian Neubauer Date: Sun, 19 Dec 2021 01:46:47 +0100 Subject: [PATCH 06/95] Fix tree-sitter-llvm submodule (#1298) Fix the path to the submodule and init the submodule. --- .gitmodules | 2 +- helix-syntax/languages/tree-sitter-llvm | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 160000 helix-syntax/languages/tree-sitter-llvm diff --git a/.gitmodules b/.gitmodules index 4b142adf..a899c778 100644 --- a/.gitmodules +++ b/.gitmodules @@ -146,7 +146,7 @@ path = helix-syntax/languages/tree-sitter-wgsl url = https://github.com/szebniok/tree-sitter-wgsl shallow = true -[submodule "helix-syntax/tree-sitter-llvm"] +[submodule "helix-syntax/languages/tree-sitter-llvm"] path = helix-syntax/languages/tree-sitter-llvm url = https://github.com/benwilliamgraham/tree-sitter-llvm shallow = true diff --git a/helix-syntax/languages/tree-sitter-llvm b/helix-syntax/languages/tree-sitter-llvm new file mode 160000 index 00000000..d4f61bed --- /dev/null +++ b/helix-syntax/languages/tree-sitter-llvm @@ -0,0 +1 @@ +Subproject commit d4f61bed8ecb632addcd5e088c4f4cb9c1bf1c5b From d52eda5d1bf6c8912a62bfcd68a3fcb84efe3dd4 Mon Sep 17 00:00:00 2001 From: Gokul Soumya Date: Sun, 19 Dec 2021 06:50:52 +0530 Subject: [PATCH 07/95] Improve yaml syntax highlighting highlighting (#1294) --- runtime/queries/yaml/highlights.scm | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/runtime/queries/yaml/highlights.scm b/runtime/queries/yaml/highlights.scm index a7efb5e7..e4fed27a 100644 --- a/runtime/queries/yaml/highlights.scm +++ b/runtime/queries/yaml/highlights.scm @@ -1,9 +1,19 @@ -(block_mapping_pair key: (_) @variable.other.member) -(flow_mapping (_ key: (_) @variable.other.member)) +(block_mapping_pair + key: (flow_node [(double_quote_scalar) (single_quote_scalar)] @variable.other.member)) +(block_mapping_pair + key: (flow_node (plain_scalar (string_scalar) @variable.other.member))) + +(flow_mapping + (_ key: (flow_node [(double_quote_scalar) (single_quote_scalar)] @variable.other.member))) +(flow_mapping + (_ key: (flow_node (plain_scalar (string_scalar) @variable.other.member)))) + (boolean_scalar) @constant.builtin.boolean (null_scalar) @constant.builtin (double_quote_scalar) @string (single_quote_scalar) @string +(block_scalar) @string +(string_scalar) @string (escape_sequence) @constant.character.escape (integer_scalar) @constant.numeric.integer (float_scalar) @constant.numeric.float @@ -30,4 +40,4 @@ "}" ] @punctuation.bracket -["*" "&"] @punctuation.special +["*" "&" "---" "..."] @punctuation.special From 8208d22601dfbecbdaa14be273e998eccfd63220 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Sun, 19 Dec 2021 13:46:00 +0900 Subject: [PATCH 08/95] nix: Update flake.lock --- flake.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/flake.lock b/flake.lock index 2c59f993..acd10f76 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "devshell": { "locked": { - "lastModified": 1637575296, - "narHash": "sha256-ZY8YR5u8aglZPe27+AJMnPTG6645WuavB+w0xmhTarw=", + "lastModified": 1639692811, + "narHash": "sha256-wOOBH0fVsfNqw/5ZWRoKspyesoXBgiwEOUBH4c7JKEo=", "owner": "numtide", "repo": "devshell", - "rev": "0e56ef21ba1a717169953122c7415fa6a8cd2618", + "rev": "d3a1f5bec3632b33346865b1c165bf2420bb2f52", "type": "github" }, "original": { @@ -41,11 +41,11 @@ ] }, "locked": { - "lastModified": 1638425401, - "narHash": "sha256-xc8ayvR3u90hSCMEy0zHHKav7lEgljAFXL4oIkWRp3M=", + "lastModified": 1639807801, + "narHash": "sha256-y32tMq1LTRVbMW3QN5i98iOQjQt2QSsif3ayUkD1o3g=", "owner": "yusdacra", "repo": "nix-cargo-integration", - "rev": "1f8b511bb30f7d7b9051dfbb4784390bc0d48d37", + "rev": "b5bbaa4f5239e6f0619846f9a5380f07baa853d3", "type": "github" }, "original": { @@ -56,11 +56,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1638376152, - "narHash": "sha256-ucgLpVqhFnClH7YRUHBHnmiOd82RZdFR3XJt36ks5fE=", + "lastModified": 1639699734, + "narHash": "sha256-tlX6WebGmiHb2Hmniff+ltYp+7dRfdsBxw9YczLsP60=", "owner": "nixos", "repo": "nixpkgs", - "rev": "6daa4a5c045d40e6eae60a3b6e427e8700f1c07f", + "rev": "03ec468b14067729a285c2c7cfa7b9434a04816c", "type": "github" }, "original": { @@ -99,11 +99,11 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1638497756, - "narHash": "sha256-zKOvMKqGp71ZBnR+hBlPcv4TwNN82COW9EF+6ygrFs8=", + "lastModified": 1639880499, + "narHash": "sha256-/BibDmFwgWuuTUkNVO6YlvuTSWM9dpBvlZoTAPs7ORI=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "783722a22ee5d762ac5c1c7b418b57b3010c827a", + "rev": "c6c83589ae048af20d93d01eb07a4176012093d0", "type": "github" }, "original": { From 7c01d926536bcaacc92bbf4a2b1a06e96e6268a0 Mon Sep 17 00:00:00 2001 From: Gokul Soumya Date: Sun, 19 Dec 2021 00:05:43 +0530 Subject: [PATCH 09/95] Add link and quote queries for markdown - Rename markup.underline.link to markup.link.url - Add markup.link.label - Add markup.quote (The constructor theme scope was missing from the docs, so unrelated to this commit). --- book/src/themes.md | 6 ++++-- runtime/queries/latex/highlights.scm | 2 +- runtime/queries/markdown/highlights.scm | 7 ++++--- runtime/queries/svelte/highlights.scm | 4 ++-- theme.toml | 2 +- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/book/src/themes.md b/book/src/themes.md index b6de7002..fce2c0ca 100644 --- a/book/src/themes.md +++ b/book/src/themes.md @@ -105,6 +105,7 @@ We use a similar set of scopes as - `type` - Types - `builtin` - Primitive types provided by the language (`int`, `usize`) +- `constructor` - `constant` (TODO: constant.other.placeholder for %v) - `builtin` Special constants provided by the language (`true`, `false`, `nil` etc) @@ -169,8 +170,9 @@ We use a similar set of scopes as - `numbered` - `bold` - `italic` - - `underline` - - `link` + - `link` + - `url` + - `label` - `quote` - `raw` - `inline` diff --git a/runtime/queries/latex/highlights.scm b/runtime/queries/latex/highlights.scm index 2e308f77..0a030b31 100644 --- a/runtime/queries/latex/highlights.scm +++ b/runtime/queries/latex/highlights.scm @@ -371,7 +371,7 @@ ((generic_command name:(generic_command_name) @_name . - arg: (_) @markup.underline.link) + arg: (_) @markup.link.url) (#match? @_name "^(\\\\url|\\\\href)$")) (ERROR) @error diff --git a/runtime/queries/markdown/highlights.scm b/runtime/queries/markdown/highlights.scm index a102719b..a0bd3462 100644 --- a/runtime/queries/markdown/highlights.scm +++ b/runtime/queries/markdown/highlights.scm @@ -10,15 +10,16 @@ (fenced_code_block) ] @markup.raw.block +(block_quote) @markup.quote + (code_span) @markup.raw.inline (emphasis) @markup.italic (strong_emphasis) @markup.bold -(link_destination) @markup.underline.link - -; (link_label) @markup.label ; TODO: rename +(link_destination) @markup.link.url +(link_label) @markup.link.label [ (list_marker_plus) diff --git a/runtime/queries/svelte/highlights.scm b/runtime/queries/svelte/highlights.scm index f9eef6b5..22b0c551 100644 --- a/runtime/queries/svelte/highlights.scm +++ b/runtime/queries/svelte/highlights.scm @@ -20,12 +20,12 @@ ((element (start_tag (tag_name) @_tag) (text) @markup.inline) (#match? @_tag "^(code|kbd)$")) -((element (start_tag (tag_name) @_tag) (text) @markup.underline.link) +((element (start_tag (tag_name) @_tag) (text) @markup.link.url) (#eq? @_tag "a")) ((attribute (attribute_name) @_attr - (quoted_attribute_value (attribute_value) @markup.underline.link)) + (quoted_attribute_value (attribute_value) @markup.link.url)) (#match? @_attr "^(href|src)$")) (tag_name) @tag diff --git a/theme.toml b/theme.toml index 0a79861e..b316e814 100644 --- a/theme.toml +++ b/theme.toml @@ -31,7 +31,7 @@ label = "honey" "markup.heading" = "lilac" "markup.bold" = { modifiers = ["bold"] } "markup.italic" = { modifiers = ["italic"] } -"markup.underline.link" = { fg = "silver", modifiers = ["underlined"] } +"markup.link.url" = { fg = "silver", modifiers = ["underlined"] } "markup.raw" = "almond" # TODO: diferentiate doc comment From e72786df8eae5684c0330be18f190a33f516da76 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Sun, 19 Dec 2021 08:56:56 -0600 Subject: [PATCH 10/95] Add tree-sitter-comment (#1300) * Add tree-sitter-comment Fix #1164 * fix precedence in tree-sitter-comment highlights connects https://github.com/helix-editor/helix/pull/1170 * set injection-regex for comment language * remove comment filetype * fix comment injections for neovim-style injections tags * add comment injections for elixir * remove f.comment * fix spacing in .gitmodules * run 'cargo xtask docgen' Co-authored-by: Ivan Tham --- .gitmodules | 4 +++ book/src/generated/lang-support.md | 1 + helix-syntax/languages/tree-sitter-comment | 1 + languages.toml | 9 ++++++- runtime/queries/comment/highlights.scm | 30 ++++++++++++++++++++++ runtime/queries/elixir/injections.scm | 2 ++ runtime/queries/glsl/injections.scm | 6 +++-- runtime/queries/julia/injections.scm | 8 +++--- runtime/queries/ledger/injections.scm | 4 +-- runtime/queries/python/injections.scm | 2 ++ runtime/queries/rust/injections.scm | 3 +++ runtime/queries/svelte/injections.scm | 4 +-- runtime/queries/tsq/injections.scm | 2 ++ 13 files changed, 66 insertions(+), 10 deletions(-) create mode 160000 helix-syntax/languages/tree-sitter-comment create mode 100644 runtime/queries/comment/highlights.scm create mode 100644 runtime/queries/elixir/injections.scm create mode 100644 runtime/queries/python/injections.scm create mode 100644 runtime/queries/tsq/injections.scm diff --git a/.gitmodules b/.gitmodules index a899c778..c7b81336 100644 --- a/.gitmodules +++ b/.gitmodules @@ -142,6 +142,10 @@ path = helix-syntax/languages/tree-sitter-perl url = https://github.com/ganezdragon/tree-sitter-perl shallow = true +[submodule "helix-syntax/languages/tree-sitter-comment"] + path = helix-syntax/languages/tree-sitter-comment + url = https://github.com/stsewd/tree-sitter-comment + shallow = true [submodule "helix-syntax/languages/tree-sitter-wgsl"] path = helix-syntax/languages/tree-sitter-wgsl url = https://github.com/szebniok/tree-sitter-wgsl diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 3255b9af..cb91872b 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -4,6 +4,7 @@ | c | ✓ | | | `clangd` | | c-sharp | ✓ | | | | | cmake | ✓ | | | `cmake-language-server` | +| comment | ✓ | | | | | cpp | ✓ | | | `clangd` | | css | ✓ | | | | | dart | ✓ | | ✓ | `dart` | diff --git a/helix-syntax/languages/tree-sitter-comment b/helix-syntax/languages/tree-sitter-comment new file mode 160000 index 00000000..5dd3c62f --- /dev/null +++ b/helix-syntax/languages/tree-sitter-comment @@ -0,0 +1 @@ +Subproject commit 5dd3c62f1bbe378b220fe16b317b85247898639e diff --git a/languages.toml b/languages.toml index 5c2bc8bb..0695022e 100644 --- a/languages.toml +++ b/languages.toml @@ -406,6 +406,13 @@ shebangs = ["racket"] comment-token = ";" language-server = { command = "racket", args = ["-l", "racket-langserver"] } +[[language]] +name = "comment" +scope = "scope.comment" +roots = [] +file-types = [] +injection-regex = "comment" + [[language]] name = "wgsl" scope = "source.wgsl" @@ -448,4 +455,4 @@ roots = ["build.sbt"] file-types = ["scala", "sbt"] comment-token = "//" indent = { tab-width = 2, unit = " " } -language-server = { command = "metals" } \ No newline at end of file +language-server = { command = "metals" } diff --git a/runtime/queries/comment/highlights.scm b/runtime/queries/comment/highlights.scm new file mode 100644 index 00000000..88685d59 --- /dev/null +++ b/runtime/queries/comment/highlights.scm @@ -0,0 +1,30 @@ +[ + "(" + ")" +] @punctuation.bracket + +":" @punctuation.delimiter + +((tag (name) @warning) + (#match? @warning "^(TODO|HACK|WARNING)$")) + +("text" @warning + (#match? @warning "^(TODO|HACK|WARNING)$")) + +((tag (name) @error) + (match? @error "^(FIXME|XXX|BUG)$")) + +("text" @error + (match? @error "^(FIXME|XXX|BUG)$")) + +(tag + (name) @ui.text + (user)? @constant) + +; Issue number (#123) +("text" @constant.numeric + (#match? @constant.numeric "^#[0-9]+$")) + +; User mention (@user) +("text" @tag + (#match? @tag "^[@][a-zA-Z0-9_-]+$")) diff --git a/runtime/queries/elixir/injections.scm b/runtime/queries/elixir/injections.scm new file mode 100644 index 00000000..321c90ad --- /dev/null +++ b/runtime/queries/elixir/injections.scm @@ -0,0 +1,2 @@ +((comment) @injection.content + (#set! injection.language "comment")) diff --git a/runtime/queries/glsl/injections.scm b/runtime/queries/glsl/injections.scm index 7d3323b1..b01b8b4b 100644 --- a/runtime/queries/glsl/injections.scm +++ b/runtime/queries/glsl/injections.scm @@ -1,3 +1,5 @@ -(preproc_arg) @glsl +((preproc_arg) @injection.content + (#set! injection.language "glsl")) -(comment) @comment +((comment) @injection.content + (#set! injection.language "comment")) diff --git a/runtime/queries/julia/injections.scm b/runtime/queries/julia/injections.scm index be2412c0..3cf7339f 100644 --- a/runtime/queries/julia/injections.scm +++ b/runtime/queries/julia/injections.scm @@ -1,5 +1,7 @@ ; TODO: re-add when markdown is added. -; ((triple_string) @markdown -; (#offset! @markdown 0 3 0 -3)) +; ((triple_string) @injection.content +; (#offset! @injection.content 0 3 0 -3) +; (#set! injection.language "markdown")) -(comment) @comment +((comment) @injection.content + (#set! injection.language "comment")) diff --git a/runtime/queries/ledger/injections.scm b/runtime/queries/ledger/injections.scm index 2d948141..c1714786 100644 --- a/runtime/queries/ledger/injections.scm +++ b/runtime/queries/ledger/injections.scm @@ -1,2 +1,2 @@ -(comment) @comment -(note) @comment +([(comment) (note)] @injection.content + (#set! injection.language "comment")) diff --git a/runtime/queries/python/injections.scm b/runtime/queries/python/injections.scm new file mode 100644 index 00000000..321c90ad --- /dev/null +++ b/runtime/queries/python/injections.scm @@ -0,0 +1,2 @@ +((comment) @injection.content + (#set! injection.language "comment")) diff --git a/runtime/queries/rust/injections.scm b/runtime/queries/rust/injections.scm index 6035d418..d8382e49 100644 --- a/runtime/queries/rust/injections.scm +++ b/runtime/queries/rust/injections.scm @@ -1,3 +1,6 @@ +([(line_comment) (block_comment)] @injection.content + (#set! injection.language "comment")) + ((macro_invocation (token_tree) @injection.content) (#set! injection.language "rust") diff --git a/runtime/queries/svelte/injections.scm b/runtime/queries/svelte/injections.scm index 266f4701..04e860cf 100644 --- a/runtime/queries/svelte/injections.scm +++ b/runtime/queries/svelte/injections.scm @@ -26,5 +26,5 @@ (#set! injection.language "typescript") ) -(comment) @comment - +((comment) @injection.content + (#set! injection.language "comment")) diff --git a/runtime/queries/tsq/injections.scm b/runtime/queries/tsq/injections.scm new file mode 100644 index 00000000..321c90ad --- /dev/null +++ b/runtime/queries/tsq/injections.scm @@ -0,0 +1,2 @@ +((comment) @injection.content + (#set! injection.language "comment")) From 23091c9d29f575379d01b7011890da044a302433 Mon Sep 17 00:00:00 2001 From: Sebastian Neubauer Date: Mon, 20 Dec 2021 03:42:23 +0100 Subject: [PATCH 11/95] Highlight comments in c, cpp, cmake and llvm (#1309) Also, reuse the c injections in glsl --- runtime/queries/c/injections.scm | 2 ++ runtime/queries/cmake/injections.scm | 4 ++++ runtime/queries/cpp/injections.scm | 1 + runtime/queries/glsl/injections.scm | 5 ++--- runtime/queries/llvm/injections.scm | 2 ++ 5 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 runtime/queries/c/injections.scm create mode 100644 runtime/queries/cmake/injections.scm create mode 100644 runtime/queries/cpp/injections.scm create mode 100644 runtime/queries/llvm/injections.scm diff --git a/runtime/queries/c/injections.scm b/runtime/queries/c/injections.scm new file mode 100644 index 00000000..321c90ad --- /dev/null +++ b/runtime/queries/c/injections.scm @@ -0,0 +1,2 @@ +((comment) @injection.content + (#set! injection.language "comment")) diff --git a/runtime/queries/cmake/injections.scm b/runtime/queries/cmake/injections.scm new file mode 100644 index 00000000..6cb6c254 --- /dev/null +++ b/runtime/queries/cmake/injections.scm @@ -0,0 +1,4 @@ +((line_comment) @injection.content + (#set! injection.language "comment")) +((bracket_comment) @injection.content + (#set! injection.language "comment")) diff --git a/runtime/queries/cpp/injections.scm b/runtime/queries/cpp/injections.scm new file mode 100644 index 00000000..a5a5208c --- /dev/null +++ b/runtime/queries/cpp/injections.scm @@ -0,0 +1 @@ +; inherits: c diff --git a/runtime/queries/glsl/injections.scm b/runtime/queries/glsl/injections.scm index b01b8b4b..6330ea3e 100644 --- a/runtime/queries/glsl/injections.scm +++ b/runtime/queries/glsl/injections.scm @@ -1,5 +1,4 @@ +; inherits: c + ((preproc_arg) @injection.content (#set! injection.language "glsl")) - -((comment) @injection.content - (#set! injection.language "comment")) diff --git a/runtime/queries/llvm/injections.scm b/runtime/queries/llvm/injections.scm new file mode 100644 index 00000000..321c90ad --- /dev/null +++ b/runtime/queries/llvm/injections.scm @@ -0,0 +1,2 @@ +((comment) @injection.content + (#set! injection.language "comment")) From f1c634326b83e4c7f9e4a7c8a504e561f602466c Mon Sep 17 00:00:00 2001 From: Gokul Soumya Date: Mon, 20 Dec 2021 08:17:40 +0530 Subject: [PATCH 12/95] Improve rust syntax highlighting (#1295) - Highlight fragment specifiers (expr, tt, in macro definitions) with @type. - Highlight attributes as macros --- runtime/queries/rust/highlights.scm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/runtime/queries/rust/highlights.scm b/runtime/queries/rust/highlights.scm index 539d9550..60dd4644 100644 --- a/runtime/queries/rust/highlights.scm +++ b/runtime/queries/rust/highlights.scm @@ -242,10 +242,9 @@ ; --- ; Macros ; --- - (meta_item - (identifier) @attribute) -(attribute_item) @attribute + (identifier) @function.macro) + (inner_attribute_item) @attribute (macro_definition @@ -259,7 +258,7 @@ "!" @function.macro) (metavariable) @variable.parameter -(fragment_specifier) @variable.parameter +(fragment_specifier) @type From 7438db66ae93c9164fdc29bdf31bd9b8ef861efb Mon Sep 17 00:00:00 2001 From: Sebastian Zivota Date: Mon, 20 Dec 2021 14:37:47 +0100 Subject: [PATCH 13/95] Add dracula theme (#1258) * Add dracula theme * remove unused colors * correctly name constant.character.escape * Change cursors and selections * add some missing ui scopes * sorting --- runtime/themes/dracula.toml | 50 +++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 runtime/themes/dracula.toml diff --git a/runtime/themes/dracula.toml b/runtime/themes/dracula.toml new file mode 100644 index 00000000..956fd0f5 --- /dev/null +++ b/runtime/themes/dracula.toml @@ -0,0 +1,50 @@ +# Author : Sebastian Zivota +"comment" = { fg = "comment" } +"constant" = { fg = "purple" } +"constant.character.escape" = { fg = "pink" } +"function" = { fg = "green" } +"keyword" = { fg = "pink" } +"operator" = { fg = "pink" } +"punctuation" = { fg = "foreground" } +"string" = { fg = "yellow" } +"string.regexp" = { fg = "red" } +"tag" = { fg = "pink" } +"type" = { fg = "cyan", modifiers = ["italic"] } +"type.enum.variant" = { fg = "foreground", modifiers = ["italic"] } +"variable" = { fg = "foreground" } +"variable.builtin" = { fg = "cyan", modifiers = ["italic"] } +"variable.parameter" = { fg ="orange", modifiers = ["italic"] } + +"ui.background" = { fg = "foreground", bg = "background" } +"ui.cursor" = { fg = "background", bg = "orange", modifiers = ["dim"] } +"ui.cursor.match" = { fg = "green", modifiers = ["underlined"] } +"ui.cursor.primary" = { fg = "background", bg = "cyan", modifier = ["dim"] } +"ui.help" = { fg = "foreground", bg = "background_dark" } +"ui.linenr" = { fg = "comment" } +"ui.linenr.selected" = { fg = "foreground" } +"ui.menu" = { fg = "foreground", bg = "background_dark" } +"ui.menu.selected" = { fg = "cyan", bg = "background_dark" } +"ui.popup" = { fg = "foreground" } +"ui.selection" = { fg = "background", bg = "purple", modifiers = ["dim"] } +"ui.selection.primary" = { fg = "background", bg = "pink" } +"ui.statusline" = { fg = "foreground", bg = "background_dark" } +"ui.statusline.inactive" = { fg = "comment", bg = "background_dark" } +"ui.text" = { fg = "foreground" } +"ui.text.focus" = { fg = "cyan" } +"ui.window" = { fg = "foreground" } + +"error" = { fg = "red" } +"warning" = { fg = "cyan" } + +[palette] +background = "#282a36" +background_dark = "#21222c" +foreground = "#f8f8f2" +comment = "#6272a4" +red = "#ff5555" +orange = "#ffb86c" +yellow = "#f1fa8c" +green = "#50fa7b" +purple = "#bd93f9" +cyan = "#8be9fd" +pink = "#ff79c6" From 614e0e00268f3bb5e49fd77e77bc24f20c7fbb48 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Dec 2021 08:46:43 +0900 Subject: [PATCH 14/95] build(deps): bump tokio from 1.14.0 to 1.15.0 (#1321) Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.14.0 to 1.15.0. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.14.0...tokio-1.15.0) --- updated-dependencies: - dependency-name: tokio dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 9 ++++----- helix-lsp/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cd6c0496..cc529a7d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1069,11 +1069,10 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e992e41e0d2fb9f755b37446f20900f64446ef54874f40a60c78f021ac6144" +checksum = "fbbf1c778ec206785635ce8ad57fe52b3009ae9e0c9f574a728f3049d3e55838" dependencies = [ - "autocfg", "bytes", "libc", "memchr", @@ -1089,9 +1088,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9efc1aba077437943f7515666aa2b882dfabfbfdf89c819ea75a8d6e9eaba5e" +checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" dependencies = [ "proc-macro2", "quote", diff --git a/helix-lsp/Cargo.toml b/helix-lsp/Cargo.toml index 5e4619ef..b7fe94ab 100644 --- a/helix-lsp/Cargo.toml +++ b/helix-lsp/Cargo.toml @@ -23,5 +23,5 @@ lsp-types = { version = "0.91", features = ["proposed"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" -tokio = { version = "1.14", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot"] } +tokio = { version = "1.15", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot"] } tokio-stream = "0.1.8" From 65b7acea75dcfc89de8b8775b3c835e1f75a164c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Dec 2021 08:46:59 +0900 Subject: [PATCH 15/95] build(deps): bump num_cpus from 1.13.0 to 1.13.1 (#1320) Bumps [num_cpus](https://github.com/seanmonstar/num_cpus) from 1.13.0 to 1.13.1. - [Release notes](https://github.com/seanmonstar/num_cpus/releases) - [Changelog](https://github.com/seanmonstar/num_cpus/blob/master/CHANGELOG.md) - [Commits](https://github.com/seanmonstar/num_cpus/compare/v1.13.0...v1.13.1) --- updated-dependencies: - dependency-name: num_cpus dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cc529a7d..71ca82fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -690,9 +690,9 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ "hermit-abi", "libc", From 25691061a2b1ca21d16e68502729ac12c09501b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Dec 2021 08:47:39 +0900 Subject: [PATCH 16/95] build(deps): bump futures-util from 0.3.18 to 0.3.19 (#1319) Bumps [futures-util](https://github.com/rust-lang/futures-rs) from 0.3.18 to 0.3.19. - [Release notes](https://github.com/rust-lang/futures-rs/releases) - [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.18...0.3.19) --- updated-dependencies: - dependency-name: futures-util dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 71ca82fd..b02ea08b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -258,9 +258,9 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "629316e42fe7c2a0b9a65b47d159ceaa5453ab14e8f0a3c5eedbb8cd55b4a445" +checksum = "d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7" [[package]] name = "futures-executor" @@ -275,15 +275,15 @@ dependencies = [ [[package]] name = "futures-task" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dabf1872aaab32c886832f2276d2f5399887e2bd613698a02359e4ea83f8de12" +checksum = "6ee7c6485c30167ce4dfb83ac568a849fe53274c831081476ee13e0dce1aad72" [[package]] name = "futures-util" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d22213122356472061ac0f1ab2cee28d2bac8491410fd68c2af53d1cedb83e" +checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164" dependencies = [ "futures-core", "futures-task", From 73f97fbb96b4dd2a851bd3886f5121ad89d00180 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Dec 2021 08:47:56 +0900 Subject: [PATCH 17/95] build(deps): bump futures-executor from 0.3.18 to 0.3.19 (#1317) Bumps [futures-executor](https://github.com/rust-lang/futures-rs) from 0.3.18 to 0.3.19. - [Release notes](https://github.com/rust-lang/futures-rs/releases) - [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.18...0.3.19) --- updated-dependencies: - dependency-name: futures-executor dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b02ea08b..81b0dd6c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -264,9 +264,9 @@ checksum = "d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7" [[package]] name = "futures-executor" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b808bf53348a36cab739d7e04755909b9fcaaa69b7d7e588b37b6ec62704c97" +checksum = "29d6d2ff5bb10fb95c85b8ce46538a2e5f5e7fdc755623a7d4529ab8a4ed9d2a" dependencies = [ "futures-core", "futures-task", From 692ed7500f70958d0f0ab418748beeea8cf054d6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Dec 2021 08:48:13 +0900 Subject: [PATCH 18/95] build(deps): bump actions/upload-artifact from 2.3.0 to 2.3.1 (#1316) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 2.3.0 to 2.3.1. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v2.3.0...v2.3.1) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1ce3e092..7b0b7ee2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -102,7 +102,7 @@ jobs: fi cp -r runtime dist - - uses: actions/upload-artifact@v2.3.0 + - uses: actions/upload-artifact@v2.3.1 with: name: bins-${{ matrix.build }} path: dist From e02c0d1573da7a683cdf8a00b108d851f4709592 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Dec 2021 08:48:33 +0900 Subject: [PATCH 19/95] build(deps): bump signal-hook from 0.3.12 to 0.3.13 (#1318) Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.3.12 to 0.3.13. - [Release notes](https://github.com/vorner/signal-hook/releases) - [Changelog](https://github.com/vorner/signal-hook/blob/master/CHANGELOG.md) - [Commits](https://github.com/vorner/signal-hook/compare/v0.3.12...v0.3.13) --- updated-dependencies: - dependency-name: signal-hook dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 81b0dd6c..70ef6d30 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -919,9 +919,9 @@ dependencies = [ [[package]] name = "signal-hook" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c35dfd12afb7828318348b8c408383cf5071a086c1d4ab1c0f9840ec92dbb922" +checksum = "647c97df271007dcea485bb74ffdb57f2e683f1306c854f468a0c244badabf2d" dependencies = [ "libc", "signal-hook-registry", From 5dfdc95f6f7e4fe1851fd72da7eaee5628a90187 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Dec 2021 08:48:53 +0900 Subject: [PATCH 20/95] build(deps): bump once_cell from 1.8.0 to 1.9.0 (#1322) Bumps [once_cell](https://github.com/matklad/once_cell) from 1.8.0 to 1.9.0. - [Release notes](https://github.com/matklad/once_cell/releases) - [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md) - [Commits](https://github.com/matklad/once_cell/compare/v1.8.0...v1.9.0) --- updated-dependencies: - dependency-name: once_cell dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- helix-core/Cargo.toml | 2 +- helix-term/Cargo.toml | 2 +- helix-view/Cargo.toml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 70ef6d30..fdcf8229 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -700,9 +700,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" [[package]] name = "parking_lot" diff --git a/helix-core/Cargo.toml b/helix-core/Cargo.toml index 0a2a56d9..839b07ac 100644 --- a/helix-core/Cargo.toml +++ b/helix-core/Cargo.toml @@ -23,7 +23,7 @@ unicode-width = "0.1" unicode-general-category = "0.4" # slab = "0.4.2" tree-sitter = "0.20" -once_cell = "1.8" +once_cell = "1.9" arc-swap = "1" regex = "1" diff --git a/helix-term/Cargo.toml b/helix-term/Cargo.toml index 623c5bb9..58c713cb 100644 --- a/helix-term/Cargo.toml +++ b/helix-term/Cargo.toml @@ -27,7 +27,7 @@ helix-view = { version = "0.5", path = "../helix-view" } helix-lsp = { version = "0.5", path = "../helix-lsp" } anyhow = "1" -once_cell = "1.8" +once_cell = "1.9" tokio = { version = "1", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot"] } num_cpus = "1" diff --git a/helix-view/Cargo.toml b/helix-view/Cargo.toml index 34f55eb6..9c3a83f8 100644 --- a/helix-view/Cargo.toml +++ b/helix-view/Cargo.toml @@ -21,7 +21,7 @@ helix-lsp = { version = "0.5", path = "../helix-lsp"} crossterm = { version = "0.22", optional = true } # Conversion traits -once_cell = "1.8" +once_cell = "1.9" url = "2" tokio = { version = "1", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot"] } From f16651b590b7f8679e520407002d6da0f169cac2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Dec 2021 08:49:10 +0900 Subject: [PATCH 21/95] build(deps): bump serde from 1.0.131 to 1.0.132 (#1323) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.131 to 1.0.132. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.131...v1.0.132) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fdcf8229..27268feb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -877,18 +877,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.131" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ad69dfbd3e45369132cc64e6748c2d65cdfb001a2b1c232d128b4ad60561c1" +checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.131" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b710a83c4e0dff6a3d511946b95274ad9ca9e5d3ae497b63fda866ac955358d2" +checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276" dependencies = [ "proc-macro2", "quote", From 205dc8776b6ff4f5ab331df9c33b33e44caab12c Mon Sep 17 00:00:00 2001 From: Sebastian Neubauer Date: Tue, 21 Dec 2021 03:02:53 +0100 Subject: [PATCH 22/95] Add fish highlighting (#1308) The highlights were copied and modified from https://github.com/nvim-treesitter/nvim-treesitter/blob/master/queries/fish/highlights.scm --- .gitmodules | 4 + book/src/generated/lang-support.md | 1 + helix-syntax/languages/tree-sitter-fish | 1 + languages.toml | 11 ++ runtime/queries/fish/highlights.scm | 156 ++++++++++++++++++++++++ runtime/queries/fish/indents.toml | 12 ++ runtime/queries/fish/injections.scm | 2 + runtime/queries/fish/textobjects.scm | 1 + 8 files changed, 188 insertions(+) create mode 160000 helix-syntax/languages/tree-sitter-fish create mode 100644 runtime/queries/fish/highlights.scm create mode 100644 runtime/queries/fish/indents.toml create mode 100644 runtime/queries/fish/injections.scm create mode 100644 runtime/queries/fish/textobjects.scm diff --git a/.gitmodules b/.gitmodules index c7b81336..dcec2813 100644 --- a/.gitmodules +++ b/.gitmodules @@ -162,3 +162,7 @@ path = helix-syntax/languages/tree-sitter-dart url = https://github.com/UserNobody14/tree-sitter-dart.git shallow = true +[submodule "helix-syntax/languages/tree-sitter-fish"] + path = helix-syntax/languages/tree-sitter-fish + url = https://github.com/ram02z/tree-sitter-fish + shallow = true diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index cb91872b..24b75b64 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -9,6 +9,7 @@ | css | ✓ | | | | | dart | ✓ | | ✓ | `dart` | | elixir | ✓ | | | `elixir-ls` | +| fish | ✓ | ✓ | ✓ | | | glsl | ✓ | | ✓ | | | go | ✓ | ✓ | ✓ | `gopls` | | html | ✓ | | | | diff --git a/helix-syntax/languages/tree-sitter-fish b/helix-syntax/languages/tree-sitter-fish new file mode 160000 index 00000000..04e54ab6 --- /dev/null +++ b/helix-syntax/languages/tree-sitter-fish @@ -0,0 +1 @@ +Subproject commit 04e54ab6585dfd4fee6ddfe5849af56f101b6d4f diff --git a/languages.toml b/languages.toml index 0695022e..61eb47ec 100644 --- a/languages.toml +++ b/languages.toml @@ -45,6 +45,17 @@ comment-token = "#" language-server = { command = "elixir-ls" } indent = { tab-width = 2, unit = " " } +[[language]] +name = "fish" +scope = "source.fish" +injection-regex = "fish" +file-types = ["fish"] +shebangs = ["fish"] +roots = [] +comment-token = "#" + +indent = { tab-width = 4, unit = " " } + [[language]] name = "mint" scope = "source.mint" diff --git a/runtime/queries/fish/highlights.scm b/runtime/queries/fish/highlights.scm new file mode 100644 index 00000000..def53931 --- /dev/null +++ b/runtime/queries/fish/highlights.scm @@ -0,0 +1,156 @@ +;; Operators + +[ + "&&" + "||" + "|" + "&" + "=" + "!=" + ".." + "!" + (direction) + (stream_redirect) + (test_option) +] @operator + +[ + "not" + "and" + "or" +] @keyword.operator + +;; Conditionals + +(if_statement +[ + "if" + "end" +] @keyword.control.conditional) + +(switch_statement +[ + "switch" + "end" +] @keyword.control.conditional) + +(case_clause +[ + "case" +] @keyword.control.conditional) + +(else_clause +[ + "else" +] @keyword.control.conditional) + +(else_if_clause +[ + "else" + "if" +] @keyword.control.conditional) + +;; Loops/Blocks + +(while_statement +[ + "while" + "end" +] @keyword.control.repeat) + +(for_statement +[ + "for" + "end" +] @keyword.control.repeat) + +(begin_statement +[ + "begin" + "end" +] @keyword.control.repeat) + +;; Keywords + +[ + "in" + (break) + (continue) +] @keyword + +"return" @keyword.control.return + +;; Punctuation + +[ + "[" + "]" + "{" + "}" + "(" + ")" +] @punctuation.bracket + +"," @punctuation.delimiter + +;; Commands + +(command + argument: [ + (word) @variable.parameter (#match? @variable.parameter "^-") + ] +) + +; non-bultin command names +(command name: (word) @function) + +; derived from builtin -n (fish 3.2.2) +(command + name: [ + (word) @function.builtin + (#match? @function.builtin "^(\.|:|_|alias|argparse|bg|bind|block|breakpoint|builtin|cd|command|commandline|complete|contains|count|disown|echo|emit|eval|exec|exit|fg|functions|history|isatty|jobs|math|printf|pwd|random|read|realpath|set|set_color|source|status|string|test|time|type|ulimit|wait)$") + ] +) + +(test_command "test" @function.builtin) + +;; Functions + +(function_definition ["function" "end"] @keyword.function) + +(function_definition + name: [ + (word) (concatenation) + ] +@function) + +(function_definition + option: [ + (word) + (concatenation (word)) + ] @variable.parameter (#match? @variable.parameter "^-") +) + +;; Strings + +[(double_quote_string) (single_quote_string)] @string +(escape_sequence) @constant.character.escape + +;; Variables + +(variable_name) @variable +(variable_expansion) @constant + +;; Nodes + +(integer) @constant.numeric.integer +(float) @constant.numeric.float +(comment) @comment +(test_option) @string + +((word) @constant.builtin.boolean +(#match? @constant.builtin.boolean "^(true|false)$")) + +;; Error + +(ERROR) @error diff --git a/runtime/queries/fish/indents.toml b/runtime/queries/fish/indents.toml new file mode 100644 index 00000000..6f1e563a --- /dev/null +++ b/runtime/queries/fish/indents.toml @@ -0,0 +1,12 @@ +indent = [ + "function_definition", + "while_statement", + "for_statement", + "if_statement", + "begin_statement", + "switch_statement", +] + +outdent = [ + "end" +] diff --git a/runtime/queries/fish/injections.scm b/runtime/queries/fish/injections.scm new file mode 100644 index 00000000..321c90ad --- /dev/null +++ b/runtime/queries/fish/injections.scm @@ -0,0 +1,2 @@ +((comment) @injection.content + (#set! injection.language "comment")) diff --git a/runtime/queries/fish/textobjects.scm b/runtime/queries/fish/textobjects.scm new file mode 100644 index 00000000..67fd6614 --- /dev/null +++ b/runtime/queries/fish/textobjects.scm @@ -0,0 +1 @@ +(function_definition) @function.around From 176fbe760a56945089de9f77e06f05f1639ba9be Mon Sep 17 00:00:00 2001 From: Gokul Soumya Date: Tue, 21 Dec 2021 07:33:44 +0530 Subject: [PATCH 23/95] docs: Add note about tree-sitter query precedence (#1314) --- book/src/guides/adding_languages.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/book/src/guides/adding_languages.md b/book/src/guides/adding_languages.md index 9ad2c285..987ad088 100644 --- a/book/src/guides/adding_languages.md +++ b/book/src/guides/adding_languages.md @@ -42,7 +42,16 @@ These are the available keys and descriptions for the file. ## Queries -For a language to have syntax-highlighting and indentation among other things, you have to add queries. Add a directory for your language with the path `runtime/queries//`. The tree-sitter [website](https://tree-sitter.github.io/tree-sitter/syntax-highlighting#queries) gives more info on how to write queries. +For a language to have syntax-highlighting and indentation among +other things, you have to add queries. Add a directory for your +language with the path `runtime/queries//`. The tree-sitter +[website](https://tree-sitter.github.io/tree-sitter/syntax-highlighting#queries) +gives more info on how to write queries. + +> NOTE: When evaluating queries, the first matching query takes +precedence, which is different from other editors like neovim where +the last matching query supercedes the ones before it. See +[this issue][neovim-query-precedence] for an example. ## Common Issues @@ -58,3 +67,4 @@ For a language to have syntax-highlighting and indentation among other things, y [treesitter-language-injection]: https://tree-sitter.github.io/tree-sitter/syntax-highlighting#language-injection [languages.toml]: https://github.com/helix-editor/helix/blob/master/languages.toml +[neovim-query-precedence]: https://github.com/helix-editor/helix/pull/1170#issuecomment-997294090 From 1c082cb4efa520608a581359365ac80c283362ab Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Tue, 21 Dec 2021 11:38:32 +0800 Subject: [PATCH 24/95] Add README for helix-syntax (#1312) --- helix-syntax/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 helix-syntax/README.md diff --git a/helix-syntax/README.md b/helix-syntax/README.md new file mode 100644 index 00000000..bba2197a --- /dev/null +++ b/helix-syntax/README.md @@ -0,0 +1,13 @@ +helix-syntax +============ + +Syntax highlighting for helix, (shallow) submodules resides here. + +Differences from nvim-treesitter +-------------------------------- + +As the syntax are commonly ported from +. + +Note that we do not support the custom `#any-of` predicate which is +supported by neovim so one needs to change it to `#match` with regex. From 5b4540fc2d8201f4bfe336cc10c1096059217225 Mon Sep 17 00:00:00 2001 From: Skyler Hawthorne Date: Tue, 21 Dec 2021 04:17:33 -0500 Subject: [PATCH 25/95] Auto pairs selection (#1254) * use auto pairs with selections Previously, the auto pairs code was converting the user selection into its cursor form, and setting the transaction's selection to that cursor. This has the effect of destroying the user's selection if they type a pair character that gets auto completed. This fixes the code to work with the user's selection, inserting auto pairs where appropriate, but either keeping or extending the user's selection. * use movement::Direction instead of bool * assume 0-width cursor is forward --- helix-core/src/auto_pairs.rs | 335 ++++++++++++++++++++++++++--------- helix-core/src/selection.rs | 20 +++ 2 files changed, 275 insertions(+), 80 deletions(-) diff --git a/helix-core/src/auto_pairs.rs b/helix-core/src/auto_pairs.rs index c037afef..1b3de6ea 100644 --- a/helix-core/src/auto_pairs.rs +++ b/helix-core/src/auto_pairs.rs @@ -1,7 +1,7 @@ //! When typing the opening character of one of the possible pairs defined below, //! this module provides the functionality to insert the paired closing character. -use crate::{Range, Rope, Selection, Tendril, Transaction}; +use crate::{movement::Direction, Range, Rope, Selection, Tendril, Transaction}; use log::debug; use smallvec::SmallVec; @@ -30,7 +30,6 @@ const CLOSE_BEFORE: &str = ")]}'\":;,> \n\r\u{000B}\u{000C}\u{0085}\u{2028}\u{20 // [TODO] // * delete implementation where it erases the whole bracket (|) -> | -// * do not reduce to cursors; use whole selections, and surround with pair // * change to multi character pairs to handle cases like placing the cursor in the // middle of triple quotes, and more exotic pairs like Jinja's {% %} @@ -38,20 +37,18 @@ const CLOSE_BEFORE: &str = ")]}'\":;,> \n\r\u{000B}\u{000C}\u{0085}\u{2028}\u{20 pub fn hook(doc: &Rope, selection: &Selection, ch: char) -> Option { debug!("autopairs hook selection: {:#?}", selection); - let cursors = selection.clone().cursors(doc.slice(..)); - for &(open, close) in PAIRS { if open == ch { if open == close { - return Some(handle_same(doc, &cursors, open, CLOSE_BEFORE, OPEN_BEFORE)); + return Some(handle_same(doc, selection, open, CLOSE_BEFORE, OPEN_BEFORE)); } else { - return Some(handle_open(doc, &cursors, open, close, CLOSE_BEFORE)); + return Some(handle_open(doc, selection, open, close, CLOSE_BEFORE)); } } if close == ch { // && char_at pos == close - return Some(handle_close(doc, &cursors, open, close)); + return Some(handle_close(doc, selection, open, close)); } } @@ -66,6 +63,36 @@ fn prev_char(doc: &Rope, pos: usize) -> Option { doc.get_char(pos - 1) } +/// calculate what the resulting range should be for an auto pair insertion +fn get_next_range( + start_range: &Range, + offset: usize, + typed_char: char, + len_inserted: usize, +) -> Range { + let end_head = start_range.head + offset + typed_char.len_utf8(); + + let end_anchor = match (start_range.len(), start_range.direction()) { + // if we have a zero width cursor, it shifts to the same number + (0, _) => end_head, + + // if we are inserting for a regular one-width cursor, the anchor + // moves with the head + (1, Direction::Forward) => end_head - 1, + (1, Direction::Backward) => end_head + 1, + + // if we are appending, the anchor stays where it is; only offset + // for multiple range insertions + (_, Direction::Forward) => start_range.anchor + offset, + + // when we are inserting in front of a selection, we need to move + // the anchor over by however many characters were inserted overall + (_, Direction::Backward) => start_range.anchor + offset + len_inserted, + }; + + Range::new(end_anchor, end_head) +} + fn handle_open( doc: &Rope, selection: &Selection, @@ -74,36 +101,32 @@ fn handle_open( close_before: &str, ) -> Transaction { let mut end_ranges = SmallVec::with_capacity(selection.len()); - let mut offs = 0; let transaction = Transaction::change_by_selection(doc, selection, |start_range| { - let start_head = start_range.head; - - let next = doc.get_char(start_head); - let end_head = start_head + offs + open.len_utf8(); - - let end_anchor = if start_range.is_empty() { - end_head - } else { - start_range.anchor + offs - }; - - end_ranges.push(Range::new(end_anchor, end_head)); + let cursor = start_range.cursor(doc.slice(..)); + let next_char = doc.get_char(cursor); + let len_inserted; - match next { + let change = match next_char { Some(ch) if !close_before.contains(ch) => { - offs += open.len_utf8(); - (start_head, start_head, Some(Tendril::from_char(open))) + len_inserted = open.len_utf8(); + (cursor, cursor, Some(Tendril::from_char(open))) } // None | Some(ch) if close_before.contains(ch) => {} _ => { // insert open & close let pair = Tendril::from_iter([open, close]); - offs += open.len_utf8() + close.len_utf8(); - (start_head, start_head, Some(pair)) + len_inserted = open.len_utf8() + close.len_utf8(); + (cursor, cursor, Some(pair)) } - } + }; + + let next_range = get_next_range(start_range, offs, open, len_inserted); + end_ranges.push(next_range); + offs += len_inserted; + + change }); let t = transaction.with_selection(Selection::new(end_ranges, selection.primary_index())); @@ -117,28 +140,28 @@ fn handle_close(doc: &Rope, selection: &Selection, _open: char, close: char) -> let mut offs = 0; let transaction = Transaction::change_by_selection(doc, selection, |start_range| { - let start_head = start_range.head; - let next = doc.get_char(start_head); - let end_head = start_head + offs + close.len_utf8(); + let cursor = start_range.cursor(doc.slice(..)); + let next_char = doc.get_char(cursor); + let mut len_inserted = 0; - let end_anchor = if start_range.is_empty() { - end_head + let change = if next_char == Some(close) { + // return transaction that moves past close + (cursor, cursor, None) // no-op } else { - start_range.anchor + offs + len_inserted += close.len_utf8(); + (cursor, cursor, Some(Tendril::from_char(close))) }; - end_ranges.push(Range::new(end_anchor, end_head)); + let next_range = get_next_range(start_range, offs, close, len_inserted); + end_ranges.push(next_range); + offs += len_inserted; - if next == Some(close) { - // return transaction that moves past close - (start_head, start_head, None) // no-op - } else { - offs += close.len_utf8(); - (start_head, start_head, Some(Tendril::from_char(close))) - } + change }); - transaction.with_selection(Selection::new(end_ranges, selection.primary_index())) + let t = transaction.with_selection(Selection::new(end_ranges, selection.primary_index())); + debug!("auto pair transaction: {:#?}", t); + t } /// handle cases where open and close is the same, or in triples ("""docstring""") @@ -154,42 +177,41 @@ fn handle_same( let mut offs = 0; let transaction = Transaction::change_by_selection(doc, selection, |start_range| { - let start_head = start_range.head; - let end_head = start_head + offs + token.len_utf8(); + let cursor = start_range.cursor(doc.slice(..)); + let mut len_inserted = 0; - // if selection, retain anchor, if cursor, move over - let end_anchor = if start_range.is_empty() { - end_head - } else { - start_range.anchor + offs - }; + let next_char = doc.get_char(cursor); + let prev_char = prev_char(doc, cursor); - end_ranges.push(Range::new(end_anchor, end_head)); - - let next = doc.get_char(start_head); - let prev = prev_char(doc, start_head); - - if next == Some(token) { + let change = if next_char == Some(token) { // return transaction that moves past close - (start_head, start_head, None) // no-op + (cursor, cursor, None) // no-op } else { let mut pair = Tendril::with_capacity(2 * token.len_utf8() as u32); pair.push_char(token); // for equal pairs, don't insert both open and close if either // side has a non-pair char - if (next.is_none() || close_before.contains(next.unwrap())) - && (prev.is_none() || open_before.contains(prev.unwrap())) + if (next_char.is_none() || close_before.contains(next_char.unwrap())) + && (prev_char.is_none() || open_before.contains(prev_char.unwrap())) { pair.push_char(token); } - offs += pair.len(); - (start_head, start_head, Some(pair)) - } + len_inserted += pair.len(); + (cursor, cursor, Some(pair)) + }; + + let next_range = get_next_range(start_range, offs, token, len_inserted); + end_ranges.push(next_range); + offs += len_inserted; + + change }); - transaction.with_selection(Selection::new(end_ranges, selection.primary_index())) + let t = transaction.with_selection(Selection::new(end_ranges, selection.primary_index())); + debug!("auto pair transaction: {:#?}", t); + t } #[cfg(test)] @@ -252,7 +274,20 @@ mod test { &Selection::single(1, 0), PAIRS, |open, close| format!("{}{}", open, close), - &Selection::single(1, 1), + &Selection::single(2, 1), + ); + } + + /// [] -> append ( -> ([]) + #[test] + fn test_append_blank() { + test_hooks_with_pairs( + // this is what happens when you have a totally blank document and then append + &Rope::from("\n\n"), + &Selection::single(0, 2), + PAIRS, + |open, close| format!("\n{}{}\n", open, close), + &Selection::single(0, 3), ); } @@ -276,26 +311,50 @@ mod test { ) }, &Selection::new( - smallvec!(Range::point(1), Range::point(4), Range::point(7),), + smallvec!(Range::new(2, 1), Range::new(5, 4), Range::new(8, 7),), 0, ), ); } - // [TODO] broken until it works with selections /// fo[o] -> append ( -> fo[o(]) - #[ignore] #[test] fn test_append() { test_hooks_with_pairs( - &Rope::from("foo"), + &Rope::from("foo\n"), &Selection::single(2, 4), - PAIRS, - |open, close| format!("foo{}{}", open, close), + differing_pairs(), + |open, close| format!("foo{}{}\n", open, close), &Selection::single(2, 5), ); } + /// fo[o] fo[o(]) + /// fo[o] -> append ( -> fo[o(]) + /// fo[o] fo[o(]) + #[test] + fn test_append_multi() { + test_hooks_with_pairs( + &Rope::from("foo\nfoo\nfoo\n"), + &Selection::new( + smallvec!(Range::new(2, 4), Range::new(6, 8), Range::new(10, 12)), + 0, + ), + differing_pairs(), + |open, close| { + format!( + "foo{open}{close}\nfoo{open}{close}\nfoo{open}{close}\n", + open = open, + close = close + ) + }, + &Selection::new( + smallvec!(Range::new(2, 5), Range::new(8, 11), Range::new(14, 17)), + 0, + ), + ); + } + /// ([]) -> insert ) -> ()[] #[test] fn test_insert_close_inside_pair() { @@ -307,7 +366,23 @@ mod test { &Selection::single(2, 1), *close, &doc, - &Selection::point(2), + &Selection::single(3, 2), + ); + } + } + + /// [(]) -> append ) -> [()] + #[test] + fn test_append_close_inside_pair() { + for (open, close) in PAIRS { + let doc = Rope::from(format!("{}{}\n", open, close)); + + test_hooks( + &doc, + &Selection::single(0, 2), + *close, + &doc, + &Selection::single(0, 3), ); } } @@ -323,8 +398,33 @@ mod test { ); let expected_sel = Selection::new( - // smallvec!(Range::new(3, 2), Range::new(6, 5), Range::new(9, 8),), - smallvec!(Range::point(2), Range::point(5), Range::point(8),), + smallvec!(Range::new(3, 2), Range::new(6, 5), Range::new(9, 8),), + 0, + ); + + for (open, close) in PAIRS { + let doc = Rope::from(format!( + "{open}{close}\n{open}{close}\n{open}{close}\n", + open = open, + close = close + )); + + test_hooks(&doc, &sel, *close, &doc, &expected_sel); + } + } + + /// [(]) [()] + /// [(]) -> append ) -> [()] + /// [(]) [()] + #[test] + fn test_append_close_inside_pair_multi_cursor() { + let sel = Selection::new( + smallvec!(Range::new(0, 2), Range::new(3, 5), Range::new(6, 8),), + 0, + ); + + let expected_sel = Selection::new( + smallvec!(Range::new(0, 3), Range::new(3, 6), Range::new(6, 9),), 0, ); @@ -343,7 +443,7 @@ mod test { #[test] fn test_insert_open_inside_pair() { let sel = Selection::single(2, 1); - let expected_sel = Selection::point(2); + let expected_sel = Selection::single(3, 2); for (open, close) in differing_pairs() { let doc = Rope::from(format!("{}{}", open, close)); @@ -357,11 +457,49 @@ mod test { } } + /// [word(]) -> append ( -> [word((])) + #[test] + fn test_append_open_inside_pair() { + let sel = Selection::single(0, 6); + let expected_sel = Selection::single(0, 7); + + for (open, close) in differing_pairs() { + let doc = Rope::from(format!("word{}{}", open, close)); + let expected_doc = Rope::from(format!( + "word{open}{open}{close}{close}", + open = open, + close = close + )); + + test_hooks(&doc, &sel, *open, &expected_doc, &expected_sel); + } + } + /// ([]) -> insert " -> ("[]") #[test] fn test_insert_nested_open_inside_pair() { let sel = Selection::single(2, 1); - let expected_sel = Selection::point(2); + let expected_sel = Selection::single(3, 2); + + for (outer_open, outer_close) in differing_pairs() { + let doc = Rope::from(format!("{}{}", outer_open, outer_close,)); + + for (inner_open, inner_close) in matching_pairs() { + let expected_doc = Rope::from(format!( + "{}{}{}{}", + outer_open, inner_open, inner_close, outer_close + )); + + test_hooks(&doc, &sel, *inner_open, &expected_doc, &expected_sel); + } + } + } + + /// [(]) -> append " -> [("]") + #[test] + fn test_append_nested_open_inside_pair() { + let sel = Selection::single(0, 2); + let expected_sel = Selection::single(0, 3); for (outer_open, outer_close) in differing_pairs() { let doc = Rope::from(format!("{}{}", outer_open, outer_close,)); @@ -385,21 +523,44 @@ mod test { &Selection::single(1, 0), PAIRS, |open, _| format!("{}word", open), - &Selection::point(1), + &Selection::single(2, 1), ) } - // [TODO] broken until it works with selections /// [wor]d -> insert ( -> ([wor]d #[test] - #[ignore] fn test_insert_open_with_selection() { test_hooks_with_pairs( &Rope::from("word"), - &Selection::single(0, 4), + &Selection::single(3, 0), PAIRS, |open, _| format!("{}word", open), - &Selection::single(1, 5), + &Selection::single(4, 1), + ) + } + + /// [wor]d -> append ) -> [wor)]d + #[test] + fn test_append_close_inside_non_pair_with_selection() { + let sel = Selection::single(0, 4); + let expected_sel = Selection::single(0, 5); + + for (_, close) in PAIRS { + let doc = Rope::from("word"); + let expected_doc = Rope::from(format!("wor{}d", close)); + test_hooks(&doc, &sel, *close, &expected_doc, &expected_sel); + } + } + + /// foo[ wor]d -> insert ( -> foo([) wor]d + #[test] + fn test_insert_open_trailing_word_with_selection() { + test_hooks_with_pairs( + &Rope::from("foo word"), + &Selection::single(7, 3), + differing_pairs(), + |open, close| format!("foo{}{} word", open, close), + &Selection::single(9, 4), ) } @@ -413,7 +574,7 @@ mod test { fn test_insert_open_after_non_pair() { let doc = Rope::from("word"); let sel = Selection::single(5, 4); - let expected_sel = Selection::point(5); + let expected_sel = Selection::single(6, 5); test_hooks_with_pairs( &doc, @@ -431,4 +592,18 @@ mod test { &expected_sel, ); } + + /// appending with only a cursor should stay a cursor + /// + /// [] -> append to end "foo -> "foo[]" + #[test] + fn test_append_single_cursor() { + test_hooks_with_pairs( + &Rope::from("\n"), + &Selection::single(0, 1), + PAIRS, + |open, close| format!("{}{}\n", open, close), + &Selection::single(1, 2), + ); + } } diff --git a/helix-core/src/selection.rs b/helix-core/src/selection.rs index 116a1c7c..884c98ac 100644 --- a/helix-core/src/selection.rs +++ b/helix-core/src/selection.rs @@ -7,6 +7,7 @@ use crate::{ ensure_grapheme_boundary_next, ensure_grapheme_boundary_prev, next_grapheme_boundary, prev_grapheme_boundary, }, + movement::Direction, Assoc, ChangeSet, RopeSlice, }; use smallvec::{smallvec, SmallVec}; @@ -82,6 +83,13 @@ impl Range { std::cmp::max(self.anchor, self.head) } + /// Total length of the range. + #[inline] + #[must_use] + pub fn len(&self) -> usize { + self.to() - self.from() + } + /// The (inclusive) range of lines that the range overlaps. #[inline] #[must_use] @@ -102,6 +110,18 @@ impl Range { self.anchor == self.head } + /// `Direction::Backward` when head < anchor. + /// `Direction::Backward` otherwise. + #[inline] + #[must_use] + pub fn direction(&self) -> Direction { + if self.head < self.anchor { + Direction::Backward + } else { + Direction::Forward + } + } + /// Check two ranges for overlap. #[must_use] pub fn overlaps(&self, other: &Self) -> bool { From 600ce70cf6d50ce37b96bfde90c6ade8db6cd8c3 Mon Sep 17 00:00:00 2001 From: WindSoilder Date: Tue, 21 Dec 2021 17:17:55 +0800 Subject: [PATCH 26/95] Improve dedent behavior (#1232) * tmp add code for dedent * finish normal_mode with dedent behavior * use function pointer * rebase from origin * check dedent condition inside normal_mode implementation * using if let... * fix check * using char_is_whitespace instead of ch.is_whitespace * fix clippy * abstract restore_indent function --- helix-term/src/commands.rs | 31 +++++++++++++++++++++++++++++++ helix-view/src/document.rs | 4 ++++ 2 files changed, 35 insertions(+) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 28f955eb..297b49a1 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -3610,6 +3610,7 @@ fn normal_mode(cx: &mut Context) { doc.mode = Mode::Normal; + try_restore_indent(doc, view.id); doc.append_changes_to_history(view.id); // if leaving append mode, move cursor back by 1 @@ -3627,6 +3628,36 @@ fn normal_mode(cx: &mut Context) { } } +fn try_restore_indent(doc: &mut Document, view_id: ViewId) { + let doc_changes = doc.changes().changes(); + let text = doc.text().slice(..); + let pos = doc.selection(view_id).primary().cursor(text); + let mut can_restore_indent = false; + + // Removes trailing whitespace if insert mode is exited after starting a blank new line. + use helix_core::chars::char_is_whitespace; + use helix_core::Operation; + if let [Operation::Retain(move_pos), Operation::Insert(ref inserted_str), Operation::Retain(_)] = + doc_changes + { + if move_pos + inserted_str.len32() as usize == pos + && inserted_str.starts_with('\n') + && inserted_str.chars().skip(1).all(char_is_whitespace) + { + can_restore_indent = true; + } + } + + if can_restore_indent { + let transaction = + Transaction::change_by_selection(doc.text(), doc.selection(view_id), |range| { + let line_start_pos = text.line_to_char(range.cursor_line(text)); + (line_start_pos, pos, None) + }); + doc.apply(&transaction, view_id); + } +} + // Store a jump on the jumplist. fn push_jump(editor: &mut Editor) { let (view, doc) = current!(editor); diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index 2cb33fe3..c71d1850 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -889,6 +889,10 @@ impl Document { self.indent_style.as_str() } + pub fn changes(&self) -> &ChangeSet { + &self.changes + } + #[inline] /// File path on disk. pub fn path(&self) -> Option<&PathBuf> { From 75a8b789d20edf8b2e1d3da75497a9936953de68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Dzivjak?= Date: Tue, 21 Dec 2021 10:21:45 +0100 Subject: [PATCH 27/95] LSP code action commands (#1304) * feat(lsp): codeAction commands * Don't block on command call * Fix lifetime of command execution * Fix lint issues --- helix-lsp/src/client.rs | 14 +++++++++- helix-lsp/src/lib.rs | 7 +++++ helix-term/src/application.rs | 48 ++++++++++++++++++++++++++++------- helix-term/src/commands.rs | 33 +++++++++++++++++++++--- 4 files changed, 89 insertions(+), 13 deletions(-) diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs index 271fd9d5..f1de8752 100644 --- a/helix-lsp/src/client.rs +++ b/helix-lsp/src/client.rs @@ -202,7 +202,7 @@ impl Client { Ok(result) => Output::Success(Success { jsonrpc: Some(Version::V2), id, - result, + result: serde_json::to_value(result)?, }), Err(error) => Output::Failure(Failure { jsonrpc: Some(Version::V2), @@ -800,4 +800,16 @@ impl Client { let response = self.request::(params).await?; Ok(response.unwrap_or_default()) } + + pub fn command(&self, command: lsp::Command) -> impl Future> { + let params = lsp::ExecuteCommandParams { + command: command.command, + arguments: command.arguments.unwrap_or_default(), + work_done_progress_params: lsp::WorkDoneProgressParams { + work_done_token: None, + }, + }; + + self.call::(params) + } } diff --git a/helix-lsp/src/lib.rs b/helix-lsp/src/lib.rs index 15cae582..8fb321bc 100644 --- a/helix-lsp/src/lib.rs +++ b/helix-lsp/src/lib.rs @@ -203,6 +203,7 @@ pub mod util { #[derive(Debug, PartialEq, Clone)] pub enum MethodCall { WorkDoneProgressCreate(lsp::WorkDoneProgressCreateParams), + ApplyWorkspaceEdit(lsp::ApplyWorkspaceEditParams), } impl MethodCall { @@ -215,6 +216,12 @@ impl MethodCall { .expect("Failed to parse WorkDoneCreate params"); Self::WorkDoneProgressCreate(params) } + lsp::request::ApplyWorkspaceEdit::METHOD => { + let params: lsp::ApplyWorkspaceEditParams = params + .parse() + .expect("Failed to parse ApplyWorkspaceEdit params"); + Self::ApplyWorkspaceEdit(params) + } _ => { log::warn!("unhandled lsp request: {}", method); return None; diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index 3e0b6d59..9a46a7fe 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -1,8 +1,12 @@ use helix_core::{merge_toml_values, syntax}; use helix_lsp::{lsp, util::lsp_pos_to_pos, LspProgressMap}; use helix_view::{theme, Editor}; +use serde_json::json; -use crate::{args::Args, compositor::Compositor, config::Config, job::Jobs, ui}; +use crate::{ + args::Args, commands::apply_workspace_edit, compositor::Compositor, config::Config, job::Jobs, + ui, +}; use log::{error, warn}; @@ -530,14 +534,6 @@ impl Application { Call::MethodCall(helix_lsp::jsonrpc::MethodCall { method, params, id, .. }) => { - let language_server = match self.editor.language_servers.get_by_id(server_id) { - Some(language_server) => language_server, - None => { - warn!("can't find language server with id `{}`", server_id); - return; - } - }; - let call = match MethodCall::parse(&method, params) { Some(call) => call, None => { @@ -567,8 +563,42 @@ impl Application { if spinner.is_stopped() { spinner.start(); } + let language_server = + match self.editor.language_servers.get_by_id(server_id) { + Some(language_server) => language_server, + None => { + warn!("can't find language server with id `{}`", server_id); + return; + } + }; + tokio::spawn(language_server.reply(id, Ok(serde_json::Value::Null))); } + MethodCall::ApplyWorkspaceEdit(params) => { + apply_workspace_edit( + &mut self.editor, + helix_lsp::OffsetEncoding::Utf8, + ¶ms.edit, + ); + + let language_server = + match self.editor.language_servers.get_by_id(server_id) { + Some(language_server) => language_server, + None => { + warn!("can't find language server with id `{}`", server_id); + return; + } + }; + + tokio::spawn(language_server.reply( + id, + Ok(json!(lsp::ApplyWorkspaceEditResponse { + applied: true, + failure_reason: None, + failed_change: None, + })), + )); + } } } e => unreachable!("{:?}", e), diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 297b49a1..ee6a5989 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -3277,12 +3277,19 @@ pub fn code_action(cx: &mut Context) { move |editor, code_action, _action| match code_action { lsp::CodeActionOrCommand::Command(command) => { log::debug!("code action command: {:?}", command); - editor.set_error(String::from("Handling code action command is not implemented yet, see https://github.com/helix-editor/helix/issues/183")); + execute_lsp_command(editor, command.clone()); } lsp::CodeActionOrCommand::CodeAction(code_action) => { log::debug!("code action: {:?}", code_action); if let Some(ref workspace_edit) = code_action.edit { - apply_workspace_edit(editor, offset_encoding, workspace_edit) + log::debug!("edit: {:?}", workspace_edit); + apply_workspace_edit(editor, offset_encoding, workspace_edit); + } + + // if code action provides both edit and command first the edit + // should be applied and then the command + if let Some(command) = &code_action.command { + execute_lsp_command(editor, command.clone()); } } }, @@ -3293,6 +3300,26 @@ pub fn code_action(cx: &mut Context) { ) } +pub fn execute_lsp_command(editor: &mut Editor, cmd: lsp::Command) { + let (_view, doc) = current!(editor); + + let language_server = match doc.language_server() { + Some(language_server) => language_server, + None => return, + }; + + // the command is executed on the server and communicated back + // to the client asynchronously using workspace edits + let command_future = language_server.command(cmd); + tokio::spawn(async move { + let res = command_future.await; + + if let Err(e) = res { + log::error!("execute LSP command: {}", e); + } + }); +} + pub fn apply_document_resource_op(op: &lsp::ResourceOp) -> std::io::Result<()> { use lsp::ResourceOp; use std::fs; @@ -3346,7 +3373,7 @@ pub fn apply_document_resource_op(op: &lsp::ResourceOp) -> std::io::Result<()> { } } -fn apply_workspace_edit( +pub fn apply_workspace_edit( editor: &mut Editor, offset_encoding: OffsetEncoding, workspace_edit: &lsp::WorkspaceEdit, From dba22c60ed7fc336ad619b1246333f0116b47bcd Mon Sep 17 00:00:00 2001 From: Midnight Exigent <36641328+midnightexigent@users.noreply.github.com> Date: Tue, 21 Dec 2021 10:22:15 +0100 Subject: [PATCH 28/95] Support dockerfiles (#1303) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * allow language.config (in languages.toml) to be passed in as a toml object * Change config field for languages from json string to toml object * remove indents on languages.toml config * fix: remove patch version from serde_json import in helix-core * Use same tree-sitter-zig as upstream/master * fix(completion_popup): Fixes #1256 * Update helix-term/src/ui/completion.rs * feat(languages): Add support for `Dockerfile`s * docs(cargo-xtask-docgen): * improvement(langs-dockerfile): Add `injection-regex` to `languages.toml` for `Dockerfile` * improvement(langs-dockerfile): Add injections.scm * Update .gitmodules Co-authored-by: Blaž Hrastnik --- .gitmodules | 4 ++ book/src/generated/lang-support.md | 1 + helix-syntax/languages/tree-sitter-dockerfile | 1 + languages.toml | 11 ++++ runtime/queries/dockerfile/highlights.scm | 51 +++++++++++++++++++ runtime/queries/dockerfile/injections.scm | 6 +++ 6 files changed, 74 insertions(+) create mode 160000 helix-syntax/languages/tree-sitter-dockerfile create mode 100644 runtime/queries/dockerfile/highlights.scm create mode 100644 runtime/queries/dockerfile/injections.scm diff --git a/.gitmodules b/.gitmodules index dcec2813..edfe3c39 100644 --- a/.gitmodules +++ b/.gitmodules @@ -162,6 +162,10 @@ path = helix-syntax/languages/tree-sitter-dart url = https://github.com/UserNobody14/tree-sitter-dart.git shallow = true +[submodule "helix-syntax/languages/tree-sitter-dockerfile"] + path = helix-syntax/languages/tree-sitter-dockerfile + url = https://github.com/camdencheek/tree-sitter-dockerfile.git + shallow = true [submodule "helix-syntax/languages/tree-sitter-fish"] path = helix-syntax/languages/tree-sitter-fish url = https://github.com/ram02z/tree-sitter-fish diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 24b75b64..c7054201 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -8,6 +8,7 @@ | cpp | ✓ | | | `clangd` | | css | ✓ | | | | | dart | ✓ | | ✓ | `dart` | +| dockerfile | ✓ | | | `docker-langserver` | | elixir | ✓ | | | `elixir-ls` | | fish | ✓ | ✓ | ✓ | | | glsl | ✓ | | ✓ | | diff --git a/helix-syntax/languages/tree-sitter-dockerfile b/helix-syntax/languages/tree-sitter-dockerfile new file mode 160000 index 00000000..7af32bc0 --- /dev/null +++ b/helix-syntax/languages/tree-sitter-dockerfile @@ -0,0 +1 @@ +Subproject commit 7af32bc04a66ab196f5b9f92ac471f29372ae2ce diff --git a/languages.toml b/languages.toml index 61eb47ec..50c6f7f9 100644 --- a/languages.toml +++ b/languages.toml @@ -467,3 +467,14 @@ file-types = ["scala", "sbt"] comment-token = "//" indent = { tab-width = 2, unit = " " } language-server = { command = "metals" } + +[[language]] +name = "dockerfile" +scope = "source.dockerfile" +injection-regex = "docker|dockerfile" +roots = ["Dockerfile"] +file-types = ["Dockerfile"] +comment-token = "#" +indent = { tab-width = 2, unit = " " } +language-server = { command = "docker-langserver", args = ["--stdio"] } + diff --git a/runtime/queries/dockerfile/highlights.scm b/runtime/queries/dockerfile/highlights.scm new file mode 100644 index 00000000..5a945fb9 --- /dev/null +++ b/runtime/queries/dockerfile/highlights.scm @@ -0,0 +1,51 @@ +[ + "FROM" + "AS" + "RUN" + "CMD" + "LABEL" + "EXPOSE" + "ENV" + "ADD" + "COPY" + "ENTRYPOINT" + "VOLUME" + "USER" + "WORKDIR" + "ARG" + "ONBUILD" + "STOPSIGNAL" + "HEALTHCHECK" + "SHELL" + "MAINTAINER" + "CROSS_BUILD" +] @keyword + +[ + ":" + "@" +] @operator + +(comment) @comment + + +(image_spec + (image_tag + ":" @punctuation.special) + (image_digest + "@" @punctuation.special)) + +(double_quoted_string) @string + +(expansion + [ + "$" + "{" + "}" + ] @punctuation.special +) @none + +((variable) @constant + (#match? @constant "^[A-Z][A-Z_0-9]*$")) + + diff --git a/runtime/queries/dockerfile/injections.scm b/runtime/queries/dockerfile/injections.scm new file mode 100644 index 00000000..20396f1a --- /dev/null +++ b/runtime/queries/dockerfile/injections.scm @@ -0,0 +1,6 @@ +((comment) @injection.content + (#set! injection.language "comment")) + +([(shell_command) (shell_fragment)] @injection.content + (#set! injection.language "bash")) + From 34766e242ab0a059c8313b068b98d275e2a879b8 Mon Sep 17 00:00:00 2001 From: Dylan Richardson Date: Tue, 21 Dec 2021 18:45:02 -0600 Subject: [PATCH 29/95] languages: add .dockerfile extension (#1330) Many folks use `.dockerfile` as an extension for dockerfiles in addition to plain `Dockerfile`. This change associates both file extensions with dockerfile syntax highlighting --- languages.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages.toml b/languages.toml index 50c6f7f9..54fa63ee 100644 --- a/languages.toml +++ b/languages.toml @@ -473,7 +473,7 @@ name = "dockerfile" scope = "source.dockerfile" injection-regex = "docker|dockerfile" roots = ["Dockerfile"] -file-types = ["Dockerfile"] +file-types = ["Dockerfile", "dockerfile"] comment-token = "#" indent = { tab-width = 2, unit = " " } language-server = { command = "docker-langserver", args = ["--stdio"] } From a8618cf1119afe439916b775f0dd5710fdb5082f Mon Sep 17 00:00:00 2001 From: Gokul Soumya Date: Thu, 23 Dec 2021 08:40:24 +0530 Subject: [PATCH 30/95] Add precise rust queries for use, mod, as (#1339) - Differentiates between `as` keyword as a binary type cast operator and import renamer. - `mod` and `use` are now under `@keyword.control.import`, but `mod` is a `@keyword` if used as `mod name;`. --- runtime/queries/rust/highlights.scm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/runtime/queries/rust/highlights.scm b/runtime/queries/rust/highlights.scm index 60dd4644..26496c66 100644 --- a/runtime/queries/rust/highlights.scm +++ b/runtime/queries/rust/highlights.scm @@ -127,11 +127,16 @@ "await" ] @keyword.control +"use" @keyword.control.import +(mod_item "mod" @keyword.control.import !body) +(use_as_clause "as" @keyword.control.import) + +(type_cast_expression "as" @keyword.operator) + [ (crate) (super) "as" - "use" "pub" "mod" "extern" From bb684a2b42b4c984428233f2c9197cbac0e93efa Mon Sep 17 00:00:00 2001 From: Stuart Hinson Date: Thu, 23 Dec 2021 20:05:29 -0500 Subject: [PATCH 31/95] Typo fix in ocaml indents.toml (#1342) --- runtime/queries/ocaml/indents.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/queries/ocaml/indents.toml b/runtime/queries/ocaml/indents.toml index 9b6462d8..7586b83a 100644 --- a/runtime/queries/ocaml/indents.toml +++ b/runtime/queries/ocaml/indents.toml @@ -8,6 +8,6 @@ indent = [ "match_case", ] -oudent = [ +outdent = [ "}", ] From 02f24e1214a6eb425904e3812da58a2b73ababe9 Mon Sep 17 00:00:00 2001 From: Stuart Hinson Date: Thu, 23 Dec 2021 20:57:31 -0500 Subject: [PATCH 32/95] Fix match brackets comment (#1346) --- helix-core/src/match_brackets.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-core/src/match_brackets.rs b/helix-core/src/match_brackets.rs index cd554005..0189dedd 100644 --- a/helix-core/src/match_brackets.rs +++ b/helix-core/src/match_brackets.rs @@ -11,7 +11,7 @@ const PAIRS: &[(char, char)] = &[ ('\"', '\"'), ]; -// limit matching pairs to only ( ) { } [ ] < > +// limit matching pairs to only ( ) { } [ ] < > ' ' " " // Returns the position of the matching bracket under cursor. // From b2f8f2ba7739f8e2b0fbaf47ae9ecd07aa35333d Mon Sep 17 00:00:00 2001 From: Gokul Soumya Date: Fri, 24 Dec 2021 07:48:04 +0530 Subject: [PATCH 33/95] Update onedark theme to use new scopes (#1297) --- runtime/themes/onedark.toml | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/runtime/themes/onedark.toml b/runtime/themes/onedark.toml index 40ed1abe..4ab1dd95 100644 --- a/runtime/themes/onedark.toml +++ b/runtime/themes/onedark.toml @@ -3,27 +3,38 @@ "attribute" = { fg = "yellow" } "comment" = { fg = "light-gray", modifiers = ["italic"] } "constant" = { fg = "cyan" } -"constant.builtin" = { fg = "blue" } +"constant.numeric" = { fg = "gold" } +"constant.builtin" = { fg = "gold" } +"constant.character.escape" = { fg = "gold" } "constructor" = { fg = "blue" } -"escape" = { fg = "gold" } "function" = { fg = "blue" } "function.builtin" = { fg = "blue" } "function.macro" = { fg = "purple" } "keyword" = { fg = "red" } "keyword.control" = { fg = "purple" } +"keyword.control.import" = { fg = "red" } "keyword.directive" = { fg = "purple" } "label" = { fg = "purple" } "namespace" = { fg = "blue" } -"number" = { fg = "gold" } "operator" = { fg = "purple" } +"keyword.operator" = { fg = "purple" } "property" = { fg = "red" } "special" = { fg = "blue" } "string" = { fg = "green" } "type" = { fg = "yellow" } -"type.builtin" = { fg = "yellow" } # "variable" = { fg = "blue" } "variable.builtin" = { fg = "blue" } "variable.parameter" = { fg = "red" } +"variable.other.member" = { fg = "red" } + +"markup.heading" = { fg = "red" } +"markup.raw.inline" = { fg = "green" } +"markup.bold" = { fg = "gold", modifiers = ["bold"] } +"markup.italic" = { fg = "purple", modifiers = ["italic"] } +"markup.list" = { fg = "red" } +"markup.quote" = { fg = "yellow" } +"markup.link.url" = { fg = "cyan", modifiers = ["underlined"]} +"markup.link.label" = { fg = "purple" } diagnostic = { modifiers = ["underlined"] } "info" = { fg = "blue", modifiers = ["bold"] } From 13d804418f35878ca155d36d0bb9c0c1a51fcd5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Fri, 24 Dec 2021 16:56:13 +0200 Subject: [PATCH 34/95] Enable Rust proc macro support (#1350) --- languages.toml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/languages.toml b/languages.toml index 54fa63ee..dd18fa19 100644 --- a/languages.toml +++ b/languages.toml @@ -8,10 +8,6 @@ auto-format = true comment-token = "//" language-server = { command = "rust-analyzer" } indent = { tab-width = 4, unit = " " } -[language.config] -cargo = { loadOutDirsFromCheck = true } -procMacro = { enable = false } -diagnostics = { disabled = ["unresolved-proc-macro"] } [[language]] name = "toml" @@ -477,4 +473,3 @@ file-types = ["Dockerfile", "dockerfile"] comment-token = "#" indent = { tab-width = 2, unit = " " } language-server = { command = "docker-langserver", args = ["--stdio"] } - From 8aa0b8eacfaacf0b2c1a9bad84e6ae34fb51ce14 Mon Sep 17 00:00:00 2001 From: chunghha Date: Fri, 24 Dec 2021 23:20:20 -0600 Subject: [PATCH 35/95] chore: update rose pine themes to support markup (#1353) --- runtime/themes/rose_pine.toml | 10 ++++++++++ runtime/themes/rose_pine_dawn.toml | 15 ++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/runtime/themes/rose_pine.toml b/runtime/themes/rose_pine.toml index 256b33c8..a3c12bce 100644 --- a/runtime/themes/rose_pine.toml +++ b/runtime/themes/rose_pine.toml @@ -1,4 +1,5 @@ # Author: RayGervais +# Author: ChrisHa "ui.background" = { bg = "base" } "ui.menu" = "surface" @@ -44,6 +45,15 @@ "diagnostic" = "rose" "error" = "love" +"markup.heading" = { fg = "rose" } +"markup.raw.inline" = { fg = "foam" } +"markup.bold" = { fg = "gold", modifiers = ["bold"] } +"markup.italic" = { fg = "iris", modifiers = ["italic"] } +"markup.list" = { fg = "love" } +"markup.quote" = { fg = "rose" } +"markup.link.url" = { fg = "pine", modifiers = ["underlined"]} +"markup.link.label" = { fg = "foam" } + [palette] base = "#191724" surface = "#1f1d2e" diff --git a/runtime/themes/rose_pine_dawn.toml b/runtime/themes/rose_pine_dawn.toml index 43ba24ed..6654c8c9 100644 --- a/runtime/themes/rose_pine_dawn.toml +++ b/runtime/themes/rose_pine_dawn.toml @@ -1,8 +1,8 @@ -# Author: ChrisHa # Author: RayGervais +# Author: ChrisHa -"ui.background" = { bg = "base" } -"ui.menu" = "surface" +"ui.background" = { bg = "surface" } +"ui.menu" = "base" "ui.menu.selected" = { fg = "iris", bg = "surface" } "ui.linenr" = {fg = "subtle" } "ui.popup" = { bg = "overlay" } @@ -45,6 +45,15 @@ "diagnostic" = "rose" "error" = "love" +"markup.heading" = { fg = "rose" } +"markup.raw.inline" = { fg = "foam" } +"markup.bold" = { fg = "gold", modifiers = ["bold"] } +"markup.italic" = { fg = "iris", modifiers = ["italic"] } +"markup.list" = { fg = "love" } +"markup.quote" = { fg = "rose" } +"markup.link.url" = { fg = "pine", modifiers = ["underlined"]} +"markup.link.label" = { fg = "foam" } + [palette] base = "#faf4ed" surface = "#fffaf3" From 60f3225c7f3375b546e8ec9032739d073a7c363c Mon Sep 17 00:00:00 2001 From: BB Date: Sat, 25 Dec 2021 05:24:29 +0000 Subject: [PATCH 36/95] Truncate the start of file paths in the StatusLine (#1351) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Truncate the start of file paths in the StatusLine * cargo fmt Co-authored-by: Bódi Balázs <97936@4ig.hu> --- helix-term/src/ui/editor.rs | 40 +++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index c5b43898..390b3759 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -548,21 +548,6 @@ impl EditorView { } surface.set_string(viewport.x + 5, viewport.y, progress, base_style); - let rel_path = doc.relative_path(); - let path = rel_path - .as_ref() - .map(|p| p.to_string_lossy()) - .unwrap_or_else(|| SCRATCH_BUFFER_NAME.into()); - - let title = format!("{}{}", path, if doc.is_modified() { "[+]" } else { "" }); - surface.set_stringn( - viewport.x + 8, - viewport.y, - title, - viewport.width.saturating_sub(6) as usize, - base_style, - ); - //------------------------------- // Right side of the status line. //------------------------------- @@ -646,6 +631,31 @@ impl EditorView { &right_side_text, right_side_text.width() as u16, ); + + //------------------------------- + // Middle / File path / Title + //------------------------------- + let title = { + let rel_path = doc.relative_path(); + let path = rel_path + .as_ref() + .map(|p| p.to_string_lossy()) + .unwrap_or_else(|| SCRATCH_BUFFER_NAME.into()); + format!("{}{}", path, if doc.is_modified() { "[+]" } else { "" }) + }; + + surface.set_string_truncated( + viewport.x + 8, // 8: 1 space + 3 char mode string + 1 space + 1 spinner + 1 space + viewport.y, + title, + viewport + .width + .saturating_sub(6) + .saturating_sub(right_side_text.width() as u16 + 1) as usize, // "+ 1": a space between the title and the selection info + base_style, + true, + true, + ); } /// Handle events by looking them up in `self.keymaps`. Returns None From 0e7d757869bbae914a7e832e2511c2071eeacee5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Dzivjak?= Date: Sat, 25 Dec 2021 06:32:43 +0100 Subject: [PATCH 37/95] feat(lsp): configurable diagnostic severity (#1325) * feat(lsp): configurable diagnostic severity Allow severity of diagnostic messages to be configured. E.g. allow turning of Hint level diagnostics. Fixes: https://github.com/helix-editor/helix/issues/1007 * Use language_config() method * Add documentation for diagnostic_severity * Use unreachable for unknown severity level * fix: documentation for diagnostic_severity config --- book/src/guides/adding_languages.md | 25 ++++++++++++----------- book/src/languages.md | 1 - helix-core/src/diagnostic.rs | 15 ++++++++++---- helix-core/src/indent.rs | 2 ++ helix-core/src/syntax.rs | 3 +++ helix-term/src/application.rs | 31 ++++++++++++++++++++--------- 6 files changed, 51 insertions(+), 26 deletions(-) diff --git a/book/src/guides/adding_languages.md b/book/src/guides/adding_languages.md index 987ad088..5844a48e 100644 --- a/book/src/guides/adding_languages.md +++ b/book/src/guides/adding_languages.md @@ -27,18 +27,19 @@ directory](../configuration.md). These are the available keys and descriptions for the file. -| Key | Description | -| ---- | ----------- | -| name | The name of the language | -| scope | A string like `source.js` that identifies the language. Currently, we strive to match the scope names used by popular TextMate grammars and by the Linguist library. Usually `source.` or `text.` in case of markup languages | -| injection-regex | regex pattern that will be tested against a language name in order to determine whether this language should be used for a potential [language injection][treesitter-language-injection] site. | -| file-types | The filetypes of the language, for example `["yml", "yaml"]` | -| shebangs | The interpreters from the shebang line, for example `["sh", "bash"]` | -| roots | A set of marker files to look for when trying to find the workspace root. For example `Cargo.lock`, `yarn.lock` | -| auto-format | Whether to autoformat this language when saving | -| comment-token | The token to use as a comment-token | -| indent | The indent to use. Has sub keys `tab-width` and `unit` | -| config | Language server configuration | +| Key | Description | +| ---- | ----------- | +| name | The name of the language | +| scope | A string like `source.js` that identifies the language. Currently, we strive to match the scope names used by popular TextMate grammars and by the Linguist library. Usually `source.` or `text.` in case of markup languages | +| injection-regex | regex pattern that will be tested against a language name in order to determine whether this language should be used for a potential [language injection][treesitter-language-injection] site. | +| file-types | The filetypes of the language, for example `["yml", "yaml"]` | +| shebangs | The interpreters from the shebang line, for example `["sh", "bash"]` | +| roots | A set of marker files to look for when trying to find the workspace root. For example `Cargo.lock`, `yarn.lock` | +| auto-format | Whether to autoformat this language when saving | +| diagnostic-severity | Minimal severity of diagnostic for it to be displayed. (Allowed values: `Error`, `Warning`, `Info`, `Hint`) | +| comment-token | The token to use as a comment-token | +| indent | The indent to use. Has sub keys `tab-width` and `unit` | +| config | Language server configuration | ## Queries diff --git a/book/src/languages.md b/book/src/languages.md index cef61501..4c4dc326 100644 --- a/book/src/languages.md +++ b/book/src/languages.md @@ -11,4 +11,3 @@ Changes made to the `languages.toml` file in a user's [configuration directory]( name = "rust" auto-format = false ``` - diff --git a/helix-core/src/diagnostic.rs b/helix-core/src/diagnostic.rs index 4fcf51c9..210ad639 100644 --- a/helix-core/src/diagnostic.rs +++ b/helix-core/src/diagnostic.rs @@ -1,12 +1,19 @@ //! LSP diagnostic utility types. +use serde::{Deserialize, Serialize}; /// Describes the severity level of a [`Diagnostic`]. -#[derive(Debug, Clone, Copy, Eq, PartialEq)] +#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Deserialize, Serialize)] pub enum Severity { - Error, - Warning, - Info, Hint, + Info, + Warning, + Error, +} + +impl Default for Severity { + fn default() -> Self { + Self::Hint + } } /// A range of `char`s within the text. diff --git a/helix-core/src/indent.rs b/helix-core/src/indent.rs index b6f5081a..c2baf3cc 100644 --- a/helix-core/src/indent.rs +++ b/helix-core/src/indent.rs @@ -442,6 +442,7 @@ where ); let doc = Rope::from(doc); + use crate::diagnostic::Severity; use crate::syntax::{ Configuration, IndentationConfiguration, LanguageConfiguration, Loader, }; @@ -459,6 +460,7 @@ where roots: vec![], comment_token: None, auto_format: false, + diagnostic_severity: Severity::Warning, language_server: None, indent: Some(IndentationConfiguration { tab_width: 4, diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index ef35fc75..cdae0210 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -1,5 +1,6 @@ use crate::{ chars::char_is_line_ending, + diagnostic::Severity, regex::Regex, transaction::{ChangeSet, Operation}, Rope, RopeSlice, Tendril, @@ -63,6 +64,8 @@ pub struct LanguageConfiguration { #[serde(default)] pub auto_format: bool, + #[serde(default)] + pub diagnostic_severity: Severity, // content_regex #[serde(default, skip_serializing, deserialize_with = "deserialize_regex")] diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index 9a46a7fe..c7202feb 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -378,6 +378,7 @@ impl Application { let doc = self.editor.document_by_path_mut(&path); if let Some(doc) = doc { + let lang_conf = doc.language_config(); let text = doc.text(); let diagnostics = params @@ -415,19 +416,31 @@ impl Application { return None; }; + let severity = + diagnostic.severity.map(|severity| match severity { + DiagnosticSeverity::ERROR => Error, + DiagnosticSeverity::WARNING => Warning, + DiagnosticSeverity::INFORMATION => Info, + DiagnosticSeverity::HINT => Hint, + severity => unreachable!( + "unrecognized diagnostic severity: {:?}", + severity + ), + }); + + if let Some(lang_conf) = lang_conf { + if let Some(severity) = severity { + if severity < lang_conf.diagnostic_severity { + return None; + } + } + }; + Some(Diagnostic { range: Range { start, end }, line: diagnostic.range.start.line as usize, message: diagnostic.message, - severity: diagnostic.severity.map( - |severity| match severity { - DiagnosticSeverity::ERROR => Error, - DiagnosticSeverity::WARNING => Warning, - DiagnosticSeverity::INFORMATION => Info, - DiagnosticSeverity::HINT => Hint, - severity => unimplemented!("{:?}", severity), - }, - ), + severity, // code // source }) From 5d7b5db8ab284e0c2a41e6fbda08857f87406780 Mon Sep 17 00:00:00 2001 From: Gabriel Berto Date: Sat, 25 Dec 2021 07:00:57 -0300 Subject: [PATCH 38/95] Resolve completion item (#1315) Co-authored-by: Gabriel Berto --- helix-lsp/src/client.rs | 8 +++++++ helix-term/src/ui/completion.rs | 40 +++++++++++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs index f1de8752..43804daa 100644 --- a/helix-lsp/src/client.rs +++ b/helix-lsp/src/client.rs @@ -556,6 +556,14 @@ impl Client { self.call::(params) } + pub async fn resolve_completion_item( + &self, + completion_item: lsp::CompletionItem, + ) -> Result { + self.request::(completion_item) + .await + } + pub fn text_document_signature_help( &self, text_document: lsp::TextDocumentIdentifier, diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs index a55201ff..274330c0 100644 --- a/helix-term/src/ui/completion.rs +++ b/helix-term/src/ui/completion.rs @@ -154,8 +154,19 @@ impl Completion { ); doc.apply(&transaction, view.id); - if let Some(additional_edits) = &item.additional_text_edits { - // gopls uses this to add extra imports + // apply additional edits, mostly used to auto import unqualified types + let resolved_additional_text_edits = if item.additional_text_edits.is_some() { + None + } else { + Completion::resolve_completion_item(doc, item.clone()) + .and_then(|item| item.additional_text_edits) + }; + + if let Some(additional_edits) = item + .additional_text_edits + .as_ref() + .or_else(|| resolved_additional_text_edits.as_ref()) + { if !additional_edits.is_empty() { let transaction = util::generate_transaction_from_edits( doc.text(), @@ -181,6 +192,31 @@ impl Completion { completion } + fn resolve_completion_item( + doc: &Document, + completion_item: lsp::CompletionItem, + ) -> Option { + let language_server = doc.language_server()?; + let completion_resolve_provider = language_server + .capabilities() + .completion_provider + .as_ref()? + .resolve_provider; + if completion_resolve_provider != Some(true) { + return None; + } + + let future = language_server.resolve_completion_item(completion_item); + let response = helix_lsp::block_on(future); + match response { + Ok(completion_item) => Some(completion_item), + Err(err) => { + log::error!("execute LSP command: {}", err); + None + } + } + } + pub fn recompute_filter(&mut self, editor: &Editor) { // recompute menu based on matches let menu = self.popup.contents_mut(); From ec878e40114d8992c3ed1221f77271a4508d3cde Mon Sep 17 00:00:00 2001 From: Sebastian Neubauer Date: Sat, 25 Dec 2021 16:10:19 +0100 Subject: [PATCH 39/95] Add textobjects and indents to cmake (#1307) --- book/src/generated/lang-support.md | 2 +- runtime/queries/cmake/indents.toml | 12 ++++++++++++ runtime/queries/cmake/textobjects.scm | 3 +++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 runtime/queries/cmake/indents.toml create mode 100644 runtime/queries/cmake/textobjects.scm diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index c7054201..2777dc4e 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -3,7 +3,7 @@ | bash | ✓ | | | `bash-language-server` | | c | ✓ | | | `clangd` | | c-sharp | ✓ | | | | -| cmake | ✓ | | | `cmake-language-server` | +| cmake | ✓ | ✓ | ✓ | `cmake-language-server` | | comment | ✓ | | | | | cpp | ✓ | | | `clangd` | | css | ✓ | | | | diff --git a/runtime/queries/cmake/indents.toml b/runtime/queries/cmake/indents.toml new file mode 100644 index 00000000..8b886a4f --- /dev/null +++ b/runtime/queries/cmake/indents.toml @@ -0,0 +1,12 @@ +indent = [ + "if_condition", + "foreach_loop", + "while_loop", + "function_def", + "macro_def", + "normal_command", +] + +outdent = [ + ")" +] diff --git a/runtime/queries/cmake/textobjects.scm b/runtime/queries/cmake/textobjects.scm new file mode 100644 index 00000000..b0d1b108 --- /dev/null +++ b/runtime/queries/cmake/textobjects.scm @@ -0,0 +1,3 @@ +(macro_def) @function.around + +(argument) @parameter.inside From 4b0b1a5657b78693efe609647360de30264fcc92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Dzivjak?= Date: Sat, 25 Dec 2021 16:10:46 +0100 Subject: [PATCH 40/95] feat(ui): file encoding in statusline (#1355) * feat(ui): file encoding in statusline Display file encoding in statusline if the encoding isn't UTF-8. * Re-export encoding_rs from core From there it can be imported by other mods that rely on it. --- Cargo.lock | 2 +- helix-core/Cargo.toml | 1 + helix-core/src/lib.rs | 2 ++ helix-term/src/ui/editor.rs | 9 ++++++++- helix-view/Cargo.toml | 1 - helix-view/src/document.rs | 33 +++++++++++++++++---------------- 6 files changed, 29 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 27268feb..40afe4e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -370,6 +370,7 @@ version = "0.5.0" dependencies = [ "arc-swap", "chrono", + "encoding_rs", "etcetera", "helix-syntax", "log", @@ -471,7 +472,6 @@ dependencies = [ "chardetng", "clipboard-win", "crossterm", - "encoding_rs", "futures-util", "helix-core", "helix-lsp", diff --git a/helix-core/Cargo.toml b/helix-core/Cargo.toml index 839b07ac..3d7fe866 100644 --- a/helix-core/Cargo.toml +++ b/helix-core/Cargo.toml @@ -35,6 +35,7 @@ toml = "0.5" similar = "2.1" etcetera = "0.3" +encoding_rs = "0.8" chrono = { version = "0.4", default-features = false, features = ["alloc", "std"] } diff --git a/helix-core/src/lib.rs b/helix-core/src/lib.rs index 92a59f31..1c78e7c0 100644 --- a/helix-core/src/lib.rs +++ b/helix-core/src/lib.rs @@ -1,3 +1,5 @@ +pub use encoding_rs as encoding; + pub mod auto_pairs; pub mod chars; pub mod comment; diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 390b3759..dd050398 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -7,7 +7,7 @@ use crate::{ }; use helix_core::{ - coords_at_pos, + coords_at_pos, encoding, graphemes::{ensure_grapheme_boundary_next, next_grapheme_boundary, prev_grapheme_boundary}, movement::Direction, syntax::{self, HighlightEvent}, @@ -621,6 +621,13 @@ impl EditorView { base_style, )); + let enc = doc.encoding(); + if enc != encoding::UTF_8 { + right_side_text + .0 + .push(Span::styled(format!(" {} ", enc.name()), base_style)); + } + // Render to the statusline. surface.set_spans( viewport.x diff --git a/helix-view/Cargo.toml b/helix-view/Cargo.toml index 9c3a83f8..121a518c 100644 --- a/helix-view/Cargo.toml +++ b/helix-view/Cargo.toml @@ -29,7 +29,6 @@ futures-util = { version = "0.3", features = ["std", "async-await"], default-fea slotmap = "1" -encoding_rs = "0.8" chardetng = "0.1" serde = { version = "1.0", features = ["derive"] } diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index c71d1850..9652d7b3 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -9,6 +9,7 @@ use std::str::FromStr; use std::sync::Arc; use helix_core::{ + encoding, history::History, indent::{auto_detect_indent_style, IndentStyle}, line_ending::auto_detect_line_ending, @@ -74,7 +75,7 @@ pub struct Document { pub(crate) selections: HashMap, path: Option, - encoding: &'static encoding_rs::Encoding, + encoding: &'static encoding::Encoding, /// Current editing mode. pub mode: Mode, @@ -143,8 +144,8 @@ impl fmt::Debug for Document { /// be used to override encoding auto-detection. pub fn from_reader( reader: &mut R, - encoding: Option<&'static encoding_rs::Encoding>, -) -> Result<(Rope, &'static encoding_rs::Encoding), Error> { + encoding: Option<&'static encoding::Encoding>, +) -> Result<(Rope, &'static encoding::Encoding), Error> { // These two buffers are 8192 bytes in size each and are used as // intermediaries during the decoding process. Text read into `buf` // from `reader` is decoded into `buf_out` as UTF-8. Once either @@ -212,11 +213,11 @@ pub fn from_reader( total_read += read; total_written += written; match result { - encoding_rs::CoderResult::InputEmpty => { + encoding::CoderResult::InputEmpty => { debug_assert_eq!(slice.len(), total_read); break; } - encoding_rs::CoderResult::OutputFull => { + encoding::CoderResult::OutputFull => { debug_assert!(slice.len() > total_read); builder.append(&buf_str[..total_written]); total_written = 0; @@ -251,7 +252,7 @@ pub fn from_reader( /// replacement characters may appear in the encoded text. pub async fn to_writer<'a, W: tokio::io::AsyncWriteExt + Unpin + ?Sized>( writer: &'a mut W, - encoding: &'static encoding_rs::Encoding, + encoding: &'static encoding::Encoding, rope: &'a Rope, ) -> Result<(), Error> { // Text inside a `Rope` is stored as non-contiguous blocks of data called @@ -286,12 +287,12 @@ pub async fn to_writer<'a, W: tokio::io::AsyncWriteExt + Unpin + ?Sized>( total_read += read; total_written += written; match result { - encoding_rs::CoderResult::InputEmpty => { + encoding::CoderResult::InputEmpty => { debug_assert_eq!(chunk.len(), total_read); debug_assert!(buf.len() >= total_written); break; } - encoding_rs::CoderResult::OutputFull => { + encoding::CoderResult::OutputFull => { debug_assert!(chunk.len() > total_read); writer.write_all(&buf[..total_written]).await?; total_written = 0; @@ -322,8 +323,8 @@ use helix_lsp::lsp; use url::Url; impl Document { - pub fn from(text: Rope, encoding: Option<&'static encoding_rs::Encoding>) -> Self { - let encoding = encoding.unwrap_or(encoding_rs::UTF_8); + pub fn from(text: Rope, encoding: Option<&'static encoding::Encoding>) -> Self { + let encoding = encoding.unwrap_or(encoding::UTF_8); let changes = ChangeSet::new(&text); let old_state = None; @@ -356,7 +357,7 @@ impl Document { /// overwritten with the `encoding` parameter. pub fn open( path: &Path, - encoding: Option<&'static encoding_rs::Encoding>, + encoding: Option<&'static encoding::Encoding>, theme: Option<&Theme>, config_loader: Option<&syntax::Loader>, ) -> Result { @@ -366,7 +367,7 @@ impl Document { std::fs::File::open(path).context(format!("unable to open {:?}", path))?; from_reader(&mut file, encoding)? } else { - let encoding = encoding.unwrap_or(encoding_rs::UTF_8); + let encoding = encoding.unwrap_or(encoding::UTF_8); (Rope::from(DEFAULT_LINE_ENDING.as_str()), encoding) }; @@ -548,7 +549,7 @@ impl Document { /// Sets the [`Document`]'s encoding with the encoding correspondent to `label`. pub fn set_encoding(&mut self, label: &str) -> Result<(), Error> { - match encoding_rs::Encoding::for_label(label.as_bytes()) { + match encoding::Encoding::for_label(label.as_bytes()) { Some(encoding) => self.encoding = encoding, None => return Err(anyhow::anyhow!("unknown encoding")), } @@ -556,7 +557,7 @@ impl Document { } /// Returns the [`Document`]'s current encoding. - pub fn encoding(&self) -> &'static encoding_rs::Encoding { + pub fn encoding(&self) -> &'static encoding::Encoding { self.encoding } @@ -1123,7 +1124,7 @@ mod test { macro_rules! test_decode { ($label:expr, $label_override:expr) => { - let encoding = encoding_rs::Encoding::for_label($label_override.as_bytes()).unwrap(); + let encoding = encoding::Encoding::for_label($label_override.as_bytes()).unwrap(); let base_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/encoding"); let path = base_path.join(format!("{}_in.txt", $label)); let ref_path = base_path.join(format!("{}_in_ref.txt", $label)); @@ -1142,7 +1143,7 @@ mod test { macro_rules! test_encode { ($label:expr, $label_override:expr) => { - let encoding = encoding_rs::Encoding::for_label($label_override.as_bytes()).unwrap(); + let encoding = encoding::Encoding::for_label($label_override.as_bytes()).unwrap(); let base_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/encoding"); let path = base_path.join(format!("{}_out.txt", $label)); let ref_path = base_path.join(format!("{}_out_ref.txt", $label)); From fd31662b70ee32d199950ba2873680fc9043c975 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Fri, 24 Dec 2021 12:44:45 -0600 Subject: [PATCH 41/95] add gitcommit grammar and language configuration --- .gitmodules | 6 +++++- book/src/generated/lang-support.md | 1 + helix-syntax/languages/tree-sitter-gitcommit | 1 + languages.toml | 8 ++++++++ 4 files changed, 15 insertions(+), 1 deletion(-) create mode 160000 helix-syntax/languages/tree-sitter-gitcommit diff --git a/.gitmodules b/.gitmodules index edfe3c39..ad100a00 100644 --- a/.gitmodules +++ b/.gitmodules @@ -165,8 +165,12 @@ [submodule "helix-syntax/languages/tree-sitter-dockerfile"] path = helix-syntax/languages/tree-sitter-dockerfile url = https://github.com/camdencheek/tree-sitter-dockerfile.git - shallow = true + shallow = true [submodule "helix-syntax/languages/tree-sitter-fish"] path = helix-syntax/languages/tree-sitter-fish url = https://github.com/ram02z/tree-sitter-fish shallow = true +[submodule "helix-syntax/languages/tree-sitter-gitcommit"] + path = helix-syntax/languages/tree-sitter-gitcommit + url = https://github.com/the-mikedavis/tree-sitter-gitcommit.git + shallow = true diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 2777dc4e..d6e0d9af 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -11,6 +11,7 @@ | dockerfile | ✓ | | | `docker-langserver` | | elixir | ✓ | | | `elixir-ls` | | fish | ✓ | ✓ | ✓ | | +| gitcommit | ✓ | | | | | glsl | ✓ | | ✓ | | | go | ✓ | ✓ | ✓ | `gopls` | | html | ✓ | | | | diff --git a/helix-syntax/languages/tree-sitter-gitcommit b/helix-syntax/languages/tree-sitter-gitcommit new file mode 160000 index 00000000..6a2ddbec --- /dev/null +++ b/helix-syntax/languages/tree-sitter-gitcommit @@ -0,0 +1 @@ +Subproject commit 6a2ddbecd49fa8e7e1fda24d43e363cfd9171ca0 diff --git a/languages.toml b/languages.toml index dd18fa19..f73011c8 100644 --- a/languages.toml +++ b/languages.toml @@ -473,3 +473,11 @@ file-types = ["Dockerfile", "dockerfile"] comment-token = "#" indent = { tab-width = 2, unit = " " } language-server = { command = "docker-langserver", args = ["--stdio"] } + +[[language]] +name = "gitcommit" +scope = "git.commitmsg" +roots = [] +file-types = ["COMMIT_EDITMSG"] +comment-token = "#" +indent = { tab-width = 2, unit = " " } From 78f93239b5814d1b1be7d1fbd2fce1a7aec12432 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Wed, 22 Dec 2021 09:01:50 -0600 Subject: [PATCH 42/95] add gitcommit highlights --- runtime/queries/gitcommit/highlights.scm | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 runtime/queries/gitcommit/highlights.scm diff --git a/runtime/queries/gitcommit/highlights.scm b/runtime/queries/gitcommit/highlights.scm new file mode 100644 index 00000000..04d70416 --- /dev/null +++ b/runtime/queries/gitcommit/highlights.scm @@ -0,0 +1,18 @@ +(subject) @markup.heading +(path) @string.special.path +(branch) @string.special.symbol +(commit) @constant +(item) @markup.link.url +(header) @tag + +(change kind: "new file" @diff.plus) +(change kind: "deleted" @diff.minus) +(change kind: "modified" @diff.delta) +(change kind: "renamed" @diff.delta.moved) + +[":" "->"] @punctuation.delimeter +(comment) @comment + +; once we have diff injections, @comment should become @none +((comment (scissors)) + (message)+ @comment) From 3b800025af0bdf7e8179cbb42ad0b4374b9005f1 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Wed, 22 Dec 2021 09:54:23 -0600 Subject: [PATCH 43/95] add diff.{plus,minus,delta} to themes --- base16_theme.toml | 4 ++++ runtime/themes/base16_default_dark.toml | 4 ++++ runtime/themes/base16_default_light.toml | 4 ++++ runtime/themes/base16_terminal.toml | 4 ++++ runtime/themes/bogster.toml | 4 ++++ runtime/themes/dark_plus.toml | 4 ++++ runtime/themes/dracula.toml | 4 ++++ runtime/themes/everforest_dark.toml | 4 ++++ runtime/themes/gruvbox.toml | 4 ++++ runtime/themes/ingrid.toml | 4 ++++ runtime/themes/monokai.toml | 6 +++++- runtime/themes/monokai_pro.toml | 5 +++++ runtime/themes/monokai_pro_machine.toml | 5 +++++ runtime/themes/monokai_pro_octagon.toml | 5 +++++ runtime/themes/monokai_pro_ristretto.toml | 5 +++++ runtime/themes/monokai_pro_spectrum.toml | 5 +++++ runtime/themes/nord.toml | 5 +++++ runtime/themes/onedark.toml | 4 ++++ runtime/themes/rose_pine.toml | 3 +++ runtime/themes/rose_pine_dawn.toml | 3 +++ runtime/themes/solarized_dark.toml | 4 ++++ runtime/themes/solarized_light.toml | 4 ++++ runtime/themes/spacebones_light.toml | 4 ++++ theme.toml | 4 ++++ 24 files changed, 101 insertions(+), 1 deletion(-) diff --git a/base16_theme.toml b/base16_theme.toml index 5ec74bcc..bb60a3ea 100644 --- a/base16_theme.toml +++ b/base16_theme.toml @@ -29,6 +29,10 @@ "namespace" = "magenta" "ui.help" = { fg = "white", bg = "black" } +"diff.plus" = "green" +"diff.delta" = "yellow" +"diff.minus" = "red" + "diagnostic" = { modifiers = ["underlined"] } "ui.gutter" = { bg = "black" } "info" = "blue" diff --git a/runtime/themes/base16_default_dark.toml b/runtime/themes/base16_default_dark.toml index fd4b0fea..33ff87fa 100644 --- a/runtime/themes/base16_default_dark.toml +++ b/runtime/themes/base16_default_dark.toml @@ -33,6 +33,10 @@ "namespace" = "base0E" "ui.help" = { fg = "base06", bg = "base01" } +"diff.plus" = "base0B" +"diff.delta" = "base09" +"diff.minus" = "base08" + "diagnostic" = { modifiers = ["underlined"] } "ui.gutter" = { bg = "base01" } "info" = "base0D" diff --git a/runtime/themes/base16_default_light.toml b/runtime/themes/base16_default_light.toml index 596990da..3f4de265 100644 --- a/runtime/themes/base16_default_light.toml +++ b/runtime/themes/base16_default_light.toml @@ -33,6 +33,10 @@ "namespace" = "base0E" "ui.help" = { fg = "base06", bg = "base01" } +"diff.plus" = "base0B" +"diff.delta" = "base09" +"diff.minus" = "base08" + "diagnostic" = { modifiers = ["underlined"] } "ui.gutter" = { bg = "base01" } "info" = "base0D" diff --git a/runtime/themes/base16_terminal.toml b/runtime/themes/base16_terminal.toml index 123ceaea..cbbfbf24 100644 --- a/runtime/themes/base16_terminal.toml +++ b/runtime/themes/base16_terminal.toml @@ -30,6 +30,10 @@ "namespace" = "light-magenta" "ui.help" = { fg = "white", bg = "black" } +"diff.plus" = "light-green" +"diff.delta" = "yellow" +"diff.minus" = "light-red" + "diagnostic" = { modifiers = ["underlined"] } "ui.gutter" = { bg = "black" } "info" = "light-blue" diff --git a/runtime/themes/bogster.toml b/runtime/themes/bogster.toml index 86a6c34b..ea6844f2 100644 --- a/runtime/themes/bogster.toml +++ b/runtime/themes/bogster.toml @@ -28,6 +28,10 @@ "module" = "#d32c5d" +"diff.plus" = "#59dcb7" +"diff.delta" = "#dc7759" +"diff.minus" = "#dc597f" + "ui.background" = { bg = "#161c23" } "ui.linenr" = { fg = "#415367" } "ui.linenr.selected" = { fg = "#e5ded6" } # TODO diff --git a/runtime/themes/dark_plus.toml b/runtime/themes/dark_plus.toml index 0554f827..78437649 100644 --- a/runtime/themes/dark_plus.toml +++ b/runtime/themes/dark_plus.toml @@ -39,6 +39,10 @@ "constant.numeric" = { fg = "pale_green" } "constant.character.escape" = { fg = "gold" } +"diff.plus" = { fg = "pale_green" } +"diff.delta" = { fg = "gold" } +"diff.minus" = { fg = "red" } + "ui.background" = { fg = "light_gray", bg = "dark_gray2" } "ui.window" = { bg = "widget" } diff --git a/runtime/themes/dracula.toml b/runtime/themes/dracula.toml index 956fd0f5..f01c7323 100644 --- a/runtime/themes/dracula.toml +++ b/runtime/themes/dracula.toml @@ -15,6 +15,10 @@ "variable.builtin" = { fg = "cyan", modifiers = ["italic"] } "variable.parameter" = { fg ="orange", modifiers = ["italic"] } +"diff.plus" = { fg = "green" } +"diff.delta" = { fg = "orange" } +"diff.minus" = { fg = "red" } + "ui.background" = { fg = "foreground", bg = "background" } "ui.cursor" = { fg = "background", bg = "orange", modifiers = ["dim"] } "ui.cursor.match" = { fg = "green", modifiers = ["underlined"] } diff --git a/runtime/themes/everforest_dark.toml b/runtime/themes/everforest_dark.toml index bbd005e6..3be9f1f0 100644 --- a/runtime/themes/everforest_dark.toml +++ b/runtime/themes/everforest_dark.toml @@ -34,6 +34,10 @@ "module" = "blue" "special" = "orange" +"diff.plus" = "green" +"diff.delta" = "orange" +"diff.minus" = "red" + "ui.background" = { bg = "bg0" } "ui.cursor" = { fg = "bg0", bg = "fg" } "ui.cursor.match" = { fg = "orange", bg = "bg_yellow" } diff --git a/runtime/themes/gruvbox.toml b/runtime/themes/gruvbox.toml index 0ff039ea..9eae0915 100644 --- a/runtime/themes/gruvbox.toml +++ b/runtime/themes/gruvbox.toml @@ -28,6 +28,10 @@ "label" = "aqua1" "module" = "aqua1" +"diff.plus" = "green1" +"diff.delta" = "orange1" +"diff.minus" = "red1" + "warning" = { fg = "orange1", bg = "bg1" } "error" = { fg = "red1", bg = "bg1" } "info" = { fg = "aqua1", bg = "bg1" } diff --git a/runtime/themes/ingrid.toml b/runtime/themes/ingrid.toml index 30829475..df8a922f 100644 --- a/runtime/themes/ingrid.toml +++ b/runtime/themes/ingrid.toml @@ -28,6 +28,10 @@ "module" = "#839A53" +"diff.plus" = "#839A53" +"diff.delta" = "#D4A520" +"diff.minus" = "#D74E50" + "ui.background" = { bg = "#FFFCFD" } "ui.linenr" = { fg = "#bbbbbb" } "ui.linenr.selected" = { fg = "#F3EAE9" } # TODO diff --git a/runtime/themes/monokai.toml b/runtime/themes/monokai.toml index 38f9f170..c8bf8ebd 100644 --- a/runtime/themes/monokai.toml +++ b/runtime/themes/monokai.toml @@ -39,6 +39,10 @@ "constant.numeric" = { fg = "#ae81ff" } "constant.character.escape" = { fg = "#ae81ff" } +"diff.plus" = { fg = "#a6e22e" } +"diff.delta" = { fg = "#fd971f" } +"diff.minus" = { fg = "#f92672" } + "ui.background" = { fg = "text", bg = "background" } "ui.window" = { bg = "widget" } @@ -65,7 +69,7 @@ "warning" = { fg = "#cca700" } "error" = { fg = "#f48771" } "info" = { fg = "#75beff" } -"hint" = { fg = "#eeeeeeb3" } +"hint" = { fg = "#eeeeeb3" } diagnostic = { modifiers = ["underlined"] } diff --git a/runtime/themes/monokai_pro.toml b/runtime/themes/monokai_pro.toml index bf8a4a84..5daeaf6c 100644 --- a/runtime/themes/monokai_pro.toml +++ b/runtime/themes/monokai_pro.toml @@ -77,6 +77,11 @@ # integer, floating point "constant.numeric" = "purple" +# vcs +"diff.plus" = "green" +"diff.delta" = "orange" +"diff.minus" = "red" + # make diagnostic underlined, to distinguish with selection text. diagnostic = { modifiers = ["underlined"] } diff --git a/runtime/themes/monokai_pro_machine.toml b/runtime/themes/monokai_pro_machine.toml index d8a701f1..0763a5fb 100644 --- a/runtime/themes/monokai_pro_machine.toml +++ b/runtime/themes/monokai_pro_machine.toml @@ -77,6 +77,11 @@ # integer, floating point "constant.numeric" = "purple" +# vcs +"diff.plus" = "green" +"diff.delta" = "orange" +"diff.minus" = "red" + # make diagnostic underlined, to distinguish with selection text. diagnostic = { modifiers = ["underlined"] } diff --git a/runtime/themes/monokai_pro_octagon.toml b/runtime/themes/monokai_pro_octagon.toml index 74459472..6a74a8d0 100644 --- a/runtime/themes/monokai_pro_octagon.toml +++ b/runtime/themes/monokai_pro_octagon.toml @@ -77,6 +77,11 @@ # integer, floating point "constant.numeric" = "purple" +# vcs +"diff.plus" = "green" +"diff.delta" = "orange" +"diff.minus" = "red" + # make diagnostic underlined, to distinguish with selection text. diagnostic = { modifiers = ["underlined"] } diff --git a/runtime/themes/monokai_pro_ristretto.toml b/runtime/themes/monokai_pro_ristretto.toml index a9cf4b34..1a1a32ff 100644 --- a/runtime/themes/monokai_pro_ristretto.toml +++ b/runtime/themes/monokai_pro_ristretto.toml @@ -77,6 +77,11 @@ # integer, floating point "constant.numeric" = "purple" +# vcs +"diff.plus" = "green" +"diff.delta" = "orange" +"diff.minus" = "red" + # make diagnostic underlined, to distinguish with selection text. diagnostic = { modifiers = ["underlined"] } diff --git a/runtime/themes/monokai_pro_spectrum.toml b/runtime/themes/monokai_pro_spectrum.toml index 232adfbd..36630493 100644 --- a/runtime/themes/monokai_pro_spectrum.toml +++ b/runtime/themes/monokai_pro_spectrum.toml @@ -77,6 +77,11 @@ # integer, floating point "constant.numeric" = "purple" +# vcs +"diff.plus" = "green" +"diff.delta" = "orange" +"diff.minus" = "red" + # make diagnostic underlined, to distinguish with selection text. diagnostic = { modifiers = ["underlined"] } diff --git a/runtime/themes/nord.toml b/runtime/themes/nord.toml index a619f902..ae1ea29b 100644 --- a/runtime/themes/nord.toml +++ b/runtime/themes/nord.toml @@ -84,6 +84,11 @@ # nord15 - integer, floating point "constant.numeric" = "nord15" +# vcs +"diff.plus" = "nord14" +"diff.delta" = "nord12" +"diff.minus" = "nord11" + [palette] nord0 = "#2e3440" nord1 = "#3b4252" diff --git a/runtime/themes/onedark.toml b/runtime/themes/onedark.toml index 4ab1dd95..dfeadbb2 100644 --- a/runtime/themes/onedark.toml +++ b/runtime/themes/onedark.toml @@ -36,6 +36,10 @@ "markup.link.url" = { fg = "cyan", modifiers = ["underlined"]} "markup.link.label" = { fg = "purple" } +"diff.plus" = "green" +"diff.delta" = "gold" +"diff.minus" = "red" + diagnostic = { modifiers = ["underlined"] } "info" = { fg = "blue", modifiers = ["bold"] } "hint" = { fg = "green", modifiers = ["bold"] } diff --git a/runtime/themes/rose_pine.toml b/runtime/themes/rose_pine.toml index a3c12bce..bf3a040b 100644 --- a/runtime/themes/rose_pine.toml +++ b/runtime/themes/rose_pine.toml @@ -38,6 +38,9 @@ "ui.window" = { bg = "base" } "ui.help" = { bg = "overlay", fg = "foam" } "text" = "text" +"diff.plus" = "foam" +"diff.delta" = "rose" +"diff.minus" = "love" "info" = "gold" "hint" = "gold" diff --git a/runtime/themes/rose_pine_dawn.toml b/runtime/themes/rose_pine_dawn.toml index 6654c8c9..cc6d287e 100644 --- a/runtime/themes/rose_pine_dawn.toml +++ b/runtime/themes/rose_pine_dawn.toml @@ -38,6 +38,9 @@ "ui.window" = { bg = "base" } "ui.help" = { bg = "overlay", fg = "foam" } "text" = "text" +"diff.plus" = "foam" +"diff.delta" = "rose" +"diff.minus" = "love" "info" = "gold" "hint" = "gold" diff --git a/runtime/themes/solarized_dark.toml b/runtime/themes/solarized_dark.toml index 979fdaac..ab345c8d 100644 --- a/runtime/themes/solarized_dark.toml +++ b/runtime/themes/solarized_dark.toml @@ -22,6 +22,10 @@ "module" = { fg = "violet" } "tag" = { fg = "magenta" } +"diff.plus" = { fg = "green" } +"diff.delta" = { fg = "orange" } +"diff.minus" = { fg = "red" } + # 背景 "ui.background" = { bg = "base03" } diff --git a/runtime/themes/solarized_light.toml b/runtime/themes/solarized_light.toml index ded90cc4..6b0137fb 100644 --- a/runtime/themes/solarized_light.toml +++ b/runtime/themes/solarized_light.toml @@ -22,6 +22,10 @@ "module" = { fg = "violet" } "tag" = { fg = "magenta" } +"diff.plus" = { fg = "green" } +"diff.delta" = { fg = "orange" } +"diff.minus" = { fg = "red" } + # 背景 "ui.background" = { bg = "base03" } diff --git a/runtime/themes/spacebones_light.toml b/runtime/themes/spacebones_light.toml index 92f116ab..fcbe7b37 100644 --- a/runtime/themes/spacebones_light.toml +++ b/runtime/themes/spacebones_light.toml @@ -30,6 +30,10 @@ "label" = "#b1951d" "module" = "#b1951d" +"diff.plus" = "#2d9574" +"diff.delta" = "#715ab1" +"diff.minus" = "#ba2f59" + "warning" = { fg = "#da8b55" } "error" = { fg = "#e0211d" } "info" = { fg = "#b1951d" } diff --git a/theme.toml b/theme.toml index b316e814..ca0b2805 100644 --- a/theme.toml +++ b/theme.toml @@ -34,6 +34,10 @@ label = "honey" "markup.link.url" = { fg = "silver", modifiers = ["underlined"] } "markup.raw" = "almond" +"diff.plus" = "#35bf86" +"diff.minus" = "#f22c86" +"diff.delta" = "#6f44f0" + # TODO: diferentiate doc comment # concat (ERROR) @error.syntax and "MISSING ;" selectors for errors From c1f4c0e67acc65a263440fce98514c9e6de1940d Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Wed, 22 Dec 2021 09:58:51 -0600 Subject: [PATCH 44/95] add new scopes to themes docs --- book/src/themes.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/book/src/themes.md b/book/src/themes.md index fce2c0ca..8eee334b 100644 --- a/book/src/themes.md +++ b/book/src/themes.md @@ -178,6 +178,12 @@ We use a similar set of scopes as - `inline` - `block` +- `diff` - version control changes + - `plus` - additions + - `minus` - deletions + - `delta` - modifications + - `moved` - renamed or moved files/changes + #### Interface These scopes are used for theming the editor interface. From 28c9afdd0e83da37c782fc82b859d8451df1b877 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Thu, 23 Dec 2021 09:53:01 -0600 Subject: [PATCH 45/95] add commented-out diff and rebase injection queries --- runtime/queries/gitcommit/injections.scm | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 runtime/queries/gitcommit/injections.scm diff --git a/runtime/queries/gitcommit/injections.scm b/runtime/queries/gitcommit/injections.scm new file mode 100644 index 00000000..2837a586 --- /dev/null +++ b/runtime/queries/gitcommit/injections.scm @@ -0,0 +1,15 @@ +; once a diff grammar is available, we can inject diff highlighting into the +; trailer after scissors (git commit --verbose) +; see https://github.com/helix-editor/helix/pull/1338#issuecomment-1000013539 +; +; ((comment (scissors)) +; (message) @injection.content +; (#set! injection.language "diff")) + +; --- + +; once a rebase grammar is available, we can inject rebase highlighting into +; interactive rebase summary sections like so: +; +; ((rebase_command) @injection.content +; (#set! injection.language "git-rebase")) From c3fb86cbaa5c6973fe014a4401c4e0d6f663384d Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Fri, 24 Dec 2021 16:49:27 -0600 Subject: [PATCH 46/95] tree-sitter-gitcommit->tree-sitter-git-commit --- .gitmodules | 6 +++--- book/src/generated/lang-support.md | 2 +- helix-syntax/languages/tree-sitter-git-commit | 1 + helix-syntax/languages/tree-sitter-gitcommit | 1 - languages.toml | 2 +- runtime/queries/{gitcommit => git-commit}/highlights.scm | 0 runtime/queries/{gitcommit => git-commit}/injections.scm | 0 7 files changed, 6 insertions(+), 6 deletions(-) create mode 160000 helix-syntax/languages/tree-sitter-git-commit delete mode 160000 helix-syntax/languages/tree-sitter-gitcommit rename runtime/queries/{gitcommit => git-commit}/highlights.scm (100%) rename runtime/queries/{gitcommit => git-commit}/injections.scm (100%) diff --git a/.gitmodules b/.gitmodules index ad100a00..d5bd61c9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -170,7 +170,7 @@ path = helix-syntax/languages/tree-sitter-fish url = https://github.com/ram02z/tree-sitter-fish shallow = true -[submodule "helix-syntax/languages/tree-sitter-gitcommit"] - path = helix-syntax/languages/tree-sitter-gitcommit - url = https://github.com/the-mikedavis/tree-sitter-gitcommit.git +[submodule "helix-syntax/languages/tree-sitter-git-commit"] + path = helix-syntax/languages/tree-sitter-git-commit + url = https://github.com/the-mikedavis/tree-sitter-git-commit.git shallow = true diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index d6e0d9af..9c42005b 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -11,7 +11,7 @@ | dockerfile | ✓ | | | `docker-langserver` | | elixir | ✓ | | | `elixir-ls` | | fish | ✓ | ✓ | ✓ | | -| gitcommit | ✓ | | | | +| git-commit | ✓ | | | | | glsl | ✓ | | ✓ | | | go | ✓ | ✓ | ✓ | `gopls` | | html | ✓ | | | | diff --git a/helix-syntax/languages/tree-sitter-git-commit b/helix-syntax/languages/tree-sitter-git-commit new file mode 160000 index 00000000..5cd4776c --- /dev/null +++ b/helix-syntax/languages/tree-sitter-git-commit @@ -0,0 +1 @@ +Subproject commit 5cd4776c86c82d9d6afdc8c73a47a08057aef618 diff --git a/helix-syntax/languages/tree-sitter-gitcommit b/helix-syntax/languages/tree-sitter-gitcommit deleted file mode 160000 index 6a2ddbec..00000000 --- a/helix-syntax/languages/tree-sitter-gitcommit +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6a2ddbecd49fa8e7e1fda24d43e363cfd9171ca0 diff --git a/languages.toml b/languages.toml index f73011c8..616ef234 100644 --- a/languages.toml +++ b/languages.toml @@ -475,7 +475,7 @@ indent = { tab-width = 2, unit = " " } language-server = { command = "docker-langserver", args = ["--stdio"] } [[language]] -name = "gitcommit" +name = "git-commit" scope = "git.commitmsg" roots = [] file-types = ["COMMIT_EDITMSG"] diff --git a/runtime/queries/gitcommit/highlights.scm b/runtime/queries/git-commit/highlights.scm similarity index 100% rename from runtime/queries/gitcommit/highlights.scm rename to runtime/queries/git-commit/highlights.scm diff --git a/runtime/queries/gitcommit/injections.scm b/runtime/queries/git-commit/injections.scm similarity index 100% rename from runtime/queries/gitcommit/injections.scm rename to runtime/queries/git-commit/injections.scm From 6af0d51dc5510be43dd6688ee1053ce01b601d83 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Fri, 24 Dec 2021 18:35:29 -0600 Subject: [PATCH 47/95] highlight rebase-commands as markup.raw --- runtime/queries/git-commit/highlights.scm | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/queries/git-commit/highlights.scm b/runtime/queries/git-commit/highlights.scm index 04d70416..a74bb381 100644 --- a/runtime/queries/git-commit/highlights.scm +++ b/runtime/queries/git-commit/highlights.scm @@ -4,6 +4,7 @@ (commit) @constant (item) @markup.link.url (header) @tag +(rebase_command) @markup.raw (change kind: "new file" @diff.plus) (change kind: "deleted" @diff.minus) From a306a1052a51c686b24a6f339190878b8029a894 Mon Sep 17 00:00:00 2001 From: Tamo Date: Sun, 26 Dec 2021 02:04:33 +0100 Subject: [PATCH 48/95] Update settings at runtime (#798) * feat: Update settings at runtime fix the clippy warning * update the documentation * use to_value instead of to_vec+from_value * drop the equal * remove an useless comment * apply suggestion --- book/src/generated/typable-cmd.md | 1 + helix-term/src/commands.rs | 37 +++++++++++++++++++++++++++++++ helix-term/src/ui/mod.rs | 27 ++++++++++++++++++++++ helix-view/src/editor.rs | 20 +++++++++++++---- 4 files changed, 81 insertions(+), 4 deletions(-) diff --git a/book/src/generated/typable-cmd.md b/book/src/generated/typable-cmd.md index bb21fd6b..f12082bb 100644 --- a/book/src/generated/typable-cmd.md +++ b/book/src/generated/typable-cmd.md @@ -41,3 +41,4 @@ | `:hsplit`, `:hs`, `:sp` | Open the file in a horizontal split. | | `:tutor` | Open the tutorial. | | `:goto`, `:g` | Go to line number. | +| `:set-option`, `:set` | Set a config option at runtime | diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index ee6a5989..7b1235f8 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -2637,6 +2637,36 @@ pub mod cmd { let (view, doc) = current!(cx.editor); view.ensure_cursor_in_view(doc, line); + Ok(()) + } + + fn setting( + cx: &mut compositor::Context, + args: &[Cow], + _event: PromptEvent, + ) -> anyhow::Result<()> { + let runtime_config = &mut cx.editor.config; + + if args.len() != 2 { + anyhow::bail!("Bad arguments. Usage: `:set key field`"); + } + + let (key, arg) = (&args[0].to_lowercase(), &args[1]); + + match key.as_ref() { + "scrolloff" => runtime_config.scrolloff = arg.parse()?, + "scroll-lines" => runtime_config.scroll_lines = arg.parse()?, + "mouse" => runtime_config.mouse = arg.parse()?, + "line-number" => runtime_config.line_number = arg.parse()?, + "middle-click_paste" => runtime_config.middle_click_paste = arg.parse()?, + "smart-case" => runtime_config.smart_case = arg.parse()?, + "auto-pairs" => runtime_config.auto_pairs = arg.parse()?, + "auto-completion" => runtime_config.auto_completion = arg.parse()?, + "completion-trigger-len" => runtime_config.completion_trigger_len = arg.parse()?, + "auto-info" => runtime_config.auto_info = arg.parse()?, + "true-color" => runtime_config.true_color = arg.parse()?, + _ => anyhow::bail!("Unknown key `{}`.", args[0]), + } Ok(()) } @@ -2928,6 +2958,13 @@ pub mod cmd { doc: "Go to line number.", fun: goto_line_number, completer: None, + }, + TypableCommand { + name: "set-option", + aliases: &["set"], + doc: "Set a config option at runtime", + fun: setting, + completer: Some(completers::setting), } ]; diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs index f57e2e2b..9e096311 100644 --- a/helix-term/src/ui/mod.rs +++ b/helix-term/src/ui/mod.rs @@ -174,7 +174,9 @@ pub mod completers { use crate::ui::prompt::Completion; use fuzzy_matcher::skim::SkimMatcherV2 as Matcher; use fuzzy_matcher::FuzzyMatcher; + use helix_view::editor::Config; use helix_view::theme; + use once_cell::sync::Lazy; use std::borrow::Cow; use std::cmp::Reverse; @@ -208,6 +210,31 @@ pub mod completers { names } + pub fn setting(input: &str) -> Vec { + static KEYS: Lazy> = Lazy::new(|| { + serde_json::to_value(Config::default()) + .unwrap() + .as_object() + .unwrap() + .keys() + .cloned() + .collect() + }); + + let matcher = Matcher::default(); + + let mut matches: Vec<_> = KEYS + .iter() + .filter_map(|name| matcher.fuzzy_match(name, input).map(|score| (name, score))) + .collect(); + + matches.sort_unstable_by_key(|(_file, score)| Reverse(*score)); + matches + .into_iter() + .map(|(name, _)| ((0..), name.into())) + .collect() + } + pub fn filename(input: &str) -> Vec { filename_impl(input, |entry| { let is_dir = entry.file_type().map_or(false, |entry| entry.is_dir()); diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index fd6eb4d5..f4b0f73e 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -27,7 +27,7 @@ pub use helix_core::register::Registers; use helix_core::syntax; use helix_core::{Position, Selection}; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; fn deserialize_duration_millis<'de, D>(deserializer: D) -> Result where @@ -37,7 +37,7 @@ where Ok(Duration::from_millis(millis)) } -#[derive(Debug, Clone, PartialEq, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "kebab-case", default, deny_unknown_fields)] pub struct FilePickerConfig { /// IgnoreOptions @@ -77,7 +77,7 @@ impl Default for FilePickerConfig { } } -#[derive(Debug, Clone, PartialEq, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "kebab-case", default, deny_unknown_fields)] pub struct Config { /// Padding to keep between the edge of the screen and the cursor when scrolling. Defaults to 5. @@ -109,7 +109,7 @@ pub struct Config { pub true_color: bool, } -#[derive(Debug, Copy, Clone, PartialEq, Eq, Deserialize)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "kebab-case")] pub enum LineNumber { /// Show absolute line number @@ -119,6 +119,18 @@ pub enum LineNumber { Relative, } +impl std::str::FromStr for LineNumber { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + match s.to_lowercase().as_str() { + "absolute" | "abs" => Ok(Self::Absolute), + "relative" | "rel" => Ok(Self::Relative), + _ => anyhow::bail!("Line number can only be `absolute` or `relative`."), + } + } +} + impl Default for Config { fn default() -> Self { Self { From c7a59e24e6e1609dd65e5ee66fef52f76aabe9b7 Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Sun, 12 Dec 2021 21:09:01 +0800 Subject: [PATCH 49/95] Switch macro Q and q --- book/src/keymap.md | 4 ++-- helix-term/src/keymap.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/book/src/keymap.md b/book/src/keymap.md index d84b17b8..e1df545d 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -77,8 +77,8 @@ | `Alt-c` | Change selection (delete and enter insert mode, without yanking) | `change_selection_noyank` | | `Ctrl-a` | Increment object (number) under cursor | `increment` | | `Ctrl-x` | Decrement object (number) under cursor | `decrement` | -| `q` | Start/stop macro recording to the selected register | `record_macro` | -| `Q` | Play back a recorded macro from the selected register | `play_macro` | +| `Q` | Start/stop macro recording to the selected register | `record_macro` | +| `q` | Play back a recorded macro from the selected register | `play_macro` | #### Shell diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index 257d5f29..917a0990 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -593,8 +593,8 @@ impl Default for Keymaps { // paste_all "P" => paste_before, - "q" => record_macro, - "Q" => play_macro, + "Q" => record_macro, + "q" => play_macro, ">" => indent, "<" => unindent, From 5326a051176d30060e60a8c8d6e718c9ca8a32d7 Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Sun, 12 Dec 2021 21:32:55 +0800 Subject: [PATCH 50/95] Improve macro error handling --- helix-term/src/commands.rs | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 7b1235f8..e3944cd7 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -6031,23 +6031,17 @@ fn record_macro(cx: &mut Context) { fn play_macro(cx: &mut Context) { let reg = cx.register.unwrap_or('@'); - let keys = match cx - .editor - .registers - .get(reg) - .and_then(|reg| reg.read().get(0)) - .context("Register empty") - .and_then(|s| { - s.split_whitespace() - .map(str::parse::) - .collect::, _>>() - .context("Failed to parse macro") - }) { - Ok(keys) => keys, - Err(e) => { - cx.editor.set_error(format!("{}", e)); - return; + let keys: Vec = if let Some([keys]) = cx.editor.registers.read(reg) { + match keys.split_whitespace().map(str::parse).collect() { + Ok(keys) => keys, + Err(err) => { + cx.editor.set_error(format!("Invalid macro: {}", err)); + return; + } } + } else { + cx.editor.set_error(format!("Register [{}] empty", reg)); + return; }; let count = cx.count(); From 9a32617b3093ce6ab3b925d9f1c6b17218c1b491 Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Sun, 12 Dec 2021 21:51:57 +0800 Subject: [PATCH 51/95] Rename play macro to replay macro Macro needs to be defined first before playing so replay is more accurate. Also, replay have the same length as record which makes it looks nice. --- book/src/keymap.md | 2 +- helix-term/src/commands.rs | 6 +++--- helix-term/src/keymap.rs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/book/src/keymap.md b/book/src/keymap.md index e1df545d..b7a1e54b 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -78,7 +78,7 @@ | `Ctrl-a` | Increment object (number) under cursor | `increment` | | `Ctrl-x` | Decrement object (number) under cursor | `decrement` | | `Q` | Start/stop macro recording to the selected register | `record_macro` | -| `q` | Play back a recorded macro from the selected register | `play_macro` | +| `q` | Play back a recorded macro from the selected register | `replay_macro` | #### Shell diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index e3944cd7..ac42682f 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -396,7 +396,7 @@ impl MappableCommand { increment, "Increment", decrement, "Decrement", record_macro, "Record macro", - play_macro, "Play macro", + replay_macro, "Replay macro", ); } @@ -6015,7 +6015,7 @@ fn record_macro(cx: &mut Context) { keys.pop(); let s = keys .into_iter() - .map(|key| format!("{}", key)) + .map(|key| key.to_string()) .collect::>() .join(" "); cx.editor.registers.get_mut(reg).write(vec![s]); @@ -6029,7 +6029,7 @@ fn record_macro(cx: &mut Context) { } } -fn play_macro(cx: &mut Context) { +fn replay_macro(cx: &mut Context) { let reg = cx.register.unwrap_or('@'); let keys: Vec = if let Some([keys]) = cx.editor.registers.read(reg) { match keys.split_whitespace().map(str::parse).collect() { diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index 917a0990..08c8032b 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -594,7 +594,7 @@ impl Default for Keymaps { "P" => paste_before, "Q" => record_macro, - "q" => play_macro, + "q" => replay_macro, ">" => indent, "<" => unindent, From b9cb3930e2838347a97f501e025ee52ea377ed52 Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Sun, 12 Dec 2021 21:54:14 +0800 Subject: [PATCH 52/95] Mark macros as experimental in docs Given that currently macro does not integrate well with registers and the internal representation of macros is expected to be changed. --- book/src/keymap.md | 66 +++++++++++++++++++------------------- helix-term/src/commands.rs | 1 + 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/book/src/keymap.md b/book/src/keymap.md index b7a1e54b..581e70e9 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -46,39 +46,39 @@ ### Changes -| Key | Description | Command | -| ----- | ----------- | ------- | -| `r` | Replace with a character | `replace` | -| `R` | Replace with yanked text | `replace_with_yanked` | -| `~` | Switch case of the selected text | `switch_case` | -| `` ` `` | Set the selected text to lower case | `switch_to_lowercase` | -| `` Alt-` `` | Set the selected text to upper case | `switch_to_uppercase` | -| `i` | Insert before selection | `insert_mode` | -| `a` | Insert after selection (append) | `append_mode` | -| `I` | Insert at the start of the line | `prepend_to_line` | -| `A` | Insert at the end of the line | `append_to_line` | -| `o` | Open new line below selection | `open_below` | -| `O` | Open new line above selection | `open_above` | -| `.` | Repeat last change | N/A | -| `u` | Undo change | `undo` | -| `U` | Redo change | `redo` | -| `Alt-u` | Move backward in history | `earlier` | -| `Alt-U` | Move forward in history | `later` | -| `y` | Yank selection | `yank` | -| `p` | Paste after selection | `paste_after` | -| `P` | Paste before selection | `paste_before` | -| `"` `` | Select a register to yank to or paste from | `select_register` | -| `>` | Indent selection | `indent` | -| `<` | Unindent selection | `unindent` | -| `=` | Format selection (currently nonfunctional/disabled) (**LSP**) | `format_selections` | -| `d` | Delete selection | `delete_selection` | -| `Alt-d` | Delete selection, without yanking | `delete_selection_noyank` | -| `c` | Change selection (delete and enter insert mode) | `change_selection` | -| `Alt-c` | Change selection (delete and enter insert mode, without yanking) | `change_selection_noyank` | -| `Ctrl-a` | Increment object (number) under cursor | `increment` | -| `Ctrl-x` | Decrement object (number) under cursor | `decrement` | -| `Q` | Start/stop macro recording to the selected register | `record_macro` | -| `q` | Play back a recorded macro from the selected register | `replay_macro` | +| Key | Description | Command | +| ----- | ----------- | ------- | +| `r` | Replace with a character | `replace` | +| `R` | Replace with yanked text | `replace_with_yanked` | +| `~` | Switch case of the selected text | `switch_case` | +| `` ` `` | Set the selected text to lower case | `switch_to_lowercase` | +| `` Alt-` `` | Set the selected text to upper case | `switch_to_uppercase` | +| `i` | Insert before selection | `insert_mode` | +| `a` | Insert after selection (append) | `append_mode` | +| `I` | Insert at the start of the line | `prepend_to_line` | +| `A` | Insert at the end of the line | `append_to_line` | +| `o` | Open new line below selection | `open_below` | +| `O` | Open new line above selection | `open_above` | +| `.` | Repeat last change | N/A | +| `u` | Undo change | `undo` | +| `U` | Redo change | `redo` | +| `Alt-u` | Move backward in history | `earlier` | +| `Alt-U` | Move forward in history | `later` | +| `y` | Yank selection | `yank` | +| `p` | Paste after selection | `paste_after` | +| `P` | Paste before selection | `paste_before` | +| `"` `` | Select a register to yank to or paste from | `select_register` | +| `>` | Indent selection | `indent` | +| `<` | Unindent selection | `unindent` | +| `=` | Format selection (currently nonfunctional/disabled) (**LSP**) | `format_selections` | +| `d` | Delete selection | `delete_selection` | +| `Alt-d` | Delete selection, without yanking | `delete_selection_noyank` | +| `c` | Change selection (delete and enter insert mode) | `change_selection` | +| `Alt-c` | Change selection (delete and enter insert mode, without yanking) | `change_selection_noyank` | +| `Ctrl-a` | Increment object (number) under cursor | `increment` | +| `Ctrl-x` | Decrement object (number) under cursor | `decrement` | +| `Q` | Start/stop macro recording to the selected register (experimental) | `record_macro` | +| `q` | Play back a recorded macro from the selected register (experimental) | `replay_macro` | #### Shell diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index ac42682f..d0a94160 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -6031,6 +6031,7 @@ fn record_macro(cx: &mut Context) { fn replay_macro(cx: &mut Context) { let reg = cx.register.unwrap_or('@'); + // TODO: macro keys should be parsed one by one and not space delimited (see kak) let keys: Vec = if let Some([keys]) = cx.editor.registers.read(reg) { match keys.split_whitespace().map(str::parse).collect() { Ok(keys) => keys, From ee3eb4057a1c8a0c979371674451105ac5453b58 Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Sun, 12 Dec 2021 22:05:11 +0800 Subject: [PATCH 53/95] Update macro display as [q] in message --- helix-term/src/commands.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index d0a94160..fdc242fe 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -6020,12 +6020,12 @@ fn record_macro(cx: &mut Context) { .join(" "); cx.editor.registers.get_mut(reg).write(vec![s]); cx.editor - .set_status(format!("Recorded to register {}", reg)); + .set_status(format!("Recorded to register [{}]", reg)); } else { let reg = cx.register.take().unwrap_or('@'); cx.editor.macro_recording = Some((reg, Vec::new())); cx.editor - .set_status(format!("Recording to register {}", reg)); + .set_status(format!("Recording to register [{}]", reg)); } } From 2d4bc0aec743c6d62344da6fda2c0c84e75a82be Mon Sep 17 00:00:00 2001 From: Omnikar Date: Sun, 12 Dec 2021 10:36:52 -0500 Subject: [PATCH 54/95] Change how macros separate keypresses * Keypresses are no longer separated by spaces * Single-character keypresses are serialized as-is * Multi-character keypresses are delimited by `<>` --- helix-term/src/commands.rs | 46 +++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index fdc242fe..4e0f3ef7 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -6015,9 +6015,15 @@ fn record_macro(cx: &mut Context) { keys.pop(); let s = keys .into_iter() - .map(|key| key.to_string()) - .collect::>() - .join(" "); + .map(|key| { + let s = key.to_string(); + if s.chars().count() == 1 { + s + } else { + format!("<{}>", s) + } + }) + .collect::(); cx.editor.registers.get_mut(reg).write(vec![s]); cx.editor .set_status(format!("Recorded to register [{}]", reg)); @@ -6032,8 +6038,38 @@ fn record_macro(cx: &mut Context) { fn replay_macro(cx: &mut Context) { let reg = cx.register.unwrap_or('@'); // TODO: macro keys should be parsed one by one and not space delimited (see kak) - let keys: Vec = if let Some([keys]) = cx.editor.registers.read(reg) { - match keys.split_whitespace().map(str::parse).collect() { + let keys: Vec = if let Some([keys_str]) = cx.editor.registers.read(reg) { + let mut keys_res: anyhow::Result<_> = Ok(Vec::new()); + let mut i = 0; + while let Ok(keys) = &mut keys_res { + if i >= keys_str.len() { + break; + } + if !keys_str.is_char_boundary(i) { + i += 1; + continue; + } + + let s = &keys_str[i..]; + let mut end_i = 1; + while !s.is_char_boundary(end_i) { + end_i += 1; + } + let c = &s[..end_i]; + if c != "<" { + keys.push(c); + i += end_i; + } else { + match s.find('>').context("'>' expected") { + Ok(end_i) => { + keys.push(&s[1..end_i]); + i += end_i + 1; + } + Err(err) => keys_res = Err(err), + } + } + } + match keys_res.and_then(|keys| keys.into_iter().map(str::parse).collect()) { Ok(keys) => keys, Err(err) => { cx.editor.set_error(format!("Invalid macro: {}", err)); From 8340d73545a0757ff3ddd83d019b3d41a923f017 Mon Sep 17 00:00:00 2001 From: Omnikar Date: Sat, 25 Dec 2021 03:38:14 -0500 Subject: [PATCH 55/95] Extract macro parsing to `helix-view` and add unit tests --- helix-term/src/commands.rs | 35 +-------- helix-view/src/input.rs | 153 +++++++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+), 33 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 4e0f3ef7..524c50ce 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -6037,39 +6037,8 @@ fn record_macro(cx: &mut Context) { fn replay_macro(cx: &mut Context) { let reg = cx.register.unwrap_or('@'); - // TODO: macro keys should be parsed one by one and not space delimited (see kak) let keys: Vec = if let Some([keys_str]) = cx.editor.registers.read(reg) { - let mut keys_res: anyhow::Result<_> = Ok(Vec::new()); - let mut i = 0; - while let Ok(keys) = &mut keys_res { - if i >= keys_str.len() { - break; - } - if !keys_str.is_char_boundary(i) { - i += 1; - continue; - } - - let s = &keys_str[i..]; - let mut end_i = 1; - while !s.is_char_boundary(end_i) { - end_i += 1; - } - let c = &s[..end_i]; - if c != "<" { - keys.push(c); - i += end_i; - } else { - match s.find('>').context("'>' expected") { - Ok(end_i) => { - keys.push(&s[1..end_i]); - i += end_i + 1; - } - Err(err) => keys_res = Err(err), - } - } - } - match keys_res.and_then(|keys| keys.into_iter().map(str::parse).collect()) { + match helix_view::input::parse_macro(keys_str) { Ok(keys) => keys, Err(err) => { cx.editor.set_error(format!("Invalid macro: {}", err)); @@ -6080,8 +6049,8 @@ fn replay_macro(cx: &mut Context) { cx.editor.set_error(format!("Register [{}] empty", reg)); return; }; - let count = cx.count(); + let count = cx.count(); cx.callback = Some(Box::new( move |compositor: &mut Compositor, cx: &mut compositor::Context| { for _ in 0..count { diff --git a/helix-view/src/input.rs b/helix-view/src/input.rs index 92caa517..14dadc3b 100644 --- a/helix-view/src/input.rs +++ b/helix-view/src/input.rs @@ -254,6 +254,43 @@ impl From for crossterm::event::KeyEvent { } } +pub fn parse_macro(keys_str: &str) -> anyhow::Result> { + use anyhow::Context; + let mut keys_res: anyhow::Result<_> = Ok(Vec::new()); + let mut i = 0; + while let Ok(keys) = &mut keys_res { + if i >= keys_str.len() { + break; + } + if !keys_str.is_char_boundary(i) { + i += 1; + continue; + } + + let s = &keys_str[i..]; + let mut end_i = 1; + while !s.is_char_boundary(end_i) { + end_i += 1; + } + let c = &s[..end_i]; + if c == ">" { + keys_res = Err(anyhow!("Unmatched '>'")); + } else if c != "<" { + keys.push(c); + i += end_i; + } else { + match s.find('>').context("'>' expected") { + Ok(end_i) => { + keys.push(&s[1..end_i]); + i += end_i + 1; + } + Err(err) => keys_res = Err(err), + } + } + } + keys_res.and_then(|keys| keys.into_iter().map(str::parse).collect()) +} + #[cfg(test)] mod test { use super::*; @@ -339,4 +376,120 @@ mod test { assert!(str::parse::("123").is_err()); assert!(str::parse::("S--").is_err()); } + + #[test] + fn parsing_valid_macros() { + assert_eq!( + parse_macro("xdo").ok(), + Some(vec![ + KeyEvent { + code: KeyCode::Char('x'), + modifiers: KeyModifiers::NONE, + }, + KeyEvent { + code: KeyCode::Char('d'), + modifiers: KeyModifiers::NONE, + }, + KeyEvent { + code: KeyCode::Char('o'), + modifiers: KeyModifiers::NONE, + }, + ]), + ); + + assert_eq!( + parse_macro("vhxx").ok(), + Some(vec![ + KeyEvent { + code: KeyCode::Char('w'), + modifiers: KeyModifiers::CONTROL, + }, + KeyEvent { + code: KeyCode::Char('v'), + modifiers: KeyModifiers::NONE, + }, + KeyEvent { + code: KeyCode::Char('w'), + modifiers: KeyModifiers::CONTROL, + }, + KeyEvent { + code: KeyCode::Char('h'), + modifiers: KeyModifiers::NONE, + }, + KeyEvent { + code: KeyCode::Char('o'), + modifiers: KeyModifiers::CONTROL, + }, + KeyEvent { + code: KeyCode::Char('x'), + modifiers: KeyModifiers::NONE, + }, + KeyEvent { + code: KeyCode::Char('x'), + modifiers: KeyModifiers::NONE, + }, + KeyEvent { + code: KeyCode::Char('s'), + modifiers: KeyModifiers::ALT, + }, + ]) + ); + + assert_eq!( + parse_macro(":o foo.bar").ok(), + Some(vec![ + KeyEvent { + code: KeyCode::Char(':'), + modifiers: KeyModifiers::NONE, + }, + KeyEvent { + code: KeyCode::Char('o'), + modifiers: KeyModifiers::NONE, + }, + KeyEvent { + code: KeyCode::Char(' '), + modifiers: KeyModifiers::NONE, + }, + KeyEvent { + code: KeyCode::Char('f'), + modifiers: KeyModifiers::NONE, + }, + KeyEvent { + code: KeyCode::Char('o'), + modifiers: KeyModifiers::NONE, + }, + KeyEvent { + code: KeyCode::Char('o'), + modifiers: KeyModifiers::NONE, + }, + KeyEvent { + code: KeyCode::Char('.'), + modifiers: KeyModifiers::NONE, + }, + KeyEvent { + code: KeyCode::Char('b'), + modifiers: KeyModifiers::NONE, + }, + KeyEvent { + code: KeyCode::Char('a'), + modifiers: KeyModifiers::NONE, + }, + KeyEvent { + code: KeyCode::Char('r'), + modifiers: KeyModifiers::NONE, + }, + KeyEvent { + code: KeyCode::Enter, + modifiers: KeyModifiers::NONE, + }, + ]) + ); + } + + #[test] + fn parsing_invalid_macros_fails() { + assert!(parse_macro("abc123").is_err()); + assert!(parse_macro("wd").is_err()); + } } From 7001665342ade12823fba4f358a7e8efc2245a2b Mon Sep 17 00:00:00 2001 From: Stuart Hinson Date: Sun, 26 Dec 2021 23:07:09 -0500 Subject: [PATCH 56/95] Add ruby indents (#1372) * Add ruby indents * Include ruby in generated docs --- book/src/generated/lang-support.md | 2 +- runtime/queries/ruby/indents.toml | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 runtime/queries/ruby/indents.toml diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 9c42005b..28094484 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -34,7 +34,7 @@ | protobuf | ✓ | | ✓ | | | python | ✓ | ✓ | ✓ | `pylsp` | | racket | | | | `racket` | -| ruby | ✓ | | | `solargraph` | +| ruby | ✓ | | ✓ | `solargraph` | | rust | ✓ | ✓ | ✓ | `rust-analyzer` | | scala | ✓ | | ✓ | `metals` | | svelte | ✓ | | ✓ | `svelteserver` | diff --git a/runtime/queries/ruby/indents.toml b/runtime/queries/ruby/indents.toml new file mode 100644 index 00000000..b417751f --- /dev/null +++ b/runtime/queries/ruby/indents.toml @@ -0,0 +1,25 @@ +indent = [ + "argument_list", + "array", + "begin", + "block", + "call", + "class", + "case", + "do_block", + "elsif", + "if", + "hash", + "method", + "module", + "singleton_class", + "singleton_method", +] + +outdent = [ + ")", + "}", + "]", + "end", + "when", +] From a4641a8613bcbe4ad01d28d3d2a6f4509fef96a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Dzivjak?= Date: Mon, 27 Dec 2021 05:11:06 +0100 Subject: [PATCH 57/95] feat(commands): sort command (#1288) * feat(commands): sort/rsort command Add basic implementation of sort command. * Sort by selections instead, implement reverse sort * Generate docs * Rename sort! to rsort --- book/src/generated/typable-cmd.md | 2 + helix-term/src/commands.rs | 66 ++++++++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/book/src/generated/typable-cmd.md b/book/src/generated/typable-cmd.md index f12082bb..45129cc1 100644 --- a/book/src/generated/typable-cmd.md +++ b/book/src/generated/typable-cmd.md @@ -42,3 +42,5 @@ | `:tutor` | Open the tutorial. | | `:goto`, `:g` | Go to line number. | | `:set-option`, `:set` | Set a config option at runtime | +| `:sort` | Sort ranges in selection. | +| `:rsort` | Sort ranges in selection in reverse order. | diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 524c50ce..16a2cf35 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -2671,6 +2671,56 @@ pub mod cmd { Ok(()) } + fn sort( + cx: &mut compositor::Context, + args: &[Cow], + _event: PromptEvent, + ) -> anyhow::Result<()> { + sort_impl(cx, args, false) + } + + fn sort_reverse( + cx: &mut compositor::Context, + args: &[Cow], + _event: PromptEvent, + ) -> anyhow::Result<()> { + sort_impl(cx, args, true) + } + + fn sort_impl( + cx: &mut compositor::Context, + _args: &[Cow], + reverse: bool, + ) -> anyhow::Result<()> { + let (view, doc) = current!(cx.editor); + let text = doc.text().slice(..); + + let selection = doc.selection(view.id); + + let mut fragments: Vec<_> = selection + .fragments(text) + .map(|fragment| Tendril::from_slice(&fragment)) + .collect(); + + fragments.sort_by(match reverse { + true => |a: &Tendril, b: &Tendril| b.cmp(a), + false => |a: &Tendril, b: &Tendril| a.cmp(b), + }); + + let transaction = Transaction::change( + doc.text(), + selection + .into_iter() + .zip(fragments) + .map(|(s, fragment)| (s.from(), s.to(), Some(fragment))), + ); + + doc.apply(&transaction, view.id); + doc.append_changes_to_history(view.id); + + Ok(()) + } + pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ TypableCommand { name: "quit", @@ -2965,7 +3015,21 @@ pub mod cmd { doc: "Set a config option at runtime", fun: setting, completer: Some(completers::setting), - } + }, + TypableCommand { + name: "sort", + aliases: &[], + doc: "Sort ranges in selection.", + fun: sort, + completer: None, + }, + TypableCommand { + name: "rsort", + aliases: &[], + doc: "Sort ranges in selection in reverse order.", + fun: sort_reverse, + completer: None, + }, ]; pub static TYPABLE_COMMAND_MAP: Lazy> = From 5b69e9b46623f586cedcf42b0c43dbc5c1bf0eaf Mon Sep 17 00:00:00 2001 From: Omnikar Date: Mon, 27 Dec 2021 18:03:14 -0500 Subject: [PATCH 58/95] Fix indentation (#1387) --- helix-term/src/commands.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 16a2cf35..04dd222b 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -2744,18 +2744,18 @@ pub mod cmd { completer: Some(completers::filename), }, TypableCommand { - name: "buffer-close", - aliases: &["bc", "bclose"], - doc: "Close the current buffer.", - fun: buffer_close, - completer: None, // FIXME: buffer completer + name: "buffer-close", + aliases: &["bc", "bclose"], + doc: "Close the current buffer.", + fun: buffer_close, + completer: None, // FIXME: buffer completer }, TypableCommand { - name: "buffer-close!", - aliases: &["bc!", "bclose!"], - doc: "Close the current buffer forcefully (ignoring unsaved changes).", - fun: force_buffer_close, - completer: None, // FIXME: buffer completer + name: "buffer-close!", + aliases: &["bc!", "bclose!"], + doc: "Close the current buffer forcefully (ignoring unsaved changes).", + fun: force_buffer_close, + completer: None, // FIXME: buffer completer }, TypableCommand { name: "write", From 1d2009e4f0e5029b99b70c00f78e4f8974f5a7f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Dec 2021 09:35:08 +0900 Subject: [PATCH 59/95] build(deps): bump chardetng from 0.1.15 to 0.1.17 (#1390) Bumps [chardetng](https://github.com/hsivonen/chardetng) from 0.1.15 to 0.1.17. - [Release notes](https://github.com/hsivonen/chardetng/releases) - [Commits](https://github.com/hsivonen/chardetng/compare/v0.1.15...v0.1.17) --- updated-dependencies: - dependency-name: chardetng dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 40afe4e5..fd4c3b06 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -78,9 +78,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chardetng" -version = "0.1.15" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83ee29c16b81c32fbc882ecc568305793338a8353952573db837f4f4a6cd5c2e" +checksum = "14b8f0b65b7b08ae3c8187e8d77174de20cb6777864c6b832d8ad365999cf1ea" dependencies = [ "cfg-if", "encoding_rs", From dc1faa35cbb92231c037241d01e25ae18ac36176 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Dec 2021 09:35:17 +0900 Subject: [PATCH 60/95] build(deps): bump anyhow from 1.0.51 to 1.0.52 (#1392) Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.51 to 1.0.52. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.51...1.0.52) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fd4c3b06..83343fc4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.51" +version = "1.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203" +checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3" [[package]] name = "arc-swap" From bd2ab5be4331a2ab6d406378a9c0868eb2f72819 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Dzivjak?= Date: Wed, 29 Dec 2021 10:17:46 +0100 Subject: [PATCH 61/95] feat(commands): ensure_selections_forward (#1393) * feat(commands): ensure_selections_forward Add command that ensures that selections are in forward direction. Fixes: https://github.com/helix-editor/helix/issues/1332 * Add keybinding for ensure_selections_forward Add `A-:` keybinding for the ensure_selections_forward command. * Re-use range.flip for flip_selections command --- helix-core/src/selection.rs | 9 +++++++++ helix-term/src/commands.rs | 17 ++++++++++++++++- helix-term/src/keymap.rs | 2 ++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/helix-core/src/selection.rs b/helix-core/src/selection.rs index 884c98ac..06ea9d67 100644 --- a/helix-core/src/selection.rs +++ b/helix-core/src/selection.rs @@ -122,6 +122,15 @@ impl Range { } } + // flips the direction of the selection + pub fn flip(&self) -> Self { + Self { + anchor: self.head, + head: self.anchor, + horiz: self.horiz, + } + } + /// Check two ranges for overlap. #[must_use] pub fn overlaps(&self, other: &Self) -> bool { diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 04dd222b..9c1650b8 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -266,6 +266,7 @@ impl MappableCommand { change_selection_noyank, "Change selection (delete and enter insert mode, without yanking)", collapse_selection, "Collapse selection onto a single cursor", flip_selections, "Flip selection cursor and anchor", + ensure_selections_forward, "Ensure the selection is in forward direction", insert_mode, "Insert before selection", append_mode, "Insert after selection (append)", command_mode, "Enter command mode", @@ -1904,7 +1905,21 @@ fn flip_selections(cx: &mut Context) { let selection = doc .selection(view.id) .clone() - .transform(|range| Range::new(range.head, range.anchor)); + .transform(|range| range.flip()); + doc.set_selection(view.id, selection); +} + +fn ensure_selections_forward(cx: &mut Context) { + let (view, doc) = current!(cx.editor); + + let selection = doc + .selection(view.id) + .clone() + .transform(|r| match r.direction() { + Direction::Forward => r, + Direction::Backward => r.flip(), + }); + doc.set_selection(view.id, selection); } diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index 08c8032b..72833212 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -617,6 +617,8 @@ impl Default for Keymaps { "A-(" => rotate_selection_contents_backward, "A-)" => rotate_selection_contents_forward, + "A-:" => ensure_selections_forward, + "esc" => normal_mode, "C-b" | "pageup" => page_up, "C-f" | "pagedown" => page_down, From 34db33e1dcbb845134f36f90695799a2de472e35 Mon Sep 17 00:00:00 2001 From: Stuart Hinson Date: Wed, 29 Dec 2021 04:18:17 -0500 Subject: [PATCH 62/95] Use a fuzzy matcher for commands (#1386) * Use a fuzzy matcher for commands * Take Clippy up on its suggestion * Rescope FUZZY_MATCHER --- helix-term/src/commands.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 9c1650b8..139e7ceb 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -26,6 +26,7 @@ use helix_view::{ }; use anyhow::{anyhow, bail, ensure, Context as _}; +use fuzzy_matcher::FuzzyMatcher; use helix_lsp::{ block_on, lsp, util::{lsp_pos_to_pos, lsp_range_to_range, pos_to_lsp_pos, range_to_lsp_range}, @@ -3064,6 +3065,9 @@ fn command_mode(cx: &mut Context) { ":".into(), Some(':'), |input: &str| { + static FUZZY_MATCHER: Lazy = + Lazy::new(fuzzy_matcher::skim::SkimMatcherV2::default); + // we use .this over split_whitespace() because we care about empty segments let parts = input.split(' ').collect::>(); @@ -3073,7 +3077,7 @@ fn command_mode(cx: &mut Context) { let end = 0..; cmd::TYPABLE_COMMAND_LIST .iter() - .filter(|command| command.name.contains(input)) + .filter(|command| FUZZY_MATCHER.fuzzy_match(command.name, input).is_some()) .map(|command| (end.clone(), Cow::Borrowed(command.name))) .collect() } else { From f1ed042c84fedebc1eff91d00c9c58477e912edc Mon Sep 17 00:00:00 2001 From: WindSoilder Date: Wed, 29 Dec 2021 17:21:20 +0800 Subject: [PATCH 63/95] Fix: when goto normal mode, only want to remove indentation if the line is blank with no text following (#1349) * when opened new line contains other characters after current position, don't dedent * abstract checking logic --- helix-term/src/commands.rs | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 139e7ceb..9d7d11eb 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -3776,26 +3776,30 @@ fn normal_mode(cx: &mut Context) { } fn try_restore_indent(doc: &mut Document, view_id: ViewId) { - let doc_changes = doc.changes().changes(); - let text = doc.text().slice(..); - let pos = doc.selection(view_id).primary().cursor(text); - let mut can_restore_indent = false; - - // Removes trailing whitespace if insert mode is exited after starting a blank new line. use helix_core::chars::char_is_whitespace; use helix_core::Operation; - if let [Operation::Retain(move_pos), Operation::Insert(ref inserted_str), Operation::Retain(_)] = - doc_changes - { - if move_pos + inserted_str.len32() as usize == pos - && inserted_str.starts_with('\n') - && inserted_str.chars().skip(1).all(char_is_whitespace) + + fn inserted_a_new_blank_line(changes: &[Operation], pos: usize, line_end_pos: usize) -> bool { + if let [Operation::Retain(move_pos), Operation::Insert(ref inserted_str), Operation::Retain(_)] = + changes { - can_restore_indent = true; + move_pos + inserted_str.len32() as usize == pos + && inserted_str.starts_with('\n') + && inserted_str.chars().skip(1).all(char_is_whitespace) + && pos == line_end_pos // ensure no characters exists after current position + } else { + false } } - if can_restore_indent { + let doc_changes = doc.changes().changes(); + let text = doc.text().slice(..); + let range = doc.selection(view_id).primary(); + let pos = range.cursor(text); + let line_end_pos = line_end_char_index(&text, range.cursor_line(text)); + + if inserted_a_new_blank_line(doc_changes, pos, line_end_pos) { + // Removes tailing whitespaces. let transaction = Transaction::change_by_selection(doc.text(), doc.selection(view_id), |range| { let line_start_pos = text.line_to_char(range.cursor_line(text)); From 8c29b76bccc51c19c90f7c9ee156fe2cb6f52e2c Mon Sep 17 00:00:00 2001 From: Sebastian Neubauer Date: Wed, 29 Dec 2021 10:30:44 +0100 Subject: [PATCH 64/95] Improve llvm highlighting and queries (#1388) * Improve llvm highlighting and queries The llvm tree-sitter parser was updated to support scopes and more accurate highlighting. * Group highlight expressions better --- book/src/generated/lang-support.md | 2 +- helix-syntax/languages/tree-sitter-llvm | 2 +- runtime/queries/llvm/highlights.scm | 162 ++++++++++++++++++++++-- runtime/queries/llvm/indents.toml | 8 ++ runtime/queries/llvm/locals.scm | 14 ++ runtime/queries/llvm/textobjects.scm | 16 +++ 6 files changed, 193 insertions(+), 11 deletions(-) create mode 100644 runtime/queries/llvm/indents.toml create mode 100644 runtime/queries/llvm/locals.scm create mode 100644 runtime/queries/llvm/textobjects.scm diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 28094484..5d172751 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -21,7 +21,7 @@ | julia | ✓ | | | `julia` | | latex | ✓ | | | | | ledger | ✓ | | | | -| llvm | ✓ | | | | +| llvm | ✓ | ✓ | ✓ | | | lua | ✓ | | ✓ | | | markdown | ✓ | | | | | mint | | | | `mint` | diff --git a/helix-syntax/languages/tree-sitter-llvm b/helix-syntax/languages/tree-sitter-llvm index d4f61bed..3b213925 160000 --- a/helix-syntax/languages/tree-sitter-llvm +++ b/helix-syntax/languages/tree-sitter-llvm @@ -1 +1 @@ -Subproject commit d4f61bed8ecb632addcd5e088c4f4cb9c1bf1c5b +Subproject commit 3b213925b9c4f42c1acfe2e10bfbb438d9c6834d diff --git a/runtime/queries/llvm/highlights.scm b/runtime/queries/llvm/highlights.scm index 73afe85e..cb705197 100644 --- a/runtime/queries/llvm/highlights.scm +++ b/runtime/queries/llvm/highlights.scm @@ -1,14 +1,158 @@ (type) @type -(statement) @keyword.operator +(type_keyword) @type.builtin + +(type [ + (local_var) + (global_var) + ] @type) + +(argument) @variable.parameter + +(_ inst_name: _ @keyword.operator) + +[ + "catch" + "filter" +] @keyword.operator + +[ + "to" + "nuw" + "nsw" + "exact" + "unwind" + "from" + "cleanup" + "swifterror" + "volatile" + "inbounds" + "inrange" + (icmp_cond) + (fcmp_cond) + (fast_math) +] @keyword.control + +(_ callee: _ @function) +(function_header name: _ @function) + +[ + "declare" + "define" + (calling_conv) +] @keyword.function + +[ + "target" + "triple" + "datalayout" + "source_filename" + "addrspace" + "blockaddress" + "align" + "syncscope" + "within" + "uselistorder" + "uselistorder_bb" + "module" + "asm" + "sideeffect" + "alignstack" + "inteldialect" + "unwind" + "type" + "global" + "constant" + "externally_initialized" + "alias" + "ifunc" + "section" + "comdat" + "thread_local" + "localdynamic" + "initialexec" + "localexec" + "any" + "exactmatch" + "largest" + "nodeduplicate" + "samesize" + "distinct" + "attributes" + "vscale" + "no_cfi" + (linkage_aux) + (dso_local) + (visibility) + (dll_storage_class) + (unnamed_addr) + (attribute_name) +] @keyword + + +(function_header [ + (linkage) + (calling_conv) + (unnamed_addr) + ] @keyword.function) + +[ + (string) + (cstring) +] @string + (number) @constant.numeric.integer (comment) @comment -(string) @string (label) @label -(keyword) @keyword -"ret" @keyword.control.return -(boolean) @constant.builtin.boolean +(_ inst_name: "ret" @keyword.control.return) (float) @constant.numeric.float -(constant) @constant -(identifier) @variable -(symbol) @punctuation.delimiter -(bracket) @punctuation.bracket + +[ + (local_var) + (global_var) +] @variable + +[ + (struct_value) + (array_value) + (vector_value) +] @constructor + +[ + "(" + ")" + "[" + "]" + "{" + "}" + "<" + ">" + "<{" + "}>" +] @punctuation.bracket + +[ + "," + ":" +] @punctuation.delimiter + +[ + "=" + "|" + "x" + "..." +] @operator + +[ + "true" + "false" +] @constant.builtin.boolean + +[ + "undef" + "poison" + "null" + "none" + "zeroinitializer" +] @constant.builtin + +(ERROR) @error diff --git a/runtime/queries/llvm/indents.toml b/runtime/queries/llvm/indents.toml new file mode 100644 index 00000000..8cd603c8 --- /dev/null +++ b/runtime/queries/llvm/indents.toml @@ -0,0 +1,8 @@ +indent = [ + "function_body", + "instruction", +] + +outdent = [ + "}", +] diff --git a/runtime/queries/llvm/locals.scm b/runtime/queries/llvm/locals.scm new file mode 100644 index 00000000..1946c287 --- /dev/null +++ b/runtime/queries/llvm/locals.scm @@ -0,0 +1,14 @@ +; Scopes + +(function_body) @local.scope + +; Definitions + +(argument + (value (var (local_var) @local.definition))) + +(instruction + (local_var) @local.definition) + +; References +(local_var) @local.reference diff --git a/runtime/queries/llvm/textobjects.scm b/runtime/queries/llvm/textobjects.scm new file mode 100644 index 00000000..3738a3bb --- /dev/null +++ b/runtime/queries/llvm/textobjects.scm @@ -0,0 +1,16 @@ +(define + body: (_) @function.inside) @function.around + +(struct_type + (struct_body) @class.inside) @class.around + +(packed_struct_type + (struct_body) @class.inside) @class.around + +(array_type + (array_vector_body) @class.inside) @class.around + +(vector_type + (array_vector_body) @class.inside) @class.around + +(argument) @parameter.inside From 49444f9c0569a070ffd3c82cee6146656a0ac63c Mon Sep 17 00:00:00 2001 From: ath3 <45574139+ath3@users.noreply.github.com> Date: Wed, 29 Dec 2021 16:30:20 +0100 Subject: [PATCH 65/95] Convert Windows style path separator in completers to Unix style (#1389) --- helix-term/src/ui/mod.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs index 9e096311..9bf88840 100644 --- a/helix-term/src/ui/mod.rs +++ b/helix-term/src/ui/mod.rs @@ -313,7 +313,7 @@ pub mod completers { return None; } - //let is_dir = entry.file_type().map_or(false, |entry| entry.is_dir()); + let is_dir = entry.file_type().map_or(false, |entry| entry.is_dir()); let path = entry.path(); let mut path = if is_tilde { @@ -331,7 +331,12 @@ pub mod completers { path.push(""); } - let path = path.to_str().unwrap().to_owned(); + let path = if cfg!(windows) && is_dir { + // Convert Windows style path separator to Unix style + path.to_str().unwrap().replace("\\", "/") + } else { + path.to_str().unwrap().to_owned() + }; Some((end.clone(), Cow::from(path))) }) }) // TODO: unwrap or skip From bcf3808e9763bfe1bbf70f6053f890c80639d7c9 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Wed, 29 Dec 2021 09:31:23 -0600 Subject: [PATCH 66/95] Add tree-sitter-git-diff (#1373) * add submodule on tree-sitter-git-diff * add git-diff highlights * inject git-diff into git-commit * update tree-sitter-git-commit with fix for bad diff case * add git-diff to language support docs * include-children in diff injections This ensures that children nodes of $.message are included in the injection, such as $.user or issue/pr numbers. Without this change, diffs containing '#' or '@' characters can trip up the injection and be parsed separately. See https://github.com/helix-editor/helix/pull/1373#issuecomment-1001215629 * set diff language's scope as source.diff --- .gitmodules | 4 ++++ book/src/generated/lang-support.md | 1 + helix-syntax/languages/tree-sitter-git-commit | 2 +- helix-syntax/languages/tree-sitter-git-diff | 1 + languages.toml | 9 +++++++++ runtime/queries/git-commit/highlights.scm | 4 ---- runtime/queries/git-commit/injections.scm | 13 ++++--------- runtime/queries/git-diff/highlights.scm | 6 ++++++ 8 files changed, 26 insertions(+), 14 deletions(-) create mode 160000 helix-syntax/languages/tree-sitter-git-diff create mode 100644 runtime/queries/git-diff/highlights.scm diff --git a/.gitmodules b/.gitmodules index d5bd61c9..422671b4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -174,3 +174,7 @@ path = helix-syntax/languages/tree-sitter-git-commit url = https://github.com/the-mikedavis/tree-sitter-git-commit.git shallow = true +[submodule "helix-syntax/languages/tree-sitter-git-diff"] + path = helix-syntax/languages/tree-sitter-git-diff + url = https://github.com/the-mikedavis/tree-sitter-git-diff.git + shallow = true diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 5d172751..91575c62 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -12,6 +12,7 @@ | elixir | ✓ | | | `elixir-ls` | | fish | ✓ | ✓ | ✓ | | | git-commit | ✓ | | | | +| git-diff | ✓ | | | | | glsl | ✓ | | ✓ | | | go | ✓ | ✓ | ✓ | `gopls` | | html | ✓ | | | | diff --git a/helix-syntax/languages/tree-sitter-git-commit b/helix-syntax/languages/tree-sitter-git-commit index 5cd4776c..066e395e 160000 --- a/helix-syntax/languages/tree-sitter-git-commit +++ b/helix-syntax/languages/tree-sitter-git-commit @@ -1 +1 @@ -Subproject commit 5cd4776c86c82d9d6afdc8c73a47a08057aef618 +Subproject commit 066e395e1107df17183cf3ae4230f1a1406cc972 diff --git a/helix-syntax/languages/tree-sitter-git-diff b/helix-syntax/languages/tree-sitter-git-diff new file mode 160000 index 00000000..c12e6ecb --- /dev/null +++ b/helix-syntax/languages/tree-sitter-git-diff @@ -0,0 +1 @@ +Subproject commit c12e6ecb54485f764250556ffd7ccb18f8e2942b diff --git a/languages.toml b/languages.toml index 616ef234..c3ae9f62 100644 --- a/languages.toml +++ b/languages.toml @@ -481,3 +481,12 @@ roots = [] file-types = ["COMMIT_EDITMSG"] comment-token = "#" indent = { tab-width = 2, unit = " " } + +[[language]] +name = "git-diff" +scope = "source.diff" +roots = [] +file-types = ["diff"] +injection-regex = "diff" +comment-token = "#" +indent = { tab-width = 2, unit = " " } diff --git a/runtime/queries/git-commit/highlights.scm b/runtime/queries/git-commit/highlights.scm index a74bb381..ffcc31ae 100644 --- a/runtime/queries/git-commit/highlights.scm +++ b/runtime/queries/git-commit/highlights.scm @@ -13,7 +13,3 @@ [":" "->"] @punctuation.delimeter (comment) @comment - -; once we have diff injections, @comment should become @none -((comment (scissors)) - (message)+ @comment) diff --git a/runtime/queries/git-commit/injections.scm b/runtime/queries/git-commit/injections.scm index 2837a586..bd96f1de 100644 --- a/runtime/queries/git-commit/injections.scm +++ b/runtime/queries/git-commit/injections.scm @@ -1,12 +1,7 @@ -; once a diff grammar is available, we can inject diff highlighting into the -; trailer after scissors (git commit --verbose) -; see https://github.com/helix-editor/helix/pull/1338#issuecomment-1000013539 -; -; ((comment (scissors)) -; (message) @injection.content -; (#set! injection.language "diff")) - -; --- +((comment (scissors)) + (message) @injection.content + (#set! injection.include-children) + (#set! injection.language "diff")) ; once a rebase grammar is available, we can inject rebase highlighting into ; interactive rebase summary sections like so: diff --git a/runtime/queries/git-diff/highlights.scm b/runtime/queries/git-diff/highlights.scm new file mode 100644 index 00000000..1c1a8829 --- /dev/null +++ b/runtime/queries/git-diff/highlights.scm @@ -0,0 +1,6 @@ +[(addition) (new_file)] @diff.plus +[(deletion) (old_file)] @diff.minus + +(commit) @constant +(location) @attribute +(command) @markup.bold From a066f59dc87608935ef4a3a3df3edf180c809e11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Thu, 30 Dec 2021 15:20:22 +0900 Subject: [PATCH 67/95] Don't just filter commands by fuzzy match, also order the matches --- helix-term/src/commands.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 9d7d11eb..6259ecb2 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -3074,11 +3074,19 @@ fn command_mode(cx: &mut Context) { // simple heuristic: if there's no just one part, complete command name. // if there's a space, per command completion kicks in. if parts.len() <= 1 { - let end = 0..; - cmd::TYPABLE_COMMAND_LIST + let mut matches: Vec<_> = cmd::TYPABLE_COMMAND_LIST .iter() - .filter(|command| FUZZY_MATCHER.fuzzy_match(command.name, input).is_some()) - .map(|command| (end.clone(), Cow::Borrowed(command.name))) + .filter_map(|command| { + FUZZY_MATCHER + .fuzzy_match(command.name, input) + .map(|score| (command.name, score)) + }) + .collect(); + + matches.sort_unstable_by_key(|(_file, score)| std::cmp::Reverse(*score)); + matches + .into_iter() + .map(|(name, _)| (0.., name.into())) .collect() } else { let part = parts.last().unwrap(); From 8fda87af2bb0625c502a23ddbd78a7447ada7bcb Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Thu, 30 Dec 2021 16:58:47 -0600 Subject: [PATCH 68/95] add tree-sitter-git-rebase (#1402) * add submodule on tree-sitter-rebase, add to languages * add basic highlights query * inject bash in execute statements * update tree-sitter-rebase * tree-sitter-rebase->tree-sitter-git-rebase * get injection working with tree-sitter-git-commit * set scope under source.gitrebase * unset include-children on commit message injections * Revert "unset include-children on commit message injections" This reverts commit 2ecee155ea8e229651920b291062c2ee84b47944. * fix generated language docs * use rebase_command scopes from tree-sitter-git-commit --- .gitmodules | 4 ++++ book/src/generated/lang-support.md | 1 + helix-syntax/languages/tree-sitter-git-rebase | 1 + languages.toml | 9 +++++++++ runtime/queries/git-commit/highlights.scm | 1 - runtime/queries/git-commit/injections.scm | 8 +++----- runtime/queries/git-rebase/highlights.scm | 11 +++++++++++ runtime/queries/git-rebase/injections.scm | 4 ++++ 8 files changed, 33 insertions(+), 6 deletions(-) create mode 160000 helix-syntax/languages/tree-sitter-git-rebase create mode 100644 runtime/queries/git-rebase/highlights.scm create mode 100644 runtime/queries/git-rebase/injections.scm diff --git a/.gitmodules b/.gitmodules index 422671b4..22f70c80 100644 --- a/.gitmodules +++ b/.gitmodules @@ -178,3 +178,7 @@ path = helix-syntax/languages/tree-sitter-git-diff url = https://github.com/the-mikedavis/tree-sitter-git-diff.git shallow = true +[submodule "helix-syntax/languages/tree-sitter-git-rebase"] + path = helix-syntax/languages/tree-sitter-git-rebase + url = https://github.com/the-mikedavis/tree-sitter-git-rebase.git + shallow = true diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 91575c62..09284d46 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -13,6 +13,7 @@ | fish | ✓ | ✓ | ✓ | | | git-commit | ✓ | | | | | git-diff | ✓ | | | | +| git-rebase | ✓ | | | | | glsl | ✓ | | ✓ | | | go | ✓ | ✓ | ✓ | `gopls` | | html | ✓ | | | | diff --git a/helix-syntax/languages/tree-sitter-git-rebase b/helix-syntax/languages/tree-sitter-git-rebase new file mode 160000 index 00000000..332dc528 --- /dev/null +++ b/helix-syntax/languages/tree-sitter-git-rebase @@ -0,0 +1 @@ +Subproject commit 332dc528f27044bc4427024dbb33e6941fc131f2 diff --git a/languages.toml b/languages.toml index c3ae9f62..3d9bac7b 100644 --- a/languages.toml +++ b/languages.toml @@ -490,3 +490,12 @@ file-types = ["diff"] injection-regex = "diff" comment-token = "#" indent = { tab-width = 2, unit = " " } + +[[language]] +name = "git-rebase" +scope = "source.gitrebase" +roots = [] +file-types = ["git-rebase-todo"] +injection-regex = "git-rebase" +comment-token = "#" +indent = { tab-width = 2, unit = " " } diff --git a/runtime/queries/git-commit/highlights.scm b/runtime/queries/git-commit/highlights.scm index ffcc31ae..0b50d419 100644 --- a/runtime/queries/git-commit/highlights.scm +++ b/runtime/queries/git-commit/highlights.scm @@ -4,7 +4,6 @@ (commit) @constant (item) @markup.link.url (header) @tag -(rebase_command) @markup.raw (change kind: "new file" @diff.plus) (change kind: "deleted" @diff.minus) diff --git a/runtime/queries/git-commit/injections.scm b/runtime/queries/git-commit/injections.scm index bd96f1de..cf0657f7 100644 --- a/runtime/queries/git-commit/injections.scm +++ b/runtime/queries/git-commit/injections.scm @@ -3,8 +3,6 @@ (#set! injection.include-children) (#set! injection.language "diff")) -; once a rebase grammar is available, we can inject rebase highlighting into -; interactive rebase summary sections like so: -; -; ((rebase_command) @injection.content -; (#set! injection.language "git-rebase")) +((rebase_command) @injection.content + (#set! injection.include-children) + (#set! injection.language "git-rebase")) diff --git a/runtime/queries/git-rebase/highlights.scm b/runtime/queries/git-rebase/highlights.scm new file mode 100644 index 00000000..4f007037 --- /dev/null +++ b/runtime/queries/git-rebase/highlights.scm @@ -0,0 +1,11 @@ +(operation operator: ["p" "pick" "r" "reword" "e" "edit" "s" "squash" "m" "merge" "d" "drop" "b" "break" "x" "exec"] @keyword) +(operation operator: ["l" "label" "t" "reset"] @function) +(operation operator: ["f" "fixup"] @function.special) + +(option) @operator +(label) @string.special.symbol +(commit) @constant +"#" @punctuation.delimiter +(comment) @comment + +(ERROR) @error diff --git a/runtime/queries/git-rebase/injections.scm b/runtime/queries/git-rebase/injections.scm new file mode 100644 index 00000000..070129b6 --- /dev/null +++ b/runtime/queries/git-rebase/injections.scm @@ -0,0 +1,4 @@ +((operation + operator: ["x" "exec"] + (command) @injection.content) + (#set! injection.language "bash")) From 8a019b423f5d51bcfc107da9cb50aa90eacff19d Mon Sep 17 00:00:00 2001 From: Alexis Mousset Date: Fri, 31 Dec 2021 09:06:54 +0100 Subject: [PATCH 69/95] Detect workspace root using language markers (#1370) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Detect workspace root using language markers * Avoid allocating root_markers * Update helix-core/src/lib.rs Co-authored-by: Blaž Hrastnik * Update helix-core/src/lib.rs Co-authored-by: Kirawi <67773714+kirawi@users.noreply.github.com> Co-authored-by: Blaž Hrastnik Co-authored-by: Kirawi <67773714+kirawi@users.noreply.github.com> --- helix-core/src/lib.rs | 32 ++++++++++++++++++++++++++------ helix-lsp/src/client.rs | 6 +++++- helix-lsp/src/lib.rs | 1 + helix-term/src/commands.rs | 3 ++- languages.toml | 2 +- 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/helix-core/src/lib.rs b/helix-core/src/lib.rs index 1c78e7c0..7fd23b97 100644 --- a/helix-core/src/lib.rs +++ b/helix-core/src/lib.rs @@ -39,8 +39,14 @@ pub fn find_first_non_whitespace_char(line: RopeSlice) -> Option { line.chars().position(|ch| !ch.is_whitespace()) } -/// Find `.git` root. -pub fn find_root(root: Option<&str>) -> Option { +/// Find project root. +/// +/// Order of detection: +/// * Top-most folder containing a root marker in current git repository +/// * Git repostory root if no marker detected +/// * Top-most folder containing a root marker if not git repository detected +/// * Current working directory as fallback +pub fn find_root(root: Option<&str>, root_markers: &[String]) -> Option { let current_dir = std::env::current_dir().expect("unable to determine current directory"); let root = match root { @@ -52,16 +58,30 @@ pub fn find_root(root: Option<&str>) -> Option { current_dir.join(root) } } - None => current_dir, + None => current_dir.clone(), }; + let mut top_marker = None; for ancestor in root.ancestors() { - // TODO: also use defined roots if git isn't found + for marker in root_markers { + if ancestor.join(marker).exists() { + top_marker = Some(ancestor); + break; + } + } + // don't go higher than repo if ancestor.join(".git").is_dir() { - return Some(ancestor.to_path_buf()); + // Use workspace if detected from marker + return Some(top_marker.unwrap_or(ancestor).to_path_buf()); } } - None + + // In absence of git repo, use workspace if detected + if top_marker.is_some() { + top_marker.map(|a| a.to_path_buf()) + } else { + Some(current_dir) + } } pub fn runtime_dir() -> std::path::PathBuf { diff --git a/helix-lsp/src/client.rs b/helix-lsp/src/client.rs index 43804daa..c80f70b5 100644 --- a/helix-lsp/src/client.rs +++ b/helix-lsp/src/client.rs @@ -31,6 +31,7 @@ pub struct Client { pub(crate) capabilities: OnceCell, offset_encoding: OffsetEncoding, config: Option, + root_markers: Vec, } impl Client { @@ -39,6 +40,7 @@ impl Client { cmd: &str, args: &[String], config: Option, + root_markers: Vec, id: usize, ) -> Result<(Self, UnboundedReceiver<(usize, Call)>, Arc)> { let process = Command::new(cmd) @@ -68,6 +70,7 @@ impl Client { capabilities: OnceCell::new(), offset_encoding: OffsetEncoding::Utf8, config, + root_markers, }; Ok((client, server_rx, initialize_notify)) @@ -225,7 +228,8 @@ impl Client { pub(crate) async fn initialize(&self) -> Result { // TODO: delay any requests that are triggered prior to initialize - let root = find_root(None).and_then(|root| lsp::Url::from_file_path(root).ok()); + let root = find_root(None, &self.root_markers) + .and_then(|root| lsp::Url::from_file_path(root).ok()); if self.config.is_some() { log::info!("Using custom LSP config: {}", self.config.as_ref().unwrap()); diff --git a/helix-lsp/src/lib.rs b/helix-lsp/src/lib.rs index 8fb321bc..1eb1c151 100644 --- a/helix-lsp/src/lib.rs +++ b/helix-lsp/src/lib.rs @@ -326,6 +326,7 @@ impl Registry { &config.command, &config.args, language_config.config.clone(), + language_config.roots.clone(), id, )?; self.incoming.push(UnboundedReceiverStream::new(incoming)); diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 6259ecb2..ed728115 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -3154,7 +3154,8 @@ fn command_mode(cx: &mut Context) { } fn file_picker(cx: &mut Context) { - let root = find_root(None).unwrap_or_else(|| PathBuf::from("./")); + // We don't specify language markers, root will be the root of the current git repo + let root = find_root(None, &[]).unwrap_or_else(|| PathBuf::from("./")); let picker = ui::file_picker(root, &cx.editor.config); cx.push_layer(Box::new(picker)); } diff --git a/languages.toml b/languages.toml index 3d9bac7b..f088a3aa 100644 --- a/languages.toml +++ b/languages.toml @@ -3,7 +3,7 @@ name = "rust" scope = "source.rust" injection-regex = "rust" file-types = ["rs"] -roots = [] +roots = ["Cargo.toml", "Cargo.lock"] auto-format = true comment-token = "//" language-server = { command = "rust-analyzer" } From 0dab6c8c17c027092e117a48f60feb099cd8d59c Mon Sep 17 00:00:00 2001 From: Flakebi Date: Wed, 29 Dec 2021 17:26:28 +0100 Subject: [PATCH 70/95] Fix markdown code-block highlighting Markdown code blocks should be highlighted as a single block, so set injection.include-children. --- runtime/queries/markdown/injections.scm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/runtime/queries/markdown/injections.scm b/runtime/queries/markdown/injections.scm index ff3c5fe6..10dcab0b 100644 --- a/runtime/queries/markdown/injections.scm +++ b/runtime/queries/markdown/injections.scm @@ -1,6 +1,7 @@ (fenced_code_block (info_string) @injection.language - (code_fence_content) @injection.content) + (code_fence_content) @injection.content + (#set! injection.include-children)) ((html_block) @injection.content (#set! injection.language "html")) From aaa42e1a69e4bf88e6761e51085957201295ca52 Mon Sep 17 00:00:00 2001 From: Martin Junghanns Date: Sun, 2 Jan 2022 05:45:22 +0100 Subject: [PATCH 71/95] Underline diagnostics in bogster theme (#1399) --- runtime/themes/bogster.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/runtime/themes/bogster.toml b/runtime/themes/bogster.toml index ea6844f2..493e5ace 100644 --- a/runtime/themes/bogster.toml +++ b/runtime/themes/bogster.toml @@ -53,3 +53,6 @@ "error" = "#dc597f" "info" = "#59dcb7" "hint" = "#59c0dc" + +# make diagnostic underlined, to distinguish with selection text. +diagnostic = { modifiers = ["underlined"] } From 93a948d889f3d8fba97a37f163d080f9908dbaa3 Mon Sep 17 00:00:00 2001 From: Kirawi <67773714+kirawi@users.noreply.github.com> Date: Sun, 2 Jan 2022 20:46:57 -0500 Subject: [PATCH 72/95] switch redundant current! usage to doc! (#1416) --- helix-term/src/commands.rs | 42 ++++++++++++------------------- helix-term/src/ui/editor.rs | 50 +++++++++++++++++++++---------------- 2 files changed, 44 insertions(+), 48 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index ed728115..e61c3cf3 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -1545,7 +1545,7 @@ fn searcher(cx: &mut Context, direction: Direction) { let reg = cx.register.unwrap_or('/'); let scrolloff = cx.editor.config.scrolloff; - let (_, doc) = current!(cx.editor); + let doc = doc!(cx.editor); // TODO: could probably share with select_on_matches? @@ -2046,7 +2046,7 @@ pub mod cmd { fn write_impl(cx: &mut compositor::Context, path: Option<&Cow>) -> anyhow::Result<()> { let jobs = &mut cx.jobs; - let (_, doc) = current!(cx.editor); + let doc = doc_mut!(cx.editor); if let Some(ref path) = path { doc.set_path(Some(path.as_ref().as_ref())) @@ -2099,8 +2099,7 @@ pub mod cmd { _args: &[Cow], _event: PromptEvent, ) -> anyhow::Result<()> { - let (_, doc) = current!(cx.editor); - + let doc = doc!(cx.editor); if let Some(format) = doc.format() { let callback = make_format_callback(doc.id(), doc.version(), Modified::LeaveModified, format); @@ -2409,7 +2408,7 @@ pub mod cmd { args: &[Cow], _event: PromptEvent, ) -> anyhow::Result<()> { - let (_, doc) = current!(cx.editor); + let doc = doc!(cx.editor); let default_sep = Cow::Borrowed(doc.line_ending.as_str()); let separator = args.first().unwrap_or(&default_sep); yank_joined_to_clipboard_impl(cx.editor, separator, ClipboardType::Clipboard) @@ -2428,7 +2427,7 @@ pub mod cmd { args: &[Cow], _event: PromptEvent, ) -> anyhow::Result<()> { - let (_, doc) = current!(cx.editor); + let doc = doc!(cx.editor); let default_sep = Cow::Borrowed(doc.line_ending.as_str()); let separator = args.first().unwrap_or(&default_sep); yank_joined_to_clipboard_impl(cx.editor, separator, ClipboardType::Selection) @@ -2555,7 +2554,7 @@ pub mod cmd { args: &[Cow], _event: PromptEvent, ) -> anyhow::Result<()> { - let (_, doc) = current!(cx.editor); + let doc = doc_mut!(cx.editor); if let Some(label) = args.first() { doc.set_encoding(label) } else { @@ -3247,7 +3246,7 @@ fn symbol_picker(cx: &mut Context) { nested_to_flat(list, file, child); } } - let (_, doc) = current!(cx.editor); + let doc = doc!(cx.editor); let language_server = match doc.language_server() { Some(language_server) => language_server, @@ -3268,7 +3267,7 @@ fn symbol_picker(cx: &mut Context) { let symbols = match symbols { lsp::DocumentSymbolResponse::Flat(symbols) => symbols, lsp::DocumentSymbolResponse::Nested(symbols) => { - let (_view, doc) = current!(editor); + let doc = doc!(editor); let mut flat_symbols = Vec::new(); for symbol in symbols { nested_to_flat(&mut flat_symbols, &doc.identifier(), symbol) @@ -3310,17 +3309,15 @@ fn symbol_picker(cx: &mut Context) { } fn workspace_symbol_picker(cx: &mut Context) { - let (_, doc) = current!(cx.editor); - + let doc = doc!(cx.editor); + let current_path = doc.path().cloned(); let language_server = match doc.language_server() { Some(language_server) => language_server, None => return, }; let offset_encoding = language_server.offset_encoding(); - let future = language_server.workspace_symbols("".to_string()); - let current_path = doc_mut!(cx.editor).path().cloned(); cx.callback( future, move |_editor: &mut Editor, @@ -3430,8 +3427,7 @@ pub fn code_action(cx: &mut Context) { } pub fn execute_lsp_command(editor: &mut Editor, cmd: lsp::Command) { - let (_view, doc) = current!(editor); - + let doc = doc!(editor); let language_server = match doc.language_server() { Some(language_server) => language_server, None => return, @@ -4185,27 +4181,21 @@ fn goto_pos(editor: &mut Editor, pos: usize) { } fn goto_first_diag(cx: &mut Context) { - let editor = &mut cx.editor; - let (_, doc) = current!(editor); - + let doc = doc!(cx.editor); let pos = match doc.diagnostics().first() { Some(diag) => diag.range.start, None => return, }; - - goto_pos(editor, pos); + goto_pos(cx.editor, pos); } fn goto_last_diag(cx: &mut Context) { - let editor = &mut cx.editor; - let (_, doc) = current!(editor); - + let doc = doc!(cx.editor); let pos = match doc.diagnostics().last() { Some(diag) => diag.range.start, None => return, }; - - goto_pos(editor, pos); + goto_pos(cx.editor, pos); } fn goto_next_diag(cx: &mut Context) { @@ -5270,7 +5260,7 @@ pub fn completion(cx: &mut Context) { move |editor: &mut Editor, compositor: &mut Compositor, response: Option| { - let (_, doc) = current!(editor); + let doc = doc!(editor); if doc.mode() != Mode::Insert { // we're not in insert mode anymore return; diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index dd050398..8d811ed2 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -781,8 +781,9 @@ impl EditorView { pub fn clear_completion(&mut self, editor: &mut Editor) { self.completion = None; + // Clear any savepoints - let (_, doc) = current!(editor); + let doc = doc_mut!(editor); doc.savepoint = None; editor.clear_idle_timer(); // don't retrigger } @@ -940,14 +941,18 @@ impl EditorView { } impl Component for EditorView { - fn handle_event(&mut self, event: Event, cx: &mut Context) -> EventResult { - let mut cxt = commands::Context { - editor: cx.editor, + fn handle_event( + &mut self, + event: Event, + context: &mut crate::compositor::Context, + ) -> EventResult { + let mut cx = commands::Context { + editor: context.editor, count: None, register: None, callback: None, on_next_key_callback: None, - jobs: cx.jobs, + jobs: context.jobs, }; match event { @@ -957,18 +962,19 @@ impl Component for EditorView { EventResult::Consumed(None) } Event::Key(key) => { - cxt.editor.reset_idle_timer(); + cx.editor.reset_idle_timer(); let mut key = KeyEvent::from(key); canonicalize_key(&mut key); + // clear status - cxt.editor.status_msg = None; + cx.editor.status_msg = None; - let (_, doc) = current!(cxt.editor); + let doc = doc!(cx.editor); let mode = doc.mode(); if let Some(on_next_key) = self.on_next_key.take() { // if there's a command waiting input, do that first - on_next_key(&mut cxt, key); + on_next_key(&mut cx, key); } else { match mode { Mode::Insert => { @@ -980,8 +986,8 @@ impl Component for EditorView { if let Some(completion) = &mut self.completion { // use a fake context here let mut cx = Context { - editor: cxt.editor, - jobs: cxt.jobs, + editor: cx.editor, + jobs: cx.jobs, scroll: None, }; let res = completion.handle_event(event, &mut cx); @@ -991,40 +997,40 @@ impl Component for EditorView { if callback.is_some() { // assume close_fn - self.clear_completion(cxt.editor); + self.clear_completion(cx.editor); } } } // if completion didn't take the event, we pass it onto commands if !consumed { - self.insert_mode(&mut cxt, key); + self.insert_mode(&mut cx, key); // lastly we recalculate completion if let Some(completion) = &mut self.completion { - completion.update(&mut cxt); + completion.update(&mut cx); if completion.is_empty() { - self.clear_completion(cxt.editor); + self.clear_completion(cx.editor); } } } } - mode => self.command_mode(mode, &mut cxt, key), + mode => self.command_mode(mode, &mut cx, key), } } - self.on_next_key = cxt.on_next_key_callback.take(); + self.on_next_key = cx.on_next_key_callback.take(); // appease borrowck - let callback = cxt.callback.take(); + let callback = cx.callback.take(); // if the command consumed the last view, skip the render. // on the next loop cycle the Application will then terminate. - if cxt.editor.should_close() { + if cx.editor.should_close() { return EventResult::Ignored; } - let (view, doc) = current!(cxt.editor); - view.ensure_cursor_in_view(doc, cxt.editor.config.scrolloff); + let (view, doc) = current!(cx.editor); + view.ensure_cursor_in_view(doc, cx.editor.config.scrolloff); // mode transitions match (mode, doc.mode()) { @@ -1053,7 +1059,7 @@ impl Component for EditorView { EventResult::Consumed(callback) } - Event::Mouse(event) => self.handle_mouse_event(event, &mut cxt), + Event::Mouse(event) => self.handle_mouse_event(event, &mut cx), } } From 8f2af713408b8b40cf71873bbc0ddc009a7b3da5 Mon Sep 17 00:00:00 2001 From: Sebastian Neubauer Date: Mon, 3 Jan 2022 02:57:55 +0100 Subject: [PATCH 73/95] Add LLVM TableGen highlighting (#1409) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a tree-sitter grammar and highlights for TableGen files. TableGen and its grammar are described here: https://llvm.org/docs/TableGen/index.html Co-authored-by: Blaž Hrastnik --- .gitmodules | 4 + book/src/generated/lang-support.md | 1 + helix-syntax/languages/tree-sitter-tablegen | 1 + languages.toml | 9 +++ runtime/queries/tablegen/highlights.scm | 90 +++++++++++++++++++++ runtime/queries/tablegen/indents.toml | 7 ++ runtime/queries/tablegen/injections.scm | 2 + runtime/queries/tablegen/textobjects.scm | 7 ++ 8 files changed, 121 insertions(+) create mode 160000 helix-syntax/languages/tree-sitter-tablegen create mode 100644 runtime/queries/tablegen/highlights.scm create mode 100644 runtime/queries/tablegen/indents.toml create mode 100644 runtime/queries/tablegen/injections.scm create mode 100644 runtime/queries/tablegen/textobjects.scm diff --git a/.gitmodules b/.gitmodules index 22f70c80..b617e60c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -178,6 +178,10 @@ path = helix-syntax/languages/tree-sitter-git-diff url = https://github.com/the-mikedavis/tree-sitter-git-diff.git shallow = true +[submodule "helix-syntax/languages/tree-sitter-tablegen"] + path = helix-syntax/languages/tree-sitter-tablegen + url = https://github.com/Flakebi/tree-sitter-tablegen + shallow = true [submodule "helix-syntax/languages/tree-sitter-git-rebase"] path = helix-syntax/languages/tree-sitter-git-rebase url = https://github.com/the-mikedavis/tree-sitter-git-rebase.git diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 09284d46..73712ff2 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -40,6 +40,7 @@ | rust | ✓ | ✓ | ✓ | `rust-analyzer` | | scala | ✓ | | ✓ | `metals` | | svelte | ✓ | | ✓ | `svelteserver` | +| tablegen | ✓ | ✓ | ✓ | | | toml | ✓ | | | | | tsq | ✓ | | | | | tsx | ✓ | | | `typescript-language-server` | diff --git a/helix-syntax/languages/tree-sitter-tablegen b/helix-syntax/languages/tree-sitter-tablegen new file mode 160000 index 00000000..568dd8a9 --- /dev/null +++ b/helix-syntax/languages/tree-sitter-tablegen @@ -0,0 +1 @@ +Subproject commit 568dd8a937347175fd58db83d4c4cdaeb6069bd2 diff --git a/languages.toml b/languages.toml index f088a3aa..7a895a60 100644 --- a/languages.toml +++ b/languages.toml @@ -436,6 +436,15 @@ file-types = ["ll"] comment-token = ";" indent = { tab-width = 2, unit = " " } +[[language]] +name = "tablegen" +scope = "source.tablegen" +roots = [] +file-types = ["td"] +comment-token = "//" +indent = { tab-width = 2, unit = " " } +injection-regex = "tablegen" + [[language]] name = "markdown" scope = "source.md" diff --git a/runtime/queries/tablegen/highlights.scm b/runtime/queries/tablegen/highlights.scm new file mode 100644 index 00000000..8ade5ba9 --- /dev/null +++ b/runtime/queries/tablegen/highlights.scm @@ -0,0 +1,90 @@ +[ + (comment) + (multiline_comment) +] @comment + +[ + "(" + ")" + "[" + "]" + "{" + "}" + "<" + ">" +] @punctuation.bracket + +[ + "," + ";" + "." +] @punctuation.delimiter + +[ + "#" + "-" + "..." + ":" +] @operator + +[ + "=" + "!cond" + (operator_keyword) +] @function + +[ + "true" + "false" +] @constant.builtin.boolean + +[ + "?" +] @constant.builtin + +(var) @variable + +(template_arg (identifier) @variable.parameter) + +(_ argument: (value (identifier) @variable.parameter)) + +(type) @type + +"code" @type.builtin + +(number) @constant.numeric.integer +[ + (string_string) + (code_string) +] @string + +(preprocessor) @keyword.directive + +[ + "class" + "field" + "let" + "defvar" + "def" + "defset" + "defvar" + "assert" +] @keyword + +[ + "let" + "in" + "foreach" + "if" + "then" + "else" +] @keyword.operator + +"include" @keyword.control.import + +[ + "multiclass" + "defm" +] @namespace + +(ERROR) @error diff --git a/runtime/queries/tablegen/indents.toml b/runtime/queries/tablegen/indents.toml new file mode 100644 index 00000000..43532f4d --- /dev/null +++ b/runtime/queries/tablegen/indents.toml @@ -0,0 +1,7 @@ +indent = [ + "statement", +] + +outdent = [ + "}", +] diff --git a/runtime/queries/tablegen/injections.scm b/runtime/queries/tablegen/injections.scm new file mode 100644 index 00000000..0b476f86 --- /dev/null +++ b/runtime/queries/tablegen/injections.scm @@ -0,0 +1,2 @@ +([ (comment) (multiline_comment)] @injection.content + (#set! injection.language "comment")) diff --git a/runtime/queries/tablegen/textobjects.scm b/runtime/queries/tablegen/textobjects.scm new file mode 100644 index 00000000..2cb80268 --- /dev/null +++ b/runtime/queries/tablegen/textobjects.scm @@ -0,0 +1,7 @@ +(class + body: (_) @class.inside) @class.around + +(multiclass + body: (_) @class.inside) @class.around + +(_ argument: _ @parameter.inside) From 4da050b4bb639755e30447518aa79f7511c8952c Mon Sep 17 00:00:00 2001 From: Triton171 Date: Mon, 3 Jan 2022 03:03:57 +0100 Subject: [PATCH 74/95] Add basic indentation for languages without treesitter-based indentation rules (always use the indent of the current line for a new line). (#1341) Fix several bugs in the treesitter indentation calculation. Co-authored-by: Triton171 --- helix-core/src/indent.rs | 140 +++++++++++++----------------- helix-term/src/commands.rs | 68 ++++++++------- runtime/queries/rust/indents.toml | 1 + 3 files changed, 98 insertions(+), 111 deletions(-) diff --git a/helix-core/src/indent.rs b/helix-core/src/indent.rs index c2baf3cc..28066aa6 100644 --- a/helix-core/src/indent.rs +++ b/helix-core/src/indent.rs @@ -1,6 +1,5 @@ use crate::{ chars::{char_is_line_ending, char_is_whitespace}, - find_first_non_whitespace_char, syntax::{IndentQuery, LanguageConfiguration, Syntax}, tree_sitter::Node, Rope, RopeSlice, @@ -174,8 +173,7 @@ pub fn auto_detect_indent_style(document_text: &Rope) -> Option { /// To determine indentation of a newly inserted line, figure out the indentation at the last col /// of the previous line. -#[allow(dead_code)] -fn indent_level_for_line(line: RopeSlice, tab_width: usize) -> usize { +pub fn indent_level_for_line(line: RopeSlice, tab_width: usize) -> usize { let mut len = 0; for ch in line.chars() { match ch { @@ -210,10 +208,15 @@ fn get_highest_syntax_node_at_bytepos(syntax: &Syntax, pos: usize) -> Option, newline: bool) -> usize { - // NOTE: can't use contains() on query because of comparing Vec and &str - // https://doc.rust-lang.org/std/vec/struct.Vec.html#method.contains - +/// Calculate the indentation at a given treesitter node. +/// If newline is false, then any "indent" nodes on the line are ignored ("outdent" still applies). +/// This is because the indentation is only increased starting at the second line of the node. +fn calculate_indentation( + query: &IndentQuery, + node: Option, + line: usize, + newline: bool, +) -> usize { let mut increment: isize = 0; let mut node = match node { @@ -221,70 +224,45 @@ fn calculate_indentation(query: &IndentQuery, node: Option, newline: bool) None => return 0, }; - let mut prev_start = node.start_position().row; - - // if we're calculating indentation for a brand new line then the current node will become the - // parent node. We need to take it's indentation level into account too. - let node_kind = node.kind(); - if newline && query.indent.contains(node_kind) { - increment += 1; - } - - while let Some(parent) = node.parent() { - let parent_kind = parent.kind(); - let start = parent.start_position().row; - - // detect deeply nested indents in the same line - // .map(|a| { <-- ({ is two scopes - // let len = 1; <-- indents one level - // }) <-- }) is two scopes - let starts_same_line = start == prev_start; - - if query.outdent.contains(node.kind()) && !starts_same_line { - // we outdent by skipping the rules for the current level and jumping up - // node = parent; - increment -= 1; - // continue; + let mut current_line = line; + let mut consider_indent = newline; + let mut increment_from_line: isize = 0; + + loop { + let node_kind = node.kind(); + let start = node.start_position().row; + if current_line != start { + // Indent/dedent by at most one per line: + // .map(|a| { <-- ({ is two scopes + // let len = 1; <-- indents one level + // }) <-- }) is two scopes + if consider_indent || increment_from_line < 0 { + increment += increment_from_line.signum(); + } + increment_from_line = 0; + current_line = start; + consider_indent = true; } - if query.indent.contains(parent_kind) // && not_first_or_last_sibling - && !starts_same_line - { - // println!("is_scope {}", parent_kind); - prev_start = start; - increment += 1 + if query.outdent.contains(node_kind) { + increment_from_line -= 1; + } + if query.indent.contains(node_kind) { + increment_from_line += 1; } - // if last_scope && increment > 0 && ...{ ignore } - - node = parent; + if let Some(parent) = node.parent() { + node = parent; + } else { + break; + } + } + if consider_indent || increment_from_line < 0 { + increment += increment_from_line.signum(); } - increment.max(0) as usize } -#[allow(dead_code)] -fn suggested_indent_for_line( - language_config: &LanguageConfiguration, - syntax: Option<&Syntax>, - text: RopeSlice, - line_num: usize, - _tab_width: usize, -) -> usize { - if let Some(start) = find_first_non_whitespace_char(text.line(line_num)) { - return suggested_indent_for_pos( - Some(language_config), - syntax, - text, - start + text.line_to_char(line_num), - false, - ); - }; - - // if the line is blank, indent should be zero - 0 -} - // TODO: two usecases: if we are triggering this for a new, blank line: // - it should return 0 when mass indenting stuff // - it should look up the wrapper node and count it too when we press o/O @@ -293,23 +271,20 @@ pub fn suggested_indent_for_pos( syntax: Option<&Syntax>, text: RopeSlice, pos: usize, + line: usize, new_line: bool, -) -> usize { +) -> Option { if let (Some(query), Some(syntax)) = ( language_config.and_then(|config| config.indent_query()), syntax, ) { let byte_start = text.char_to_byte(pos); let node = get_highest_syntax_node_at_bytepos(syntax, byte_start); - - // let config = load indentation query config from Syntax(should contain language_config) - // TODO: special case for comments // TODO: if preserve_leading_whitespace - calculate_indentation(query, node, new_line) + Some(calculate_indentation(query, node, line, new_line)) } else { - // TODO: heuristics for non-tree sitter grammars - 0 + None } } @@ -484,14 +459,23 @@ where for i in 0..doc.len_lines() { let line = text.line(i); - let indent = indent_level_for_line(line, tab_width); - assert_eq!( - suggested_indent_for_line(&language_config, Some(&syntax), text, i, tab_width), - indent, - "line {}: {}", - i, - line - ); + if let Some(pos) = crate::find_first_non_whitespace_char(line) { + let indent = indent_level_for_line(line, tab_width); + assert_eq!( + suggested_indent_for_pos( + Some(&language_config), + Some(&syntax), + text, + text.line_to_char(i) + pos, + i, + false + ), + Some(indent), + "line {}: \"{}\"", + i, + line + ); + } } } } diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index e61c3cf3..842d8b60 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -3689,22 +3689,22 @@ fn open(cx: &mut Context, open: Open) { let mut offs = 0; let mut transaction = Transaction::change_by_selection(contents, selection, |range| { - let line = range.cursor_line(text); + let cursor_line = range.cursor_line(text); - let line = match open { + let new_line = match open { // adjust position to the end of the line (next line - 1) - Open::Below => line + 1, + Open::Below => cursor_line + 1, // adjust position to the end of the previous line (current line - 1) - Open::Above => line, + Open::Above => cursor_line, }; // Index to insert newlines after, as well as the char width // to use to compensate for those inserted newlines. - let (line_end_index, line_end_offset_width) = if line == 0 { + let (line_end_index, line_end_offset_width) = if new_line == 0 { (0, 0) } else { ( - line_end_char_index(&doc.text().slice(..), line.saturating_sub(1)), + line_end_char_index(&doc.text().slice(..), new_line.saturating_sub(1)), doc.line_ending.len_chars(), ) }; @@ -3715,8 +3715,10 @@ fn open(cx: &mut Context, open: Open) { doc.syntax(), text, line_end_index, + new_line.saturating_sub(1), true, - ); + ) + .unwrap_or_else(|| indent::indent_level_for_line(text.line(cursor_line), doc.tab_width())); let indent = doc.indent_unit().repeat(indent_level); let indent_len = indent.len(); let mut text = String::with_capacity(1 + indent_len); @@ -4451,48 +4453,48 @@ pub mod insert { }; let curr = contents.get_char(pos).unwrap_or(' '); - // TODO: offset range.head by 1? when calculating? + let current_line = text.char_to_line(pos); let indent_level = indent::suggested_indent_for_pos( doc.language_config(), doc.syntax(), text, - pos.saturating_sub(1), + pos, + current_line, true, - ); - let indent = doc.indent_unit().repeat(indent_level); - let mut text = String::with_capacity(1 + indent.len()); - text.push_str(doc.line_ending.as_str()); - text.push_str(&indent); + ) + .unwrap_or_else(|| { + indent::indent_level_for_line(text.line(current_line), doc.tab_width()) + }); - let head = pos + offs + text.chars().count(); + let indent = doc.indent_unit().repeat(indent_level); + let mut text = String::new(); + // If we are between pairs (such as brackets), we want to insert an additional line which is indented one level more and place the cursor there + let new_head_pos = if helix_core::auto_pairs::PAIRS.contains(&(prev, curr)) { + let inner_indent = doc.indent_unit().repeat(indent_level + 1); + text.reserve_exact(2 + indent.len() + inner_indent.len()); + text.push_str(doc.line_ending.as_str()); + text.push_str(&inner_indent); + let new_head_pos = pos + offs + text.chars().count(); + text.push_str(doc.line_ending.as_str()); + text.push_str(&indent); + new_head_pos + } else { + text.reserve_exact(1 + indent.len()); + text.push_str(doc.line_ending.as_str()); + text.push_str(&indent); + pos + offs + text.chars().count() + }; // TODO: range replace or extend // range.replace(|range| range.is_empty(), head); -> fn extend if cond true, new head pos // can be used with cx.mode to do replace or extend on most changes - ranges.push(Range::new( - if range.is_empty() { - head - } else { - range.anchor + offs - }, - head, - )); - - // if between a bracket pair - if helix_core::auto_pairs::PAIRS.contains(&(prev, curr)) { - // another newline, indent the end bracket one level less - let indent = doc.indent_unit().repeat(indent_level.saturating_sub(1)); - text.push_str(doc.line_ending.as_str()); - text.push_str(&indent); - } - + ranges.push(Range::new(new_head_pos, new_head_pos)); offs += text.chars().count(); (pos, pos, Some(text.into())) }); transaction = transaction.with_selection(Selection::new(ranges, selection.primary_index())); - // doc.apply(&transaction, view.id); } diff --git a/runtime/queries/rust/indents.toml b/runtime/queries/rust/indents.toml index 3900f0b9..51a0ceea 100644 --- a/runtime/queries/rust/indents.toml +++ b/runtime/queries/rust/indents.toml @@ -9,6 +9,7 @@ indent = [ "field_initializer_list", "struct_pattern", "tuple_pattern", + "unit_expression", "enum_variant_list", "call_expression", "binary_expression", From ea095ca5fb5d0227ba778f12d128c978576ae55b Mon Sep 17 00:00:00 2001 From: Kirawi <67773714+kirawi@users.noreply.github.com> Date: Sun, 2 Jan 2022 21:26:17 -0500 Subject: [PATCH 75/95] Optimize lsp_pos_to_pos (#1423) lines().count() is slow compared to len_lines() --- helix-lsp/src/lib.rs | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/helix-lsp/src/lib.rs b/helix-lsp/src/lib.rs index 1eb1c151..109546d0 100644 --- a/helix-lsp/src/lib.rs +++ b/helix-lsp/src/lib.rs @@ -66,39 +66,26 @@ pub mod util { pos: lsp::Position, offset_encoding: OffsetEncoding, ) -> Option { - let max_line = doc.lines().count().saturating_sub(1); let pos_line = pos.line as usize; - let pos_line = if pos_line > max_line { + if pos_line > doc.len_lines() - 1 { return None; - } else { - pos_line - }; + } + match offset_encoding { OffsetEncoding::Utf8 => { - let max_char = doc - .line_to_char(max_line) - .checked_add(doc.line(max_line).len_chars())?; let line = doc.line_to_char(pos_line); let pos = line.checked_add(pos.character as usize)?; - if pos <= max_char { + if pos <= doc.len_chars() { Some(pos) } else { None } } OffsetEncoding::Utf16 => { - let max_char = doc - .line_to_char(max_line) - .checked_add(doc.line(max_line).len_chars())?; - let max_cu = doc.char_to_utf16_cu(max_char); let line = doc.line_to_char(pos_line); let line_start = doc.char_to_utf16_cu(line); let pos = line_start.checked_add(pos.character as usize)?; - if pos <= max_cu { - Some(doc.utf16_cu_to_char(pos)) - } else { - None - } + doc.try_utf16_cu_to_char(pos).ok() } } } From ed97ecceb8d1f53bd192deeb38a1bde36a45edc2 Mon Sep 17 00:00:00 2001 From: Omnikar Date: Sun, 2 Jan 2022 21:31:24 -0500 Subject: [PATCH 76/95] Add `:cquit!` command and prevent `:cquit` from ignoring unsaved changes (#1414) * Add `:cquit!` command and prevent `:cquit` from ignoring unsaved changes * `cargo xtask docgen` --- book/src/generated/typable-cmd.md | 1 + helix-term/src/commands.rs | 45 +++++++++++++++++++------------ 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/book/src/generated/typable-cmd.md b/book/src/generated/typable-cmd.md index 45129cc1..65b2dc5f 100644 --- a/book/src/generated/typable-cmd.md +++ b/book/src/generated/typable-cmd.md @@ -20,6 +20,7 @@ | `:quit-all`, `:qa` | Close all views. | | `:quit-all!`, `:qa!` | Close all views forcefully (ignoring unsaved changes). | | `:cquit`, `:cq` | Quit with exit code (default 1). Accepts an optional integer exit code (:cq 2). | +| `:cquit!`, `:cq!` | Quit with exit code (default 1) forcefully (ignoring unsaved changes). Accepts an optional integer exit code (:cq! 2). | | `:theme` | Change the editor theme. | | `:clipboard-yank` | Yank main selection into system clipboard. | | `:clipboard-yank-join` | Yank joined selections into system clipboard. A separator can be provided as first argument. Default value is newline. | diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 842d8b60..ccc25c54 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -2322,12 +2322,7 @@ pub mod cmd { write_all_impl(cx, args, event, true, true) } - fn quit_all_impl( - editor: &mut Editor, - _args: &[Cow], - _event: PromptEvent, - force: bool, - ) -> anyhow::Result<()> { + fn quit_all_impl(editor: &mut Editor, force: bool) -> anyhow::Result<()> { if !force { buffers_remaining_impl(editor)?; } @@ -2343,18 +2338,18 @@ pub mod cmd { fn quit_all( cx: &mut compositor::Context, - args: &[Cow], - event: PromptEvent, + _args: &[Cow], + _event: PromptEvent, ) -> anyhow::Result<()> { - quit_all_impl(cx.editor, args, event, false) + quit_all_impl(cx.editor, false) } fn force_quit_all( cx: &mut compositor::Context, - args: &[Cow], - event: PromptEvent, + _args: &[Cow], + _event: PromptEvent, ) -> anyhow::Result<()> { - quit_all_impl(cx.editor, args, event, true) + quit_all_impl(cx.editor, true) } fn cquit( @@ -2368,12 +2363,21 @@ pub mod cmd { .unwrap_or(1); cx.editor.exit_code = exit_code; - let views: Vec<_> = cx.editor.tree.views().map(|(view, _)| view.id).collect(); - for view_id in views { - cx.editor.close(view_id); - } + quit_all_impl(cx.editor, false) + } - Ok(()) + fn force_cquit( + cx: &mut compositor::Context, + args: &[Cow], + _event: PromptEvent, + ) -> anyhow::Result<()> { + let exit_code = args + .first() + .and_then(|code| code.parse::().ok()) + .unwrap_or(1); + cx.editor.exit_code = exit_code; + + quit_all_impl(cx.editor, true) } fn theme( @@ -2877,6 +2881,13 @@ pub mod cmd { fun: cquit, completer: None, }, + TypableCommand { + name: "cquit!", + aliases: &["cq!"], + doc: "Quit with exit code (default 1) forcefully (ignoring unsaved changes). Accepts an optional integer exit code (:cq! 2).", + fun: force_cquit, + completer: None, + }, TypableCommand { name: "theme", aliases: &[], From 609f7363a18f6e8ce577e3e3ea7944524d589a99 Mon Sep 17 00:00:00 2001 From: WindSoilder Date: Mon, 3 Jan 2022 10:32:47 +0800 Subject: [PATCH 77/95] Add everforest_light, change everforest_dark string color (#1412) --- runtime/themes/everforest_dark.toml | 2 +- runtime/themes/everforest_light.toml | 90 ++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 runtime/themes/everforest_light.toml diff --git a/runtime/themes/everforest_dark.toml b/runtime/themes/everforest_dark.toml index 3be9f1f0..f5a0088c 100644 --- a/runtime/themes/everforest_dark.toml +++ b/runtime/themes/everforest_dark.toml @@ -12,7 +12,7 @@ "type" = "yellow" "constant" = "purple" "constant.numeric" = "purple" -"string" = "grey2" +"string" = "green" "comment" = "grey0" "variable" = "fg" "variable.builtin" = "blue" diff --git a/runtime/themes/everforest_light.toml b/runtime/themes/everforest_light.toml new file mode 100644 index 00000000..3038ef9c --- /dev/null +++ b/runtime/themes/everforest_light.toml @@ -0,0 +1,90 @@ +# Everforest (Dark Hard) +# Author: CptPotato + +# Original Author: +# URL: https://github.com/sainnhe/everforest +# Filename: autoload/everforest.vim +# Author: sainnhe +# Email: sainnhe@gmail.com +# License: MIT License + +"constant.character.escape" = "orange" +"type" = "yellow" +"constant" = "purple" +"constant.numeric" = "purple" +"string" = "green" +"comment" = "grey0" +"variable" = "fg" +"variable.builtin" = "blue" +"variable.parameter" = "fg" +"variable.other.member" = "fg" +"label" = "aqua" +"punctuation" = "grey2" +"punctuation.delimiter" = "grey2" +"punctuation.bracket" = "fg" +"keyword" = "red" +"operator" = "orange" +"function" = "green" +"function.builtin" = "blue" +"function.macro" = "aqua" +"tag" = "yellow" +"namespace" = "aqua" +"attribute" = "aqua" +"constructor" = "yellow" +"module" = "blue" +"special" = "orange" + +"diff.plus" = "green" +"diff.delta" = "orange" +"diff.minus" = "red" + +"ui.background" = { bg = "bg0" } +"ui.cursor" = { fg = "bg0", bg = "fg" } +"ui.cursor.match" = { fg = "orange", bg = "bg_yellow" } +"ui.cursor.insert" = { fg = "bg0", bg = "grey1" } +"ui.cursor.select" = { fg = "bg0", bg = "blue" } +"ui.linenr" = "grey0" +"ui.linenr.selected" = "fg" +"ui.statusline" = { fg = "grey2", bg = "bg2" } +"ui.statusline.inactive" = { fg = "grey0", bg = "bg1" } +"ui.popup" = { fg = "grey2", bg = "bg1" } +"ui.window" = { fg = "grey2", bg = "bg1" } +"ui.help" = { fg = "fg", bg = "bg1" } +"ui.text" = "fg" +"ui.text.focus" = "fg" +"ui.menu" = { fg = "fg", bg = "bg2" } +"ui.menu.selected" = { fg = "bg0", bg = "green" } +"ui.selection" = { bg = "bg3" } + +"hint" = "blue" +"info" = "aqua" +"warning" = "yellow" +"error" = "red" +"diagnostic" = { modifiers = ["underlined"] } + + +[palette] + +bg0 = "#fff9e8" +bg1 = "#f7f4e0" +bg2 = "#f0eed9" +bg3 = "#e9e8d2" +bg4 = "#e1ddcb" +bg5 = "#bec5b2" +bg_visual = "#edf0cd" +bg_red = "#fce5dc" +bg_green = "#f1f3d4" +bg_blue = "#eaf2eb" +bg_yellow = "#fbefd0" + +fg = "#5c6a72" +red = "#f85552" +orange = "#f57d26" +yellow = "#dfa000" +green = "#8da101" +aqua = "#35a77c" +blue = "#3a94c5" +purple = "#df69ba" +grey0 = "#a6b0a0" +grey1 = "#939f91" +grey2 = "#829181" From dbaed0ba834e772e93a0ffe4258168022cf4859e Mon Sep 17 00:00:00 2001 From: Mathis Brossier Date: Mon, 3 Jan 2022 03:50:53 +0100 Subject: [PATCH 78/95] scroll: change only main selection, only when needed (#1420) Co-authored-by: mathis --- helix-term/src/commands.rs | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index ccc25c54..a7b34062 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -1282,16 +1282,23 @@ pub fn scroll(cx: &mut Context, offset: usize, direction: Direction) { .max(view.offset.row + scrolloff) .min(last_line.saturating_sub(scrolloff)); - let head = pos_at_coords(text, Position::new(line, cursor.col), true); // this func will properly truncate to line end + // If cursor needs moving, replace primary selection + if line != cursor.row { + let head = pos_at_coords(text, Position::new(line, cursor.col), true); // this func will properly truncate to line end - let anchor = if doc.mode == Mode::Select { - range.anchor - } else { - head - }; + let anchor = if doc.mode == Mode::Select { + range.anchor + } else { + head + }; - // TODO: only manipulate main selection - doc.set_selection(view.id, Selection::single(anchor, head)); + // replace primary selection with an empty selection at cursor pos + let prim_sel = Range::new(anchor, head); + let mut sel = doc.selection(view.id).clone(); + let idx = sel.primary_index(); + sel = sel.replace(idx, prim_sel); + doc.set_selection(view.id, sel); + } } fn page_up(cx: &mut Context) { From 61fe1dc9e8998ffa83363414cbe4284260492b64 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jan 2022 10:44:03 +0900 Subject: [PATCH 79/95] build(deps): bump serde from 1.0.132 to 1.0.133 (#1432) Bumps [serde](https://github.com/serde-rs/serde) from 1.0.132 to 1.0.133. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.132...v1.0.133) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 83343fc4..ecffa4d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -877,18 +877,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" +checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276" +checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537" dependencies = [ "proc-macro2", "quote", From 78967779bde68452da655380eb4c000f607acc6b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jan 2022 10:44:10 +0900 Subject: [PATCH 80/95] build(deps): bump ropey from 1.3.1 to 1.3.2 (#1431) Bumps [ropey](https://github.com/cessen/ropey) from 1.3.1 to 1.3.2. - [Release notes](https://github.com/cessen/ropey/releases) - [Changelog](https://github.com/cessen/ropey/blob/master/CHANGELOG.md) - [Commits](https://github.com/cessen/ropey/compare/v1.3.1...v1.3.2) --- updated-dependencies: - dependency-name: ropey dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ecffa4d0..2c52de38 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -847,9 +847,9 @@ checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" [[package]] name = "ropey" -version = "1.3.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9150aff6deb25b20ed110889f070a678bcd1033e46e5e9d6fb1abeab17947f28" +checksum = "e6b9aa65bcd9f308d37c7158b4a1afaaa32b8450213e20c9b98e7d5b3cc2fec3" dependencies = [ "smallvec", ] From 96935eb28df32d5a2496c1ac5b15407b59fb5bdb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jan 2022 10:44:15 +0900 Subject: [PATCH 81/95] build(deps): bump serde_json from 1.0.73 to 1.0.74 (#1430) Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.73 to 1.0.74. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.73...v1.0.74) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2c52de38..4e7e5da5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -897,9 +897,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.73" +version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5" +checksum = "ee2bb9cd061c5865d345bb02ca49fcef1391741b672b54a0bf7b679badec3142" dependencies = [ "itoa", "ryu", From 4d59f66b76fe153abd5425ea7f11f0abc492f03e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jan 2022 10:44:48 +0900 Subject: [PATCH 82/95] build(deps): bump tree-sitter from 0.20.1 to 0.20.2 (#1429) Bumps [tree-sitter](https://github.com/tree-sitter/tree-sitter) from 0.20.1 to 0.20.2. - [Release notes](https://github.com/tree-sitter/tree-sitter/releases) - [Commits](https://github.com/tree-sitter/tree-sitter/compare/v0.20.1...v0.20.2) --- updated-dependencies: - dependency-name: tree-sitter dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4e7e5da5..e6a55b51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1119,9 +1119,9 @@ dependencies = [ [[package]] name = "tree-sitter" -version = "0.20.1" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9394e9dbfe967b5f3d6ab79e302e78b5fb7b530c368d634ff3b8d67ede138bf1" +checksum = "c36be3222512d85a112491ae0cc280a38076022414f00b64582da1b7565ffd82" dependencies = [ "cc", "regex", From 7c9d3682db8310286c309cb10828b02046246a8e Mon Sep 17 00:00:00 2001 From: dumrich <40397381+dumrich@users.noreply.github.com> Date: Mon, 3 Jan 2022 20:45:31 -0500 Subject: [PATCH 83/95] Fix grammatical error (#1427) it's to its (possessive) --- helix-tui/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-tui/README.md b/helix-tui/README.md index 97b3d1d9..5cc80aa6 100644 --- a/helix-tui/README.md +++ b/helix-tui/README.md @@ -2,5 +2,5 @@ This library is a fork of the great library [tui-rs](https://github.com/fdehau/tui-rs/). We've mainly relied on the double -buffer implementation and render diffing, side-stepping it's widget and +buffer implementation and render diffing, side-stepping its widget and layouting. From 641255ccc83648d164bf6e8e8e4e93460591830b Mon Sep 17 00:00:00 2001 From: Sebastian Neubauer Date: Tue, 4 Jan 2022 02:52:34 +0100 Subject: [PATCH 84/95] Add llvm-mir highlighting (#1398) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add injection regex for more languages To support embedding them in other languages like markdown. * Add llvm-mir highlighting LLVM Machine IR is dumped as yaml files that can embed LLVM IR and Machine IR. To support this, add a llvm-mir-yaml language that uses the yaml parser, but uses different injections to highlight IR and MIR. * Update submodule with fixed multiline comments Co-authored-by: Blaž Hrastnik --- .gitmodules | 4 + book/src/generated/lang-support.md | 2 + helix-core/src/indent.rs | 1 + helix-core/src/syntax.rs | 13 +- helix-syntax/languages/tree-sitter-llvm-mir | 1 + languages.toml | 22 +++ runtime/queries/llvm-mir-yaml/highlights.scm | 1 + runtime/queries/llvm-mir-yaml/indents.toml | 3 + runtime/queries/llvm-mir-yaml/injections.scm | 9 ++ runtime/queries/llvm-mir/highlights.scm | 136 +++++++++++++++++++ runtime/queries/llvm-mir/indents.toml | 7 + runtime/queries/llvm-mir/injections.scm | 2 + runtime/queries/llvm-mir/textobjects.scm | 3 + runtime/queries/yaml/injections.scm | 2 + 14 files changed, 203 insertions(+), 3 deletions(-) create mode 160000 helix-syntax/languages/tree-sitter-llvm-mir create mode 100644 runtime/queries/llvm-mir-yaml/highlights.scm create mode 100644 runtime/queries/llvm-mir-yaml/indents.toml create mode 100644 runtime/queries/llvm-mir-yaml/injections.scm create mode 100644 runtime/queries/llvm-mir/highlights.scm create mode 100644 runtime/queries/llvm-mir/indents.toml create mode 100644 runtime/queries/llvm-mir/injections.scm create mode 100644 runtime/queries/llvm-mir/textobjects.scm create mode 100644 runtime/queries/yaml/injections.scm diff --git a/.gitmodules b/.gitmodules index b617e60c..9297708a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -174,6 +174,10 @@ path = helix-syntax/languages/tree-sitter-git-commit url = https://github.com/the-mikedavis/tree-sitter-git-commit.git shallow = true +[submodule "helix-syntax/languages/tree-sitter-llvm-mir"] + path = helix-syntax/languages/tree-sitter-llvm-mir + url = https://github.com/Flakebi/tree-sitter-llvm-mir.git + shallow = true [submodule "helix-syntax/languages/tree-sitter-git-diff"] path = helix-syntax/languages/tree-sitter-git-diff url = https://github.com/the-mikedavis/tree-sitter-git-diff.git diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 73712ff2..ee719b56 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -24,6 +24,8 @@ | latex | ✓ | | | | | ledger | ✓ | | | | | llvm | ✓ | ✓ | ✓ | | +| llvm-mir | ✓ | ✓ | ✓ | | +| llvm-mir-yaml | ✓ | | ✓ | | | lua | ✓ | | ✓ | | | markdown | ✓ | | | | | mint | | | | `mint` | diff --git a/helix-core/src/indent.rs b/helix-core/src/indent.rs index 28066aa6..1fc2b8a5 100644 --- a/helix-core/src/indent.rs +++ b/helix-core/src/indent.rs @@ -436,6 +436,7 @@ where comment_token: None, auto_format: false, diagnostic_severity: Severity::Warning, + tree_sitter_library: None, language_server: None, indent: Some(IndentationConfiguration { tab_width: 4, diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index cdae0210..5d37c219 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -67,6 +67,8 @@ pub struct LanguageConfiguration { #[serde(default)] pub diagnostic_severity: Severity, + pub tree_sitter_library: Option, // tree-sitter library name, defaults to language_id + // content_regex #[serde(default, skip_serializing, deserialize_with = "deserialize_regex")] pub injection_regex: Option, @@ -192,9 +194,14 @@ impl LanguageConfiguration { if highlights_query.is_empty() { None } else { - let language = get_language(&crate::RUNTIME_DIR, &self.language_id) - .map_err(|e| log::info!("{}", e)) - .ok()?; + let language = get_language( + &crate::RUNTIME_DIR, + self.tree_sitter_library + .as_deref() + .unwrap_or(&self.language_id), + ) + .map_err(|e| log::info!("{}", e)) + .ok()?; let config = HighlightConfiguration::new( language, &highlights_query, diff --git a/helix-syntax/languages/tree-sitter-llvm-mir b/helix-syntax/languages/tree-sitter-llvm-mir new file mode 160000 index 00000000..06fabca1 --- /dev/null +++ b/helix-syntax/languages/tree-sitter-llvm-mir @@ -0,0 +1 @@ +Subproject commit 06fabca19454b2dc00c1b211a7cb7ad0bc2585f1 diff --git a/languages.toml b/languages.toml index 7a895a60..e8329fe7 100644 --- a/languages.toml +++ b/languages.toml @@ -334,6 +334,7 @@ file-types = ["yml", "yaml"] roots = [] comment-token = "#" indent = { tab-width = 2, unit = " " } +injection-regex = "yml|yaml" # [[language]] # name = "haskell" @@ -386,6 +387,7 @@ roots = [] comment-token = "#" indent = { tab-width = 2, unit = " " } language-server = { command = "cmake-language-server" } +injection-regex = "cmake" [[language]] name = "glsl" @@ -394,6 +396,7 @@ file-types = ["glsl", "vert", "tesc", "tese", "geom", "frag", "comp" ] roots = [] comment-token = "//" indent = { tab-width = 4, unit = " " } +injection-regex = "glsl" [[language]] name = "perl" @@ -435,6 +438,25 @@ roots = [] file-types = ["ll"] comment-token = ";" indent = { tab-width = 2, unit = " " } +injection-regex = "llvm" + +[[language]] +name = "llvm-mir" +scope = "source.llvm_mir" +roots = [] +file-types = [] +comment-token = ";" +indent = { tab-width = 2, unit = " " } +injection-regex = "mir" + +[[language]] +name = "llvm-mir-yaml" +tree-sitter-library = "yaml" +scope = "source.yaml" +roots = [] +file-types = ["mir"] +comment-token = "#" +indent = { tab-width = 2, unit = " " } [[language]] name = "tablegen" diff --git a/runtime/queries/llvm-mir-yaml/highlights.scm b/runtime/queries/llvm-mir-yaml/highlights.scm new file mode 100644 index 00000000..4ba254e8 --- /dev/null +++ b/runtime/queries/llvm-mir-yaml/highlights.scm @@ -0,0 +1 @@ +; inherits: yaml diff --git a/runtime/queries/llvm-mir-yaml/indents.toml b/runtime/queries/llvm-mir-yaml/indents.toml new file mode 100644 index 00000000..ddc3578b --- /dev/null +++ b/runtime/queries/llvm-mir-yaml/indents.toml @@ -0,0 +1,3 @@ +indent = [ + "block_mapping_pair", +] diff --git a/runtime/queries/llvm-mir-yaml/injections.scm b/runtime/queries/llvm-mir-yaml/injections.scm new file mode 100644 index 00000000..b3243022 --- /dev/null +++ b/runtime/queries/llvm-mir-yaml/injections.scm @@ -0,0 +1,9 @@ +; inherits: yaml + +((document (block_node (block_scalar) @injection.content)) + (#set! injection.language "llvm")) + +((document (block_node (block_mapping (block_mapping_pair + key: (flow_node (plain_scalar (string_scalar))) ; "body" + value: (block_node (block_scalar) @injection.content))))) + (#set! injection.language "mir")) diff --git a/runtime/queries/llvm-mir/highlights.scm b/runtime/queries/llvm-mir/highlights.scm new file mode 100644 index 00000000..79234612 --- /dev/null +++ b/runtime/queries/llvm-mir/highlights.scm @@ -0,0 +1,136 @@ +[ + (label) + (bb_ref) +] @label + +[ + (comment) + (multiline_comment) +] @comment + +[ + "(" + ")" + "[" + "]" + "{" + "}" + "<" + ">" +] @punctuation.bracket + +[ + "," + ":" + "|" + "*" +] @punctuation.delimiter + +[ + "=" + "x" +] @operator + +[ + "true" + "false" +] @constant.builtin.boolean + +[ + "null" + "_" + "unknown-address" +] @constant.builtin + +[ + (stack_object) + (constant_pool_index) + (jump_table_index) + (var) + (physical_register) + (ir_block) + (external_symbol) + (global_var) + (ir_local_var) + (metadata_ref) + (mnemonic) +] @variable + +(low_level_type) @type + +[ + (immediate_type) + (primitive_type) +] @type.builtin + +(number) @constant.numeric.integer +(float) @constant.numeric.float +(string) @string + +(instruction name: _ @keyword.operator) + +[ + "successors" + "liveins" + "pre-instr-symbol" + "post-instr-symbol" + "heap-alloc-marker" + "debug-instr-number" + "debug-location" + "mcsymbol" + "tied-def" + "target-flags" + "CustomRegMask" + "same_value" + "def_cfa_register" + "restore" + "undefined" + "offset" + "rel_offset" + "def_cfa" + "llvm_def_aspace_cfa" + "register" + "escape" + "remember_state" + "restore_state" + "window_save" + "negate_ra_sign_state" + "intpred" + "floatpred" + "shufflemask" + "liveout" + "target-index" + "blockaddress" + "intrinsic" + "load" + "store" + "unknown-size" + "on" + "from" + "into" + "align" + "basealign" + "addrspace" + "call-entry" + "custom" + "constant-pool" + "stack" + "got" + "jump-table" + "syncscope" + "address-taken" + "landing-pad" + "inlineasm-br-indirect-target" + "ehfunclet-entry" + "bbsections" + + (intpred) + (floatpred) + (memory_operand_flag) + (atomic_ordering) + (register_flag) + (instruction_flag) + (float_keyword) +] @keyword + +(ERROR) @error diff --git a/runtime/queries/llvm-mir/indents.toml b/runtime/queries/llvm-mir/indents.toml new file mode 100644 index 00000000..6a70e5ad --- /dev/null +++ b/runtime/queries/llvm-mir/indents.toml @@ -0,0 +1,7 @@ +indent = [ + "basic_block", +] + +outdent = [ + "label", +] diff --git a/runtime/queries/llvm-mir/injections.scm b/runtime/queries/llvm-mir/injections.scm new file mode 100644 index 00000000..0b476f86 --- /dev/null +++ b/runtime/queries/llvm-mir/injections.scm @@ -0,0 +1,2 @@ +([ (comment) (multiline_comment)] @injection.content + (#set! injection.language "comment")) diff --git a/runtime/queries/llvm-mir/textobjects.scm b/runtime/queries/llvm-mir/textobjects.scm new file mode 100644 index 00000000..73f6f772 --- /dev/null +++ b/runtime/queries/llvm-mir/textobjects.scm @@ -0,0 +1,3 @@ +(basic_block) @function.around + +(argument) @parameter.inside diff --git a/runtime/queries/yaml/injections.scm b/runtime/queries/yaml/injections.scm new file mode 100644 index 00000000..39bda293 --- /dev/null +++ b/runtime/queries/yaml/injections.scm @@ -0,0 +1,2 @@ +((comment) @injection.content + (#set! injection.language "comment")) From 5b1a628e81b7d2f198ef401d442ca7967c5a0135 Mon Sep 17 00:00:00 2001 From: Sebastian Neubauer Date: Tue, 4 Jan 2022 02:53:04 +0100 Subject: [PATCH 85/95] Add textobjects and indents to c and cpp (#1293) Indentation of single line statements doesn't work, i.e. for (;;) leads to for(;;) Only blocks with curly braces are indented. --- book/src/generated/lang-support.md | 4 ++-- runtime/queries/c/indents.toml | 16 ++++++++++++++++ runtime/queries/c/textobjects.scm | 13 +++++++++++++ runtime/queries/cpp/indents.toml | 17 +++++++++++++++++ runtime/queries/cpp/textobjects.scm | 7 +++++++ 5 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 runtime/queries/c/indents.toml create mode 100644 runtime/queries/c/textobjects.scm create mode 100644 runtime/queries/cpp/indents.toml create mode 100644 runtime/queries/cpp/textobjects.scm diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index ee719b56..a1fbf172 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -1,11 +1,11 @@ | Language | Syntax Highlighting | Treesitter Textobjects | Auto Indent | Default LSP | | --- | --- | --- | --- | --- | | bash | ✓ | | | `bash-language-server` | -| c | ✓ | | | `clangd` | +| c | ✓ | ✓ | ✓ | `clangd` | | c-sharp | ✓ | | | | | cmake | ✓ | ✓ | ✓ | `cmake-language-server` | | comment | ✓ | | | | -| cpp | ✓ | | | `clangd` | +| cpp | ✓ | ✓ | ✓ | `clangd` | | css | ✓ | | | | | dart | ✓ | | ✓ | `dart` | | dockerfile | ✓ | | | `docker-langserver` | diff --git a/runtime/queries/c/indents.toml b/runtime/queries/c/indents.toml new file mode 100644 index 00000000..f4076e17 --- /dev/null +++ b/runtime/queries/c/indents.toml @@ -0,0 +1,16 @@ +indent = [ + "compound_statement", + "field_declaration_list", + "enumerator_list", + "parameter_list", + "init_declarator", + "case_statement", + "condition_clause", + "expression_statement", +] + +outdent = [ + "case", + "}", + "]", +] diff --git a/runtime/queries/c/textobjects.scm b/runtime/queries/c/textobjects.scm new file mode 100644 index 00000000..b0f03668 --- /dev/null +++ b/runtime/queries/c/textobjects.scm @@ -0,0 +1,13 @@ +(function_definition + body: (_) @function.inside) @function.around + +(struct_specifier + body: (_) @class.inside) @class.around + +(enum_specifier + body: (_) @class.inside) @class.around + +(union_specifier + body: (_) @class.inside) @class.around + +(parameter_declaration) @parameter.inside diff --git a/runtime/queries/cpp/indents.toml b/runtime/queries/cpp/indents.toml new file mode 100644 index 00000000..0ca2ed8b --- /dev/null +++ b/runtime/queries/cpp/indents.toml @@ -0,0 +1,17 @@ +indent = [ + "compound_statement", + "field_declaration_list", + "enumerator_list", + "parameter_list", + "init_declarator", + "case_statement", + "condition_clause", + "expression_statement", +] + +outdent = [ + "case", + "access_specifier", + "}", + "]", +] diff --git a/runtime/queries/cpp/textobjects.scm b/runtime/queries/cpp/textobjects.scm new file mode 100644 index 00000000..6e3de1a2 --- /dev/null +++ b/runtime/queries/cpp/textobjects.scm @@ -0,0 +1,7 @@ +; inherits: c + +(lambda_expression + body: (_) @function.inside) @function.around + +(class_specifier + body: (_) @class.inside) @class.around From c8794b30eeb457934278f5cbc01d0c6854ad745d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Tue, 4 Jan 2022 18:49:53 +0900 Subject: [PATCH 86/95] Update changelog --- CHANGELOG.md | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 120 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52ca2d60..0b4b161e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,124 @@ -# 0.5.0 (2021-10-28) +# 0.6.0 (2022-01-04) + +Happy new year and a big shout out to all the contributors! We had 55 contributors in this release. + +Helix has popped up in DPorts and Fedora Linux via COPR ([#1270](https://github.com/helix-editor/helix/pull/1270)) + +As usual the following is a brief summary, refer to the git history for a full log: + +Breaking changes: + +- fix: Normalize backtab into shift-tab + +Features: + +- Macros ([#1234](https://github.com/helix-editor/helix/pull/1234)) +- Add reverse search functionality ([#958](https://github.com/helix-editor/helix/pull/958)) +- Allow keys to be mapped to sequences of commands ([#589](https://github.com/helix-editor/helix/pull/589)) +- Make it possible to keybind TypableCommands ([#1169](https://github.com/helix-editor/helix/pull/1169)) +- Detect workspace root using language markers ([#1370](https://github.com/helix-editor/helix/pull/1370)) +- Add WORD textobject ([#991](https://github.com/helix-editor/helix/pull/991)) +- Add LSP rename_symbol (space-r) ([#1011](https://github.com/helix-editor/helix/pull/1011)) +- Added workspace_symbol_picker ([#1041](https://github.com/helix-editor/helix/pull/1041)) +- Detect filetype from shebang line ([#1001](https://github.com/helix-editor/helix/pull/1001)) +- Allow piping from stdin into a buffer on startup ([#996](https://github.com/helix-editor/helix/pull/996)) +- Add auto pairs for same-char pairs ([#1219](https://github.com/helix-editor/helix/pull/1219)) +- Update settings at runtime ([#798](https://github.com/helix-editor/helix/pull/798)) +- Enable thin LTO (cccc194) + +Commands: +- :wonly -- window only ([#1057](https://github.com/helix-editor/helix/pull/1057)) +- buffer-close (:bc, :bclose) ([#1035](https://github.com/helix-editor/helix/pull/1035)) +- Add : and :goto commands ([#1128](https://github.com/helix-editor/helix/pull/1128)) +- :sort command ([#1288](https://github.com/helix-editor/helix/pull/1288)) +- Add m textobject for pair under cursor ([#961](https://github.com/helix-editor/helix/pull/961)) +- Implement "Goto next buffer / Goto previous buffer" commands ([#950](https://github.com/helix-editor/helix/pull/950)) +- Implement "Goto last modification" command ([#1067](https://github.com/helix-editor/helix/pull/1067)) +- Add trim_selections command ([#1092](https://github.com/helix-editor/helix/pull/1092)) +- Add movement shortcut for history ([#1088](https://github.com/helix-editor/helix/pull/1088)) +- Add command to inc/dec number under cursor ([#1027](https://github.com/helix-editor/helix/pull/1027)) + - Add support for dates for increment/decrement +- Align selections (&) ([#1101](https://github.com/helix-editor/helix/pull/1101)) +- Implement no-yank delete/change ([#1099](https://github.com/helix-editor/helix/pull/1099)) +- Implement black hole register ([#1165](https://github.com/helix-editor/helix/pull/1165)) +- gf as goto_file (gf) ([#1102](https://github.com/helix-editor/helix/pull/1102)) +- Add last modified file (gm) ([#1093](https://github.com/helix-editor/helix/pull/1093)) +- ensure_selections_forward ([#1393](https://github.com/helix-editor/helix/pull/1393)) +- Readline style insert mode ([#1039](https://github.com/helix-editor/helix/pull/1039)) + +Usability improvements and fixes: + +- Detect filetype on :write ([#1141](https://github.com/helix-editor/helix/pull/1141)) +- Add single and double quotes to matching pairs ([#995](https://github.com/helix-editor/helix/pull/995)) +- Launch with defaults upon invalid config/theme (rather than panicking) ([#982](https://github.com/helix-editor/helix/pull/982)) +- If switching away from an empty scratch buffer, remove it ([#935](https://github.com/helix-editor/helix/pull/935)) +- Truncate the starts of file paths instead of the ends in picker ([#951](https://github.com/helix-editor/helix/pull/951)) +- Truncate the start of file paths in the StatusLine ([#1351](https://github.com/helix-editor/helix/pull/1351)) +- Prevent picker from previewing binaries or large file ([#939](https://github.com/helix-editor/helix/pull/939)) +- Inform when reaching undo/redo bounds ([#981](https://github.com/helix-editor/helix/pull/981)) +- search_impl will only align cursor center when it isn't in view ([#959](https://github.com/helix-editor/helix/pull/959)) +- Add , , , Delete in prompt mode ([#1034](https://github.com/helix-editor/helix/pull/1034)) +- Restore screen position when aborting search ([#1047](https://github.com/helix-editor/helix/pull/1047)) +- Buffer picker: show is_modifier flag ([#1020](https://github.com/helix-editor/helix/pull/1020)) +- Add commit hash to version info, if present ([#957](https://github.com/helix-editor/helix/pull/957)) +- Implement indent-aware delete ([#1120](https://github.com/helix-editor/helix/pull/1120)) +- Jump to end char of surrounding pair from any cursor pos ([#1121](https://github.com/helix-editor/helix/pull/1121)) +- File picker configuration ([#988](https://github.com/helix-editor/helix/pull/988)) +- Fix surround cursor position calculation ([#1183](https://github.com/helix-editor/helix/pull/1183)) +- Accept count for goto_window ([#1033](https://github.com/helix-editor/helix/pull/1033)) +- Make kill_to_line_end behave like emacs ([#1235](https://github.com/helix-editor/helix/pull/1235)) +- Only use a single documentation popup ([#1241](https://github.com/helix-editor/helix/pull/1241)) +- ui: popup: Don't allow scrolling past the end of content (3307f44c) +- Open files with spaces in filename, allow opening multiple files ([#1231](https://github.com/helix-editor/helix/pull/1231)) +- Allow paste commands to take a count ([#1261](https://github.com/helix-editor/helix/pull/1261)) +- Auto pairs selection ([#1254](https://github.com/helix-editor/helix/pull/1254)) +- Use a fuzzy matcher for commands ([#1386](https://github.com/helix-editor/helix/pull/1386)) +- Add c-s to pick word under doc cursor to prompt line & search completion ([#831](https://github.com/helix-editor/helix/pull/831)) +- Fix :earlier/:later missing changeset update ([#1069](https://github.com/helix-editor/helix/pull/1069)) +- Support extend for multiple goto ([#909](https://github.com/helix-editor/helix/pull/909)) +- Add arrow-key bindings for window switching ([#933](https://github.com/helix-editor/helix/pull/933)) +- Implement key ordering for info box ([#952](https://github.com/helix-editor/helix/pull/952)) + +LSP: +- Implement MarkedString rendering (e128a8702) +- Don't panic if init fails (d31bef7) +- Configurable diagnostic severity ([#1325](https://github.com/helix-editor/helix/pull/1325)) +- Resolve completion item ([#1315](https://github.com/helix-editor/helix/pull/1315)) +- Code action command support ([#1304](https://github.com/helix-editor/helix/pull/1304)) + +Grammars: + +- Adds mint language server (#974) +- Perl (#978) (#1280) +- GLSL (#993) +- Racket (#1143) +- WGSL (#1166) +- LLVM (#1167) (#1388) (#1409) (#1398) +- Markdown (49e06787) +- Scala (#1278) +- Dart (#1250) +- Fish (#1308) +- Dockerfile (#1303) +- Git (commit, rebase, diff) (#1338) (#1402) (#1373) +- tree-sitter-comment (#1300) +- Highlight comments in c, cpp, cmake and llvm (#1309) +- Improve yaml syntax highlighting highlighting (#1294) +- Improve rust syntax highlighting (#1295) +- Add textobjects and indents to cmake (#1307) +- Add textobjects and indents to c and cpp (#1293) + +New themes: + +- Solarized dark (#999) +- Solarized light (#1010) +- Spacebones light (#1131) +- Monokai Pro (#1206) +- Base16 Light and Terminal (#1078) + - and a default 16 color theme, truecolor detection +- Dracula (#1258) + +# 0.6.0 (2021-10-28) A big shout out to all the contributors! We had 46 contributors in this release. From efaac6c5d381b2fdf24f0b91956ac6949f6a07e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Tue, 4 Jan 2022 18:54:05 +0900 Subject: [PATCH 87/95] Release 0.6 --- Cargo.lock | 14 +++++++------- helix-core/Cargo.toml | 4 ++-- helix-lsp/Cargo.toml | 4 ++-- helix-syntax/Cargo.toml | 2 +- helix-term/Cargo.toml | 8 ++++---- helix-tui/Cargo.toml | 6 +++--- helix-view/Cargo.toml | 6 +++--- xtask/Cargo.toml | 6 +++--- 8 files changed, 25 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e6a55b51..1a01da82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -366,7 +366,7 @@ dependencies = [ [[package]] name = "helix-core" -version = "0.5.0" +version = "0.6.0" dependencies = [ "arc-swap", "chrono", @@ -392,7 +392,7 @@ dependencies = [ [[package]] name = "helix-lsp" -version = "0.5.0" +version = "0.6.0" dependencies = [ "anyhow", "futures-executor", @@ -410,7 +410,7 @@ dependencies = [ [[package]] name = "helix-syntax" -version = "0.5.0" +version = "0.6.0" dependencies = [ "anyhow", "cc", @@ -421,7 +421,7 @@ dependencies = [ [[package]] name = "helix-term" -version = "0.5.0" +version = "0.6.0" dependencies = [ "anyhow", "chrono", @@ -452,7 +452,7 @@ dependencies = [ [[package]] name = "helix-tui" -version = "0.5.0" +version = "0.6.0" dependencies = [ "bitflags", "cassowary", @@ -465,7 +465,7 @@ dependencies = [ [[package]] name = "helix-view" -version = "0.5.0" +version = "0.6.0" dependencies = [ "anyhow", "bitflags", @@ -1261,7 +1261,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "xtask" -version = "0.5.0" +version = "0.6.0" dependencies = [ "helix-core", "helix-term", diff --git a/helix-core/Cargo.toml b/helix-core/Cargo.toml index 3d7fe866..3c11ec76 100644 --- a/helix-core/Cargo.toml +++ b/helix-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "helix-core" -version = "0.5.0" +version = "0.6.0" authors = ["Blaž Hrastnik "] edition = "2021" license = "MPL-2.0" @@ -13,7 +13,7 @@ include = ["src/**/*", "README.md"] [features] [dependencies] -helix-syntax = { version = "0.5", path = "../helix-syntax" } +helix-syntax = { version = "0.6", path = "../helix-syntax" } ropey = "1.3" smallvec = "1.7" diff --git a/helix-lsp/Cargo.toml b/helix-lsp/Cargo.toml index b7fe94ab..ee485f57 100644 --- a/helix-lsp/Cargo.toml +++ b/helix-lsp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "helix-lsp" -version = "0.5.0" +version = "0.6.0" authors = ["Blaž Hrastnik "] edition = "2021" license = "MPL-2.0" @@ -12,7 +12,7 @@ homepage = "https://helix-editor.com" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -helix-core = { version = "0.5", path = "../helix-core" } +helix-core = { version = "0.6", path = "../helix-core" } anyhow = "1.0" futures-executor = "0.3" diff --git a/helix-syntax/Cargo.toml b/helix-syntax/Cargo.toml index cceec412..855839be 100644 --- a/helix-syntax/Cargo.toml +++ b/helix-syntax/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "helix-syntax" -version = "0.5.0" +version = "0.6.0" authors = ["Blaž Hrastnik "] edition = "2021" license = "MPL-2.0" diff --git a/helix-term/Cargo.toml b/helix-term/Cargo.toml index 58c713cb..28b4fe2a 100644 --- a/helix-term/Cargo.toml +++ b/helix-term/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "helix-term" -version = "0.5.0" +version = "0.6.0" description = "A post-modern text editor." authors = ["Blaž Hrastnik "] edition = "2021" @@ -22,9 +22,9 @@ name = "hx" path = "src/main.rs" [dependencies] -helix-core = { version = "0.5", path = "../helix-core" } -helix-view = { version = "0.5", path = "../helix-view" } -helix-lsp = { version = "0.5", path = "../helix-lsp" } +helix-core = { version = "0.6", path = "../helix-core" } +helix-view = { version = "0.6", path = "../helix-view" } +helix-lsp = { version = "0.6", path = "../helix-lsp" } anyhow = "1" once_cell = "1.9" diff --git a/helix-tui/Cargo.toml b/helix-tui/Cargo.toml index 6df65d36..4b8d7acb 100644 --- a/helix-tui/Cargo.toml +++ b/helix-tui/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "helix-tui" -version = "0.5.0" +version = "0.6.0" authors = ["Blaž Hrastnik "] description = """ A library to build rich terminal user interfaces or dashboards @@ -21,5 +21,5 @@ cassowary = "0.3" unicode-segmentation = "1.8" crossterm = { version = "0.22", optional = true } serde = { version = "1", "optional" = true, features = ["derive"]} -helix-view = { version = "0.5", path = "../helix-view", features = ["term"] } -helix-core = { version = "0.5", path = "../helix-core" } +helix-view = { version = "0.6", path = "../helix-view", features = ["term"] } +helix-core = { version = "0.6", path = "../helix-core" } diff --git a/helix-view/Cargo.toml b/helix-view/Cargo.toml index 121a518c..3c8866fc 100644 --- a/helix-view/Cargo.toml +++ b/helix-view/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "helix-view" -version = "0.5.0" +version = "0.6.0" authors = ["Blaž Hrastnik "] edition = "2021" license = "MPL-2.0" @@ -16,8 +16,8 @@ term = ["crossterm"] [dependencies] bitflags = "1.3" anyhow = "1" -helix-core = { version = "0.5", path = "../helix-core" } -helix-lsp = { version = "0.5", path = "../helix-lsp"} +helix-core = { version = "0.6", path = "../helix-core" } +helix-lsp = { version = "0.6", path = "../helix-lsp"} crossterm = { version = "0.22", optional = true } # Conversion traits diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index fe5d55d4..717530d0 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "xtask" -version = "0.5.0" +version = "0.6.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -helix-term = { version = "0.5", path = "../helix-term" } -helix-core = { version = "0.5", path = "../helix-core" } +helix-term = { version = "0.6", path = "../helix-term" } +helix-core = { version = "0.6", path = "../helix-core" } toml = "0.5" From 1bcae78f0665e6b52fea446487fc90b93d71e881 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Tue, 4 Jan 2022 18:58:26 +0900 Subject: [PATCH 88/95] minor: Fix some changelog links --- CHANGELOG.md | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b4b161e..5c09a734 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -89,34 +89,34 @@ LSP: Grammars: -- Adds mint language server (#974) -- Perl (#978) (#1280) -- GLSL (#993) -- Racket (#1143) -- WGSL (#1166) -- LLVM (#1167) (#1388) (#1409) (#1398) +- Adds mint language server ([#974](https://github.com/helix-editor/helix/pull/974)) +- Perl ([#978](https://github.com/helix-editor/helix/pull/978)) ([#1280](https://github.com/helix-editor/helix/pull/1280)) +- GLSL ([#993](https://github.com/helix-editor/helix/pull/993)) +- Racket ([#1143](https://github.com/helix-editor/helix/pull/1143)) +- WGSL ([#1166](https://github.com/helix-editor/helix/pull/1166)) +- LLVM ([#1167](https://github.com/helix-editor/helix/pull/1167)) ([#1388](https://github.com/helix-editor/helix/pull/1388)) ([#1409](https://github.com/helix-editor/helix/pull/1409)) ([#1398](https://github.com/helix-editor/helix/pull/1398)) - Markdown (49e06787) -- Scala (#1278) -- Dart (#1250) -- Fish (#1308) -- Dockerfile (#1303) -- Git (commit, rebase, diff) (#1338) (#1402) (#1373) -- tree-sitter-comment (#1300) -- Highlight comments in c, cpp, cmake and llvm (#1309) -- Improve yaml syntax highlighting highlighting (#1294) -- Improve rust syntax highlighting (#1295) -- Add textobjects and indents to cmake (#1307) -- Add textobjects and indents to c and cpp (#1293) +- Scala ([#1278](https://github.com/helix-editor/helix/pull/1278)) +- Dart ([#1250](https://github.com/helix-editor/helix/pull/1250)) +- Fish ([#1308](https://github.com/helix-editor/helix/pull/1308)) +- Dockerfile ([#1303](https://github.com/helix-editor/helix/pull/1303)) +- Git (commit, rebase, diff) ([#1338](https://github.com/helix-editor/helix/pull/1338)) ([#1402](https://github.com/helix-editor/helix/pull/1402)) ([#1373](https://github.com/helix-editor/helix/pull/1373)) +- tree-sitter-comment ([#1300](https://github.com/helix-editor/helix/pull/1300)) +- Highlight comments in c, cpp, cmake and llvm ([#1309](https://github.com/helix-editor/helix/pull/1309)) +- Improve yaml syntax highlighting highlighting ([#1294](https://github.com/helix-editor/helix/pull/1294)) +- Improve rust syntax highlighting ([#1295](https://github.com/helix-editor/helix/pull/1295)) +- Add textobjects and indents to cmake ([#1307](https://github.com/helix-editor/helix/pull/1307)) +- Add textobjects and indents to c and cpp ([#1293](https://github.com/helix-editor/helix/pull/1293)) New themes: -- Solarized dark (#999) -- Solarized light (#1010) -- Spacebones light (#1131) -- Monokai Pro (#1206) -- Base16 Light and Terminal (#1078) +- Solarized dark ([#999](https://github.com/helix-editor/helix/pull/999)) +- Solarized light ([#1010](https://github.com/helix-editor/helix/pull/1010)) +- Spacebones light ([#1131](https://github.com/helix-editor/helix/pull/1131)) +- Monokai Pro ([#1206](https://github.com/helix-editor/helix/pull/1206)) +- Base16 Light and Terminal ([#1078](https://github.com/helix-editor/helix/pull/1078)) - and a default 16 color theme, truecolor detection -- Dracula (#1258) +- Dracula ([#1258](https://github.com/helix-editor/helix/pull/1258)) # 0.6.0 (2021-10-28) From bd0d20a2b34f3cccd7f3ea1e988bf4b68e75d6b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Tue, 4 Jan 2022 19:25:59 +0900 Subject: [PATCH 89/95] minor: Fix previous version's header --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c09a734..38927991 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -118,7 +118,7 @@ New themes: - and a default 16 color theme, truecolor detection - Dracula ([#1258](https://github.com/helix-editor/helix/pull/1258)) -# 0.6.0 (2021-10-28) +# 0.5.0 (2021-10-28) A big shout out to all the contributors! We had 46 contributors in this release. From bed9aced5f4d745d74ffff1c10b6dc4acef8129e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Wed, 5 Jan 2022 10:58:12 +0900 Subject: [PATCH 90/95] Revert "Convert Windows style path separator in completers to Unix style (#1389)" This reverts commit 49444f9c0569a070ffd3c82cee6146656a0ac63c. --- helix-term/src/ui/mod.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs index 9bf88840..9e096311 100644 --- a/helix-term/src/ui/mod.rs +++ b/helix-term/src/ui/mod.rs @@ -313,7 +313,7 @@ pub mod completers { return None; } - let is_dir = entry.file_type().map_or(false, |entry| entry.is_dir()); + //let is_dir = entry.file_type().map_or(false, |entry| entry.is_dir()); let path = entry.path(); let mut path = if is_tilde { @@ -331,12 +331,7 @@ pub mod completers { path.push(""); } - let path = if cfg!(windows) && is_dir { - // Convert Windows style path separator to Unix style - path.to_str().unwrap().replace("\\", "/") - } else { - path.to_str().unwrap().to_owned() - }; + let path = path.to_str().unwrap().to_owned(); Some((end.clone(), Cow::from(path))) }) }) // TODO: unwrap or skip From 77677039795811505d8205f4efa082fc598492fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Wed, 5 Jan 2022 11:01:30 +0900 Subject: [PATCH 91/95] fix: Only use shellwords parsing on unix platforms --- helix-term/src/commands.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index a7b34062..cac6f582 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -3147,7 +3147,16 @@ fn command_mode(cx: &mut Context) { // Handle typable commands if let Some(cmd) = cmd::TYPABLE_COMMAND_MAP.get(parts[0]) { - let args = shellwords::shellwords(input); + let args = if cfg!(unix) { + shellwords::shellwords(input) + } else { + // Windows doesn't support POSIX, so fallback for now + parts + .into_iter() + .map(|part| part.into()) + .collect::>() + }; + if let Err(e) = (cmd.fun)(cx, &args[1..], event) { cx.editor.set_error(format!("{}", e)); } From b18bda928f0c7889031ec0327b9468280dbc3791 Mon Sep 17 00:00:00 2001 From: Stuart Hinson Date: Wed, 5 Jan 2022 20:39:19 -0500 Subject: [PATCH 92/95] fix slash in search selector status message (#1449) --- helix-term/src/commands.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index cac6f582..bf12b122 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -1639,7 +1639,7 @@ fn search_selection(cx: &mut Context) { let query = doc.selection(view.id).primary().fragment(contents); let regex = regex::escape(&query); cx.editor.registers.get_mut('/').push(regex); - let msg = format!("register '{}' set to '{}'", '\\', query); + let msg = format!("register '{}' set to '{}'", '/', query); cx.editor.set_status(msg); } From 3e4f81547c679619c96d0a6477ebf1d3badfe661 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Thu, 6 Jan 2022 11:03:54 +0900 Subject: [PATCH 93/95] fix: Use std::path::MAIN_SEPARATOR to determine completion Refs #1439 --- helix-term/src/ui/mod.rs | 2 +- helix-term/src/ui/prompt.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs index 9e096311..9ff9118f 100644 --- a/helix-term/src/ui/mod.rs +++ b/helix-term/src/ui/mod.rs @@ -283,7 +283,7 @@ pub mod completers { let is_tilde = input.starts_with('~') && input.len() == 1; let path = helix_core::path::expand_tilde(Path::new(input)); - let (dir, file_name) = if input.ends_with('/') { + let (dir, file_name) = if input.ends_with(std::path::MAIN_SEPARATOR) { (path, None) } else { let file_name = path diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index 29e0339a..0202de23 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -473,7 +473,7 @@ impl Component for Prompt { } } key!(Enter) => { - if self.selection.is_some() && self.line.ends_with('/') { + if self.selection.is_some() && self.line.ends_with(std::path::MAIN_SEPARATOR) { self.completion = (self.completion_fn)(&self.line); self.exit_selection(); } else { From 66afbc9fff1ec5947ea5718f7817887aa0c853c8 Mon Sep 17 00:00:00 2001 From: Philipp Mildenberger Date: Thu, 6 Jan 2022 03:04:55 +0100 Subject: [PATCH 94/95] Fix null and boolean constants in tree-sitter-nix highlights queries (#1428) --- runtime/queries/nix/highlights.scm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/runtime/queries/nix/highlights.scm b/runtime/queries/nix/highlights.scm index 66719e87..f6682065 100644 --- a/runtime/queries/nix/highlights.scm +++ b/runtime/queries/nix/highlights.scm @@ -13,7 +13,7 @@ ] @keyword ((identifier) @variable.builtin - (#match? @variable.builtin "^(__currentSystem|__currentTime|__nixPath|__nixVersion|__storeDir|builtins|false|null|true)$") + (#match? @variable.builtin "^(__currentSystem|__currentTime|__nixPath|__nixVersion|__storeDir|builtins)$") (#is-not? local)) ((identifier) @function.builtin @@ -33,6 +33,11 @@ (uri) @string.special.uri +; boolean +((identifier) @constant.builtin.boolean (#match? @constant.builtin.boolean "^(true|false)$")) @constant.builtin.boolean +; null +((identifier) @constant.builtin (#eq? @constant.builtin "null")) @constant.builtin + (integer) @constant.numeric.integer (float) @constant.numeric.float From 2e02a1d6bc004212033b9c4e5ed0de0fd880796c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Dzivjak?= Date: Thu, 6 Jan 2022 03:12:02 +0100 Subject: [PATCH 95/95] feat(commands): shrink_selection (#1340) * feat(commands): shrink_selection Add `shrink_selection` command that can be used to shrink previously expanded selection. To make `shrink_selection` work it was necessary to add selection history to the Document since we want to shrink the selection towards the syntax tree node that was initially selected. Selection history is cleared any time the user changes selection other way than by `expand_selection`. This ensures that we don't get some funky edge cases when user calls `shrink_selection`. Related: https://github.com/helix-editor/helix/discussions/1328 * Refactor shrink_selection, move history to view * Remove useless comment * Add default key mapping for extend&shrink selection * Rework contains_selection method * Shrink selection without expand selects first child --- book/src/keymap.md | 2 ++ helix-core/src/object.rs | 29 +++++++++++++++-- helix-core/src/selection.rs | 64 +++++++++++++++++++++++++++++++++++++ helix-term/src/commands.rs | 36 ++++++++++++++++++++- helix-term/src/keymap.rs | 2 ++ helix-view/src/view.rs | 3 ++ 6 files changed, 133 insertions(+), 3 deletions(-) diff --git a/book/src/keymap.md b/book/src/keymap.md index 581e70e9..70ec13b3 100644 --- a/book/src/keymap.md +++ b/book/src/keymap.md @@ -261,6 +261,8 @@ Mappings in the style of [vim-unimpaired](https://github.com/tpope/vim-unimpaire | `]D` | Go to last diagnostic in document (**LSP**) | `goto_last_diag` | | `[space` | Add newline above | `add_newline_above` | | `]space` | Add newline below | `add_newline_below` | +| `]o` | Expand syntax tree object selection. | `expand_selection` | +| `[o` | Shrink syntax tree object selection. | `shrink_selection` | ## Insert Mode diff --git a/helix-core/src/object.rs b/helix-core/src/object.rs index 717c5994..21fa24fb 100644 --- a/helix-core/src/object.rs +++ b/helix-core/src/object.rs @@ -1,7 +1,5 @@ use crate::{Range, RopeSlice, Selection, Syntax}; -// TODO: to contract_selection we'd need to store the previous ranges before expand. -// Maybe just contract to the first child node? pub fn expand_selection(syntax: &Syntax, text: RopeSlice, selection: &Selection) -> Selection { let tree = syntax.tree(); @@ -34,3 +32,30 @@ pub fn expand_selection(syntax: &Syntax, text: RopeSlice, selection: &Selection) } }) } + +pub fn shrink_selection(syntax: &Syntax, text: RopeSlice, selection: &Selection) -> Selection { + let tree = syntax.tree(); + + selection.clone().transform(|range| { + let from = text.char_to_byte(range.from()); + let to = text.char_to_byte(range.to()); + + let descendant = match tree.root_node().descendant_for_byte_range(from, to) { + // find first child, if not possible, fallback to the node that contains selection + Some(descendant) => match descendant.child(0) { + Some(child) => child, + None => descendant, + }, + None => return range, + }; + + let from = text.byte_to_char(descendant.start_byte()); + let to = text.byte_to_char(descendant.end_byte()); + + if range.head < range.anchor { + Range::new(to, from) + } else { + Range::new(from, to) + } + }) +} diff --git a/helix-core/src/selection.rs b/helix-core/src/selection.rs index 06ea9d67..1515c4fc 100644 --- a/helix-core/src/selection.rs +++ b/helix-core/src/selection.rs @@ -140,6 +140,11 @@ impl Range { self.from() == other.from() || (self.to() > other.from() && other.to() > self.from()) } + #[inline] + pub fn contains_range(&self, other: &Self) -> bool { + self.from() <= other.from() && self.to() >= other.to() + } + pub fn contains(&self, pos: usize) -> bool { self.from() <= pos && pos < self.to() } @@ -544,6 +549,39 @@ impl Selection { pub fn len(&self) -> usize { self.ranges.len() } + + // returns true if self ⊇ other + pub fn contains(&self, other: &Selection) -> bool { + // can't contain other if it is larger + if other.len() > self.len() { + return false; + } + + let (mut iter_self, mut iter_other) = (self.iter(), other.iter()); + let (mut ele_self, mut ele_other) = (iter_self.next(), iter_other.next()); + + loop { + match (ele_self, ele_other) { + (Some(ra), Some(rb)) => { + if !ra.contains_range(rb) { + // `self` doesn't contain next element from `other`, advance `self`, we need to match all from `other` + ele_self = iter_self.next(); + } else { + // matched element from `other`, advance `other` + ele_other = iter_other.next(); + }; + } + (None, Some(_)) => { + // exhausted `self`, we can't match the reminder of `other` + return false; + } + (_, None) => { + // no elements from `other` left to match, `self` contains `other` + return true; + } + } + } + } } impl<'a> IntoIterator for &'a Selection { @@ -982,4 +1020,30 @@ mod test { &["", "abcd", "efg", "rs", "xyz"] ); } + #[test] + fn test_selection_contains() { + fn contains(a: Vec<(usize, usize)>, b: Vec<(usize, usize)>) -> bool { + let sela = Selection::new(a.iter().map(|a| Range::new(a.0, a.1)).collect(), 0); + let selb = Selection::new(b.iter().map(|b| Range::new(b.0, b.1)).collect(), 0); + sela.contains(&selb) + } + + // exact match + assert!(contains(vec!((1, 1)), vec!((1, 1)))); + + // larger set contains smaller + assert!(contains(vec!((1, 1), (2, 2), (3, 3)), vec!((2, 2)))); + + // multiple matches + assert!(contains(vec!((1, 1), (2, 2)), vec!((1, 1), (2, 2)))); + + // smaller set can't contain bigger + assert!(!contains(vec!((1, 1)), vec!((1, 1), (2, 2)))); + + assert!(contains( + vec!((1, 1), (2, 4), (5, 6), (7, 9), (10, 13)), + vec!((3, 4), (7, 9)) + )); + assert!(!contains(vec!((1, 1), (5, 6)), vec!((1, 6)))); + } } diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index bf12b122..5c26a5b2 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -362,6 +362,7 @@ impl MappableCommand { rotate_selection_contents_forward, "Rotate selection contents forward", rotate_selection_contents_backward, "Rotate selections contents backward", expand_selection, "Expand selection to parent syntax node", + shrink_selection, "Shrink selection to previously expanded syntax node", jump_forward, "Jump forward on jumplist", jump_backward, "Jump backward on jumplist", save_selection, "Save the current selection to the jumplist", @@ -5467,6 +5468,7 @@ fn rotate_selection_contents(cx: &mut Context, direction: Direction) { doc.apply(&transaction, view.id); doc.append_changes_to_history(view.id); } + fn rotate_selection_contents_forward(cx: &mut Context) { rotate_selection_contents(cx, Direction::Forward) } @@ -5482,7 +5484,39 @@ fn expand_selection(cx: &mut Context) { if let Some(syntax) = doc.syntax() { let text = doc.text().slice(..); - let selection = object::expand_selection(syntax, text, doc.selection(view.id)); + + let current_selection = doc.selection(view.id); + + // save current selection so it can be restored using shrink_selection + view.object_selections.push(current_selection.clone()); + + let selection = object::expand_selection(syntax, text, current_selection); + doc.set_selection(view.id, selection); + } + }; + motion(cx.editor); + cx.editor.last_motion = Some(Motion(Box::new(motion))); +} + +fn shrink_selection(cx: &mut Context) { + let motion = |editor: &mut Editor| { + let (view, doc) = current!(editor); + let current_selection = doc.selection(view.id); + // try to restore previous selection + if let Some(prev_selection) = view.object_selections.pop() { + if current_selection.contains(&prev_selection) { + // allow shrinking the selection only if current selection contains the previous object selection + doc.set_selection(view.id, prev_selection); + return; + } else { + // clear existing selection as they can't be shrinked to anyway + view.object_selections.clear(); + } + } + // if not previous selection, shrink to first child + if let Some(syntax) = doc.syntax() { + let text = doc.text().slice(..); + let selection = object::shrink_selection(syntax, text, current_selection); doc.set_selection(view.id, selection); } }; diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index 72833212..49f8469a 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -569,11 +569,13 @@ impl Default for Keymaps { "d" => goto_prev_diag, "D" => goto_first_diag, "space" => add_newline_above, + "o" => shrink_selection, }, "]" => { "Right bracket" "d" => goto_next_diag, "D" => goto_last_diag, "space" => add_newline_below, + "o" => expand_selection, }, "/" => search, diff --git a/helix-view/src/view.rs b/helix-view/src/view.rs index 94d67acd..89a6c196 100644 --- a/helix-view/src/view.rs +++ b/helix-view/src/view.rs @@ -80,6 +80,8 @@ pub struct View { // uses two docs because we want to be able to swap between the // two last modified docs which we need to manually keep track of pub last_modified_docs: [Option; 2], + /// used to store previous selections of tree-sitter objecs + pub object_selections: Vec, } impl View { @@ -92,6 +94,7 @@ impl View { jumps: JumpList::new((doc, Selection::point(0))), // TODO: use actual sel last_accessed_doc: None, last_modified_docs: [None, None], + object_selections: Vec::new(), } }