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