diff --git a/README.md b/README.md index e160fda..95d9886 100644 --- a/README.md +++ b/README.md @@ -354,397 +354,3239 @@ Will be sorted into appropriate categories in the future. # ensure Deno is installed # https://deno.land/manual@v1.29.1/getting_started/installation -# generate .code-snippets +# generate .code-snippets and documentation npm run generate ``` --- -## 🚧 Experimenting with formatting + +## Snippets + + +### Assignments + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PrefixNameBody
+ +`c` + +const + + ```javascript +const $0 + ``` + +
+ +`l` + +let + + ```javascript +let $0 + ``` + +
+ +`ca` + +const assignment + + ```javascript +const $1 = $0 + ``` + +
+ +`la` + +let assignment + + ```javascript +let $1 = $0 + ``` + +
+ +`cas` + +const string assignment + + ```javascript +const $1 = '$0' + ``` + +
+ +`car` + +const array assignment + + ```javascript +const $1 = [$0] + ``` + +
+ +`cao` + +const object assignment + + ```javascript +const $1 = { $0 } + ``` + +
+ +`dob` + +object destructuring + + ```javascript +const { $0 } = ${1:object} + ``` + +
+ +`dar` + +array destructuring + + ```javascript +const [$0] = ${1:array} + ``` + +
+ +### Flow control + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PrefixNameBody
+ +`if` + +if statement + + ```javascript +if ($1) { + $2 +} + ``` + +
+ +`ifel` + +if/else statement + + ```javascript +if ($1) { + $2 +} else { + $3 +} + ``` + +
+ +`ifei` + +if/else-if statement + + ```javascript +if ($1) { + $2 +} else if ($3) { + $4 +} + ``` + +
+ +`el` + +else statement + + ```javascript +else { + $3 +} + ``` + +
+ +`ei` + +else if statement + + ```javascript +else if ($1) { + $2 +} + ``` + +
+ +`ter` + +ternary operator + + ```javascript +$1 ? $2 : $3 + ``` + +
+ +`tera` + +ternary expression assignment + + ```javascript +const ${1:name} = $2 ? $3 : $4 + ``` + +
+ +`sw` + +switch + + ```javascript +switch ($1) { + case $2 : $3 + default: $0 +} + ``` + +
+ +`cas` + +case + + ```javascript +case ${1:value}: + $0 + break; + ``` + +
+ +`tc` + +try/catch + + ```javascript +try { + $1 +} catch (error) { + $0 +} + ``` + +
+ +`tcf` + +try/catch/finally + + ```javascript +try { + $1 +} catch (error) { + $2 +} finally { + $3 +} + ``` + +
+ +`tf` + +try/finally + + ```javascript +try { + $1 +} finally { + $2 +} + ``` + +
+ +### Functions + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PrefixNameBody
+ +`fn` + +function + + ```javascript +function ${1:name}($2) { + $0 +} + ``` + +
+ +`fna` + +async function + + ```javascript +async function ${1:name}($2) { + $0 +} + ``` + +
+ +`nfn` + +named arrow function + + ```javascript +const ${1:name} = ($2) => {$0} + ``` + +
+ +`nfna` + +async named arrow function + + ```javascript +const ${1:name} = async ($2) => {$0} + ``` + +
+ +`af` + +arrow function + + ```javascript +($1) => $0 + ``` + +
+ +`afa` + +async arrow function + + ```javascript +async ($1) => $0 + ``` + +
+ +`afb` + +arrow function with body + + ```javascript +($1) => { + $0 +} + ``` + +
+ +`afba` + +async arrow function with body + + ```javascript +async ($1) => { + $0 +} + ``` + +
+ +`efn` + +export function + + ```javascript +export function ${1:name}($2) { + $0 +} + ``` + +
+ +`edfn` + +export default function + + ```javascript +export default function ${1:name}($2) { + $0 +} + ``` + +
+ +`enfn` + +export named arrow function + + ```javascript +export const ${1:name} = ($2) => {$0} + ``` + +
+ +`iife` + +immediately-invoked function expression + + ```javascript +((${1:arguments}) => { + $0 +})($2) + ``` + +
+ +### Loops + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PrefixNameBody
+ +`fl` + +for loop + + ```javascript +for (let ${1:i} = 0, ${2:len} = ${3:iterable}.length; ${1:i} < ${2:len}; ${1:i}++) { + $0 +} + ``` + +
+ +`rfl` + +reverse for loop + + ```javascript +for (let ${1:i} = ${2:iterable}.length - 1; ${1:i} >= 0; ${1:i}--) { + $0 +} + ``` + +
+ +`flr` + +for loop (range) + + ```javascript +for (let ${1:i} = 0; ${1:i} < ${2:5}; ${1:i}++) { + $0 +} + ``` + +
+ +`fin` + +for...in loop + + ```javascript +for (let ${1:key} in ${2:array}) { + $0 +} + ``` + +
+ +`fof` + +for...of loop + + ```javascript +for (let ${1:item} of ${2:items}) { + $0 +} + ``` + +
+ +`fofa` + +for await...of loop + + ```javascript +for await (let ${1:item} of ${2:items}) { + $0 +} + ``` + +
+ +`wl` + +while loop + + ```javascript +while (${1:true}) { + $0 +} + ``` + +
+ +### Classes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PrefixNameBody
+ +`cs` + +class + + ```javascript +class $1 { + $0 +} + ``` + +
+ +`cse` + +class extends + + ```javascript +class $1 extends ${2:Base} { + $0 +} + ``` + +
+ +`csc` + +class with constructor + + ```javascript +class $1 { + constructor($2) { + $0 + } +} + ``` + +
+ +`csec` + +class extends with constructor + + ```javascript +class $1 extends ${2:Base} { + constructor($3) { + $0 + } +} + ``` + +
+ +`ctor` + +class constructor + + ```javascript +constructor($1) {$0} + ``` + +
+ +`get` + +getter + + ```javascript +get ${1:property}() { + $0 +} + ``` + +
+ +`set` + +setter + + ```javascript +set ${1:property}(${2:value}) { + $0 +} + ``` + +
+ +`gs` + +getter and setter + + ```javascript +get ${1:property}() { + $0 +} +set ${1:property}(${2:value}) { + +} + ``` + +
+ +`met` + +method + + ```javascript +${1:name}($2) { + $0 +} + ``` + +
+ +`meta` + +async method + + ```javascript +async ${1:name}($2) { + $0 +} + ``` + +
+ +### Promises + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PrefixNameBody
+ +`fet` + +fetch + + ```javascript +fetch('$1').then(res => res.json()) + ``` + +
+ +`feta` + +fetch assignment + + ```javascript +const ${2|data,{ data }|} = await fetch('$1').then(res => res.json()) + ``` + +
+ +`pr` + +promise + + ```javascript +new Promise((resolve, reject) => { + $0 +}) + ``` + +
+ +`prs` + +Promise.resolve + + ```javascript +Promise.resolve($1) + ``` + +
+ +`prj` + +Promise.reject + + ```javascript +Promise.reject($1) + ``` + +
+ +`then` + +promise .then + + ```javascript +$1.then((${2:value}) => $0) + ``` + +
+ +`catch` + +promise .catch + + ```javascript +$1.catch((${2:err}) => $0) + ``` + +
+ +`thenc` + +promise .then.catch + + ```javascript +$1.then((${2:value}) => $3).catch((${4:err}) => $5) + ``` + +
+ +`pra` + +Promise.all + + ```javascript +Promise.all($1) + ``` + +
+ +`prsa` + +Promise.allSettled + + ```javascript +Promise.allSettled($1) + ``` + +
+ +`pran` + +Promise.any + + ```javascript +Promise.any($1) + ``` + +
+ +### Modules + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PrefixNameBody
+ +`im` + +import from module + + ```javascript +import { $2 } from '$1' + ``` + +
+ +`imf` + +import file + + ```javascript +import '$1' + ``` + +
+ +`imp` + +import dynamic + + ```javascript +import($0) + ``` + +
+ +`imd` + +import default + + ```javascript +import $2 from '$1'$3; + ``` + +
+ +`ima` + +import as + + ```javascript +import ${2:*} as {3:name} from '$1' + ``` + +
+ +`ime` + +import meta env + + ```javascript +import.meta.env.$0 + ``` + +
+ +`ex` + +export + + ```javascript +export $0 + ``` + +
+ +`exd` + +export default + + ```javascript +export default $0 + ``` + +
+ +`exf` + +export from + + ```javascript +export { $2 } from '$1' + ``` + +
+ +`exa` + +export all from + + ```javascript +export * from '$1' + ``` + +
+ +`exo` + +export object + + ```javascript +export const ${1:name} = { $0 } + ``` + +
+ +### Array methods + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PrefixNameBody
+ +`fe` + +Array.forEach() + + ```javascript +$1.forEach((${2:item}) => { + $0 +}) + ``` + +
+ +`map` + +Array.map() + + ```javascript +$1.map((${2:item}) => ${3}) + ``` + +
+ +`reduce` + +Array.reduce() + + ```javascript +$1.reduce((${2:acc}, ${3:curr}) => { + $0 +}, ${4:initial}) + ``` + +
+ +`reduce-right` + +Array.reduceRight() + + ```javascript +$1.reduceRight((${2:acc}, ${3:curr}) => { + $0 +}, ${4:initial}) + ``` + +
+ +`filter` + +Array.filter() + + ```javascript +$1.filter((${2:item}) => ${3}) + ``` + +
+ +`find` + +Array.find() + + ```javascript +$1.find((${2:item}) => ${3}) + ``` + +
+ +`every` + +Array.every() + + ```javascript +$1.every((${2:item}) => ${3}) + ``` + +
+ +`some` + +Array.some() + + ```javascript +$1.some((${2:item}) => ${3}) + ``` + +
+ +`reverse` + +Array.reverse() + + ```javascript +$1.reverse() + ``` + +
+ +`map-string` + +Array.map() as string + + ```javascript +$1.map(String) + ``` + +
+ +`map-number` + +Array.map() as number + + ```javascript +$1.map(Number) + ``` + +
+ +`filter-true` + +Array.filter() truthy + + ```javascript +$1.filter(Boolean) + ``` + +
+ +### Objects + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PrefixNameBody
+ +`oe` + +Object.entries + + ```javascript +Object.entries($0) + ``` + +
+ +`ofe` + +Object.fromEntries + + ```javascript +Object.fromEntries($0) + ``` + +
+ +`ok` + +Object.keys + + ```javascript +Object.keys($0) + ``` + +
+ +`ov` + +Object.values + + ```javascript +Object.values($0) + ``` + +
+ +### Returns + + + + + + + + + + + + + + + + + + + + + + + + + + +
PrefixNameBody
+ +`re` + +return + + ```javascript +return $0 + ``` + +
+ +`reo` + +return object + + ```javascript +return { + $0 +} + ``` + +
+ +`rei` + +return object inline + + ```javascript +return ({$0}) + ``` + +
+ +### Operators, Expressions, Literals +Grouping them all together for now + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PrefixNameBody
+ +`or` + +OR (||) + + ```javascript +|| $0 + ``` + +
+ +`and` + +AND (&&) + + ```javascript +&& $0 + ``` + +
+ +`nc` + +nullish coalescing (??) + + ```javascript +?? $0 + ``` + +
+ +`eq` + +strict equality (===) + + ```javascript +=== $0 + ``` + +
+ +`ore` + +logical OR expression + + ```javascript +${1:value} || ${0:value} + ``` + +
+ +`ande` + +logical AND expression + + ```javascript +${1:value} && ${0:value} + ``` + +
+ +`nce` + +nullish coalescing expression (??) + + ```javascript +${1:item} ?? ${0:default} + ``` + +
+ +`eqe` + +strict equality expression + + ```javascript +${1:value} === ${2:value} + ``` + +
+ +`ora` + +logical OR assignment (||=) + + ```javascript +${1:name} ||= ${0:default} + ``` + +
+ +`nca` + +nullish coalescing assignment (??=) + + ```javascript +${1:name} ??= ${0:default} + ``` + +
+ +`inc` + +addition assignment + + ```javascript +$1 += ${0:1} + ``` + +
+ +`sub` + +subtraction assignment + + ```javascript +$1 -= ${0:1} + ``` + +
+ +`mul` + +multiplication assignment + + ```javascript +$1 *= ${0:1} + ``` + +
+ +`div` + +division assignment + + ```javascript +$1 /= ${0:1} + ``` + +
+ +`ol` + +object literal + + ```javascript +{ $1: $0 } + ``` + +
+ +`al` + +array literal + + ```javascript +[$0] + ``` + +
+ +`tl` + +template literal + + ```javascript +`$0` + ``` + +
+ +`tlo` + +template literal operation + + ```javascript +${$1}$0 + ``` + +
+ +`tle` + +template literal expression + + ```javascript +`$1${$2}$3` + ``` + +
+ +### Console + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PrefixNameBody
+ +`cl` + +console.log + + ```javascript +console.log($0) + ``` + +
+ +`ci` + +console.info + + ```javascript +console.info($1) + ``` + +
+ +`cdi` + +console.dir + + ```javascript +console.dir($1) + ``` + +
+ +`ce` + +console.error + + ```javascript +console.error($1) + ``` + +
+ +`cw` + +console.warn + + ```javascript +console.warn($1) + ``` + +
+ +`ct` + +console.time + + ```javascript +console.time('$1') +$0 +console.timeEnd('$1') + ``` + +
+ +`ctb` + +console.table + + ```javascript +console.table($1) + ``` + +
+ +`clr` + +console.clear + + ```javascript +console.clear() + ``` + +
+ +`clm` + +console.log message + + ```javascript +console.log('$0') + ``` + +
+ +`clo` + +console.log object + + ```javascript +console.log({ $0 }) + ``` + +
+ +`clc` + +console.log clipboard + + ```javascript +console.log({ $CLIPBOARD }) + ``` + +
+ +`cll` + +console.log (labeled) + + ```javascript +console.log('$1 ->', $1$2) + ``` + +
+ +`cel` + +console.error (labeled) + + ```javascript +console.error('$1 ->', $1$2) + ``` + +
+ +`cwl` + +console.warn (labeled) + + ```javascript +console.warn('$1 ->', ${2:$1}) + ``` + +
+ +### Timers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PrefixNameBody
+ +`si` + +set interval + + ```javascript +setInterval(() => { + $0 +}, ${1:delay}) + ``` + +
+ +`st` + +set timeout + + ```javascript +setTimeout(() => { + $0 +}, ${1:delay}) + ``` + +
+ +`sim` + +set immediate + + ```javascript +setImmediate(() => { + $0 +}) + ``` + +
+ +`nt` + +process next tick + + ```javascript +process.nextTick(() => { + $0 +}) + ``` + +
+ +### JSON + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PrefixNameBody
+ +`jp` + +JSON parse + + ```javascript +JSON.parse(${1:json}) + ``` + +
+ +`js` + +JSON stringify + + ```javascript +JSON.stringify(${1:value}) + ``` + +
+ +`jsp` + +JSON stringify (pretty) + + ```javascript +JSON.stringify(${1:value}, null, 2) + ``` + +
+ +`jss` + +JSON.stringify if not string + + ```javascript +typeof ${1:value} === 'string' ? value : JSON.stringify($1) + ``` + +
+ +### DOM + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PrefixNameBody
+ +`qs` + +query selector + + ```javascript +${1:document}.querySelector('$2') + ``` + +
+ +`qsa` + +query selector all + + ```javascript +${1:document}.querySelectorAll('$2') + ``` + +
+ +`qsaa` + +query selector all as array + + ```javascript +[...${1:document}.querySelectorAll('$2')] + ``` + +
+ +`ael` + +event listener + + ```javascript +${1:document}.addEventListener('${2:click}', (e$3) => $0) + ``` + +
+ +`qsae` + +query selector with event listener + + ```javascript +${1:document}.querySelector('$2')?.addEventListener('${3:click}', (e$4) => $0) + ``` + +
+ +`gid` + +get element by id + + ```javascript +${1:document}.getElementById('$2') + ``` + +
+ +`on` + +event handler + + ```javascript +${1:emitter}.on('${2:event}', (${3:arguments}) => { + $0 +}) + ``` + +
+ +### Dates + + + + + + + + + + + + + + + + + + + + +
PrefixNameBody
+ +`nd` + +new Date() + + ```javascript +new Date($1) + ``` + +
+ +`now` + +Date.now() + + ```javascript +Date.now() + ``` + +
+ +### Testing + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + - - - + + + - - - + + + - - - + + + - - - + + + + +
PrefixNameBody
+ +`desc` + +describe + + ```javascript +describe('${1:description}', () => { + $0 +}) + ``` + +
+ +`cont` + +context + + ```javascript +context('${1:description}', () => { + $0 +}) + ``` + +
+ +`it` + +test (synchronous) + + ```javascript +it('${1:description}', () => { + $0 +}) + ``` + +
PrefixDescriptionBody + +`ita` + +test (asynchronous) + + ```javascript +it('${1:description}', async () => { + $0 +}) + ``` + +
+ +`itc` + +test (callback) + + ```javascript +it('${1:description}', (done) => { + $0 + done() +}) + ``` + +
+ - `c` +`bf` - - const - +before test suite ```javascript - const $0 +before(() => { + $0 +}) ``` -
+ - `l` +`bfe` - let +before each test ```javascript - let $0 +beforeEach(() => { + $0 +}) ``` -
+ - `ca` +`aft` - const assignment +after test suite ```javascript - const $1 = $0 +after(() => { + $0 +}) ``` -
+ - `la` +`afe` - let assignment +after each test ```javascript - let $1 = $0 +afterEach(() => { + $0 +}) ``` -
+ +### Types + + + + + + + - - - + + + + + + + + - - - + + + - - - + + + - - - + + + - - - + + + + + + + +
PrefixNameBody
+ - `cas` +`aia` - const string assignment +is array ```javascript - const $1 = '$0' +Array.isArray($0) ``` -
+ +`tof` + +typeof + + ```javascript +typeof ${1:value} === '${2|bigint,boolean,function,number,object,symbol,undefined|}' + ``` + +
+ - `car` +`iof` - const array assignment +instanceof ```javascript - const $1 = [$0] +${1:object} instanceof ${0:Class} ``` -
+ - `cao` +`isnil` - const object assignment +is nil ```javascript - const $1 = { $0 } +${1:value} == null ``` -
+ - `dob` +`nnil` - object destructuring +is not nil ```javascript - const { $0 } = ${1:object} +${1:value} != null ``` -
+ - `dar` +`isnan` - array destructuring +is NaN ```javascript - const [$0] = ${1:array} +isNan($0) ``` -
+ +`nnan` +is not NaN + + ```javascript +!isNan($0) + ``` + +
+### Misc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PrefixNameBody
+ +`us` + +'use strict' statement + + ```javascript +'use strict' + ``` + +
+ +`pse` + +process.server + + ```javascript +process.server + ``` + +
+ +`pcl` + +process.client + + ```javascript +process.client + ``` + +
+ +`env` + +env variable + + ```javascript +process.env.$0 + ``` + +
+ +`envv` + +env variable (vite) + + ```javascript +import.meta.env.$0 + ``` + +
+### Uncategorized +Will be sorted into appropriate categories in the future. + + + + + + + + + + + + + - + + + + + + + + + + + + + + - - - + + + - - - + + + - - - + + + + +
PrefixNameBody
+ +`uniq` + +array of unique values + + ```javascript +[...new Set(${0:array})] + ``` + +
PrefixDescriptionBody + +`pi` + +parse int + + ```javascript +parseInt(${1:value}, ${2|10,2,8,16|}) + ``` + +
+ +`pf` + +parse float + + ```javascript +parseFloat(${1:value}) + ``` + +
+ +`am` + +array merge + + ```javascript +[...${1:arr}$2] + ``` + +
+ - `if` +`om` - - if statement - +object merge ```javascript - if ($1) { - $2 - } +{ ...${1:object}$2 } ``` -
+ - `ifel` +`aat` - if/else statement +array.at ```javascript - if ($1) { - $2 - } else { - $3 - } +${1:items}.at(${2:0}) ``` -
+ - `ifei` +`seq` - if/else-if statement +sequence of 0..n ```javascript - if ($1) { - $2 - } else if ($3) { - $4 - } +[...Array(${1:length}).keys()] ``` -
+ + +## TypeScript specific +Only applied to .ts and .tsx files + +### Declarations + + + + + + + - - - + + + - - - + + + - - - + + + - - - + + + + +
PrefixNameBody
+ - `el` +`cat` - else statement +const assignment (typed) ```javascript - else { - $3 - } +const ${1:name}: ${2:string} = ${3:value} ``` -
+ - `ei` +`lat` - else if statement +let assignment (typed) ```javascript - else if ($1) { - $2 - } +let ${1:name}: ${2:string} = ${3:value} ``` -
+ - `ter` +`caat` - ternary operator +array assignment (typed) ```javascript - $1 ? $2 : $3 +const ${1:items}: ${2:string}[] = [$0] ``` -
+ - `tera` +`caot` - ternary expression assignment +object assignment (typed) ```javascript - const ${1:name} = $2 ? $3 : $4 +const ${1:name}: ${2:object} = { $0 } ``` -
+ +### Types + + + + + + + - - - + + + - - - + + + + - - - + + + + - - - + + + + - - - + + + +
PrefixNameBody
+ - `sw` +`int` - switch +interface ```javascript - switch ($1) { - case $2 : $3 - default: $0 - } +interface ${1:Model} { + $0 +} ``` -
+ - `sw` +`inte` - case +interface extends ```javascript - case ${1:value}: - $0 - break; +interface ${1:Model} extends ${2:Base} { + $0 +} ``` -
- - `try/catch` + + +`tp` - try/catch +type ```javascript - try { - $1 - } catch (error) { - $0 - } +type ${1:Model} = $0 ``` -
+ - `try/catch/finally` +`tpu` - try/catch/finally +type union ```javascript - try { - $1 - } catch (error) { - $2 - } finally { - $3 - } +type ${1:Model} = ${2:first} | ${3:second} ``` -
+ - `try/finally` +`tpi` - try/finally +type intersection ```javascript - try { - $1 - } finally { - $2 - } +type ${1:Model} = ${2:first} & ${3:second} ``` - -
+ + diff --git a/package.json b/package.json index 2c610cd..57e48d2 100644 --- a/package.json +++ b/package.json @@ -38,9 +38,8 @@ }, "scripts": { "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" + "generate": "deno run -A src/app.ts --snippets --docs", + "generate:snippets": "deno run -A src/app.ts --snippets" }, "contributes": { "snippets": [ diff --git a/src/app.ts b/src/app.ts index 85c509f..bc073eb 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,38 +1,43 @@ import { parse } from "./deps.ts"; -import { VscSnippetDefinition } from "./models/app.ts"; -import { variants } from "./snippets/app.ts"; -import { logTables } from "./utils/markdown.ts"; +import { generateDocs, populateDocsBlock } from "./docs-gen/snippets.ts"; +import { languages } from "./snippets/app.ts"; import { convertToVscSnippet, - generateSnippetsFile, + generateSnippets, groupSnippets, } from "./utils/snippets.ts"; const flags = parse(Deno.args, { - boolean: ["table", "snippets"], - default: { snippets: true }, + boolean: ["snippets", "docs"], + default: { snippets: false, docs: false }, }); -if (!flags.table && !flags.snippets) { - console.log("Please specify at least one flag: --table or --snippets"); +if (!flags.snippets && !flags.docs) { + console.log("Please specify at least one flag: --snippets or --docs"); } else { - variants.forEach((variant) => { - const categorizedVscSnippets: VscSnippetDefinition[] = variant - .snippetsWithMeta.map( - (item) => ({ - ...item, - snippets: convertToVscSnippet(item.snippets), - }), - ); + if (flags.snippets) { + console.log("\nGenerating snippets..."); + languages.forEach((language) => { + const categorizedVscSnippets = language + .snippetDefinitions.map( + (item) => { + const snippets = convertToVscSnippet(item.snippets); + return { ...item, snippets }; + }, + ); - if (flags.table) { - logTables(variant.label, categorizedVscSnippets); - } - if (flags.snippets) { const variantVscSnippet = groupSnippets( categorizedVscSnippets.map((item) => item.snippets), ); - generateSnippetsFile(variant.extension, variantVscSnippet); - } - }); + generateSnippets(language.fileExtension, variantVscSnippet); + }); + } + + // TODO: probably better to make it generate from vsc json + // pass in meta, and snippets converted to vsc format + if (flags.docs) { + console.log("\nGenerating docs..."); + const docs = generateDocs(languages); + populateDocsBlock(docs); + } } diff --git a/src/deps.ts b/src/deps.ts index e289bc0..8c108ac 100644 --- a/src/deps.ts +++ b/src/deps.ts @@ -1,3 +1,10 @@ -export { parse } from "https://deno.land/std@0.168.0/flags/mod.ts"; export { ensureDirSync } from "https://deno.land/std@0.141.0/fs/ensure_dir.ts"; +export { parse } from "https://deno.land/std@0.168.0/flags/mod.ts"; export { markdownTable } from "https://esm.sh/markdown-table@3"; + +import replace, * as _replace from "npm:replace-in-file"; + +// Fix types +export const replaceInFile = replace as unknown as ( + config: _replace.ReplaceInFileConfig, +) => Promise<_replace.ReplaceResult[]>; diff --git a/src/docs-gen/snippets.ts b/src/docs-gen/snippets.ts new file mode 100644 index 0000000..130a737 --- /dev/null +++ b/src/docs-gen/snippets.ts @@ -0,0 +1,100 @@ +import { replaceInFile } from "../deps.ts"; +import { XSnippetDefinition, XSnippetVariant } from "../models/app.ts"; +import { + $col, + $colCode, + $colCodeBlock, + $row, + $table, + htmlComment, + joinByDoubleNewLine, + joinByNewLine, +} from "./table-html.ts"; + +type SnippetRow = { + prefix: string; + name: string; + body: string | string[]; +}; + +const snippetRow = ({ prefix, name, body }: SnippetRow) => { + const parsedBody = Array.isArray(body) ? body.join("\n") : body; + const cols = joinByNewLine([ + $colCode(prefix), + $col(name), + $colCodeBlock(parsedBody), + ]); + + return $row(cols); +}; + +const generateSnippetTable = (items: SnippetRow[]) => { + const headings = ["Prefix", "Name", "Body"]; + const rows = items.map(snippetRow); + + return $table(headings, rows); +}; + +const generateSnippetSection = ( + { meta, snippets }: XSnippetDefinition, +) => { + const title = `### ${meta.title}`; + const description = meta.description ?? ""; + const table = generateSnippetTable( + Object.entries(snippets).map(([prefix, value]) => ({ + ...value, + prefix, + })), + ); + + return joinByNewLine([title, description, table, ""]); +}; + +const generateVariantSection = (variant: XSnippetVariant) => { + const title = `## ${variant.label}`; + const description = variant.description ?? ""; + const sections = variant.snippetDefinitions.map(generateSnippetSection); + + return joinByNewLine([title, description, "", ...sections]); +}; + +export const generateDocs = (variants: XSnippetVariant[]) => { + return joinByDoubleNewLine(variants.map(generateVariantSection)); +}; + +const docsGenId = "docs-gen"; +const docsGen = { + start: htmlComment(`START:${docsGenId}`), + end: htmlComment(`END:${docsGenId}`), +}; + +const docsBlock = (s: string) => { + return joinByNewLine([docsGen.start, s, docsGen.end]); +}; + +export const populateDocsBlock = async (input: string) => { + const regex = new RegExp( + `${docsGen.start}[\\s\\S]*?${docsGen.end}`, + "g", + ); + + const file = "./README.md"; + const options = { + files: file, + from: regex, + to: docsBlock(input), + }; + + try { + const results = await replaceInFile(options); + const readmeResult = results.find((r) => r.file === file); + + if (readmeResult?.hasChanged) { + console.log("✅ README updated"); + } else { + console.log("👍 README already up to date"); + } + } catch (error) { + console.error("Error while updating README:", error); + } +}; diff --git a/src/docs-gen/table-html.ts b/src/docs-gen/table-html.ts new file mode 100644 index 0000000..c93ca6a --- /dev/null +++ b/src/docs-gen/table-html.ts @@ -0,0 +1,53 @@ +export const joinInline = (s: string[]) => s.join(""); +export const joinByNewLine = (s: string[]) => s.join("\n"); +export const joinByDoubleNewLine = (s: string[]) => s.join("\n\n"); +export const indent = (s: string, size = 2) => `${" ".repeat(size)}${s}`; +export const escapeBackticks = (s: string) => s.replace(/`/g, "\`"); + +export const htmlComment = (s: string) => ``; +export const code = (s: string) => { + return escapeBackticks("`" + s + "`"); +}; + +export const codeBlock = (s: string, lang = "javascript") => { + return joinByNewLine([ + `${indent(escapeBackticks("```" + lang))}`, + s, + `${indent(escapeBackticks("```"))}`, + ]); +}; + +export const $row = (s: string) => { + return joinByNewLine(["", "", s, ""]); +}; + +export const $colDoubleNewLine = ( + s: string, + cb?: (input: string) => string, +) => { + return joinByDoubleNewLine(["", cb?.(s) ?? s, ""]); +}; + +export const $col = (s: string) => { + return `${s}`; +}; +export const $colCode = (s: string) => { + return $colDoubleNewLine(s, code); +}; +export const $colCodeBlock = (s: string) => { + return $colDoubleNewLine(s, codeBlock); +}; + +export const $headerRow = (headers: string[]) => { + const cols = joinByNewLine(headers.map($col)); + return $row(cols); +}; + +export const $table = (headings: string[], rows: string[]) => { + return joinByNewLine([ + "", + $headerRow(headings), + joinByNewLine(rows), + "
", + ]); +}; diff --git a/src/utils/markdown.ts b/src/docs-gen/table-md.ts similarity index 90% rename from src/utils/markdown.ts rename to src/docs-gen/table-md.ts index ac7c422..f178231 100644 --- a/src/utils/markdown.ts +++ b/src/docs-gen/table-md.ts @@ -1,6 +1,6 @@ -import { VscSnippetDefinition, VscSnippetDict } from "../models/app.ts"; import { markdownTable } from "../deps.ts"; -import { replaceSymbol } from "./general.ts"; +import { VscSnippetDefinition, VscSnippetDict } from "../models/app.ts"; +import { replaceSymbol } from "../utils/general.ts"; export const code = (str: string) => `\`${str}\``; @@ -13,7 +13,8 @@ export const serializeForMarkdown = (str: string) => { .replace(/\t/g, "  ") .replace(/\|/g, "\\|"); } - // TODO: dont remove | when it is in `` + // TODO: don't remove | when it is in code block + // but it differs for every .md implementation return str.replace(/\|/g, "\\|"); }; diff --git a/src/models/app.ts b/src/models/app.ts index 4022fce..e9ec6ce 100644 --- a/src/models/app.ts +++ b/src/models/app.ts @@ -19,3 +19,11 @@ export type GenericSnippetDictWithMeta = { }; export type XSnippetDefinition = GenericSnippetDictWithMeta; export type VscSnippetDefinition = GenericSnippetDictWithMeta; + +export type XSnippetVariant = { + label: string; + description?: string; + language: string; + fileExtension: string; + snippetDefinitions: XSnippetDefinition[]; +}; diff --git a/src/snippets/app.ts b/src/snippets/app.ts index c088aa5..94cec68 100644 --- a/src/snippets/app.ts +++ b/src/snippets/app.ts @@ -1,24 +1,19 @@ -import { XSnippetDefinition } from "../models/app.ts"; +import { XSnippetVariant } from "../models/app.ts"; import { javascript } from "./js/app.ts"; import { typescript } from "./ts/app.ts"; -type SnippetVariant = { - label: string; - language: string; - extension: string; - snippetsWithMeta: XSnippetDefinition[]; -}; -export const variants: SnippetVariant[] = [ +export const languages: XSnippetVariant[] = [ { label: "Snippets", language: "javascript", - extension: "js", - snippetsWithMeta: javascript, + fileExtension: "js", + snippetDefinitions: javascript, }, { label: "TypeScript specific", + description: "Only applied to .ts and .tsx files", language: "typescript", - extension: "ts", - snippetsWithMeta: typescript, + fileExtension: "ts", + snippetDefinitions: typescript, }, ]; diff --git a/src/utils/snippets.ts b/src/utils/snippets.ts index 33b83f0..4cb3219 100644 --- a/src/utils/snippets.ts +++ b/src/utils/snippets.ts @@ -17,13 +17,21 @@ export const groupSnippets = (dicts: VscSnippetDict[]) => { })); }; -export const generateSnippetsFile = (name: string, data: VscSnippetDict) => { +export const generateSnippets = (name: string, data: VscSnippetDict) => { const path = "./dist"; - ensureDirSync(path); - const file = `${path}/${name}.code-snippets`; + const fileName = `${name}.code-snippets`; + try { + ensureDirSync(path); + const file = `${path}/${fileName}`; - Deno.writeTextFileSync( - file, - JSON.stringify(data, null, 2), - ); + Deno.writeTextFileSync( + file, + JSON.stringify(data, null, 2), + ); + + console.log(`✅ ${fileName}`); + } catch (error) { + console.log(`❌ ${fileName}`); + console.error(error); + } };