1 module workspaced.com.snippets.plain; 2 3 import std.regex; 4 5 import workspaced.api; 6 import workspaced.com.snippets; 7 8 /// 9 struct PlainSnippet 10 { 11 /// Grammar scopes in which to complete this snippet 12 SnippetLevel[] levels; 13 /// Shortcut to type for this snippet 14 string shortcut; 15 /// Label for this snippet. 16 string title; 17 /// Text with interactive snippet locations to insert assuming global indentation. 18 string snippet; 19 /// Markdown documentation for this snippet 20 string documentation; 21 /// Plain text to insert assuming global level indentation. Optional if snippet is a simple string only using plain variables and snippet locations. 22 string plain; 23 24 /// Creates a resolved snippet based on this plain snippet, filling in plain if neccessary. This drops the levels value. 25 /// Params: 26 /// provider = the providerId to fill in 27 Snippet buildSnippet(string provider) const 28 { 29 Snippet built; 30 built.providerId = provider; 31 built.title = this.title; 32 built.shortcut = this.shortcut; 33 built.documentation = this.documentation; 34 built.snippet = this.snippet; 35 built.plain = this.plain.length ? this.plain 36 : this.snippet.replaceAll(ctRegex!`\$(\d+|[A-Z_]+|\{.*?\})`, ""); 37 built.resolved = true; 38 return built; 39 } 40 } 41 42 //dfmt off 43 static immutable PlainSnippet[] plainSnippets = [ 44 45 // entry points 46 47 PlainSnippet( 48 [SnippetLevel.global], 49 "main", 50 "void main(string[] args)", 51 "void main(string[] args) {\n\t$0\n}", 52 "Normal D entry point main function with arguments and no return value" 53 ), 54 PlainSnippet( 55 [SnippetLevel.global], 56 "maini", 57 "int main(string[] args)", 58 "int main(string[] args) {\n\t${0:return 0;}\n}", 59 "Normal D entry point main function with arguments and integer status return value" 60 ), 61 PlainSnippet( 62 [SnippetLevel.global], 63 "mainc", 64 "-betterC void main(int argc, const(char)** argv)", 65 "void main(int argc, const(char)** argv) {\n\t$0\n}", 66 "C entry point when using D with -betterC with no return value" 67 ), 68 PlainSnippet( 69 [SnippetLevel.global], 70 "mainci", 71 "-betterC int main(int argc, const(char)** argv)", 72 "int main(int argc, const(char)** argv) {\n\t${0:return 0;}\n}", 73 "C entry point when using D with -betterC with integer status return value" 74 ), 75 76 // properties 77 78 PlainSnippet( 79 [SnippetLevel.global, SnippetLevel.type], 80 "refproperty", 81 "ref property as getter + setter", 82 "ref ${3:auto} ${1:value}() @property { return ${2:_${1:value}}; }", 83 "property returning a value as ref for use as getter & setter", 84 "ref auto value() @property { return _value; }" 85 ), 86 PlainSnippet( 87 [SnippetLevel.global, SnippetLevel.type], 88 "getset", 89 "getter + setter", 90 "void ${1:value}(${3:auto} value) @property { ${2:_${1:value}} = value; }\n" ~ 91 "${3:auto} ${1:value}() @property const { return ${2:_${1:value}}; }", 92 "separate methods for getter and setter", 93 "void value(auto value) @property { _value = value; }\n" ~ 94 "auto value() @property const { return _value; }" 95 ), 96 PlainSnippet( 97 [SnippetLevel.global, SnippetLevel.type], 98 "get", 99 "getter property", 100 "${3:auto} ${1:value}() @property const { return ${2:_${1:value}}; }", 101 "methods for a getter of any value", 102 "auto value() @property const { return _value; }" 103 ), 104 PlainSnippet( 105 [SnippetLevel.global, SnippetLevel.type], 106 "set", 107 "setter property", 108 "void ${1:value}(${3:auto} value) @property { ${2:_${1:value}} = value; }", 109 "method for use as setter for any value", 110 "void value(auto value) @property { _value = value; }" 111 ), 112 113 // operator overloading 114 // todo: automatic generation of types and differences in classes 115 116 PlainSnippet( 117 [SnippetLevel.type], 118 "opUnary", 119 "auto opUnary!(op)()", 120 "${1:auto} opUnary(string op)() {\n\t$0\n}", 121 "Unary operators in form of `<op>this` which only work on this object.\n\n" 122 ~ "Overloadable unary operators: `-`, `+`, `~`, `*`, `++` (pre-increment), `--` (pre-decrement)\n\n" 123 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#unary]" 124 ), 125 PlainSnippet( 126 [SnippetLevel.type], 127 "opIndexUnary", 128 "auto opIndexUnary!(op)(index)", 129 "${1:auto} opIndexUnary(string op)(${2:size_t index}) {\n\t$0\n}", 130 "Unary operators in form of `<op>this[index1, index2...]` which only work on this object.\n\n" 131 ~ "Valid unary operators: `-`, `+`, `~`, `*`, `++` (pre-increment), `--` (pre-decrement)\n\n" 132 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#index_unary_operators]" 133 ), 134 PlainSnippet( 135 [SnippetLevel.type], 136 "opIndexUnarySlice", 137 "auto opIndexUnary!(op)(slice)", 138 "${1:auto} opIndexUnary(string op)($2) {\n\t$0\n}", 139 "Unary operators in form of `<op>this[start .. end]` or `<op>this[]` which only work on this object.\n\n" 140 ~ "Valid unary operators: `-`, `+`, `~`, `*`, `++` (pre-increment), `--` (pre-decrement)\n\n" 141 ~ "The argument for this function is either empty to act on an entire slice like `<op>this[]` or a " 142 ~ "helper object returned by `opSlice`.\n\n" 143 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#slice_unary_operators]" 144 ), 145 PlainSnippet( 146 [SnippetLevel.type], 147 "opSliceUnary", 148 "auto opSliceUnary!(op)(slice)", 149 "${1:auto} opSliceUnary(string op)(${2:size_t start, size_t end}) {\n\t$0\n}", 150 "Unary operators in form of `<op>this[start .. end]` or `<op>this[]` which only work on this object.\n\n" 151 ~ "Valid unary operators: `-`, `+`, `~`, `*`, `++` (pre-increment), `--` (pre-decrement)\n\n" 152 ~ "The argument for this function is either empty to act on an entire slice like `<op>this[]` or " 153 ~ "the start and end indices to operate on.\n\n" 154 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#slice_unary_operators]" 155 ), 156 PlainSnippet( 157 [SnippetLevel.type], 158 "opCast", 159 "T opCast!(T)()", 160 "${1:T} opCast(${1:T})() const {\n\t$0\n}", 161 "Explicit cast operator in form of `cast(<T>)this` which works on this object.\n\n" 162 ~ "Used when explicitly casting to any type or when implicitly casting to bool.\n\n" 163 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#cast]" 164 ), 165 PlainSnippet( 166 [SnippetLevel.type], 167 "opCastBool", 168 "bool opCast!(T : bool)()", 169 "bool opCast(T : bool)() const {\n\t$0\n}", 170 "Explicit cast operator in form of `cast(bool)this` or implicit boolean conversion with " 171 ~ "`!!this` or `if (this)` which works on this object.\n\n" 172 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#boolean_operators]" 173 ), 174 PlainSnippet( 175 [SnippetLevel.type], 176 "opBinary", 177 "auto opBinary(rhs)", 178 "${1:auto} opBinary(string op, R)(${2:const R rhs}) const {\n\t$0\n}", 179 "Binary operators in form of `this <op> rhs` which return a new instance based off this object.\n\n" 180 ~ "Overloadable binary operators: `+`, `-`, `*`, `/`, `%`, `^^`, `&`, `|`, `^`, `<<`, `>>`, `>>>`, `~`, `in`\n\n" 181 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#binary]" 182 ), 183 PlainSnippet( 184 [SnippetLevel.type], 185 "opBinaryRight", 186 "auto opBinaryRight(lhs)", 187 "${1:auto} opBinaryRight(string op, L)(${2:const L lhs}) const {\n\t$0\n}", 188 "Binary operators in form of `lhs <op> this` which return a new instance based off this object.\n\n" 189 ~ "Overloadable binary operators: `+`, `-`, `*`, `/`, `%`, `^^`, `&`, `|`, `^`, `<<`, `>>`, `>>>`, `~`, `in`\n\n" 190 ~ "This overload has the same importance as opBinary. It is an error if both opBinary and opBinaryRight match with " 191 ~ "the same specificity.\n\n" 192 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#binary]" 193 ), 194 PlainSnippet( 195 [SnippetLevel.type], 196 "opEquals", 197 "bool opEquals(other) in struct", 198 "bool opEquals(R)(${1:const R other}) const {\n\t$0\n}", 199 "Equality operators in form of `this == other` or `other == this` and also used for `!=`.\n\n" 200 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#equals]" 201 ), 202 PlainSnippet( 203 [SnippetLevel.type], 204 "opEqualsClass", 205 "bool opEquals(other) in class", 206 "override bool opEquals(${1:Object other}) {\n\t$0\n}", 207 "Equality operators in form of `this == other` or `other == this` and also used for `!=`.\n\n" 208 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#equals]" 209 ), 210 PlainSnippet( 211 [SnippetLevel.type], 212 "toHash", 213 "size_t toHash() in struct", 214 "size_t toHash() const @safe pure nothrow {\n\t$0\n}", 215 "Hash generation for associative arrays.\n\n" 216 ~ "Reference: [https://dlang.org/spec/hash-map.html#using_classes_as_key]" 217 ), 218 PlainSnippet( 219 [SnippetLevel.type], 220 "toHashClass", 221 "size_t toHash() in class", 222 "override size_t toHash() @safe nothrow {\n\t$0\n}", 223 "Hash generation for associative arrays.\n\n" 224 ~ "Reference: [https://dlang.org/spec/hash-map.html#using_struct_as_key]" 225 ), 226 PlainSnippet( 227 [SnippetLevel.type], 228 "opCmp", 229 "int opCmp(other) in struct", 230 "int opCmp(R)(${1:const R other}) const {\n\t$0\n}", 231 "Comparision operator in form of `this.opCmp(rhs) < 0` for `<`, `<=`, `>` and `>=`.\n\n" 232 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#compare]" 233 ), 234 PlainSnippet( 235 [SnippetLevel.type], 236 "opCmpClass", 237 "int opCmp(other) in class", 238 "override int opCmp(${1:Object other}) {\n\t$0\n}", 239 "Comparision operator in form of `this.opCmp(rhs) < 0` for `<`, `<=`, `>` and `>=`.\n\n" 240 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#compare]" 241 ), 242 PlainSnippet( 243 [SnippetLevel.type], 244 "opCall", 245 "auto opCall(args)", 246 "${1:auto} opCall($2) {\n\t$0\n}", 247 "Calling operator in form of `this(args)`.\n\n" 248 ~ "Note that inside a struct this automatically disables the struct literal syntax. " 249 ~ "You need to declare a constructor which takes priority to avoid this limitation.\n\n" 250 ~ "This operator can be overloaded statically too to mimic constructors as normal calls.\n\n" 251 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#function-call]" 252 ), 253 PlainSnippet( 254 [SnippetLevel.type], 255 "opAssign", 256 "auto opAssign(value)", 257 "auto opAssign(T)(${1:T value}) {\n\t$0\n\treturn this;\n}", 258 "Assignment operator overload in form of `this = value`.\n\n" 259 ~ "For classes `value` may not be of the same type as `this` (identity assignment). However other values " 260 ~ "are still allowed. For structs no such restriction exists.\n\n" 261 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#assignment]" 262 ), 263 PlainSnippet( 264 [SnippetLevel.type], 265 "opIndexAssign", 266 "auto opIndexAssign(value, indices...)", 267 "auto opIndexAssign(T)(${1:T value}, ${2:size_t index}) {\n\t${0:return value;}\n}", 268 "Assignment operator overload in form of `this[index1, index2...] = value`.\n\n" 269 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#index_assignment_operator]" 270 ), 271 PlainSnippet( 272 [SnippetLevel.type], 273 "opIndexAssignSlice", 274 "auto opIndexAssign(value, slice)", 275 "auto opIndexAssign(T)(${1:T value}) {\n\t${0:return value;}\n}", 276 "Assignment operator overload in form of `this[start .. end] = value` or `this[] = value`.\n\n" 277 ~ "The argument for this function is either empty to act on an entire slice like `this[] = value` or a " 278 ~ "helper object returned by `opSlice` after the value to assign.\n\n" 279 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#index_assignment_operator]" 280 ), 281 PlainSnippet( 282 [SnippetLevel.type], 283 "opSliceAssign", 284 "auto opSliceAssign(value, slice)", 285 "auto opSliceAssign(T)(${1:T value}, ${2:size_t start, size_t end}) {\n\t${0:return value;}\n}", 286 "Assignment operator overload in form of `this[start .. end] = value` or `this[] = value`.\n\n" 287 ~ "The argument for this function is either empty to act on an entire slice like `this[] = value` " 288 ~ "or the start and end indices after the value to assign.\n\n" 289 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#index_assignment_operator]" 290 ), 291 PlainSnippet( 292 [SnippetLevel.type], 293 "opOpAssign", 294 "auto opOpAssign!(op)(value)", 295 "auto opOpAssign(string op, T)(${1:T value}) {\n\t$0;\n\treturn this;\n}", 296 "Operator assignment operator overload in form of `this op= value`.\n\n" 297 ~ "Overloadable operators: `+=`, `-=`, `*=`, `/=`, `%=`, `^^=`, `&=`, `|=`, `^=`, `<<=`, `>>=`, `>>>=`, `~=`\n\n" 298 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#op-assign]" 299 ), 300 PlainSnippet( 301 [SnippetLevel.type], 302 "opIndexOpAssign", 303 "auto opIndexOpAssign!(op)(value, index)", 304 "auto opIndexOpAssign(string op, T)(${1:T value}, ${2:size_t index}) {\n\t${0:return value;}\n}", 305 "Operator index assignment operator overload in form of `this[index1, index2...] op= value`.\n\n" 306 ~ "Overloadable operators: `+=`, `-=`, `*=`, `/=`, `%=`, `^^=`, `&=`, `|=`, `^=`, `<<=`, `>>=`, `>>>=`, `~=`\n\n" 307 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#index_op_assignment]" 308 ), 309 PlainSnippet( 310 [SnippetLevel.type], 311 "opIndexOpAssignSlice", 312 "auto opIndexOpAssign!(op)(value, slice)", 313 "auto opIndexOpAssign(string op, T)(${1:T value}) {\n\t${0:return value;}\n}", 314 "Operator index assignment operator overload in form of `this[start .. end] op= value`.\n\n" 315 ~ "Overloadable operators: `+=`, `-=`, `*=`, `/=`, `%=`, `^^=`, `&=`, `|=`, `^=`, `<<=`, `>>=`, `>>>=`, `~=`\n\n" 316 ~ "The argument for this function is either empty to act on an entire slice like `this[] op= value` or a " 317 ~ "helper object returned by `opSlice` after the value to assign.\n\n" 318 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#slice_op_assignment]" 319 ), 320 PlainSnippet( 321 [SnippetLevel.type], 322 "opSliceOpAssign", 323 "auto opSliceOpAssign!(op)(value, start, end)", 324 "auto opSliceOpAssign(string op, T)(${1:T value}, ${2:size_t start, size_t end}) {\n\t${0:return value;}\n}", 325 "Operator index assignment operator overload in form of `this[start .. end] op= value`.\n\n" 326 ~ "Overloadable operators: `+=`, `-=`, `*=`, `/=`, `%=`, `^^=`, `&=`, `|=`, `^=`, `<<=`, `>>=`, `>>>=`, `~=`\n\n" 327 ~ "The argument for this function is either empty to act on an entire slice like `this[] = value` " 328 ~ "or the start and end indices after the value to assign.\n\n" 329 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#slice_op_assignment]" 330 ), 331 PlainSnippet( 332 [SnippetLevel.type], 333 "opIndex", 334 "auto opIndex(index)", 335 "${1:ref auto} opIndex(${2:size_t index}) {\n\t$0\n}", 336 "Array index operator overload in form of `this[index1, index2...]`.\n\n" 337 ~ "Indices may specify any type and may also be the helper objects returned by opSlice.\n\n" 338 ~ "Leaving the index arguments empty means this returns a slice of the whole object. (often a shallow copy)\n\n" 339 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#array-ops]" 340 ), 341 PlainSnippet( 342 [SnippetLevel.type], 343 "opSlice", 344 "auto opSlice(index)", 345 "${1:size_t[2]} opSlice(${2:size_t start, size_t end}) {\n\t${0:return [start, end];}\n}", 346 "Array slice operator overload in form of `this[start .. end]`.\n\n" 347 ~ "`opSlice` returns a helper object which is used in the index methods to operate on. " 348 ~ "It does not return the value of the array slice result, use opIndex for this.\n\n" 349 ~ "This snippet defines an overload for any dimension of the array (any comma count), " 350 ~ "use `opSliceN` for any dimensionality.\n\n" 351 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#array-ops]" 352 ), 353 PlainSnippet( 354 [SnippetLevel.type], 355 "opSliceN", 356 "auto opSlice!(n)(index)", 357 "${1:size_t[2]} opSlice(size_t dim : ${2:0})(${3:size_t start, size_t end}) {\n\t${0:return [start, end];}\n}", 358 "Array slice operator overload in form of `this[start .. end]`.\n\n" 359 ~ "`opSlice` returns a helper object which is used in the index methods to operate on. " 360 ~ "It does not return the value of the array slice result, use opIndex for this.\n\n" 361 ~ "This snippet defines an overload for n-th dimension of the array, meaning this is the " 362 ~ "`n`th value in the comma separated index list, starting at n=0.\n\n" 363 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#array-ops]" 364 ), 365 PlainSnippet( 366 [SnippetLevel.type], 367 "opDollar", 368 "auto opDollar()", 369 "${1:size_t} opDollar() {\n\t${0:return length;}\n}", 370 "Dollar operator overload in form of `this[$]`.\n\n" 371 ~ "`opDollar` returns a the value which the dollar sign in the index call returns. " 372 ~ "Commonly this is the length of the array.\n\n" 373 ~ "This snippet defines an overload for any dimension of the array (any comma count), " 374 ~ "use `opDollarN` for any dimensionality.\n\n" 375 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#array-ops]" 376 ), 377 PlainSnippet( 378 [SnippetLevel.type], 379 "opDollarN", 380 "auto opDollar!(n)()", 381 "${1:size_t} opDollar(size_t dim : ${2:0})() {\n\t${0:return length;}\n}", 382 "Dollar operator overload in form of `this[$]`.\n\n" 383 ~ "`opDollar` returns a the value which the dollar sign in the index call returns. " 384 ~ "Commonly this is the length of the array.\n\n" 385 ~ "This snippet defines an overload for n-th dimension of the array, meaning this is the " 386 ~ "`n`th length in the comma separated index list, starting at n=0.\n\n" 387 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#array-ops]" 388 ), 389 PlainSnippet( 390 [SnippetLevel.type], 391 "opDispatch", 392 "auto opDispatch!(member)()", 393 "${1:auto} opDispatch(${2:string member})() {\n\t$0\n}", 394 "Compile-Time dynamic dispatch operator forwarding unknown member calls and properties in form of `this.member`.\n\n" 395 ~ "`opDispatch` will be executed for any method call or property access not matching another one. This should " 396 ~ "be used on special wrapper types without many other fields to avoid false calls in case of non-matching " 397 ~ "overloads. Defining this operator may also cause issues when trying to use CTFE functions with matching " 398 ~ "names.\n\n" 399 ~ "Reference: [https://dlang.org/spec/operatoroverloading.html#dispatch]" 400 ), 401 PlainSnippet( 402 [SnippetLevel.type], 403 "opApply", 404 "int opApply(dg)", 405 "int opApply(scope int delegate(${1:ref Item}) ${2:dg}) {\n" 406 ~ "\tint result = 0;\n" 407 ~ "\n" 408 ~ "\t${3:foreach (item; array)} {\n" 409 ~ "\t\tresult = dg(item);\n" 410 ~ "\t\tif (result)\n" 411 ~ "\t\t\tbreak;\n" 412 ~ "\t}\n" 413 ~ "\n" 414 ~ "\treturn result;\n" 415 ~ "}", 416 "Explicit foreach overload when calling `foreach (items...; this)`.\n\n" 417 ~ "Note that you can also implement this functionality through a forward range." 418 ~ "`opApply` has higher precedence over range functionality.\n\n" 419 ~ "Reference: [https://dlang.org/spec/statement.html#foreach_over_struct_and_classes]" 420 ), 421 PlainSnippet( 422 [SnippetLevel.type], 423 "opApplyReverse", 424 "int opApplyReverse(dg)", 425 "int opApplyReverse(scope int delegate(${1:ref Item}) ${2:dg}) {\n" 426 ~ "\tint result = 0;\n" 427 ~ "\n" 428 ~ "\t${3:foreach_reverse (item; array)} {\n" 429 ~ "\t\tresult = dg(item);\n" 430 ~ "\t\tif (result)\n" 431 ~ "\t\t\tbreak;\n" 432 ~ "\t}\n" 433 ~ "\n" 434 ~ "\treturn result;\n" 435 ~ "}", 436 "Explicit foreach overload when calling `foreach_reverse (items...; this)`.\n\n" 437 ~ "Note that you can also implement this functionality through a backward range. " 438 ~ "`opApplyReverse` has higher precedence over range functionality.\n\n" 439 ~ "Reference: [https://dlang.org/spec/statement.html#foreach_over_struct_and_classes]" 440 ), 441 442 // Exception snippets 443 444 PlainSnippet( 445 [SnippetLevel.global, SnippetLevel.type], 446 "Exception", 447 "class MyException : Exception", 448 "class ${1:MyException} : ${2:Exception} {\n" 449 ~ "\tthis(${3:string msg, string file = __FILE__, size_t line = __LINE__, Throwable nextInChain = null}) pure nothrow @nogc @safe {\n" 450 ~ "\t\tsuper(${4:msg, file, line, nextInChain});\n" 451 ~ "\t}\n" 452 ~ "}\n$0", 453 "Class extending Exception. Use this for recoverable errors that may be catched in the application.\n\n" 454 ~ "Reference: [https://dlang.org/phobos/object.html#.Exception]" 455 ), 456 PlainSnippet( 457 [SnippetLevel.global, SnippetLevel.type], 458 "Error", 459 "class MyError : Error", 460 "class ${1:MyError} : ${2:Error} {\n" 461 ~ "\tthis(${3:string msg, Throwable nextInChain = null}) pure nothrow @nogc @safe {\n" 462 ~ "\t\tsuper(${4:msg, nextInChain});\n" 463 ~ "\t}\n" 464 ~ "}\n$0", 465 "Class extending Error. Use this for unrecoverable errors that applications should not catch.\n\n" 466 ~ "Reference: [https://dlang.org/phobos/object.html#.Exception]" 467 ), 468 469 // Builtin Types (keywords) 470 PlainSnippet( 471 [SnippetLevel.global, SnippetLevel.type, SnippetLevel.method], 472 "import", 473 "import module", 474 "import ${1:std};\n$0", 475 "Imports a module given a name.\n\nReference: [https://dlang.org/spec/module.html#import-declaration]" 476 ), 477 PlainSnippet( 478 [SnippetLevel.global, SnippetLevel.type, SnippetLevel.method], 479 "class", 480 "class MyClass", 481 "class ${1:MyClass} {\n\t$0\n}", 482 "Defines a simple class type.\n\nReference: [https://dlang.org/spec/class.html]" 483 ), 484 PlainSnippet( 485 [SnippetLevel.global, SnippetLevel.type, SnippetLevel.method], 486 "interface", 487 "interface MyInterface", 488 "interface ${1:MyInterface} {\n\t$0\n}", 489 "Defines a simple interface type.\n\nReference: [https://dlang.org/spec/interface.html]" 490 ), 491 PlainSnippet( 492 [SnippetLevel.global, SnippetLevel.type, SnippetLevel.method], 493 "struct", 494 "struct MyStruct", 495 "struct ${1:MyStruct} {\n\t$0\n}", 496 "Defines a simple struct type.\n\nReference: [https://dlang.org/spec/struct.html]" 497 ), 498 PlainSnippet( 499 [SnippetLevel.global, SnippetLevel.type, SnippetLevel.method], 500 "union", 501 "union MyUnion", 502 "union ${1:MyUnion} {\n\t$0\n}", 503 "Defines a simple union type.\n\nReference: [https://dlang.org/spec/struct.html]" 504 ), 505 PlainSnippet( 506 [SnippetLevel.global, SnippetLevel.type, SnippetLevel.method], 507 "template", 508 "template MyTemplate()", 509 "template ${1:MyTemplate}($2) {\n\t$0\n}", 510 "Defines a simple union type.\n\nReference: [https://dlang.org/spec/struct.html]" 511 ), 512 PlainSnippet( 513 [SnippetLevel.global, SnippetLevel.type, SnippetLevel.method], 514 "enums", 515 "enum MyEnum { ... }", 516 "enum ${1:MyEnum} {\n\t${0:init,}\n}", 517 "Defines a simple enumeration.\n\nReference: [https://dlang.org/spec/enum.html]" 518 ), 519 PlainSnippet( 520 [SnippetLevel.global, SnippetLevel.type, SnippetLevel.method], 521 "enumv", 522 "enum EnumValue = ...", 523 "enum ${1:EnumValue} = $2;\n$0", 524 "Defines a simple compile time constant using enum.\n\nReference: [https://dlang.org/spec/enum.html#manifest_constants]" 525 ), 526 527 // Types using phobos or some code idioms 528 PlainSnippet( 529 [SnippetLevel.global, SnippetLevel.type, SnippetLevel.method], 530 "typedef", 531 "typedef MyType : BaseType", 532 "enum ${1:MyType} : ${2:BaseType} {\n\t${0:init = 0}\n}", 533 "Creates a typesafe alias not allowing implicit casting from base type, but allows implicit conversion to " 534 ~ "the base type in most cases. Therefore the implicit casting works a lot like class/interface inheritance.\n\n" 535 ~ "Reference: (17.1.5) [https://dlang.org/spec/enum.html#named_enums]" 536 ), 537 PlainSnippet( 538 [SnippetLevel.global, SnippetLevel.type, SnippetLevel.method], 539 "Proxy", 540 "struct MyType { mixin Proxy }", 541 "struct ${1:MyType} {\n\t${2:BaseType} base;\n\tmixin Proxy!(${2:BaseType});\n}", 542 "Creates a typesafe alias not allowing implicit casting to the base type, but allows implicit conversion " 543 ~ "from the base type in most cases. Basically allows copying any base type with new properties and " 544 ~ "methods as new and separate type. Imports `std.typecons : Proxy`.\n\n" 545 ~ "Reference: [https://dlang.org/phobos/std_typecons.html#Proxy]" 546 ), 547 PlainSnippet( 548 [SnippetLevel.global], 549 "IUnknown", 550 "interface COMInterface : IUnknown", 551 "interface ${1:COMInterface} : IUnknown {\nextern(Windows):\n\t$0\n}", 552 "Win32 COM interface without implementation to talk to other applications.\n\n" 553 ~ "Reference: [https://wiki.dlang.org/COM_Programming]" 554 ), 555 PlainSnippet( 556 [SnippetLevel.global], 557 "ComObject", 558 "class MyObject : ComObject", 559 "class ${1:MyObject} : ComObject {\nextern(Windows):\n\t$0\n}", 560 "Win32 COM interface with implementation to serve to other applications.\n\n" 561 ~ "Reference: [https://wiki.dlang.org/COM_Programming]" 562 ), 563 564 // range methods 565 566 PlainSnippet( 567 [SnippetLevel.type], 568 "InputRange", 569 "InputRange (popFront, empty, front)", 570 "${1:auto} front() @property { ${2:return myElement;} }\n" 571 ~ "bool empty() @property const { ${3:return true;} }\n" 572 ~ "void popFront() { $4 }\n$0", 573 "Implements an input range for iteration support in range functions and foreach.\n\n" 574 ~ "Functions can only iterate over an InputRange exactly one time.\n\n" 575 ~ "Reference: [https://dlang.org/phobos/std_range_primitives.html#isInputRange]" 576 ), 577 PlainSnippet( 578 [SnippetLevel.type], 579 "OutputRange", 580 "OutputRange (put)", 581 "void put(${1:Item} item) {\n\t$2\n}\n$0", 582 "Implements the put function which allows to put one or more items into this range.\n\n" 583 ~ "Reference: [https://dlang.org/phobos/std_range_primitives.html#isOutputRange]" 584 ), 585 PlainSnippet( 586 [SnippetLevel.type], 587 "ForwardRange", 588 "ForwardRange (InputRange, save)", 589 "${1:auto} front() @property { ${2:return myElement;} }\n" 590 ~ "bool empty() @property const { ${3:return true;} }\n" 591 ~ "void popFront() { $4 }\n" 592 ~ "typeof(this) save() { ${5:return this;} }\n$0", 593 "Implements a forward range for iteration support in range functions and foreach.\n\n" 594 ~ "As opposed to InputRange this supports iterating over the same range multiple times.\n\n" 595 ~ "Reference: [https://dlang.org/phobos/std_range_primitives.html#isForwardRange]" 596 ), 597 PlainSnippet( 598 [SnippetLevel.type], 599 "InfiniteRange", 600 "InfiniteRange (empty = false)", 601 "enum bool empty = false;\n$0", 602 "Makes this range appear as infinite by adding `empty` as always `false` enum constant value.\n\n" 603 ~ "Reference: [https://dlang.org/phobos/std_range_primitives.html#isInfinite]" 604 ), 605 PlainSnippet( 606 [SnippetLevel.type], 607 "BidirectionalRange", 608 "BidirectionalRange (InputRange, back, popBack)", 609 "${1:auto} front() @property { ${2:return myElement;} }\n" 610 ~ "${1:auto} back() @property { ${3:return myElement;} }\n" 611 ~ "bool empty() @property const { ${4:return true;} }\n" 612 ~ "void popFront() { $5 }\n" 613 ~ "void popBack() { $6 }\n$0", 614 "Implements a bidirectional range for iteration support in range functions, foreach and foreach_reverse.\n\n" 615 ~ "Reference: [https://dlang.org/phobos/std_range_primitives.html#isBidirectionalRange]" 616 ), 617 PlainSnippet( 618 [SnippetLevel.type], 619 "RandomAccessRange", 620 "RandomAccessRange (BidirectionalRange, opIndex, length)", 621 "${1:auto} front() @property { ${2:return myElement;} }\n" 622 ~ "${1:auto} back() @property { ${3:return myElement;} }\n" 623 ~ "bool empty() @property const { ${4:return true;} }\n" 624 ~ "void popFront() { $5 }\n" 625 ~ "void popBack() { $6 }\n" 626 ~ "ref ${1:auto} opIndex(${7:size_t index}) { $8 }\n" 627 ~ "size_t length() { $9 }\n" 628 ~ "alias opDollar = length;$0", 629 "Implements a bidirectional range with random access indexing support for full array emulation.\n\n" 630 ~ "Reference: [https://dlang.org/phobos/std_range_primitives.html#isBidirectionalRange]" 631 ), 632 PlainSnippet( 633 [SnippetLevel.type], 634 "RandomAccessRangeInf", 635 "RandomAccessRange (InfiniteForwardRange, opIndex)", 636 "${1:auto} front() @property { ${2:return myElement;} }\n" 637 ~ "enum bool empty = false;\n" 638 ~ "void popFront() { $3 }\n" 639 ~ "${1:auto} opIndex(${4:size_t index}) { $5 }\n$0", 640 "Implements an infinite forward range with random access indexing support.\n\n" 641 ~ "Reference: [https://dlang.org/phobos/std_range_primitives.html#isBidirectionalRange]" 642 ), 643 ]; 644 //dfmt on 645 646 class PlainSnippetProvider : SnippetProvider 647 { 648 protected Snippet[][SnippetLevel] prebuilt; 649 650 this() 651 { 652 foreach (s; plainSnippets) 653 { 654 Snippet built = s.buildSnippet(typeid(this).name); 655 656 foreach (level; s.levels) 657 prebuilt[level] ~= built; 658 } 659 } 660 661 Future!(Snippet[]) provideSnippets(scope const WorkspaceD.Instance instance, 662 scope const(char)[] file, scope const(char)[] code, int position, const SnippetInfo info) 663 { 664 Snippet[] ret; 665 if (auto p = info.level in prebuilt) 666 ret = *p; 667 return Future!(Snippet[]).fromResult(ret); 668 } 669 670 Future!Snippet resolveSnippet(scope const WorkspaceD.Instance instance, 671 scope const(char)[] file, scope const(char)[] code, int position, 672 const SnippetInfo info, Snippet snippet) 673 { 674 snippet.resolved = true; 675 return Future!Snippet.fromResult(snippet); 676 } 677 }