30s
Version:
A command-line application for 30 seconds of code snippets
179 lines (151 loc) • 9.44 kB
JavaScript
;
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();
}