diff --git a/.gitignore b/.gitignore index aeee732..41b0052 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules *.vsix +dist diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..aa1c94e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "deno.enable": true, + "deno.unstable": true +} diff --git a/README.md b/README.md index 3f2604f..b06db1c 100644 --- a/README.md +++ b/README.md @@ -27,10 +27,10 @@ Supported file extensions: ## Setup The following is not mandatory, but provides a nicer experience. -Search for `editor.snippetSuggestions` and `editor.snippetSuggestions` in user settings, or edit the settings.json directly: +Search for `editor.tabCompletion` in user settings, or edit the settings.json directly: ```jsonc -// Tab complete will insert the best matching suggestion when pressing tab. -"editor.tabCompletion": "on" +// Tab complete snippets when their prefix match. Works best when 'quickSuggestions' aren't enabled. +"editor.tabCompletion": "onlySnippets" ``` ## Style @@ -52,269 +52,268 @@ You can use these snippets along with Prettier/ESLint to have your code automati - Can be nested, like `${1:another ${2:placeholder}}` -## Snippets +## JavaScript snippets -### Declarations +### Assignments -#### `c`   -   const statement -```js -const $0 -``` - -#### `l`   -   let statement -```js -let $0 -``` +| Prefix | Description | Body | +| ------ | ------------------ | ---------------------------- | +| `c` | const | `const $0` | +| `l` | let | `let $0` | +| `ca` | const assignment | `const $1 = $0` | +| `la` | let assignment | `let $1 = $0` | +| `cas` | const string | `const $1 = '$0'` | +| `car` | const array | `const $1 = [$0]` | +| `cao` | const object | `const $1 = { $0 }` | +| `dob` | destructure object | `const { $0 } = ${1:object}` | +| `dar` | destructure array | `const [$0] = ${1:array}` | -#### `ca`   -   const assignment -```js -const ${1:name} = ${2:value} +### Flow control ``` - -#### `la`   -   let assignment -```js -let ${1:name} = ${2:value} -``` - -#### `cas`   -   const assignment string -```js -const ${1:name} = '$0' -``` - -#### `catl`   -   const assignment string template literal -```js -const ${1:name} = `$0` -``` - -#### `caa`   -   const assignment array -```js -const ${1:name} = [$0] -``` - -#### `cao`   -   const assignment object -```js -const ${1:name} = { $0 } -``` - -#### `dob`   -   destructure object -```js -const { $2 } = ${1:object} -``` - -#### `dar`   -   destructure array -```js -const [$2] = ${1:array} -``` - -### Classes - -#### `cs`   -   class -```js -class ${1:Class} { - $0 -} -``` - -#### `csc`   -   class with constructor -```js -class ${1:Class} { - constructor($2) { - $0 - } -} -``` - -#### `cse`   -   class extends -```js -class ${1:Class} extends ${2:Base} { - $0 -} -``` - -#### `csce`   -   class extends with constructor -```js -class ${1:Class} extends ${2:Base} { - constructor($3) { - $0 - } -} -``` - -#### `met`   -   method -```js -${1:name}($2) { - $0 -} +🚧 Flow control docs ``` ### Functions - -#### `fn`   -   function -```js -function ${1:name}($2) {, - $0 -} -``` - -#### `efn`   -   export function -```js -export function ${1:name}($2) {, - $0 -} -``` - -#### `nfn`   -   named arrow function -```js -const ${1:name} = ($2) => {$0} -``` - -#### `enfn`   -   export named arrow function -```js -export const ${1:name} = ($2) => {$0} -``` - -#### `af`   -   arrow function -```js -($1) => $0 -``` - -#### `afb`   -   arrow function with body -```js -($1) => { - $0 -} -``` - -### Console - -#### `cl`   -   console.log -```js -console.log($0) -``` - -#### `clm`   -   console.log message -```js -console.log('$0') ``` - -#### `clo`   -   console.log object -```js -console.log({ $0 }) -``` - -#### `clc`   -   console.log from clipboard -```js -console.log({ $CLIPBOARD }) +🚧 Functions docs ``` -#### `ce`   -   console.error -```js -console.error($0) +### Loops ``` - -#### `cw`   -   console.warn -```js -console.warn($0) -``` - -#### `ct`   -   console.table -```js -console.table($0) -``` - -#### `cll`   -   console.log (labeled) -```js -console.log('$1 ->', ${2:$1}) +🚧 Loops docs ``` -#### `cel`   -   console.error (labeled) -```js -console.error('$1 ->', ${2:$1}) -``` - -#### `cwl`   -   console.warn (labeled) -```js -console.warn('$1 ->', ${2:$1}) -``` - -### Misc - -#### `fe`   -   fetch -```js -fetch('$1').then(res => res.json()) -``` - -#### `fea`   -   fetch assign -```js -const ${2|data,{ data }|} = await fetch('$1').then(res => res.json()) -``` - -#### `si`   -   set interval -```js -setInterval(() => { - $0 -}, ${1:delay}) -``` - -#### `st`   -   set timeout -```js -setTimeout(() => { - $0 -}, ${1:delay}) -``` - -### Imports - -#### `im`   -   import -```js -import { $2 } from '$1' -``` - -#### `imd`   -   import default -```js -import $2 from '$1' -``` - -#### `imda`   -   import all as -```js -import * as $2 from '$1' -``` - -#### `ex`   -   export from -```js -export { $2 } from '$1' +### Classes ``` +🚧 Classes docs +``` + +### Promises + +| Prefix | Description | Body | +| ------- | ------------------ | ----------------------------------------------------------------------- | +| `fet` | native fetch | `fetch('$1').then(res => res.json())` | +| `feta` | fetch assignment | `const ${2\|data,{ data }\|} = await fetch('$1').then(res => res.json())` | +| `pr` | promise | `new Promise((resolve, reject) => { $0 })` | +| `prs` | promise resolve | `Promise.resolve($1)$0` | +| `prj` | promise reject | `Promise.reject($1)$0` | +| `then` | promise.then | `$1.then((${2:value}) => $0` | +| `catch` | promise.catch | `$1.catch((${2:err}) => $0` | +| `thenc` | promise.then.catch | `$1.then((${2:value}) => $3.catch((${4:err}) => $5` | +| `pra` | promise.all | `Promise.all($1)$0` | +| `prsa` | promise.allSettled | `Promise.allSettled($1)$0` | +| `pran` | promise.any | `Promise.any($1)$0` | + + +### Modules + +| Prefix | Description | Body | +| ------ | --------------- | ------------------------------------- | +| `im` | import | `import { $2 } from '$1'$0` | +| `imf` | import file | `import '$1'` | +| `imp` | import dynamic | `import($0)` | +| `imd` | import default | `import $2 from '$1'$3;$0` | +| `ima` | import as | `import ${2:*} as {3:name} from '$1'` | +| `ime` | import meta env | `import.meta.env.$0` | +| `ex` | export | `export $0` | +| `exd` | export default | `export default $0` | +| `exf` | export from | `export { $2 } from '$1'` | +| `exa` | export all from | `export * from '$1'` | +| `exo` | export object | `export const ${1:name} = { $0 }` | + + +### Array methods +| Prefix | Description | Body | +| -------------- | -------------------------------- | ---------------------------------------------------------------- | +| `fe` | Array.forEach() | `$1.forEach((${2:item}) => { $0 })` | +| `map` | Array.map() | `$1.map((${2:item}) => ${3})$0` | +| `reduce` | Array.reduce() | `$1.reduce((${2:acc}, ${3:curr}) => { $0 }, ${4:initial})` | +| `reduce-right` | Array.reduceRight() | `$1.reduceRight((${2:acc}, ${3:curr}) => { $0 }, ${4:initial})` | +| `filter` | Array.filter() | `$1.filter((${2:item}) => ${3})$0` | +| `find` | Array.find() | `$1.find((${2:item}) => ${3})$0` | +| `every` | Array.every() | `$1.every((${2:item}) => ${3})$0` | +| `some` | Array.some() | `$1.some((${2:item}) => ${3})$0` | +| `reverse` | Array.reverse() | `$1.reverse()$0` | +| `map-string` | Array.map() as string | `$1.map(String)$0` | +| `map-number` | Array.map() as number | `$1.map(Number)$0` | +| `filter-true` | Array.filter() for truthy values | `$1.filter(Boolean)$0` | + +## Obkects + +| Prefix | Description | Body | +| ------ | ------------------ | ------------------------ | +| `oe` | Object.entries | `Object.entries($0)` | +| `ofe` | Object.fromEntries | `Object.fromEntries($0)` | +| `ok` | Object.keys | `Object.keys($0)` | +| `ov` | Object.values | `Object.values($0)` | + +### Returns + +| Prefix | Description | Body | +| ------ | -------------------- | ---------------- | +| `re` | return | `return $0` | +| `reo` | return object | `return { $0 }` | +| `rei` | return object inline | `return ({$0})` | + + +### Operators, expressions, literals +*will be better categorized* + +| Prefix | Description | Body | +| ------ | ----------------------------------- | ---------------------------- | +| `or` | OR (\|\|) | `\|\| $0` | +| `and` | AND (&&) | `&& $0` | +| `nc` | Nullish coalescing (??) | `?? $0` | +| `eq` | strict equality (===) | `=== $0` | +| `ore` | logical OR expression | `${1:value} \|\| ${0:value}` | +| `ande` | logical AND expression | `${1:value} && ${0:value}` | +| `nce` | Nullish coalescing expression (??) | `${1:item} ?? ${0:default}` | +| `eqe` | strict equality expression | `${1:value} === ${2:value}` | +| `ora` | Logical OR assignment (\|\|=) | `${1:name} \|\|= ${0:default}` | +| `nca` | Nullish coalescing assignment (??=) | `${1:name} ??= ${0:default}` | +| `inc` | addition assignment | `$1 += ${0:1}` | +| `sub` | subtraction assignment | `$1 -= ${0:1}` | +| `mul` | multiplication assignment | `$1 *= ${0:1}` | +| `div` | division assignment | `$1 /= ${0:1}` | +| `ol` | object literal | `{ $1: $0 }` | +| `al` | array literal | `[$0]` | +| `tl` | template literal | ``$0`` | +| `tlo` | template literal operation | `${$1}$0` | +| `tle` | template literal expression | ``$1${$2}$0`` | + + +| Prefix | Description | Body | +| ------ | -------------------------- | --------------------------------------------- | +| `cl` | console.log | `console.log($0)` | +| `ci` | console.info | `console.info($1)` | +| `cdi` | console.dir | `console.dir($1)` | +| `ce` | console.error | `console.error($1)` | +| `cw` | console.warn | `console.warn($1)` | +| `ct` | console.time | `console.time('$1'),$0,console.timeEnd('$1')` | +| `ctb` | console.table | `console.table($1)` | +| `clr` | console.clear | `console.clear()` | +| `clm` | console.log message | `console.log('$0')` | +| `clo` | console.log object | `console.log({ $0 })` | +| `clc` | console.log from clipboard | `console.log({ $CLIPBOARD })` | +| `cll` | console.log labeled | `console.log('$1 ->', $1$2)` | +| `cel` | console.error labeled | `console.error('$1 ->', $1$2)` | +| `cwl` | console.warn labeled | `console.warn('$1 ->', ${2:$1})` | + + +| Prefix | Description | Body | +| ------ | ---------------- | ---------------------------------------- | +| `si` | setInterval | `setInterval(() => { $0 }, ${1:delay})` | +| `st` | setTimeout | `setTimeout(() => { $0 }, ${1:delay})` | +| `sim` | setImmediate | `setImmediate(() => { $0 })` | +| `nt` | process nextTick | `process.nextTick(() => { $0 })` | + + +| Prefix | Description | Body | +| ------ | ---------------------------- | ------------------------------------------------------------- | +| `jp` | JSON.parse | `JSON.parse(${1:json})` | +| `js` | JSON.stringify | `JSON.stringify(${1:value})` | +| `jsp` | JSON.stringify pretty | `JSON.stringify(${1:value}, null, 2)` | +| `jss` | JSON.stringify if not string | `typeof ${1:value} === 'string' ? value : JSON.stringify($1)` | + + +| Prefix | Description | Body | +| ------ | ----------------------------- | -------------------------------------------------------------------------------- | +| `qs` | query selector | `${1:document}.querySelector('$2')` | +| `qsa` | query selector all | `${1:document}.querySelectorAll('$2')` | +| `qsaa` | query selector all array | `[...${1:document}.querySelectorAll('$2')]` | +| `ael` | add event listener | `${1:document}.addEventListener('${2:click}', (e$3) => $0)` | +| `qsae` | query selector event listener | `${1:document}.querySelector('$2')?.addEventListener('${3:click}', (e$4) => $0)` | +| `gid` | get element by id | `${1:document}.getElementById('$2')` | +| `on` | event handler | `${1:emitter}.on('${2:event}', (${3:arguments}) => { $0 })` | + + +| Prefix | Description | Body | +| ------ | ----------- | ---------------- | +| `nd` | new date | `new Date($1)$0` | +| `now` | Date.now() | `Date.now()` | + + +| Prefix | Description | Body | +| ------ | ------------------- | --------------------------------------------------- | +| `desc` | describe | `describe('${1:description}', () => { $0 })` | +| `cont` | context | `context('${1:description}', () => { $0 })` | +| `it` | test (synchronous) | `it('${1:description}', () => { $0 })` | +| `ita` | test (asynchronous) | `it('${1:description}', async () => { $0 })` | +| `itc` | test (callback) | `it('${1:description}', (done) => { $0 done() })` | +| `bf` | before test suite | `before(() => { $0 })` | +| `bfe` | before each test | `beforeEach(() => { $0 })` | +| `aft` | after test suite | `after(() => { $0 })` | +| `afe` | after each test | `afterEach(() => { $0 })` | + + +### Types + +| Prefix | Description | Body | +| ------- | ----------- | ---------------------------------------------------------------------------------------- | +| `aia` | is array | `Array.isArray($0)` | +| `tof` | typeof | `typeof ${1:value} === '${1}'$0` | +| `iof` | instanceof | `${1:object} instanceof ${0:Class` | +| `isnil` | is nil | `${1:value} == null` | +| `nnil` | is not nil | `${1:value} != null` | +| `isnan` | is NaN | `isNan($0)` | +| `nnan` | is not NaN | `!isNan($0)` | + + +### Miscellaneous + +| Prefix | Description | Body | +| ------ | ----------------------------- | -------------------- | +| `us` | insert 'use strict' statement | `'use strict'` | +| `pse` | process.server | `process.server` | +| `pcl` | process.client | `process.client` | +| `env` | env variable | `process.env.$0` | +| `envv` | env variable vite | `import.meta.env.$0` | + + +## Uncategorized + +⚠️ *working on it* +| Prefix | Description | Body | +| ------ | ---------------- | --------------------------------------- | +| `uniq` | uniq | `[...new Set(${0:array})]` | +| `pi` | parse int | `parseInt(${1:value}, ${2\|10,2,8,16\|})` | +| `pf` | parse float | `parseFloat(${1:value})` | +| `am` | array me | `[...${1:arr}$2]$0` | +| `om` | object merge | `[...${1:arr}$2]$0` | +| `aat` | array at | `${1:items}.at(${2:0})` | +| `seq` | sequence of 0..n | `[...Array(${1:length}).keys()]$0` | + + +## TypeScript snippets + +### Assignments + +| Prefix | Description | Body | +| ------ | ------------------------ | ------------------------------------------- | +| `cat` | const assignment (typed) | `const ${1:name}: ${2:string} = ${3:value}` | +| `lat` | let assignment (typed) | `let ${1:name}: ${2:string} = ${3:value}` | +| `caat` | const array (typed) | `const ${1:items}: ${2:string}[] = [$0]` | +| `caot` | const object (typed) | `const ${1:name}: ${2:object} = { $0 }` | + -#### `exa`   -   export all from -```js -export * from '$1' -``` +### Types -#### `exd`   -   export default -```js -export default $0 -``` +| Prefix | Description | Body | +| ------ | ----------------- | ------------------------------------------------ | +| `int` | interface | `interface ${1:Model} { $0 }` | +| `inte` | interface extends | `interface ${1:Model} extends ${2:Base} { $0 }` | +| `tp` | type | `type ${1:Model} = $0` | +| `tpu` | type union | `type ${1:Model} = ${2:first} \| ${3:second}` | +| `tpi` | type intersection | `type ${1:Model} = ${2:first} & ${3:second}` | -### Object - -#### `oe`   -   Object.entries -```js -Object.entries(${0:iterable}) -``` +*...and many more (evertyhing will be documented)* -#### `ofe`   -   Object.fromEntries -```js -Object.fromEntries(${0:iterable}) -``` +Running locally -#### `ok`   -   Object.keys -```js -Object.keys(${0:iterable}) -``` +```bash +# ensure Deno is installed +# https://deno.land/manual@v1.29.1/getting_started/installation -#### `ov`   -   Object.values -```js -Object.values(${0:iterable}) +# generate .code-snippets +npm run generate ``` - -*...and many more (evertyhing will be documented)* diff --git a/package.json b/package.json index 81b713f..92a97c3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "modern-js-snippets", "displayName": "Modern JavaScript Snippets ⚡", - "version": "0.1.0", + "version": "0.2.0", "license": "MIT", "description": "Code snippets for modern JavaScript & TypeScript", "icon": "assets/icon.png", @@ -37,33 +37,36 @@ "vscode": "^1.x.x" }, "scripts": { - "publish": "vsce package && vsce publish" + "publish": "vsce package && vsce publish", + "generate": "deno run --allow-write --allow-read src/app.ts", + "generate:table": "deno run --allow-write --allow-read src/app.ts --table --snippets=false", + "generate:all": "deno run --allow-write --allow-read src/app.ts --table --snippets" }, "contributes": { "snippets": [ { "language": "javascript", - "path": "./snippets/js.code-snippets" + "path": "./dist/js.code-snippets" }, { "language": "typescript", - "path": "./snippets/js.code-snippets" + "path": "./dist/js.code-snippets" }, { "language": "typescriptreact", - "path": "./snippets/js.code-snippets" + "path": "./dist/js.code-snippets" }, { "language": "typescriptreact", - "path": "./snippets/js.code-snippets" + "path": "./dist/js.code-snippets" }, { "language": "typescript", - "path": "./snippets/ts.code-snippets" + "path": "./dist/ts.code-snippets" }, { "language": "typescriptreact", - "path": "./snippets/ts.code-snippets" + "path": "./dist/ts.code-snippets" } ] } diff --git a/snippets/js.code-snippets b/snippets/js.code-snippets deleted file mode 100644 index bef8980..0000000 --- a/snippets/js.code-snippets +++ /dev/null @@ -1,755 +0,0 @@ -{ - // Declarations - "const ⚡": { - "prefix": "c", - "body": "const $0" - }, - "let ⚡": { - "prefix": "l", - "body": "let $0" - }, - "const assignment ⚡": { - "prefix": "ca", - "body": "const $1 = $0;" - }, - "let assignment ⚡": { - "prefix": "la", - "body": "let $1 = $0" - }, - "const string ⚡": { - "prefix": "cas", - "body": "const $1 = '$0'" - }, - "const array ⚡": { - "prefix": "car", - "body": "const $1 = [$0]" - }, - "const object ⚡": { - "prefix": "cao", - "body": "const $1 = { $0 }" - }, - // Destructuring - "destructure object ⚡": { - "prefix": "dob", - "body": "const { $0 } = ${1:object}" - }, - "destructure array ⚡": { - "prefix": "dar", - "body": "const [$0] = ${1:array}" - }, - // Class - "class ⚡": { - "prefix": "cs", - "body": "class $1 {\n\t$0\n}" - }, - "class extends ⚡": { - "prefix": "cse", - "body": "class $1 extends ${2:Base} {\n\t$0\n}" - }, - "class with constructior ⚡": { - "prefix": "csc", - "body": [ - "class $1 {", - "\tconstructor($2) {", - "\t\t$0", - "\t}", - "}" - ], - }, - "class extends with constructor ⚡": { - "prefix": "csec", - "body": [ - "class $1 extends ${2:Base} {", - "\tconstructor($3) {", - "\t\t$0", - "\t}", - "}" - ], - }, - "class constructor": { - "prefix": "ctor", - "body": "constructor($1) {$0}", - }, - "getter": { - "prefix": "get", - "body": "get ${1:property}() {\n\t$0\n}", - }, - "setter": { - "prefix": "set", - "body": "set ${1:property}(${2:value}) {\n\t$0\n}", - }, - "getter and setter": { - "prefix": "gs", - "body": "get ${1:property}() {\n\t$0\n}\nset ${1:property}(${2:value}) {\n\t\n}", - }, - "method ⚡": { - "prefix": "met", - "body": "${1:name}($2) {\n\t$0\n}" - }, - "method async ⚡": { - "prefix": "meta", - "body": "async ${1:name}($2) {\n\t$0\n}" - }, - // Functions - "function ⚡": { - "prefix": "fn", - "body": "function ${1:name}($2) {\n\t$0\n}", - }, - "async function ⚡": { - "prefix": "fna", - "body": "async function ${1:name}($2) {\n\t$0\n}", - }, - "named arrow function ⚡": { - "prefix": "nfn", - "body": "const ${1:name} = ($2) => {$0}" - }, - "async named arrow function ⚡": { - "prefix": "nfna", - "body": "const ${1:name} = async ($2) => {$0}" - }, - "arrow function ⚡": { - "prefix": "af", - "body": "($1) => $0" - }, - "async arrow function ⚡": { - "prefix": "afa", - "body": "async ($1) => $0" - }, - "arrow function with body ⚡": { - "prefix": "afb", - "body": "($1) => {\n\t$0\n}", - }, - "async arrow function with body ⚡": { - "prefix": "afba", - "body": "async ($1) => {\n\t$0\n}", - }, - "export function ⚡": { - "prefix": "efn", - "body": [ - "export function ${1:name}($2) {", - "\t$0", - "}" - ], - }, - "export default function ⚡": { - "prefix": "edfn", - "body": "export default function ${1:name}($2) {\n\t$0\n}", - }, - "export named arrow function ⚡": { - "prefix": "enfn", - "body": "export const ${1:name} = ($2) => {$0}" - }, - // TODO - "immediately-invoked function expression ⚡": { - "prefix": "iife", - "body": "((${1:arguments}) => {\n\t$0\n})(${2})", - }, - // Fetch - "native fetch ⚡": { - "prefix": "fet", - "body": "fetch('$1').then(res => res.json())" - }, - "fetch assignment ⚡": { - "prefix": "feta", - "body": "const ${2|data,{ data }|} = await fetch('$1').then(res => res.json())" - }, - // Promises - "promise ⚡": { - "prefix": "pr", - "body": "new Promise((resolve, reject) => {\n\t$0\n})", - }, - "promise resolve ⚡": { - "prefix": "prs", - "body": "Promise.resolve($1)$0", - }, - "promise reject ⚡": { - "prefix": "prj", - "body": "Promise.reject($1)$0", - }, - "promise.then ⚡": { - "prefix": "then", - "body": "$1.then((${2:value}) => $0", - }, - "promise.catch ⚡": { - "prefix": "catch", - "body": "$1.catch((${2:err}) => $0", - }, - "promise.then.catch ⚡": { - "prefix": "thenc", - "body": "$1.then((${2:value}) => $3.catch((${4:err}) => $5", - }, - "promise.all ⚡": { - "prefix": "pra", - "body": "Promise.all($1)$0", - }, - "promise.allSettled ⚡": { - "prefix": "prsa", - "body": "Promise.allSettled($1)$0", - }, - "promise.any ⚡": { - "prefix": "pran", - "body": "Promise.any($1)$0", - }, - // ES6 Modules - "import ⚡": { - "prefix": "im", - "body": "import { $2 } from '$1'$0", - }, - "import file ⚡": { - "prefix": "imf", - "body": "import '$1'", - }, - "import dynamic ⚡": { - "prefix": "imp", - "body": "import($0)", - }, - "import default ⚡": { - "prefix": "imd", - "body": "import $2 from '$1'$3;$0", - }, - "import as ⚡": { - "prefix": "ima", - "body": "import ${2:*} as {3:name} from '$1'", - }, - "import meta env ⚡": { - "prefix": "ime", - "body": "import.meta.env.$0", - }, - "export ⚡": { - "prefix": "ex", - "body": "export $0", - }, - "export default ⚡": { - "prefix": "exd", - "body": "export default $0", - }, - "export from ⚡": { - "prefix": "exf", - "body": "export { $2 } from '$1'", - }, - "export all from ⚡": { - "prefix": "exa", - "body": "export * from '$1'", - }, - // Object - "Object.entries ⚡": { - "prefix": "oe", - "body": "Object.entries($0)" - }, - "Object.fromEntries ⚡": { - "prefix": "ofe", - "body": "Object.fromEntries($0)" - }, - "Object.keys ⚡": { - "prefix": "ok", - "body": "Object.keys($0)" - }, - "Object.values ⚡": { - "prefix": "ov", - "body": "Object.values($0)" - }, - // Flow - "if ⚡": { - "prefix": "if", - "body": "if (${1}) {\n\t${2}\n}$0", - }, - "if-else ⚡": { - "prefix": "ifel", - "body": "if (${1}) {\n\t${2}\n} else {\n\t${3}\n}", - }, - "if-else-if ⚡": { - "prefix": "ifei", - "body": "if (${1}) {\n\t${2}\n} else if (${3}) {\n\t${4}\n}", - }, - "else ⚡": { - "prefix": "el", - "body": "else {\n\t${3}\n}", - }, - "else if ⚡": { - "prefix": "ei", - "body": "else if (${1}) {\n\t${2}\n}", - }, - "Ternary expression ⚡": { - "prefix": "ter", - "body": "${1} ? ${2} : ${3}" - }, - "Ternary expression assignment ⚡": { - "prefix": "tera", - "body": "const ${1:name} = ${2} ? ${3} : ${4}" - }, - "switch ⚡": { - "prefix": "switch", - "body": [ - "switch ($1) {\n\tcase $2 : $3\n\tdefault: $0\n}" - ], - }, - "case ⚡": { - "prefix": "case", - "body": [ - "case ${1:value}:", - "\tt$0", - "\tbreak;" - ], - }, - // TODO: fl or fo - "for loop": { - "prefix": "fl", - "body": "for (let ${1:i} = 0, ${2:len} = ${3:iterable}.length; ${1:i} < ${2:len}; ${1:i}++) {\n\t$0\n}", - }, - "reverse for loop": { - "prefix": "rfl", - "body": "for (let ${1:i} = ${2:iterable}.length - 1; ${1:i} >= 0; ${1:i}--) {\n\t$0\n}", - }, - "for loop range": { - "prefix": "flr", - "body": "for (let ${1:i} = 0; ${1:i} < ${2:5}; ${1:i}++) {\n\t$0\n}", - }, - // TODO: fin or foi? - "for in loop ⚡": { - "prefix": "fin", - "body": "for (let ${1:key} in ${2:array}) {\n\t$0\n}", - }, - "for in loop hasOwnProperty ": { - "prefix": "finop", - "body": "for (let ${1:key} in ${2:array}) {\n\tif (${2:array}.hasOwnProperty(${1:key})) {\n\t\t$0\n\t}\n}", - }, - "for of loop ⚡": { - "prefix": "fof", - "body": "for (let ${1:item} of ${2:items}) {\n\t$0\n}", - }, - "for of loop await ⚡": { - "prefix": "fofa", - "body": "for await (let ${1:item} of ${2:items}) {\n\t$0\n}", - }, - "while loop ⚡": { - "prefix": "wl", - "body": "while (${1:true}) {\n\t$0\n}", - }, - "try-catch ⚡": { - "prefix": "tc", - "body": [ - "try {", - "\t$1", - "} catch (error) {", - "\t$0", - "}" - ], - }, - "try-catch-finally ⚡": { - "prefix": "tcf", - "body": [ - "try {", - "\t$1", - "} catch (error) {", - "\t$2", - "} finally {", - "\t$3", - "}" - ], - }, - "try-finally ⚡": { - "prefix": "tf", - "body": [ - "try {", - "\t$1", - "} finally {", - "\t$2", - "}" - ], - }, - // JSON - "JSON.parse ⚡": { - "prefix": "jp", - "body": "JSON.parse(${1:json})" - }, - "JSON.stringify ⚡": { - "prefix": "js", - "body": "JSON.stringify(${1:value})" - }, - "JSON.stringify pretty ⚡": { - "prefix": "jsp", - "body": "JSON.stringify(${1:value}, null, 2)" - }, - "JSON.stringify if not string ⚡": { - "prefix": "jss", - "body": "typeof ${1:value} === 'string' ? value : JSON.stringify($1)" - }, - // Operations - "OR (||) ⚡": { - "prefix": "or", - "body": "|| $0" - }, - "AND (&&) ⚡": { - "prefix": "and", - "body": "&& $0" - }, - "Nullish coalescing (??) ⚡": { - "prefix": "nc", - "body": "?? $0" - }, - // TODO: more ergonomic prefix? (qq, ee)? - "strict equality (===) ⚡": { - "prefix": "eq", - "body": "=== $0" - }, - "logical OR expression ⚡": { - "prefix": "ore", - "body": "${1:value} || ${0:value}" - }, - "logical AND expression ⚡": { - "prefix": "ande", - "body": "${1:value} && ${0:value}" - }, - "Nullish coalescing expression (??) ⚡": { - "prefix": "nce", - "body": "${1:item} ?? ${0:default}" - }, - "strict equality expression ⚡": { - "prefix": "eqe", - "body": "${1:value} === ${2:value}" - }, - "Logical OR assignment (||=) ⚡": { - "prefix": "ora", - "body": "${1:name} ||= ${0:default}" - }, - "Nullish coalescing assignment (??=) ⚡": { - "prefix": "nca", - "body": "${1:name} ??= ${0:default}" - }, - "addition assignment ⚡": { - "prefix": "inc", - "body": "$1 += ${0:1}" - }, - "subtraction assignment ⚡": { - "prefix": "sub", - "body": "$1 -= ${0:1}" - }, - "multiplication assignment ⚡": { - "prefix": "mul", - "body": "$1 *= ${0:1}" - }, - "division assignment ⚡": { - "prefix": "div", - "body": "$1 /= ${0:1}" - }, - "object literal ⚡": { - "prefix": "ol", - "body": "{ $1: $0 }" - }, - "array literal ⚡": { - "prefix": "al", - "body": "[$0]" - }, - "template literal ⚡": { - "prefix": "tl", - "body": "`$0`" - }, - // TODO find better name - "template literal operation ⚡": { - "prefix": "tlo", - "body": "${$1}$0" - }, - "template literal expression ⚡": { - "prefix": "tle", - "body": "`$1${$2}$0`" - }, - // Dates - "new date ⚡": { - "prefix": "nd", - "body": "new Date($1)$0" - }, - "Date.now() ⚡": { - "prefix": "now", - "body": "Date.now()" - }, - // Types - "is array ⚡": { - "prefix": "aia", - "body": "Array.isArray($0)" - }, - "typeof ⚡": { - "prefix": "tof", - "body": "typeof ${1:value} === '${0|bigint,boolean,function,number,object,symbol,undefined|}'$0" - }, - "instanceof ⚡": { - "prefix": "iof", - "body": "${1:object} instanceof ${0:Class}" - }, - // Values - "is nil ⚡": { - "prefix": "isnil", - "body": "${1:value} == null" - }, - "is not nil ⚡": { - "prefix": "nnil", - "body": "${1:value} != null" - }, - "is NaN ⚡": { - "prefix": "isnan", - "body": "isNan($0)" - }, - "is not NaN ⚡": { - "prefix": "nnan", - "body": "!isNan($0)" - }, - // Return - "return ⚡": { - "prefix": "re", - "body": "return $0" - }, - "return object ⚡": { - "prefix": "reo", - "body": "return {\n\t$0\n}" - }, - "return object inline ⚡": { - "prefix": "rei", - "body": "return ({$0})" - }, - "uniq ⚡": { - "prefix": "uniq", - "body": "[...new Set(${0:array})]" - }, - "parse int ⚡": { - "prefix": "pi", - "body": "parseInt(${1:value}, ${2|10,2,8,16|})" - }, - "parse float ⚡": { - "prefix": "pf", - "body": "parseFloat(${1:value})" - }, - "array me ⚡": { - "prefix": "am", - "body": "[...${1:arr}$2]$0" - }, - "object merge ⚡": { - "prefix": "om", - "body": "[...${1:arr}$2]$0" - }, - "array at ⚡": { - "prefix": "aat", - "body": "${1:items}.at(${2:0})", - }, - // Iterables - "sequence of 0..n ⚡": { - "prefix": "seq", - "body": "[...Array(${1:length}).keys()]$0", - }, - "forEach loop ⚡": { - "prefix": "fe", - "body": "$1.forEach((${2:item}) => {\n\t$0\n})", - }, - "map array ⚡": { - "prefix": "map", - "body": "$1.map((${2:item}) => ${3})$0", - }, - "reduce array ⚡": { - "prefix": "reduce", - "body": "$1.reduce((${2:acc}, ${3:curr}) => {\n\t$0\n}, ${4:initial})", - }, - "reduce-right array ⚡": { - "prefix": "reduce-right", - "body": "$1.reduceRight((${2:acc}, ${3:curr}) => {\n\t$0\n}, ${4:initial})", - }, - "filter array ⚡": { - "prefix": "filter", - "body": "$1.filter((${2:item}) => ${3})$0", - }, - "find ⚡": { - "prefix": "find", - "body": "$1.find((${2:item}) => ${3})$0", - }, - "every ⚡": { - "prefix": "every", - "body": "$1.every((${2:item}) => ${3})$0", - }, - "some ⚡": { - "prefix": "some", - "body": "$1.some((${2:item}) => ${3})$0", - }, - "reverse ⚡": { - "prefix": "reverse", - "body": "$1.reverse()$0", - }, - // Common array methods - "map string ⚡": { - "prefix": "map-string", - "body": "$1.map(String)$0", - }, - "map number ⚡": { - "prefix": "map-number", - "body": "$1.map(Number)$0", - }, - "filter truthy ⚡": { - "prefix": "filter-true", - "body": "$1.filter(Boolean)$0", - }, - // TODO: what is this - "event handler": { - "prefix": "on", - "body": "${1:emitter}.on('${2:event}', (${3:arguments}) => {\n\t$0\n})", - "description": "event handler" - }, - // Console - // TODO: decide on prefixes for non .log() - "console.log ⚡": { - "prefix": "cl", - "body": "console.log($0)" - }, - "console.info ⚡": { - "prefix": "ci", - "body": "console.info($1)" - }, - "console.dir ⚡": { - "prefix": "cdi", - "body": "console.dir($1)" - }, - "console.error ⚡": { - "prefix": "ce", - "body": "console.error($1)" - }, - "console.warn ⚡": { - "prefix": "cw", - "body": "console.warn($1)" - }, - "console.time ⚡": { - "prefix": "ct", - "body": [ - "console.time('$1')", - "$0", - "console.timeEnd('$1')" - ] - }, - "console.table ⚡": { - "prefix": "ctb", - "body": "console.table($1)" - }, - "console.clear ⚡": { - "prefix": "clr", - "body": "console.clear()" - }, - "console.log message ⚡": { - "prefix": "clm", - "body": "console.log('$0')" - }, - "console.log object ⚡": { - "prefix": "clo", - "body": "console.log({ $0 })" - }, - "console.log from clipboard ⚡": { - "prefix": "clc", - "body": "console.log({ $CLIPBOARD })" - }, - "console.log labeled ⚡": { - "prefix": "cll", - "body": "console.log('$1 ->', $1$2)" - }, - "console.error labeled ⚡": { - "prefix": "cel", - "body": "console.error('$1 ->', $1$2)" - }, - "console.warn labeled ⚡": { - "prefix": "cwl", - "body": "console.warn('$1 ->', ${2:$1})" - }, - // Timers - "setInterval ⚡": { - "prefix": "si", - "body": "setInterval(() => {\n\t$0\n}, ${1:delay})", - }, - "setTimeout ⚡": { - "prefix": "st", - "body": "setTimeout(() => {\n\t$0\n}, ${1:delay})", - }, - "setImmediate ⚡": { - "prefix": "sim", - "body": "setImmediate(() => {\n\t$0\n})", - }, - "process nextTick ⚡": { - "prefix": "nt", - "body": "process.nextTick(() => {\n\t$0\n})", - }, - // DOM - "query selector ⚡": { - "prefix": "qs", - "body": "${1:document}.querySelector('$2')", - }, - "query selector all ⚡": { - "prefix": "qsa", - "body": "${1:document}.querySelectorAll('$2')", - }, - "query selector all array ⚡": { - "prefix": "qsaa", - "body": "[...${1:document}.querySelectorAll('$2')]", - }, - "add event listener ⚡": { - "prefix": "ael", - "body": "${1:document}.addEventListener('${2:click}', (e$3) => $0)", - }, - "query selector event listener ⚡": { - "prefix": "qsae", - "body": "${1:document}.querySelector('$2').addEventListener('${3:click}', (e$4) => $0)", - }, - "get element by id ⚡": { - "prefix": "gid", - "body": "${1:document}.getElementById('$2')", - }, - // TODO - // Testing (Jest, Mocha, Jasmine, etc.) - "describe ⚡": { - "prefix": "desc", - "body": "describe('${1:description}', () => {\n\t$0\n})", - }, - "context ⚡": { - "prefix": "cont", - "body": "context('${1:description}', () => {\n\t$0\n})", - }, - "test (synchronous) ⚡": { - "prefix": "it", - "body": "it('${1:description}', () => {\n\t$0\n})", - }, - "test (asynchronous) ⚡": { - "prefix": "ita", - "body": "it('${1:description}', async () => {\n\t$0\n})", - }, - "test (callback) ⚡": { - "prefix": "itc", - "body": "it('${1:description}', (done) => {\n\t$0\n\tdone()\n})", - }, - "before test suite ⚡": { - "prefix": "bf", - "body": "before(() => {\n\t$0\n})", - }, - "before each test ⚡": { - "prefix": "bfe", - "body": "beforeEach(() => {\n\t$0\n})", - }, - "after test suite ⚡": { - "prefix": "aft", - "body": "after(() => {\n\t$0\n})", - }, - "after each test ⚡": { - "prefix": "afe", - "body": "afterEach(() => {\n\t$0\n})", - }, - // Miscellaneous - "insert 'use strict' statement ⚡": { - "prefix": "us", - "body": "'use strict'", - }, - "process.server ⚡": { - "prefix": "pse", - "body": "process.server", - }, - "process.client ⚡": { - "prefix": "pcl", - "body": "process.client", - }, - "env variable ⚡": { - "prefix": "env", - "body": "process.env.$0", - }, - "env variable vite ⚡": { - "prefix": "env vite", - "body": "import.meta.env.$0", - } -} diff --git a/snippets/ts.code-snippets b/snippets/ts.code-snippets deleted file mode 100644 index 76ba117..0000000 --- a/snippets/ts.code-snippets +++ /dev/null @@ -1,68 +0,0 @@ -{ - "const assignment (typed) ⚡": { - "prefix": "cat", - "body": [ - "const ${1:name}: ${2:string} = ${3:value}" - ], - "description": "const assignment" - }, - "let assignment (typed) ⚡": { - "prefix": "lat", - "body": [ - "let ${1:name}: ${2:string} = ${3:value}" - ], - "description": "let assignment" - }, - "const array (typed) ⚡": { - "prefix": "caat", - "body": [ - "const ${1:items}: ${2:string}[] = [$0]" - ], - "description": "array assignment" - }, - "const object (typed) ⚡": { - "prefix": "caot", - "body": [ - "const ${1:name}: ${2:object} = { $0 }" - ], - "description": "object assignment" - }, - "interface ⚡": { - "prefix": "int", - "body": [ - "interface ${1:Model} {\n\t$0\n}" - ], - "description": "" - }, - "interface extends ⚡": { - "prefix": "inte", - "body": [ - "interface ${1:Model} extends ${2:Base} {\n\t$0\n}" - ], - "description": "" - }, - "type ⚡": { - "prefix": "tp", - "body": [ - "type ${1:Model} = $0", - "" - ], - "description": "" - }, - "type union ⚡": { - "prefix": "tpu", - "body": [ - "type ${1:Model} = ${2:first} | ${3:second}", - "" - ], - "description": "" - }, - "type intersection ⚡": { - "prefix": "tpi", - "body": [ - "type ${1:Model} = ${2:first} & ${3:second}", - "" - ], - "description": "" - }, -} diff --git a/src/app.ts b/src/app.ts new file mode 100644 index 0000000..11045d2 --- /dev/null +++ b/src/app.ts @@ -0,0 +1,28 @@ +import { parse } from "https://deno.land/std@0.168.0/flags/mod.ts"; +import { variants } from "./snippets/app.ts"; +import { + convertToVscSnippet, + generateSnippetsFile, + groupSnippets, + logTables, +} from "./utils/app.ts"; + +const flags = parse(Deno.args, { + boolean: ["table", "snippets"], + default: { snippets: true }, +}); + +if (!flags.table && !flags.snippets) { + console.log("Please specify at least one flag: --table or --snippets"); +} else { + variants.forEach((variant) => { + const categorizedVscSnippets = variant.snippets.map(convertToVscSnippet); + if (flags.table) { + logTables(variant.label, categorizedVscSnippets); + } + if (flags.snippets) { + const variantVscSnippet = groupSnippets(categorizedVscSnippets); + generateSnippetsFile(variant.extension, variantVscSnippet); + } + }); +} diff --git a/src/models/app.ts b/src/models/app.ts new file mode 100644 index 0000000..57544e4 --- /dev/null +++ b/src/models/app.ts @@ -0,0 +1,11 @@ +export type VscSnippet = { + prefix: string | string[]; + body: string | string[]; + description?: string; +}; + +export type VscSnippetDict = Record; + +export type XSnippet = Omit & { name: string }; + +export type XSnippetDict = Record; diff --git a/src/snippets/app.ts b/src/snippets/app.ts new file mode 100644 index 0000000..ded33ea --- /dev/null +++ b/src/snippets/app.ts @@ -0,0 +1,17 @@ +import { javascript } from "./js/app.ts"; +import { typescript } from "./ts/app.ts"; + +export const variants = [ + { + label: "JavaScript", + language: "javascript", + extension: "js", + snippets: javascript, + }, + { + label: "TypeScript", + language: "typescript", + extension: "ts", + snippets: typescript, + }, +]; diff --git a/src/snippets/js/app.ts b/src/snippets/js/app.ts new file mode 100644 index 0000000..14cf1d6 --- /dev/null +++ b/src/snippets/js/app.ts @@ -0,0 +1,43 @@ +import { arrayMethods } from "./array-methods.ts"; +import { classes } from "./classes.ts"; +import { console } from "./console.ts"; +import { dates } from "./dates.ts"; +import { declarations } from "./declarations.ts"; +import { dom } from "./dom.ts"; +import { flowControl } from "./flow-control.ts"; +import { functions } from "./functions.ts"; +import { json } from "./json.ts"; +import { loops } from "./loops.ts"; +import { misc } from "./misc.ts"; +import { modules } from "./modules.ts"; +import { objects } from "./objects.ts"; +import { operatorsExpressionsLiterals } from "./operators-expressions-literals.ts"; +import { promises } from "./promises.ts"; +import { returns } from "./returns.ts"; +import { testing } from "./testing.ts"; +import { timers } from "./timers.ts"; +import { types } from "./types.ts"; +import { uncategorized } from "./uncategorized.ts"; + +export const javascript = [ + declarations, + flowControl, + functions, + loops, + classes, + promises, + modules, + arrayMethods, + objects, + returns, + operatorsExpressionsLiterals, + console, + timers, + json, + dom, + dates, + testing, + types, + misc, + uncategorized, +]; diff --git a/src/snippets/js/array-methods.ts b/src/snippets/js/array-methods.ts new file mode 100644 index 0000000..e513267 --- /dev/null +++ b/src/snippets/js/array-methods.ts @@ -0,0 +1,50 @@ +export const arrayMethods = { + fe: { + name: "Array.forEach()", + body: "$1.forEach((${2:item}) => {\n\t$0\n})", + }, + map: { + name: "Array.map()", + body: "$1.map((${2:item}) => ${3})$0", + }, + reduce: { + name: "Array.reduce()", + body: "$1.reduce((${2:acc}, ${3:curr}) => {\n\t$0\n}, ${4:initial})", + }, + "reduce-right": { + name: "Array.reduceRight()", + body: "$1.reduceRight((${2:acc}, ${3:curr}) => {\n\t$0\n}, ${4:initial})", + }, + filter: { + name: "Array.filter()", + body: "$1.filter((${2:item}) => ${3})$0", + }, + find: { + name: "Array.find()", + body: "$1.find((${2:item}) => ${3})$0", + }, + every: { + name: "Array.every()", + body: "$1.every((${2:item}) => ${3})$0", + }, + some: { + name: "Array.some()", + body: "$1.some((${2:item}) => ${3})$0", + }, + reverse: { + name: "Array.reverse()", + body: "$1.reverse()$0", + }, + "map-string": { + name: "Array.map() as string", + body: "$1.map(String)$0", + }, + "map-number": { + name: "Array.map() as number", + body: "$1.map(Number)$0", + }, + "filter-true": { + name: "Array.filter() for truthy values", + body: "$1.filter(Boolean)$0", + }, +}; diff --git a/src/snippets/js/classes.ts b/src/snippets/js/classes.ts new file mode 100644 index 0000000..9c2927b --- /dev/null +++ b/src/snippets/js/classes.ts @@ -0,0 +1,55 @@ +export const classes = { + cs: { + name: "class", + body: "class $1 {\n\t$0\n}", + }, + cse: { + name: "class extends", + body: "class $1 extends ${2:Base} {\n\t$0\n}", + }, + csc: { + name: "class with constructior", + body: [ + "class $1 {", + "\tconstructor($2) {", + "\t\t$0", + "\t}", + "}", + ], + }, + csec: { + name: "class extends with constructor", + body: [ + "class $1 extends ${2:Base} {", + "\tconstructor($3) {", + "\t\t$0", + "\t}", + "}", + ], + }, + ctor: { + name: "class constructor", + body: "constructor($1) {$0}", + }, + get: { + name: "getter", + body: "get ${1:property}() {\n\t$0\n}", + }, + set: { + name: "setter", + body: "set ${1:property}(${2:value}) {\n\t$0\n}", + }, + gs: { + name: "getter and setter", + body: + "get ${1:property}() {\n\t$0\n}\nset ${1:property}(${2:value}) {\n\t\n}", + }, + met: { + name: "method", + body: "${1:name}($2) {\n\t$0\n}", + }, + meta: { + name: "method async", + body: "async ${1:name}($2) {\n\t$0\n}", + }, +}; diff --git a/src/snippets/js/console.ts b/src/snippets/js/console.ts new file mode 100644 index 0000000..f92fb62 --- /dev/null +++ b/src/snippets/js/console.ts @@ -0,0 +1,62 @@ +export const console = { + cl: { + name: "console.log", + body: "console.log($0)", + }, + ci: { + name: "console.info", + body: "console.info($1)", + }, + cdi: { + name: "console.dir", + body: "console.dir($1)", + }, + ce: { + name: "console.error", + body: "console.error($1)", + }, + cw: { + name: "console.warn", + body: "console.warn($1)", + }, + ct: { + name: "console.time", + body: [ + "console.time('$1')", + "$0", + "console.timeEnd('$1')", + ], + }, + ctb: { + name: "console.table", + body: "console.table($1)", + }, + clr: { + name: "console.clear", + body: "console.clear()", + }, + clm: { + name: "console.log message", + body: "console.log('$0')", + }, + clo: { + name: "console.log object", + body: "console.log({ $0 })", + }, + clc: { + name: "console.log from clipboard", + body: "console.log({ $CLIPBOARD })", + }, + cll: { + name: "console.log labeled", + body: "console.log('$1 ->', $1$2)", + }, + cel: { + name: "console.error labeled", + body: "console.error('$1 ->', $1$2)", + }, + cwl: { + name: "console.warn labeled", + body: "console.warn('$1 ->', ${2:$1})", + }, +}; diff --git a/src/snippets/js/dates.ts b/src/snippets/js/dates.ts new file mode 100644 index 0000000..c71c365 --- /dev/null +++ b/src/snippets/js/dates.ts @@ -0,0 +1,10 @@ +export const dates = { + nd: { + name: "new date", + body: "new Date($1)$0", + }, + now: { + name: "Date.now()", + body: "Date.now()", + }, +}; diff --git a/src/snippets/js/declarations.ts b/src/snippets/js/declarations.ts new file mode 100644 index 0000000..4ccaa4f --- /dev/null +++ b/src/snippets/js/declarations.ts @@ -0,0 +1,38 @@ +export const declarations = { + c: { + name: "const", + body: "const $0", + }, + l: { + name: "let", + body: "let $0", + }, + ca: { + name: "const assignment", + body: "const $1 = $0", + }, + la: { + name: "let assignment", + body: "let $1 = $0", + }, + cas: { + name: "const string", + body: "const $1 = '$0'", + }, + car: { + name: "const array", + body: "const $1 = [$0]", + }, + cao: { + name: "const object", + body: "const $1 = { $0 }", + }, + dob: { + name: "destructure object", + body: "const { $0 } = ${1:object}", + }, + dar: { + name: "destructure array", + body: "const [$0] = ${1:array}", + }, +}; diff --git a/src/snippets/js/dom.ts b/src/snippets/js/dom.ts new file mode 100644 index 0000000..b698baf --- /dev/null +++ b/src/snippets/js/dom.ts @@ -0,0 +1,31 @@ +export const dom = { + qs: { + name: "query selector", + body: "${1:document}.querySelector('$2')", + }, + qsa: { + name: "query selector all", + body: "${1:document}.querySelectorAll('$2')", + }, + qsaa: { + name: "query selector all array", + body: "[...${1:document}.querySelectorAll('$2')]", + }, + ael: { + name: "add event listener", + body: "${1:document}.addEventListener('${2:click}', (e$3) => $0)", + }, + qsae: { + name: "query selector event listener", + body: + "${1:document}.querySelector('$2')?.addEventListener('${3:click}', (e$4) => $0)", + }, + gid: { + name: "get element by id", + body: "${1:document}.getElementById('$2')", + }, + on: { + name: "event handler", + body: "${1:emitter}.on('${2:event}', (${3:arguments}) => {\n\t$0\n})", + }, +}; diff --git a/src/snippets/js/flow-control.ts b/src/snippets/js/flow-control.ts new file mode 100644 index 0000000..6084abb --- /dev/null +++ b/src/snippets/js/flow-control.ts @@ -0,0 +1,76 @@ +export const flowControl = { + if: { + name: "if", + body: "if (${1}) {\n\t${2}\n}$0", + }, + ifel: { + name: "if-else", + body: "if (${1}) {\n\t${2}\n} else {\n\t${3}\n}", + }, + ifei: { + name: "if-else-if", + body: "if (${1}) {\n\t${2}\n} else if (${3}) {\n\t${4}\n}", + }, + el: { + name: "else", + body: "else {\n\t${3}\n}", + }, + ei: { + name: "else if", + body: "else if (${1}) {\n\t${2}\n}", + }, + ter: { + name: "Ternary expression", + body: "${1} ? ${2} : ${3}", + }, + tera: { + name: "Ternary expression assignment", + body: "const ${1:name} = ${2} ? ${3} : ${4}", + }, + switch: { + name: "switch", + body: [ + "switch ($1) {\n\tcase $2 : $3\n\tdefault: $0\n}", + ], + }, + case: { + name: "case", + body: [ + "case ${1:value}:", + "\tt$0", + "\tbreak;", + ], + }, + tc: { + name: "try-catch", + body: [ + "try {", + "\t$1", + "} catch (error) {", + "\t$0", + "}", + ], + }, + tcf: { + name: "try-catch-finally", + body: [ + "try {", + "\t$1", + "} catch (error) {", + "\t$2", + "} finally {", + "\t$3", + "}", + ], + }, + tf: { + name: "try-finally", + body: [ + "try {", + "\t$1", + "} finally {", + "\t$2", + "}", + ], + }, +}; diff --git a/src/snippets/js/functions.ts b/src/snippets/js/functions.ts new file mode 100644 index 0000000..cede75b --- /dev/null +++ b/src/snippets/js/functions.ts @@ -0,0 +1,54 @@ +export const functions = { + fn: { + name: "function", + body: "function ${1:name}($2) {\n\t$0\n}", + }, + fna: { + name: "async function", + body: "async function ${1:name}($2) {\n\t$0\n}", + }, + nfn: { + name: "named arrow function", + body: "const ${1:name} = ($2) => {$0}", + }, + nfna: { + name: "async named arrow function", + body: "const ${1:name} = async ($2) => {$0}", + }, + af: { + name: "arrow function", + body: "($1) => $0", + }, + afa: { + name: "async arrow function", + body: "async ($1) => $0", + }, + afb: { + name: "arrow function with body", + body: "($1) => {\n\t$0\n}", + }, + afba: { + name: "async arrow function with body", + body: "async ($1) => {\n\t$0\n}", + }, + efn: { + name: "export function", + body: [ + "export function ${1:name}($2) {", + "\t$0", + "}", + ], + }, + edfn: { + name: "export default function", + body: "export default function ${1:name}($2) {\n\t$0\n}", + }, + enfn: { + name: "export named arrow function", + body: "export const ${1:name} = ($2) => {$0}", + }, + iife: { + name: "immediately-invoked function expression", + body: "((${1:arguments}) => {\n\t$0\n})(${2})", + }, +}; diff --git a/src/snippets/js/json.ts b/src/snippets/js/json.ts new file mode 100644 index 0000000..cc3e888 --- /dev/null +++ b/src/snippets/js/json.ts @@ -0,0 +1,18 @@ +export const json = { + jp: { + name: "JSON.parse", + body: "JSON.parse(${1:json})", + }, + js: { + name: "JSON.stringify", + body: "JSON.stringify(${1:value})", + }, + jsp: { + name: "JSON.stringify pretty", + body: "JSON.stringify(${1:value}, null, 2)", + }, + jss: { + name: "JSON.stringify if not string", + body: "typeof ${1:value} === 'string' ? value : JSON.stringify($1)", + }, +}; diff --git a/src/snippets/js/loops.ts b/src/snippets/js/loops.ts new file mode 100644 index 0000000..de8d788 --- /dev/null +++ b/src/snippets/js/loops.ts @@ -0,0 +1,37 @@ +export const loops = { + fl: { + name: "for loop", + body: + "for (let ${1:i} = 0, ${2:len} = ${3:iterable}.length; ${1:i} < ${2:len}; ${1:i}++) {\n\t$0\n}", + }, + rfl: { + name: "reverse for loop", + body: + "for (let ${1:i} = ${2:iterable}.length - 1; ${1:i} >= 0; ${1:i}--) {\n\t$0\n}", + }, + flr: { + name: "for loop range", + body: "for (let ${1:i} = 0; ${1:i} < ${2:5}; ${1:i}++) {\n\t$0\n}", + }, + fin: { + name: "for in loop", + body: "for (let ${1:key} in ${2:array}) {\n\t$0\n}", + }, + finop: { + name: "for in loop hasOwnProperty ", + body: + "for (let ${1:key} in ${2:array}) {\n\tif (${2:array}.hasOwnProperty(${1:key})) {\n\t\t$0\n\t}\n}", + }, + fof: { + name: "for of loop", + body: "for (let ${1:item} of ${2:items}) {\n\t$0\n}", + }, + fofa: { + name: "for of loop await", + body: "for await (let ${1:item} of ${2:items}) {\n\t$0\n}", + }, + wl: { + name: "while loop", + body: "while (${1:true}) {\n\t$0\n}", + }, +}; diff --git a/src/snippets/js/misc.ts b/src/snippets/js/misc.ts new file mode 100644 index 0000000..e7b8854 --- /dev/null +++ b/src/snippets/js/misc.ts @@ -0,0 +1,22 @@ +export const misc = { + us: { + name: "insert 'use strict' statement", + body: "'use strict'", + }, + pse: { + name: "process.server", + body: "process.server", + }, + pcl: { + name: "process.client", + body: "process.client", + }, + env: { + name: "env variable", + body: "process.env.$0", + }, + envv: { + name: "env variable vite", + body: "import.meta.env.$0", + }, +}; diff --git a/src/snippets/js/modules.ts b/src/snippets/js/modules.ts new file mode 100644 index 0000000..ccf36f1 --- /dev/null +++ b/src/snippets/js/modules.ts @@ -0,0 +1,46 @@ +export const modules = { + im: { + name: "import", + body: "import { $2 } from '$1'$0", + }, + imf: { + name: "import file", + body: "import '$1'", + }, + imp: { + name: "import dynamic", + body: "import($0)", + }, + imd: { + name: "import default", + body: "import $2 from '$1'$3;$0", + }, + ima: { + name: "import as", + body: "import ${2:*} as {3:name} from '$1'", + }, + ime: { + name: "import meta env", + body: "import.meta.env.$0", + }, + ex: { + name: "export", + body: "export $0", + }, + exd: { + name: "export default", + body: "export default $0", + }, + exf: { + name: "export from", + body: "export { $2 } from '$1'", + }, + exa: { + name: "export all from", + body: "export * from '$1'", + }, + exo: { + name: "export object", + body: "export const ${1:name} = { $0 }", + }, +}; diff --git a/src/snippets/js/objects.ts b/src/snippets/js/objects.ts new file mode 100644 index 0000000..e856b65 --- /dev/null +++ b/src/snippets/js/objects.ts @@ -0,0 +1,19 @@ +// TODO: find a better category for this +export const objects = { + oe: { + name: "Object.entries", + body: "Object.entries($0)", + }, + ofe: { + name: "Object.fromEntries", + body: "Object.fromEntries($0)", + }, + ok: { + name: "Object.keys", + body: "Object.keys($0)", + }, + ov: { + name: "Object.values", + body: "Object.values($0)", + }, +}; diff --git a/src/snippets/js/operators-expressions-literals.ts b/src/snippets/js/operators-expressions-literals.ts new file mode 100644 index 0000000..e3dea49 --- /dev/null +++ b/src/snippets/js/operators-expressions-literals.ts @@ -0,0 +1,79 @@ +// TODO: categorrize +export const operatorsExpressionsLiterals = { + or: { + name: "OR (||)", + body: "|| $0", + }, + and: { + name: "AND (&&)", + body: "&& $0", + }, + nc: { + name: "Nullish coalescing (??)", + body: "?? $0", + }, + eq: { + name: "strict equality (===)", + body: "=== $0", + }, + ore: { + name: "logical OR expression", + body: "${1:value} || ${0:value}", + }, + ande: { + name: "logical AND expression", + body: "${1:value} && ${0:value}", + }, + nce: { + name: "Nullish coalescing expression (??)", + body: "${1:item} ?? ${0:default}", + }, + eqe: { + name: "strict equality expression", + body: "${1:value} === ${2:value}", + }, + ora: { + name: "Logical OR assignment (||=)", + body: "${1:name} ||= ${0:default}", + }, + nca: { + name: "Nullish coalescing assignment (??=)", + body: "${1:name} ??= ${0:default}", + }, + inc: { + name: "addition assignment", + body: "$1 += ${0:1}", + }, + sub: { + name: "subtraction assignment", + body: "$1 -= ${0:1}", + }, + mul: { + name: "multiplication assignment", + body: "$1 *= ${0:1}", + }, + div: { + name: "division assignment", + body: "$1 /= ${0:1}", + }, + ol: { + name: "object literal", + body: "{ $1: $0 }", + }, + al: { + name: "array literal", + body: "[$0]", + }, + tl: { + name: "template literal", + body: "`$0`", + }, + tlo: { + name: "template literal operation", + body: "${$1}$0", + }, + tle: { + name: "template literal expression", + body: "`$1${$2}$0`", + }, +}; diff --git a/src/snippets/js/promises.ts b/src/snippets/js/promises.ts new file mode 100644 index 0000000..75ca7f8 --- /dev/null +++ b/src/snippets/js/promises.ts @@ -0,0 +1,47 @@ +export const promises = { + fet: { + name: "native fetch", + body: "fetch('$1').then(res => res.json())", + }, + feta: { + name: "fetch assignment", + body: + "const ${2|data,{ data }|} = await fetch('$1').then(res => res.json())", + }, + pr: { + name: "promise", + body: "new Promise((resolve, reject) => {\n\t$0\n})", + }, + prs: { + name: "promise resolve", + body: "Promise.resolve($1)$0", + }, + prj: { + name: "promise reject", + body: "Promise.reject($1)$0", + }, + then: { + name: "promise.then", + body: "$1.then((${2:value}) => $0", + }, + catch: { + name: "promise.catch", + body: "$1.catch((${2:err}) => $0", + }, + thenc: { + name: "promise.then.catch", + body: "$1.then((${2:value}) => $3.catch((${4:err}) => $5", + }, + pra: { + name: "promise.all", + body: "Promise.all($1)$0", + }, + prsa: { + name: "promise.allSettled", + body: "Promise.allSettled($1)$0", + }, + pran: { + name: "promise.any", + body: "Promise.any($1)$0", + }, +}; diff --git a/src/snippets/js/returns.ts b/src/snippets/js/returns.ts new file mode 100644 index 0000000..0e385f4 --- /dev/null +++ b/src/snippets/js/returns.ts @@ -0,0 +1,14 @@ +export const returns = { + re: { + name: "return", + body: "return $0", + }, + reo: { + name: "return object", + body: "return {\n\t$0\n}", + }, + rei: { + name: "return object inline", + body: "return ({$0})", + }, +}; diff --git a/src/snippets/js/testing.ts b/src/snippets/js/testing.ts new file mode 100644 index 0000000..7fe5b10 --- /dev/null +++ b/src/snippets/js/testing.ts @@ -0,0 +1,38 @@ +export const testing = { + desc: { + name: "describe", + body: "describe('${1:description}', () => {\n\t$0\n})", + }, + cont: { + name: "context", + body: "context('${1:description}', () => {\n\t$0\n})", + }, + it: { + name: "test (synchronous)", + body: "it('${1:description}', () => {\n\t$0\n})", + }, + ita: { + name: "test (asynchronous)", + body: "it('${1:description}', async () => {\n\t$0\n})", + }, + itc: { + name: "test (callback)", + body: "it('${1:description}', (done) => {\n\t$0\n\tdone()\n})", + }, + bf: { + name: "before test suite", + body: "before(() => {\n\t$0\n})", + }, + bfe: { + name: "before each test", + body: "beforeEach(() => {\n\t$0\n})", + }, + aft: { + name: "after test suite", + body: "after(() => {\n\t$0\n})", + }, + afe: { + name: "after each test", + body: "afterEach(() => {\n\t$0\n})", + }, +}; diff --git a/src/snippets/js/timers.ts b/src/snippets/js/timers.ts new file mode 100644 index 0000000..41d60e4 --- /dev/null +++ b/src/snippets/js/timers.ts @@ -0,0 +1,18 @@ +export const timers = { + si: { + name: "setInterval", + body: "setInterval(() => {\n\t$0\n}, ${1:delay})", + }, + st: { + name: "setTimeout", + body: "setTimeout(() => {\n\t$0\n}, ${1:delay})", + }, + sim: { + name: "setImmediate", + body: "setImmediate(() => {\n\t$0\n})", + }, + nt: { + name: "process nextTick", + body: "process.nextTick(() => {\n\t$0\n})", + }, +}; diff --git a/src/snippets/js/types.ts b/src/snippets/js/types.ts new file mode 100644 index 0000000..231bf0c --- /dev/null +++ b/src/snippets/js/types.ts @@ -0,0 +1,31 @@ +export const types = { + aia: { + name: "is array", + body: "Array.isArray($0)", + }, + tof: { + name: "typeof", + body: + "typeof ${1:value} === '${2|bigint,boolean,function,number,object,symbol,undefined|}'$0", + }, + iof: { + name: "instanceof", + body: "${1:object} instanceof ${0:Class}", + }, + isnil: { + name: "is nil", + body: "${1:value} == null", + }, + nnil: { + name: "is not nil", + body: "${1:value} != null", + }, + isnan: { + name: "is NaN", + body: "isNan($0)", + }, + nnan: { + name: "is not NaN", + body: "!isNan($0)", + }, +}; diff --git a/src/snippets/js/uncategorized.ts b/src/snippets/js/uncategorized.ts new file mode 100644 index 0000000..11a9ea7 --- /dev/null +++ b/src/snippets/js/uncategorized.ts @@ -0,0 +1,30 @@ +export const uncategorized = { + uniq: { + name: "uniq", + body: "[...new Set(${0:array})]", + }, + pi: { + name: "parse int", + body: "parseInt(${1:value}, ${2|10,2,8,16|})", + }, + pf: { + name: "parse float", + body: "parseFloat(${1:value})", + }, + am: { + name: "array me", + body: "[...${1:arr}$2]$0", + }, + om: { + name: "object merge", + body: "[...${1:arr}$2]$0", + }, + aat: { + name: "array at", + body: "${1:items}.at(${2:0})", + }, + seq: { + name: "sequence of 0..n", + body: "[...Array(${1:length}).keys()]$0", + }, +}; diff --git a/src/snippets/ts/app.ts b/src/snippets/ts/app.ts new file mode 100644 index 0000000..58e5d9b --- /dev/null +++ b/src/snippets/ts/app.ts @@ -0,0 +1,7 @@ +import { declarations } from "./declarations.ts"; +import { types } from "./types.ts"; + +export const typescript = [ + declarations, + types, +]; diff --git a/src/snippets/ts/declarations.ts b/src/snippets/ts/declarations.ts new file mode 100644 index 0000000..ae52ea9 --- /dev/null +++ b/src/snippets/ts/declarations.ts @@ -0,0 +1,18 @@ +export const declarations = { + cat: { + name: "const assignment (typed)", + body: "const ${1:name}: ${2:string} = ${3:value}", + }, + lat: { + name: "let assignment (typed)", + body: "let ${1:name}: ${2:string} = ${3:value}", + }, + caat: { + name: "const array (typed)", + body: "const ${1:items}: ${2:string}[] = [$0]", + }, + caot: { + name: "const object (typed)", + body: "const ${1:name}: ${2:object} = { $0 }", + }, +}; diff --git a/src/snippets/ts/types.ts b/src/snippets/ts/types.ts new file mode 100644 index 0000000..b02e70d --- /dev/null +++ b/src/snippets/ts/types.ts @@ -0,0 +1,22 @@ +export const types = { + int: { + name: "interface", + body: "interface ${1:Model} {\n\t$0\n}", + }, + inte: { + name: "interface extends", + body: "interface ${1:Model} extends ${2:Base} {\n\t$0\n}", + }, + tp: { + name: "type", + body: "type ${1:Model} = $0", + }, + tpu: { + name: "type union", + body: "type ${1:Model} = ${2:first} | ${3:second}", + }, + tpi: { + name: "type intersection", + body: "type ${1:Model} = ${2:first} & ${3:second}", + }, +}; diff --git a/src/utils/app.ts b/src/utils/app.ts new file mode 100644 index 0000000..6a17323 --- /dev/null +++ b/src/utils/app.ts @@ -0,0 +1,58 @@ +import { ensureDirSync } from "https://deno.land/std@0.141.0/fs/ensure_dir.ts"; +import { markdownTable } from "https://esm.sh/markdown-table@3"; +import { VscSnippet, VscSnippetDict, XSnippetDict } from "../models/app.ts"; + +const SYMBOL = "⚡"; + +const code = (str: string) => `\`${str}\``; +const replaceSymbol = (str: string) => str.replace(` ${SYMBOL}`, ""); + +export const convertToVscSnippet = (snippets: XSnippetDict) => { + return Object.entries(snippets) + .reduce((acc, [prefix, { name, body }]) => { + const styledName = `${name} ${SYMBOL}`; + acc[styledName] = { prefix, body } as VscSnippet; + return acc; + }, {} as VscSnippetDict); +}; + +export const groupSnippets = (dicts: VscSnippetDict[]) => { + return dicts.reduce((acc, curr) => ({ + ...acc, + ...curr, + })); +}; + +export const generateSnippetsFile = (name: string, data: VscSnippetDict) => { + const file = `./dist/${name}.code-snippets`; + ensureDirSync("./dist"); + + Deno.writeTextFileSync( + file, + JSON.stringify(data, null, 2), + ); +}; + +export const generateMarkdownTable = (input: VscSnippetDict) => { + const header = ["Prefix", "Description", "Body"]; + + const rows = Object.entries(input) + .map(([name, { prefix, body }]) => [ + code(prefix as string), + replaceSymbol(name), + code(body as string), + ]); + + // TODO: handle multiline code + // escape || + + return markdownTable([header, ...rows]); +}; + +export const logTables = (language: string, snippets: VscSnippetDict[]) => { + console.log(`## ${language}`); + snippets.forEach((s) => { + console.log(generateMarkdownTable(s)); + console.log("\n"); + }); +}; diff --git a/test.ts b/test.ts deleted file mode 100644 index d5b6803..0000000 --- a/test.ts +++ /dev/null @@ -1 +0,0 @@ -ima