Compare commits

...

7 Commits

Author SHA1 Message Date
Mathieu Agopian
827e6eb2d6
Merge 109ede2e4b into f305c7299d 2024-11-21 23:32:29 +03:00
Lens0021 / Leslie
f305c7299d
Add support for Amber-lang (#12021)
Co-authored-by: Phoenix Himself <pkaras.it@gmail.com>
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2024-11-21 10:09:42 -06:00
Valentin B.
9e0d2d0a19
chore(solidity): add highlight queries (#12102)
Add highlights for `hex` and `unicode` string prefixes and YUL booleans
2024-11-21 07:58:14 -06:00
Michael Davis
109ede2e4b
Merge branch 'master' into magopian:6045-expand-word-boundary-on-search 2024-02-10 16:26:15 -05:00
Mathieu Agopian
fa552f1c47 Implement feedback from cargo clippy 2023-03-09 11:07:45 +01:00
Mathieu Agopian
b917595e9b Document the new behavior in keymap.md 2023-02-18 19:41:06 +01:00
Mathieu Agopian
428c5c74fd Expand selection to whole word when pressing * 2023-02-18 19:18:05 +01:00
7 changed files with 165 additions and 22 deletions

View File

@ -3,6 +3,7 @@
| ada | ✓ | ✓ | | `ada_language_server` |
| adl | ✓ | ✓ | ✓ | |
| agda | ✓ | | | |
| amber | ✓ | | | |
| astro | ✓ | | | |
| awk | ✓ | ✓ | | `awk-language-server` |
| bash | ✓ | ✓ | ✓ | `bash-language-server` |

View File

@ -154,13 +154,13 @@ ### Search
Search commands all operate on the `/` register by default. To use a different register, use `"<char>`.
| Key | Description | Command |
| ----- | ----------- | ------- |
| `/` | Search for regex pattern | `search` |
| `?` | Search for previous pattern | `rsearch` |
| `n` | Select next search match | `search_next` |
| `N` | Select previous search match | `search_prev` |
| `*` | Use current selection as the search pattern | `search_selection` |
| Key | Description | Command |
| ----- | ----------- | ------- |
| `/` | Search for regex pattern | `search` |
| `?` | Search for previous pattern | `rsearch` |
| `n` | Select next search match | `search_next` |
| `N` | Select previous search match | `search_prev` |
| `*` | Use current selection as the search pattern, if only a single char is selected the current word (miW) is used instead | `search_selection` |
### Minor modes

View File

@ -2266,19 +2266,37 @@ fn extend_search_prev(cx: &mut Context) {
fn search_selection(cx: &mut Context) {
let register = cx.register.unwrap_or('/');
let count = cx.count();
let (view, doc) = current!(cx.editor);
let contents = doc.text().slice(..);
let regex = doc
.selection(view.id)
.iter()
.map(|selection| regex::escape(&selection.fragment(contents)))
.collect::<HashSet<_>>() // Collect into hashset to deduplicate identical regexes
.into_iter()
.collect::<Vec<_>>()
.join("|");
// Checks whether there is only one selection with a width of 1
let selections = doc.selection(view.id);
let primary = selections.primary();
let regex = if selections.len() == 1 && primary.len() == 1 {
let text = doc.text();
let text_slice = text.slice(..);
// In this case select the WORD under the cursor
let current_word = textobject::textobject_word(
text_slice,
primary,
textobject::TextObject::Inside,
count,
false,
);
let text_to_search = current_word.fragment(text_slice).to_string();
regex::escape(&text_to_search)
} else {
selections
.iter()
.map(|selection| regex::escape(&selection.fragment(contents)))
.collect::<HashSet<_>>() // Collect into hashset to deduplicate identical regexes
.into_iter()
.collect::<Vec<_>>()
.join("|")
};
let msg = format!("register '{}' set to '{}'", register, &regex);
let msg = format!("register '{}' set to '{}'", '/', &regex);
match cx.editor.registers.push(register, regex) {
Ok(_) => {
cx.editor.registers.last_search_register = register;

View File

@ -178,6 +178,56 @@ fn match_paths(app: &Application, matches: Vec<&str>) -> usize {
Ok(())
}
#[tokio::test(flavor = "multi_thread")]
async fn test_search_selection() -> anyhow::Result<()> {
// Single selection with a length of 1: search for the whole word
test_key_sequence(
&mut helpers::AppBuilder::new().build()?,
Some("ifoobar::baz<esc>3bl*"), // 3b places the cursor on the first letter of 'foobar', then move one to the right for good measure
Some(&|app| {
assert!(
r#"register '/' set to 'foobar'"# == app.editor.get_status().unwrap().0
&& Some(&"foobar".to_string()) == app.editor.registers.first('/')
);
}),
false,
)
.await?;
// Single selection with a length greather than 1: only search for the selection
test_key_sequence(
&mut helpers::AppBuilder::new().build()?,
Some("ifoobar::baz<esc>3blvll*"), // 3b places the cursor on the first letter of 'foobar', then move one to the right for good measure, then select two more chars for a total of three
Some(&|app| {
assert!(
r#"register '/' set to 'oob'"# == app.editor.get_status().unwrap().0
&& Some(&"oob".to_string()) == app.editor.registers.first('/')
);
}),
false,
)
.await?;
// Multiple selection of length 1 each : should still only search for the selection
test_key_sequence(
&mut helpers::AppBuilder::new().build()?,
Some("ifoobar::baz<ret>bar::crux<esc>k3blC*"), // k3b places the cursor on the first letter of 'foobar', then move one to the right for good measure, then adds a cursor on the line below
Some(&|app| {
assert!(
// The selections don't seem to be ordered, so we have to test for the two possible orders.
(r#"register '/' set to 'o|a'"# == app.editor.get_status().unwrap().0
|| r#"register '/' set to 'a|o'"# == app.editor.get_status().unwrap().0)
&& (Some(&"o|a".to_string()) == app.editor.registers.first('/')
|| Some(&"a|o".to_string()) == app.editor.registers.first('/'))
);
}),
false,
)
.await?;
Ok(())
}
#[tokio::test(flavor = "multi_thread")]
async fn test_multi_selection_paste() -> anyhow::Result<()> {
test((

View File

@ -3931,3 +3931,14 @@ indent = { tab-width = 4, unit = " " }
[[grammar]]
name = "spade"
source = { git = "https://gitlab.com/spade-lang/tree-sitter-spade/", rev = "4d5b141017c61fe7e168e0a5c5721ee62b0d9572" }
[[language]]
name = "amber"
scope = "source.ab"
file-types = ["ab"]
comment-token = "//"
indent = { tab-width = 4, unit = " " }
[[grammar]]
name = "amber"
source = { git = "https://github.com/amber-lang/tree-sitter-amber", rev = "c6df3ec2ec243ed76550c525e7ac3d9a10c6c814" }

View File

@ -0,0 +1,60 @@
(comment) @comment
[
"if"
"loop"
"for"
"return"
"fun"
"else"
"then"
"break"
"continue"
"and"
"or"
"not"
"let"
"pub"
"main"
"echo"
"exit"
"fun"
"import"
"from"
"as"
"in"
"fail"
"failed"
"silent"
"nameof"
"is"
"unsafe"
"trust"
] @keyword
; Literals
(boolean) @constant.builtin.boolean
(number) @constant.numeric
(null) @constant.numeric
(string) @string
(status) @keyword
(command) @string
(handler) @keyword
(block) @punctuation.delimiter
(variable_init) @keyword
(variable_assignment) @punctuation.delimiter
(variable) @variable
(escape_sequence) @constant.character.escape
(type_name_symbol) @type
(interpolation) @punctuation.delimiter
(reference) @keyword
(preprocessor_directive) @comment
(shebang) @comment
(function_definition
name: (variable) @function.method)
(function_call
name: (variable) @function.method)
(import_statement
"pub" @keyword
"import" @keyword
"from" @keyword)

View File

@ -12,6 +12,8 @@
(unicode_string_literal)
(yul_string_literal)
] @string
(hex_string_literal "hex" @string.special.symbol)
(unicode_string_literal "unicode" @string.special.symbol)
[
(number_literal)
(yul_decimal_number)
@ -20,6 +22,7 @@
[
(true)
(false)
(yul_boolean)
] @constant.builtin.boolean
(comment) @comment
@ -44,18 +47,18 @@
(type_name "(" @punctuation.bracket "=>" @punctuation.delimiter ")" @punctuation.bracket)
; Definitions
(struct_declaration
(struct_declaration
name: (identifier) @type)
(enum_declaration
(enum_declaration
name: (identifier) @type)
(contract_declaration
name: (identifier) @type)
name: (identifier) @type)
(library_declaration
name: (identifier) @type)
name: (identifier) @type)
(interface_declaration
name: (identifier) @type)
(event_definition
name: (identifier) @type)
(event_definition
name: (identifier) @type)
(function_definition
name: (identifier) @function)