UNPKG

30s

Version:

A command-line application for 30 seconds of code snippets

179 lines (151 loc) 9.44 kB
#!/usr/bin/env node 'use strict'; var _reduce = require('ramda/src/reduce'); require('core-js/modules/es.array.iterator.js'); var program = require('commander'); var snippets = require('../lib/snippets.json'); var _map = require('ramda/src/map'); var _prop = require('ramda/src/prop'); var _descend = require('ramda/src/descend'); var _sort = require('ramda/src/sort'); var _lensProp = require('ramda/src/lensProp'); var _set = require('ramda/src/set'); var _compose = require('ramda/src/compose'); var _multiply = require('ramda/src/multiply'); var _always = require('ramda/src/always'); var _ifElse = require('ramda/src/ifElse'); var _divide = require('ramda/src/divide'); var _flip = require('ramda/src/flip'); var _any = require('ramda/src/any'); var _filter = require('ramda/src/filter'); var _find = require('ramda/src/find'); require('core-js/modules/es.regexp.constructor.js'); require('core-js/modules/es.regexp.exec.js'); require('core-js/modules/es.string.replace.js'); var _endsWith = require('ramda/src/endsWith'); var _startsWith = require('ramda/src/startsWith'); var _anyPass = require('ramda/src/anyPass'); var _replace = require('ramda/src/replace'); var _is = require('ramda/src/is'); var _pick = require('ramda/src/pick'); var _toPairs = require('ramda/src/toPairs'); var _join = require('ramda/src/join'); var chalk = require('chalk'); var cliHighlight = require('cli-highlight'); var clipboardy = require('clipboardy'); var marked = require('marked'); var Renderer = require('marked-terminal'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var _reduce__default = /*#__PURE__*/_interopDefaultLegacy(_reduce); var program__default = /*#__PURE__*/_interopDefaultLegacy(program); var snippets__default = /*#__PURE__*/_interopDefaultLegacy(snippets); var _map__default = /*#__PURE__*/_interopDefaultLegacy(_map); var _prop__default = /*#__PURE__*/_interopDefaultLegacy(_prop); var _descend__default = /*#__PURE__*/_interopDefaultLegacy(_descend); var _sort__default = /*#__PURE__*/_interopDefaultLegacy(_sort); var _lensProp__default = /*#__PURE__*/_interopDefaultLegacy(_lensProp); var _set__default = /*#__PURE__*/_interopDefaultLegacy(_set); var _compose__default = /*#__PURE__*/_interopDefaultLegacy(_compose); var _multiply__default = /*#__PURE__*/_interopDefaultLegacy(_multiply); var _always__default = /*#__PURE__*/_interopDefaultLegacy(_always); var _ifElse__default = /*#__PURE__*/_interopDefaultLegacy(_ifElse); var _divide__default = /*#__PURE__*/_interopDefaultLegacy(_divide); var _flip__default = /*#__PURE__*/_interopDefaultLegacy(_flip); var _any__default = /*#__PURE__*/_interopDefaultLegacy(_any); var _filter__default = /*#__PURE__*/_interopDefaultLegacy(_filter); var _find__default = /*#__PURE__*/_interopDefaultLegacy(_find); var _endsWith__default = /*#__PURE__*/_interopDefaultLegacy(_endsWith); var _startsWith__default = /*#__PURE__*/_interopDefaultLegacy(_startsWith); var _anyPass__default = /*#__PURE__*/_interopDefaultLegacy(_anyPass); var _replace__default = /*#__PURE__*/_interopDefaultLegacy(_replace); var _is__default = /*#__PURE__*/_interopDefaultLegacy(_is); var _pick__default = /*#__PURE__*/_interopDefaultLegacy(_pick); var _toPairs__default = /*#__PURE__*/_interopDefaultLegacy(_toPairs); var _join__default = /*#__PURE__*/_interopDefaultLegacy(_join); var chalk__default = /*#__PURE__*/_interopDefaultLegacy(chalk); var marked__default = /*#__PURE__*/_interopDefaultLegacy(marked); var Renderer__default = /*#__PURE__*/_interopDefaultLegacy(Renderer); var version = "1.5.46"; const enforceSingleNewLine = x => _is__default["default"](String, x) ? _compose__default["default"](_replace__default["default"](/[\r\n]+/g, '\n'), _replace__default["default"](/[\r\n]*$/, ''))(x) : x; const randomNumberInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; const startsOrEndsWith = (val, query) => _anyPass__default["default"]([_startsWith__default["default"], _endsWith__default["default"]])(query, val); const fuzzyMatch = query => x => new RegExp(query).test(x.id); const getSnippet = (snippets, id) => _find__default["default"](x => x.id === id, snippets); const getSnippetsByTag = (snippets, id) => _filter__default["default"](x => _any__default["default"](y => y === id, x.tags), snippets); const randomSnippet = snippets => snippets[randomNumberInRange(0, snippets.length - 1)]; const computeRelevance = (id, query) => { const base = query.length * 10; const diffInChars = id.replace(query, '').length + 1; const divideByDiffInChars = _flip__default["default"](_divide__default["default"])(diffInChars); const multi = _ifElse__default["default"](_always__default["default"](startsOrEndsWith(id, query)), _multiply__default["default"](0.75), _multiply__default["default"](0.5)); if (id === query) return base; return _compose__default["default"](divideByDiffInChars, multi)(base); }; const setSearchRelevance = query => x => _set__default["default"](_lensProp__default["default"]('relevance'), computeRelevance(x.id, query), x); const searchSnippets = (snippets, query) => _compose__default["default"](_sort__default["default"](_descend__default["default"](_prop__default["default"]('relevance'))), _map__default["default"](setSearchRelevance(query)), _filter__default["default"](fuzzyMatch(query)))(snippets); marked__default["default"].setOptions({ renderer: new Renderer__default["default"]() }); const colorizedPrint = x => { const printMap = { code: y => cliHighlight.highlight(y, { language: 'javascript' }), description: y => enforceSingleNewLine(marked__default["default"](y)), example: y => cliHighlight.highlight(y, { language: 'javascript' }), id: y => chalk__default["default"].magenta.bold(y), tags: _compose__default["default"](chalk__default["default"].gray.italic, _join__default["default"](', ')) }; const print = y => _compose__default["default"](_replace__default["default"](/\n$/, ''), _join__default["default"]('\n'), _map__default["default"](([k, v]) => printMap[k](v) + (k === 'id' ? '' : '\n')), _toPairs__default["default"])(y); return _compose__default["default"](_join__default["default"]('\n\n'), _map__default["default"](print))(x); }; const printSnippet = ({ cp, layout, json }, x) => { const arr = _is__default["default"](Array, x) ? x : [x]; const layoutMap = { c: 'code', d: 'description', e: 'example', i: 'id', t: 'tags' }; const keysByLayout = _map__default["default"](k => layoutMap[k])(Array.from(layout || 'itced')); if (x == null) return ''; if (cp) { clipboardy.writeSync(_compose__default["default"](_join__default["default"]('\n'), _map__default["default"](_prop__default["default"]('code')))(arr)); } const pickedSnippet = _map__default["default"](_pick__default["default"](keysByLayout))(arr); return _compose__default["default"](console.log, json ? JSON.stringify : colorizedPrint)(pickedSnippet); }; const isTest = process.env.NODE_ENV === 'test'; const actions = { random: opts => printSnippet(opts, randomSnippet(snippets__default["default"])), search: (opts, query) => printSnippet(opts, searchSnippets(snippets__default["default"], query)), tag: (opts, id) => printSnippet(opts, getSnippetsByTag(snippets__default["default"], id)), view: (opts, id) => printSnippet(opts, getSnippet(snippets__default["default"], id)) }; const addCommand = settings => _reduce__default["default"]((acc, [key, ...args]) => acc[key](...args), program__default["default"], settings); const addAction = action => ['action', (...args) => ((input, opts = {}) => { if (!input) return program__default["default"].outputHelp(); return isTest ? // NOTE: Commander.js sadly does not include a way to hook onto given // actions for integration testing. We solve this by outputting state // when NODE_ENV is test. console.log(JSON.stringify([action, input, !!opts.cp, !!opts.json, opts.layout])) : actions[action](opts, input); })(...(action === 'random' ? [true, args[0]] : args))]; const commonOptions = [['option', '-c, --cp', 'copy code to clipboard', false], ['option', '-j, --json', 'output in json format', false], ['option', '-l, --layout <layout>', 'print in specified layout', 'itced']]; program__default["default"].version(version); addCommand([['command', 'r'], ['alias', 'random'], ['description', ['view random snippet']], ...commonOptions, addAction('random')]); addCommand([['command', 's [query]'], ['alias', 'search'], ['description', ['fuzzy search snippets by id']], ...commonOptions, addAction('search')]); addCommand([['command', 't [id]'], ['alias', 'tag'], ['description', ['view snippets by tag']], ...commonOptions, addAction('tag')]); addCommand([['command', 'v [id]'], ['alias', 'view'], ['description', ['view snippet with id']], ...commonOptions, addAction('view')]); addCommand([['command', '* [id]'], ['description', ['view snippet with id']], addAction('view')]); program__default["default"].on('--help', () => console.log(['', 'Examples:', ' 30s head', ' 30s v head', ' 30s view head', '', ' 30s r', ' 30s random', '', ' 30s s -j flatten', ' 30s search --json flatten', '', ' 30s t -l ic array', ' 30s tag --layout ic array'].join('\n'))); program__default["default"].parse(process.argv); if (process.argv.length <= 2) { program__default["default"].outputHelp(); }