├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md ├── extension.toml ├── languages └── fsharp │ ├── config.toml │ ├── highlights.scm │ ├── indents.scm │ ├── injections.scm │ └── locals.scm └── src └── lib.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "anyhow" 7 | version = "1.0.86" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" 10 | 11 | [[package]] 12 | name = "bitflags" 13 | version = "2.5.0" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" 16 | 17 | [[package]] 18 | name = "equivalent" 19 | version = "1.0.1" 20 | source = "registry+https://github.com/rust-lang/crates.io-index" 21 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 22 | 23 | [[package]] 24 | name = "hashbrown" 25 | version = "0.14.5" 26 | source = "registry+https://github.com/rust-lang/crates.io-index" 27 | checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" 28 | 29 | [[package]] 30 | name = "heck" 31 | version = "0.4.1" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 34 | dependencies = [ 35 | "unicode-segmentation", 36 | ] 37 | 38 | [[package]] 39 | name = "id-arena" 40 | version = "2.2.1" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" 43 | 44 | [[package]] 45 | name = "indexmap" 46 | version = "2.2.6" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" 49 | dependencies = [ 50 | "equivalent", 51 | "hashbrown", 52 | "serde", 53 | ] 54 | 55 | [[package]] 56 | name = "itoa" 57 | version = "1.0.11" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" 60 | 61 | [[package]] 62 | name = "leb128" 63 | version = "0.2.5" 64 | source = "registry+https://github.com/rust-lang/crates.io-index" 65 | checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" 66 | 67 | [[package]] 68 | name = "log" 69 | version = "0.4.21" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" 72 | 73 | [[package]] 74 | name = "proc-macro2" 75 | version = "1.0.83" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" 78 | dependencies = [ 79 | "unicode-ident", 80 | ] 81 | 82 | [[package]] 83 | name = "quote" 84 | version = "1.0.36" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" 87 | dependencies = [ 88 | "proc-macro2", 89 | ] 90 | 91 | [[package]] 92 | name = "ryu" 93 | version = "1.0.18" 94 | source = "registry+https://github.com/rust-lang/crates.io-index" 95 | checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" 96 | 97 | [[package]] 98 | name = "semver" 99 | version = "1.0.23" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" 102 | 103 | [[package]] 104 | name = "serde" 105 | version = "1.0.203" 106 | source = "registry+https://github.com/rust-lang/crates.io-index" 107 | checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" 108 | dependencies = [ 109 | "serde_derive", 110 | ] 111 | 112 | [[package]] 113 | name = "serde_derive" 114 | version = "1.0.203" 115 | source = "registry+https://github.com/rust-lang/crates.io-index" 116 | checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" 117 | dependencies = [ 118 | "proc-macro2", 119 | "quote", 120 | "syn", 121 | ] 122 | 123 | [[package]] 124 | name = "serde_json" 125 | version = "1.0.117" 126 | source = "registry+https://github.com/rust-lang/crates.io-index" 127 | checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" 128 | dependencies = [ 129 | "itoa", 130 | "ryu", 131 | "serde", 132 | ] 133 | 134 | [[package]] 135 | name = "smallvec" 136 | version = "1.13.2" 137 | source = "registry+https://github.com/rust-lang/crates.io-index" 138 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 139 | 140 | [[package]] 141 | name = "spdx" 142 | version = "0.10.4" 143 | source = "registry+https://github.com/rust-lang/crates.io-index" 144 | checksum = "29ef1a0fa1e39ac22972c8db23ff89aea700ab96aa87114e1fb55937a631a0c9" 145 | dependencies = [ 146 | "smallvec", 147 | ] 148 | 149 | [[package]] 150 | name = "syn" 151 | version = "2.0.66" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" 154 | dependencies = [ 155 | "proc-macro2", 156 | "quote", 157 | "unicode-ident", 158 | ] 159 | 160 | [[package]] 161 | name = "unicode-ident" 162 | version = "1.0.12" 163 | source = "registry+https://github.com/rust-lang/crates.io-index" 164 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 165 | 166 | [[package]] 167 | name = "unicode-segmentation" 168 | version = "1.11.0" 169 | source = "registry+https://github.com/rust-lang/crates.io-index" 170 | checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" 171 | 172 | [[package]] 173 | name = "unicode-xid" 174 | version = "0.2.4" 175 | source = "registry+https://github.com/rust-lang/crates.io-index" 176 | checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" 177 | 178 | [[package]] 179 | name = "wasm-encoder" 180 | version = "0.201.0" 181 | source = "registry+https://github.com/rust-lang/crates.io-index" 182 | checksum = "b9c7d2731df60006819b013f64ccc2019691deccf6e11a1804bc850cd6748f1a" 183 | dependencies = [ 184 | "leb128", 185 | ] 186 | 187 | [[package]] 188 | name = "wasm-metadata" 189 | version = "0.201.0" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | checksum = "0fd83062c17b9f4985d438603cde0a5e8c5c8198201a6937f778b607924c7da2" 192 | dependencies = [ 193 | "anyhow", 194 | "indexmap", 195 | "serde", 196 | "serde_derive", 197 | "serde_json", 198 | "spdx", 199 | "wasm-encoder", 200 | "wasmparser", 201 | ] 202 | 203 | [[package]] 204 | name = "wasmparser" 205 | version = "0.201.0" 206 | source = "registry+https://github.com/rust-lang/crates.io-index" 207 | checksum = "84e5df6dba6c0d7fafc63a450f1738451ed7a0b52295d83e868218fa286bf708" 208 | dependencies = [ 209 | "bitflags", 210 | "indexmap", 211 | "semver", 212 | ] 213 | 214 | [[package]] 215 | name = "wit-bindgen" 216 | version = "0.22.0" 217 | source = "registry+https://github.com/rust-lang/crates.io-index" 218 | checksum = "288f992ea30e6b5c531b52cdd5f3be81c148554b09ea416f058d16556ba92c27" 219 | dependencies = [ 220 | "bitflags", 221 | "wit-bindgen-rt", 222 | "wit-bindgen-rust-macro", 223 | ] 224 | 225 | [[package]] 226 | name = "wit-bindgen-core" 227 | version = "0.22.0" 228 | source = "registry+https://github.com/rust-lang/crates.io-index" 229 | checksum = "e85e72719ffbccf279359ad071497e47eb0675fe22106dea4ed2d8a7fcb60ba4" 230 | dependencies = [ 231 | "anyhow", 232 | "wit-parser", 233 | ] 234 | 235 | [[package]] 236 | name = "wit-bindgen-rt" 237 | version = "0.22.0" 238 | source = "registry+https://github.com/rust-lang/crates.io-index" 239 | checksum = "fcb8738270f32a2d6739973cbbb7c1b6dd8959ce515578a6e19165853272ee64" 240 | 241 | [[package]] 242 | name = "wit-bindgen-rust" 243 | version = "0.22.0" 244 | source = "registry+https://github.com/rust-lang/crates.io-index" 245 | checksum = "d8a39a15d1ae2077688213611209849cad40e9e5cccf6e61951a425850677ff3" 246 | dependencies = [ 247 | "anyhow", 248 | "heck", 249 | "indexmap", 250 | "wasm-metadata", 251 | "wit-bindgen-core", 252 | "wit-component", 253 | ] 254 | 255 | [[package]] 256 | name = "wit-bindgen-rust-macro" 257 | version = "0.22.0" 258 | source = "registry+https://github.com/rust-lang/crates.io-index" 259 | checksum = "d376d3ae5850526dfd00d937faea0d81a06fa18f7ac1e26f386d760f241a8f4b" 260 | dependencies = [ 261 | "anyhow", 262 | "proc-macro2", 263 | "quote", 264 | "syn", 265 | "wit-bindgen-core", 266 | "wit-bindgen-rust", 267 | ] 268 | 269 | [[package]] 270 | name = "wit-component" 271 | version = "0.201.0" 272 | source = "registry+https://github.com/rust-lang/crates.io-index" 273 | checksum = "421c0c848a0660a8c22e2fd217929a0191f14476b68962afd2af89fd22e39825" 274 | dependencies = [ 275 | "anyhow", 276 | "bitflags", 277 | "indexmap", 278 | "log", 279 | "serde", 280 | "serde_derive", 281 | "serde_json", 282 | "wasm-encoder", 283 | "wasm-metadata", 284 | "wasmparser", 285 | "wit-parser", 286 | ] 287 | 288 | [[package]] 289 | name = "wit-parser" 290 | version = "0.201.0" 291 | source = "registry+https://github.com/rust-lang/crates.io-index" 292 | checksum = "196d3ecfc4b759a8573bf86a9b3f8996b304b3732e4c7de81655f875f6efdca6" 293 | dependencies = [ 294 | "anyhow", 295 | "id-arena", 296 | "indexmap", 297 | "log", 298 | "semver", 299 | "serde", 300 | "serde_derive", 301 | "serde_json", 302 | "unicode-xid", 303 | "wasmparser", 304 | ] 305 | 306 | [[package]] 307 | name = "zed_extension_api" 308 | version = "0.0.6" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | checksum = "77ca8bcaea3feb2d2ce9dbeb061ee48365312a351faa7014c417b0365fe9e459" 311 | dependencies = [ 312 | "serde", 313 | "serde_json", 314 | "wit-bindgen", 315 | ] 316 | 317 | [[package]] 318 | name = "zed_fsharp" 319 | version = "0.1.0" 320 | dependencies = [ 321 | "serde", 322 | "zed_extension_api", 323 | ] 324 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "zed_fsharp" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["cdylib"] 8 | 9 | [dependencies] 10 | serde = { version = "1.0", features = ["derive"] } 11 | zed_extension_api = "0.0.6" 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is a basic extension for Zed to enable F# features. 2 | 3 | ## Prerequisites 4 | You must have `fsautocomplete` installed, which you can do by running `dotnet tool install --global fsautocomplete`. 5 | 6 | ## Installation 7 | 8 | Inside your [plugin directory](https://zed.dev/docs/extensions/installing-extensions#installation-location), run: 9 | 10 | ```sh 11 | git clone git@github.com:nathanjcollins/zed-fsharp.git installed/fsharp 12 | ``` 13 | 14 | You can update the plugin to a pre-release version in the Zed installed plugin tab. 15 | 16 | Feel free to contribute. 17 | -------------------------------------------------------------------------------- /extension.toml: -------------------------------------------------------------------------------- 1 | id = "fsharp" 2 | name = "F#" 3 | description = "F# language support for Zed" 4 | version = "0.0.6" 5 | schema_version = 1 6 | authors = ["Nathan Collins "] 7 | repository = "https://github.com/nathanjcollins/zed-fsharp" 8 | 9 | [language_servers.fsautocomplete] 10 | name = "fsautocomplete" 11 | language = "FSharp" 12 | 13 | [grammars.fsharp] 14 | repository = "https://github.com/ionide/tree-sitter-fsharp" 15 | commit = "c4347939b4fb439771dc2561a6923fba6a78251b" 16 | -------------------------------------------------------------------------------- /languages/fsharp/config.toml: -------------------------------------------------------------------------------- 1 | name = "FSharp" 2 | code_fence_block_name = "fsharp" 3 | grammar = "fsharp" 4 | path_suffixes = ["fs", "fsx", "fsi"] 5 | line_comments = ["// ", "/// "] 6 | autoclose_before = ";:.,=}])>" 7 | brackets = [ 8 | { start = "{", end = "}", close = true, newline = true }, 9 | { start = "[", end = "]", close = true, newline = true }, 10 | { start = "(", end = ")", close = true, newline = true }, 11 | { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] }, 12 | { start = "'", end = "'", close = true, newline = false, not_in = ["string", "comment"] }, 13 | { start = "/*", end = " */", close = true, newline = false, not_in = ["string", "comment"] }, 14 | ] 15 | -------------------------------------------------------------------------------- /languages/fsharp/highlights.scm: -------------------------------------------------------------------------------- 1 | ;; ---------------------------------------------------------------------------- 2 | ;; Literals and comments 3 | 4 | [ 5 | (line_comment) 6 | (block_comment) 7 | ] @comment 8 | 9 | (xml_doc) @comment.documentation 10 | 11 | ((const) @constant 12 | (#set! "priority" 90)) 13 | 14 | ((identifier) @variable 15 | (#set! "priority" 90)) 16 | 17 | (primary_constr_args (_) @variable.parameter) 18 | 19 | ((identifier_pattern (long_identifier (identifier) @character.special)) 20 | (#match? @character.special "^\_.*") 21 | (#set! "priority" 90)) 22 | 23 | ;; ---------------------------------------------------------------------------- 24 | ;; Punctuation 25 | 26 | (wildcard_pattern) @character.special 27 | 28 | (type_name type_name: (_) @type.definition) 29 | 30 | (type) @type 31 | 32 | (member_signature 33 | . 34 | (identifier) @function.member 35 | (curried_spec 36 | (arguments_spec 37 | "*"* @operator 38 | (argument_spec 39 | (argument_name_spec 40 | "?"? @character.special 41 | name: (_) @variable.parameter) 42 | (_) @type)))) 43 | 44 | [ 45 | (union_type_case) 46 | ] @type 47 | 48 | (rules 49 | (rule 50 | [ 51 | (type_check_pattern (_) @type) 52 | (identifier_pattern (long_identifier) . (long_identifier) @variable) 53 | (_ (identifier_pattern (long_identifier) . (long_identifier) @variable)) 54 | (_ (_ (identifier_pattern (long_identifier) . (long_identifier) @variable))) 55 | (_ (_ (_ (identifier_pattern (long_identifier) . (long_identifier) @variable)))) 56 | (_ (_ (_ (_ (identifier_pattern (long_identifier) . (long_identifier) @variable))))) 57 | (_ (_ (_ (_ (_ (identifier_pattern (long_identifier) . (long_identifier) @variable)))))) 58 | (_ (_ (_ (_ (_ (_ (identifier_pattern (long_identifier) . (long_identifier) @variable))))))) 59 | (_ (_ (_ (_ (_ (_ (_ (identifier_pattern (long_identifier) . (long_identifier) @variable)))))))) 60 | ])) 61 | 62 | (fsi_directive_decl . (string) @module) 63 | 64 | (import_decl . (_) @module) 65 | (named_module 66 | name: (_) @module) 67 | (namespace 68 | name: (_) @module) 69 | (module_defn 70 | . 71 | (_) @module) 72 | 73 | (ce_expression 74 | . 75 | (_) @constant.macro) 76 | 77 | (field_initializer 78 | field: (_) @property) 79 | 80 | (record_fields 81 | (record_field 82 | . 83 | (identifier) @property)) 84 | 85 | (dot_expression 86 | base: (_) @variable 87 | field: (_) @variable.member) 88 | 89 | (value_declaration_left . (_) @variable) 90 | 91 | (function_declaration_left 92 | . (_) @function 93 | [ 94 | (argument_patterns) 95 | (argument_patterns (long_identifier (identifier))) 96 | ] @variable.parameter) 97 | 98 | (member_defn 99 | (method_or_prop_defn 100 | [ 101 | (property_or_ident) @function 102 | (property_or_ident 103 | instance: (identifier) @variable.parameter.builtin 104 | method: (identifier) @function.method) 105 | ] 106 | args: (_)? @variable.parameter)) 107 | 108 | (application_expression 109 | . 110 | [ 111 | (_) @function.call 112 | (long_identifier_or_op (long_identifier (identifier) (identifier) @function.call)) 113 | (typed_expression . (long_identifier_or_op (long_identifier (identifier)* . (identifier) @function.call))) 114 | ] 115 | . 116 | (_)? @variable) 117 | 118 | (application_expression 119 | . 120 | [ 121 | (dot_expression base: (_) @variable.member field: (_) @function.call) 122 | (_ (dot_expression base: (_) @variable.member field: (_) @function.call)) 123 | (_ (_ (dot_expression base: (_) @variable.member field: (_) @function.call))) 124 | (_ (_ (_ (dot_expression base: (_) @variable.member field: (_) @function.call)))) 125 | (_ (_ (_ (_ (dot_expression base: (_) @variable.member field: (_) @function.call))))) 126 | (_ (_ (_ (_ (_ (dot_expression base: (_) @variable.member field: (_) @function.call)))))) 127 | ]) 128 | 129 | ((infix_expression 130 | . 131 | (_) 132 | . 133 | (infix_op) @operator 134 | . 135 | (_) @function.call 136 | ) 137 | (#eq? @operator "|>") 138 | ) 139 | 140 | ((infix_expression 141 | . 142 | (_) @function.call 143 | . 144 | (infix_op) @operator 145 | . 146 | (_) 147 | ) 148 | (#eq? @operator "<|") 149 | ) 150 | 151 | (typecast_expression 152 | . 153 | (_) @variable 154 | . 155 | (_) @type) 156 | 157 | [ 158 | (int) 159 | (int16) 160 | (uint16) 161 | (int32) 162 | (uint32) 163 | (int64) 164 | (uint64) 165 | (nativeint) 166 | (unativeint) 167 | ] @number 168 | 169 | [ 170 | (ieee32) 171 | (ieee64) 172 | (float) 173 | (decimal) 174 | ] @number.float 175 | 176 | (bool) @boolean 177 | 178 | ([ 179 | (string) 180 | (triple_quoted_string) 181 | (verbatim_string) 182 | (char) 183 | ] @spell @string) 184 | 185 | (compiler_directive_decl) @keyword.directive 186 | 187 | (attribute) @attribute 188 | 189 | [ 190 | "(" 191 | ")" 192 | "{" 193 | "}" 194 | "[" 195 | "]" 196 | "[|" 197 | "|]" 198 | "{|" 199 | "|}" 200 | "[<" 201 | ">]" 202 | ] @punctuation.bracket 203 | 204 | (format_string_eval 205 | [ 206 | "{" 207 | "}" 208 | ] @punctuation.special) 209 | 210 | [ 211 | "," 212 | ";" 213 | ] @punctuation.delimiter 214 | 215 | [ 216 | "|" 217 | "=" 218 | ">" 219 | "<" 220 | "-" 221 | "~" 222 | "->" 223 | "&&" 224 | "||" 225 | (infix_op) 226 | (prefix_op) 227 | ] @operator 228 | 229 | [ 230 | "if" 231 | "then" 232 | "else" 233 | "elif" 234 | "when" 235 | "match" 236 | "match!" 237 | "then" 238 | ] @keyword.conditional 239 | 240 | [ 241 | "and" 242 | "or" 243 | "not" 244 | "upcast" 245 | "downcast" 246 | ] @keyword.operator 247 | 248 | [ 249 | "return" 250 | "return!" 251 | "yield" 252 | "yield!" 253 | ] @keyword.return 254 | 255 | [ 256 | "for" 257 | "while" 258 | "downto" 259 | "to" 260 | ] @keyword.repeat 261 | 262 | 263 | [ 264 | "open" 265 | "#r" 266 | "#load" 267 | ] @keyword.import 268 | 269 | [ 270 | "abstract" 271 | "delegate" 272 | "static" 273 | "inline" 274 | "mutable" 275 | "override" 276 | "rec" 277 | "global" 278 | (access_modifier) 279 | ] @keyword.modifier 280 | 281 | [ 282 | "let" 283 | "let!" 284 | "use" 285 | "use!" 286 | "member" 287 | ] @keyword.function 288 | 289 | ; commenting this out as zed seems to be doing something weird with the highlighting 290 | ; [ 291 | ; "enum" 292 | ; "type" 293 | ; "inherit" 294 | ; "interface" 295 | ; ] @keyword.type 296 | 297 | [ 298 | "try" 299 | "with" 300 | "finally" 301 | ] @keyword.exception 302 | 303 | [ 304 | "as" 305 | "assert" 306 | "begin" 307 | "end" 308 | "done" 309 | "default" 310 | "in" 311 | "do" 312 | "do!" 313 | "event" 314 | "field" 315 | "fun" 316 | "function" 317 | "get" 318 | "set" 319 | "lazy" 320 | "new" 321 | "null" 322 | "of" 323 | "param" 324 | "property" 325 | "struct" 326 | "val" 327 | "module" 328 | "namespace" 329 | "enum" 330 | "type" 331 | "inherit" 332 | "interface" 333 | ] @keyword 334 | 335 | (long_identifier 336 | ((identifier)* @module) 337 | . 338 | ((identifier))) 339 | 340 | ((long_identifier 341 | (identifier)* 342 | . 343 | (identifier) @property) 344 | (#set! "priority" 91)) 345 | 346 | ((type 347 | (long_identifier (identifier) @type.builtin)) 348 | (#any-of? @type.builtin "bool" "byte" "sbyte" "int16" "uint16" "int" "uint" "int64" "uint64" "nativeint" "unativeint" "decimal" "float" "double" "float32" "single" "char" "string" "unit")) 349 | 350 | (const 351 | (unit) @constant) 352 | 353 | (preproc_if 354 | [ 355 | "#if" @keyword.directive 356 | "#endif" @keyword.directive 357 | ] 358 | condition: (_)? @keyword.directive) 359 | 360 | (preproc_else 361 | "#else" @keyword.directive) 362 | 363 | (long_identifier_or_op 364 | (op_identifier) @operator) 365 | 366 | ((identifier) @module.builtin 367 | (#any-of? @module.builtin "Array" "Async" "Directory" "File" "List" "Option" "Path" "Map" "Set" "Lazy" "Seq" "Task" "String" )) 368 | -------------------------------------------------------------------------------- /languages/fsharp/indents.scm: -------------------------------------------------------------------------------- 1 | [ 2 | (value_declaration) 3 | (module_defn) 4 | (paren_expression) 5 | (brace_expression) 6 | (anon_record_expression) 7 | (list_expression) 8 | (array_expression) 9 | (while_expression) 10 | (if_expression) 11 | (elif_expression) 12 | (rule) 13 | ] @indent.begin 14 | 15 | ((rules) @indent.begin 16 | (#set! indent.start_at_same_line)) 17 | 18 | ((application_expression) @indent.align 19 | (#set! indent.open_delimiter "(") 20 | (#set! indent.close_delimiter ")")) 21 | 22 | (paren_expression 23 | ")" @indent.branch) 24 | 25 | (brace_expression 26 | "}" @indent.branch) 27 | 28 | (anon_record_expression 29 | "|}" @indent.branch) 30 | 31 | (list_expression 32 | "]" @indent.branch) 33 | 34 | (array_expression 35 | "|]" @indent.branch) 36 | 37 | (ERROR 38 | . 39 | [ 40 | "module" 41 | "do" 42 | ]) @indent.begin 43 | 44 | [ 45 | (string) 46 | (line_comment) 47 | (block_comment) 48 | (xml_doc) 49 | ] @indent.auto 50 | -------------------------------------------------------------------------------- /languages/fsharp/injections.scm: -------------------------------------------------------------------------------- 1 | ([ 2 | (line_comment) 3 | (block_comment_content) 4 | ] @injection.content 5 | (#set! injection.language "comment")) 6 | 7 | ((xml_doc (xml_doc_content) @injection.content) 8 | (#set! injection.language "xml")) 9 | -------------------------------------------------------------------------------- /languages/fsharp/locals.scm: -------------------------------------------------------------------------------- 1 | (identifier) @local.reference 2 | 3 | [ 4 | (namespace) 5 | (named_module) 6 | (function_or_value_defn) 7 | ] @local.scope 8 | 9 | (value_declaration_left 10 | . 11 | [ 12 | (_ (identifier) @local.definition.var) 13 | (_ (_ (identifier) @local.definition.var)) 14 | (_ (_ (_ (identifier) @local.definition.var))) 15 | (_ (_ (_ (_ (identifier) @local.definition.var)))) 16 | (_ (_ (_ (_ (_ (identifier) @local.definition.var))))) 17 | (_ (_ (_ (_ (_ (_ (identifier) @local.definition.var)))))) 18 | ]) 19 | 20 | (function_declaration_left 21 | . 22 | ((_) @local.definition.function 23 | (#set! "definition.function.scope" "parent")) 24 | ((argument_patterns 25 | [ 26 | (_ (identifier) @local.definition.parameter) 27 | (_ (_ (identifier) @local.definition.parameter)) 28 | (_ (_ (_ (identifier) @local.definition.parameter))) 29 | (_ (_ (_ (_ (identifier) @local.definition.parameter)))) 30 | (_ (_ (_ (_ (_ (identifier) @local.definition.parameter))))) 31 | (_ (_ (_ (_ (_ (_ (identifier) @local.definition.parameter)))))) 32 | ]) 33 | )) 34 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | use zed_extension_api as zed; 2 | use zed_extension_api::serde_json; 3 | 4 | struct FsharpExtension {} 5 | 6 | #[derive(serde::Serialize)] 7 | #[serde(rename_all = "PascalCase")] 8 | struct FsAutocompleteInitOptions { 9 | automatic_workspace_init: bool, 10 | } 11 | 12 | impl zed::Extension for FsharpExtension { 13 | fn new() -> Self 14 | where 15 | Self: Sized, 16 | { 17 | Self {} 18 | } 19 | 20 | fn language_server_command( 21 | &mut self, 22 | language_server_id: &zed::LanguageServerId, 23 | worktree: &zed::Worktree, 24 | ) -> zed::Result { 25 | let path = worktree 26 | .which("fsautocomplete") 27 | .expect("fsautocomplete not found"); 28 | 29 | Ok(zed::Command { 30 | command: path, 31 | args: vec!["--adaptive-lsp-server-enabled".to_string()], 32 | env: Default::default(), 33 | }) 34 | } 35 | 36 | fn language_server_initialization_options( 37 | &mut self, 38 | _language_server_id: &zed::LanguageServerId, 39 | _worktree: &zed::Worktree, 40 | ) -> zed::Result> { 41 | let initialization_options = FsAutocompleteInitOptions { 42 | automatic_workspace_init: true, 43 | }; 44 | 45 | Ok(Some(serde_json::json!(initialization_options))) 46 | } 47 | } 48 | 49 | zed::register_extension!(FsharpExtension); 50 | --------------------------------------------------------------------------------