From 72748886b05931960dbd6ff4e072fd367861c5bf Mon Sep 17 00:00:00 2001 From: Midnight Exigent <36641328+midnightexigent@users.noreply.github.com> Date: Wed, 11 May 2022 12:40:30 +0200 Subject: [PATCH 1/7] feat(syntax): add strategy to associate file to language through pattern File path will match if it ends with any of the file types provided in the config. Also used this feature to add support for the .git/config and .ssh/config files --- book/src/generated/lang-support.md | 1 + helix-core/src/syntax.rs | 14 +- languages.toml | 12 +- .../queries/sshclientconfig/highlights.scm | 324 ++++++++++++++++++ 4 files changed, 349 insertions(+), 2 deletions(-) create mode 100644 runtime/queries/sshclientconfig/highlights.scm diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 95cf91a43387..f857fc0d495f 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -78,6 +78,7 @@ | scala | ✓ | | ✓ | `metals` | | solidity | ✓ | | | `solc` | | sql | ✓ | | | | +| sshclientconfig | ✓ | | | | | svelte | ✓ | | ✓ | `svelteserver` | | swift | ✓ | | | `sourcekit-lsp` | | tablegen | ✓ | ✓ | ✓ | | diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index b20d9092fae0..bb94b5e7c8bc 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -462,9 +462,10 @@ impl Loader { for file_type in &config.file_types { // entry().or_insert(Vec::new).push(language_id); + let file_type = file_type.replace('/', &std::path::MAIN_SEPARATOR.to_string()); loader .language_config_ids_by_file_type - .insert(file_type.clone(), language_id); + .insert(file_type, language_id); } for shebang in &config.shebangs { loader @@ -489,6 +490,17 @@ impl Loader { path.extension() .and_then(|extension| extension.to_str()) .and_then(|extension| self.language_config_ids_by_file_type.get(extension)) + }) + .or_else(|| { + self.language_config_ids_by_file_type + .iter() + .find_map(|(file_type, id)| { + if path.to_str()?.ends_with(file_type) { + Some(id) + } else { + None + } + }) }); configuration_id.and_then(|&id| self.language_configs.get(id).cloned()) diff --git a/languages.toml b/languages.toml index bedde5a2d402..57e76a34b950 100644 --- a/languages.toml +++ b/languages.toml @@ -947,7 +947,7 @@ name = "git-config" scope = "source.gitconfig" roots = [] # TODO: allow specifying file-types as a regex so we can read directory names (e.g. `.git/config`) -file-types = [".gitmodules", ".gitconfig"] +file-types = [".gitmodules", ".gitconfig", ".git/config", ".config/git/config"] injection-regex = "git-config" comment-token = "#" indent = { tab-width = 4, unit = "\t" } @@ -1355,3 +1355,13 @@ indent = { tab-width = 2, unit = " " } [[grammar]] name = "meson" source = { git = "https://github.com/bearcove/tree-sitter-meson", rev = "feea83be9225842490066522ced2d13eb9cce0bd" } + +[[language]] +name = "sshclientconfig" +scope = "source.sshclientconfig" +file-types = [".ssh/config"] +roots = [] + +[[grammar]] +name = "sshclientconfig" +source = { git = "https://github.com/metio/tree-sitter-ssh-client-config.git", rev = "769d7a01a2e5493b4bb5a51096c6bf4be130b024" } diff --git a/runtime/queries/sshclientconfig/highlights.scm b/runtime/queries/sshclientconfig/highlights.scm new file mode 100644 index 000000000000..83a212a20a42 --- /dev/null +++ b/runtime/queries/sshclientconfig/highlights.scm @@ -0,0 +1,324 @@ +(host) @keyword +(host_value) @identifier + +(match) @keyword +(match_value) @identifier + +(add_keys_to_agent) @keyword +(add_keys_to_agent_value) @boolean + +(address_family) @keyword +(address_family_value) @type + +(batch_mode) @keyword +(batch_mode_value) @boolean + +(bind_address) @keyword +(bind_address_value) @string + +(bind_interface) @keyword +(bind_interface_value) @string + +(canonical_domains) @keyword +(canonical_domains_value) @identifier + +(canonicalize_fallback_local) @keyword +(canonicalize_fallback_local_value) @boolean + +(canonicalize_hostname) @keyword +(canonicalize_hostname_value) @boolean + +(canonicalize_max_dots) @keyword +(canonicalize_max_dots_value) @number + +(canonicalize_permitted_cnames) @keyword +(canonicalize_permitted_cnames_value) @identifier + +(ca_signature_algorithms) @keyword +(ca_signature_algorithms_value) @identifier + +(certificate_file) @keyword +(certificate_file_value) @file + +(challenge_response_authentication) @keyword +(challenge_response_authentication_value) @boolean + +(check_host_ip) @keyword +(check_host_ip_value) @boolean + +(cipher) @keyword +(cipher_value) @identifier + +(ciphers) @keyword +(ciphers_value) @identifier + +(clear_all_forwardings) @keyword +(clear_all_forwardings_value) @boolean + +(comment) @comment + +(compression) @keyword +(compression_value) @boolean + +(connect_timeout) @keyword +(connect_timeout_value) @number + +(connection_attempts) @keyword +(connection_attempts_value) @number + +(control_master) @keyword +(control_master_value) @type + +(control_path) @keyword +(control_path_value) @file + +(control_persist) @keyword +(control_persist_value) @type + +(dynamic_forward) @keyword +(dynamic_forward_value) @string + +(enable_ssh_keysign) @keyword +(enable_ssh_keysign_value) @boolean + +(escape_char) @keyword +(escape_char_value) @string + +(exit_on_forward_failure) @keyword +(exit_on_forward_failure_value) @boolean + +(fingerprint_hash) @keyword +(fingerprint_hash_value) @identifier + +(fork_after_authentication) @keyword +(fork_after_authentication_value) @boolean + +(forward_agent) @keyword +(forward_agent_value) @boolean + +(forward_x11) @keyword +(forward_x11_value) @boolean + +(forward_x11_timeout) @keyword +(forward_x11_timeout_value) @time + +(forward_x11_trusted) @keyword +(forward_x11_trusted_value) @boolean + +(gateway_ports) @keyword +(gateway_ports_value) @boolean + +(global_known_hosts_file) @keyword +(global_known_hosts_file_value) @file + +(gssapi_authentication) @keyword +(gssapi_authentication_value) @boolean + +(gssapi_client_identity) @keyword +(gssapi_client_identity_value) @string + +(gssapi_delegate_credentials) @keyword +(gssapi_delegate_credentials_value) @boolean + +(gssapi_kex_algorithms) @keyword +(gssapi_kex_algorithms_value) @identifier + +(gssapi_key_exchange) @keyword +(gssapi_key_exchange_value) @boolean + +(gssapi_renewal_forces_rekey) @keyword +(gssapi_renewal_forces_rekey_value) @boolean + +(gssapi_server_identity) @keyword +(gssapi_server_identity_value) @string + +(gssapi_trust_dns) @keyword +(gssapi_trust_dns_value) @boolean + +(hash_known_hosts) @keyword +(hash_known_hosts_value) @boolean + +(host_key_algorithms) @keyword +(host_key_algorithms_value) @identifier + +(host_key_alias) @keyword +(host_key_alias_value) @string + +(hostbased_accepted_algorithms) @keyword +(hostbased_accepted_algorithms_value) @identifier + +(hostbased_authentication) @keyword +(hostbased_authentication_value) @boolean + +(hostname) @keyword +(hostname_value) @string + +(identities_only) @keyword +(identities_only_value) @boolean + +(identity_agent) @keyword +(identity_agent_value) @string + +(identity_file) @keyword +(identity_file_value) @file + +(ignore_unknown) @keyword +(ignore_unknown_value) @string + +(include) @keyword +(include_value) @file + +(ip_qos) @keyword +(ip_qos_value) @type + +(kbd_interactive_authentication) @keyword +(kbd_interactive_authentication_value) @boolean + +(kbd_interactive_devices) @keyword +(kbd_interactive_devices_value) @type + +(kex_algorithms) @keyword +(kex_algorithms_value) @identifier + +(known_hosts_command) @keyword +(known_hosts_command_value) @string + +(local_command) @keyword +(local_command_value) @string + +(local_forward) @keyword +(local_forward_value) @string + +(log_level) @keyword +(log_level_value) @type + +(log_verbose) @keyword +(log_verbose_value) @string + +(macs) @keyword +(macs_value) @identifier + +(no_host_authentication_for_localhost) @keyword +(no_host_authentication_for_localhost_value) @boolean + +(number_of_password_prompts) @keyword +(number_of_password_prompts_value) @number + +(password_authentication) @keyword +(password_authentication_value) @boolean + +(permit_local_command) @keyword +(permit_local_command_value) @boolean + +(permit_remote_open) @keyword +(permit_remote_open_value) @string + +(pkcs11_provider) @keyword +(pkcs11_provider_value) @string + +(port) @keyword +(port_value) @number + +(preferred_authentications) @keyword +(preferred_authentications_value) @type + +(protocol) @keyword +(protocol_value) @number + +(proxy_command) @keyword +(proxy_command_value) @string + +(proxy_jump) @keyword +(proxy_jump_value) @string + +(proxy_use_fdpass) @keyword +(proxy_use_fdpass_value) @boolean + +(pubkey_accepted_algorithms) @keyword +(pubkey_accepted_algorithms_value) @identifier + +(pubkey_accepted_key_types) @keyword +(pubkey_accepted_key_types_value) @identifier + +(pubkey_authentication) @keyword +(pubkey_authentication_value) @boolean + +(rekey_limit) @keyword +(rekey_limit_value) @string + +(remote_command) @keyword +(remote_command_value) @string + +(remote_forward) @keyword +(remote_forward_value) @string + +(request_tty) @keyword +(request_tty_value) @type + +(revoked_host_keys) @keyword +(revoked_host_keys_value) @file + +(security_key_provider) @keyword +(security_key_provider_value) @string + +(send_env) @keyword +(send_env_value) @string + +(server_alive_count_max) @keyword +(server_alive_count_max_value) @number + +(server_alive_interval) @keyword +(server_alive_interval_value) @number + +(session_type) @keyword +(session_type_value) @type + +(set_env) @keyword +(set_env_value) @string + +(stdin_null) @keyword +(stdin_null_value) @boolean + +(stream_local_bind_mask) @keyword +(stream_local_bind_mask_value) @string + +(stream_local_bind_unlink) @keyword +(stream_local_bind_unlink_value) @boolean + +(strict_host_key_checking) @keyword +(strict_host_key_checking_value) @type + +(syslog_facility) @keyword +(syslog_facility_value) @type + +(tcp_keep_alive) @keyword +(tcp_keep_alive_value) @boolean +(keep_alive) @keyword +(keep_alive_value) @boolean + +(tunnel) @keyword +(tunnel_value) @type + +(tunnel_device) @keyword +(tunnel_device_value) @string + +(update_host_keys) @keyword +(update_host_keys_value) @type + +(use_keychain) @keyword +(use_keychain_value) @boolean + +(user) @keyword +(user_value) @string + +(user_known_hosts_file) @keyword +(user_known_hosts_file_value) @file + +(verify_host_key_dns) @keyword +(verify_host_key_dns_value) @type + +(visual_host_key) @keyword +(visual_host_key_value) @boolean + +(xauth_location) @keyword +(xauth_location_value) @file From c02dc2e4e6de8096057ff7918134022451892c89 Mon Sep 17 00:00:00 2001 From: midnightexigent <36641328+midnightexigent@users.noreply.github.com> Date: Sat, 14 May 2022 20:56:05 +0200 Subject: [PATCH 2/7] Add /etc/ssh/ssh_config to languages.toml --- languages.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages.toml b/languages.toml index 321b60d657fa..d529958fcf9e 100644 --- a/languages.toml +++ b/languages.toml @@ -1359,7 +1359,7 @@ source = { git = "https://github.com/bearcove/tree-sitter-meson", rev = "feea83b [[language]] name = "sshclientconfig" scope = "source.sshclientconfig" -file-types = [".ssh/config"] +file-types = [".ssh/config", "/etc/ssh/ssh_config"] roots = [] [[grammar]] From 40f455f9455b42c4cad0e296e8c8c9c0399735be Mon Sep 17 00:00:00 2001 From: Midnight Exigent <36641328+midnightexigent@users.noreply.github.com> Date: Wed, 18 May 2022 19:38:43 +0200 Subject: [PATCH 3/7] cargo xtask docgen --- book/src/generated/lang-support.md | 1 - languages.toml | 9 --------- 2 files changed, 10 deletions(-) diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index f857fc0d495f..95cf91a43387 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -78,7 +78,6 @@ | scala | ✓ | | ✓ | `metals` | | solidity | ✓ | | | `solc` | | sql | ✓ | | | | -| sshclientconfig | ✓ | | | | | svelte | ✓ | | ✓ | `svelteserver` | | swift | ✓ | | | `sourcekit-lsp` | | tablegen | ✓ | ✓ | ✓ | | diff --git a/languages.toml b/languages.toml index 1e23871f23db..e6700324b222 100644 --- a/languages.toml +++ b/languages.toml @@ -1356,12 +1356,3 @@ indent = { tab-width = 2, unit = " " } name = "meson" source = { git = "https://github.com/bearcove/tree-sitter-meson", rev = "feea83be9225842490066522ced2d13eb9cce0bd" } -[[language]] -name = "sshclientconfig" -scope = "source.sshclientconfig" -file-types = [".ssh/config", "/etc/ssh/ssh_config"] -roots = [] - -[[grammar]] -name = "sshclientconfig" -source = { git = "https://github.com/metio/tree-sitter-ssh-client-config.git", rev = "769d7a01a2e5493b4bb5a51096c6bf4be130b024" } From 741ae7a0a9a178fdfbddca817fb989d6cebf0f22 Mon Sep 17 00:00:00 2001 From: midnightexigent <36641328+midnightexigent@users.noreply.github.com> Date: Sun, 14 Aug 2022 13:01:04 +0000 Subject: [PATCH 4/7] Update languages.md --- book/src/languages.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/book/src/languages.md b/book/src/languages.md index 841b1377d035..d0fff2850d51 100644 --- a/book/src/languages.md +++ b/book/src/languages.md @@ -62,6 +62,12 @@ These configuration keys are available: | `grammar` | The tree-sitter grammar to use (defaults to the value of `name`) | | `formatter` | The formatter for the language, it will take precedence over the lsp when defined. The formatter must be able to take the original file as input from stdin and write the formatted file to stdout | +Additionnaly, entries in `file-types` are matched accoding to different strategies, in the following order : + +1. File name is an exact match +2. File extension is an exact match +3. File path contains the value as a suffix + ### Language Server configuration The `language-server` field takes the following keys: From 4b612b7455fdec8f353ac590daaf0f3e95a97f61 Mon Sep 17 00:00:00 2001 From: midnightexigent <36641328+midnightexigent@users.noreply.github.com> Date: Sun, 14 Aug 2022 13:05:43 +0000 Subject: [PATCH 5/7] Update languages.md --- book/src/languages.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/book/src/languages.md b/book/src/languages.md index d0fff2850d51..7ebb7baa31ff 100644 --- a/book/src/languages.md +++ b/book/src/languages.md @@ -50,7 +50,7 @@ These configuration keys are available: | `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"]`. Extensions and full file names are supported. | +| `file-types` | The filetypes of the language, for example `["yml", "yaml"]`. This attempts to match by exact file name, then by file extension, then by path suffix | | `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 | @@ -64,9 +64,9 @@ These configuration keys are available: Additionnaly, entries in `file-types` are matched accoding to different strategies, in the following order : -1. File name is an exact match -2. File extension is an exact match -3. File path contains the value as a suffix +1. File name is an exact match -- example: `.zshrc` +2. File extension is an exact match -- example: `toml` +3. File path contains the value as a suffix -- example: `.git/config` ### Language Server configuration From dfa44d8a372246e8fe8fe616d08d76df6a56faf6 Mon Sep 17 00:00:00 2001 From: midnightexigent <36641328+midnightexigent@users.noreply.github.com> Date: Fri, 2 Sep 2022 09:14:12 +0000 Subject: [PATCH 6/7] Update book/src/languages.md Co-authored-by: Ivan Tham --- book/src/languages.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/languages.md b/book/src/languages.md index 7ebb7baa31ff..d7138b7c84e2 100644 --- a/book/src/languages.md +++ b/book/src/languages.md @@ -50,7 +50,7 @@ These configuration keys are available: | `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"]`. This attempts to match by exact file name, then by file extension, then by path suffix | +| `file-types` | The filetypes of the language, for example `["yml", "yaml"]`. This attempts to match by exact file name (`.zshrc`), then by file extension (`toml`), then by path suffix (`.git/config`). | | `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 | From 488dd533090980b7f930abc88523a68da49ba237 Mon Sep 17 00:00:00 2001 From: midnightexigent <36641328+midnightexigent@users.noreply.github.com> Date: Fri, 2 Sep 2022 09:14:19 +0000 Subject: [PATCH 7/7] Update book/src/languages.md Co-authored-by: Ivan Tham --- book/src/languages.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/book/src/languages.md b/book/src/languages.md index d7138b7c84e2..484c14d287b7 100644 --- a/book/src/languages.md +++ b/book/src/languages.md @@ -62,12 +62,6 @@ These configuration keys are available: | `grammar` | The tree-sitter grammar to use (defaults to the value of `name`) | | `formatter` | The formatter for the language, it will take precedence over the lsp when defined. The formatter must be able to take the original file as input from stdin and write the formatted file to stdout | -Additionnaly, entries in `file-types` are matched accoding to different strategies, in the following order : - -1. File name is an exact match -- example: `.zshrc` -2. File extension is an exact match -- example: `toml` -3. File path contains the value as a suffix -- example: `.git/config` - ### Language Server configuration The `language-server` field takes the following keys: