diff --git a/src/common/highlight/bash.js b/src/common/highlight/bash.js deleted file mode 100644 index 17c6e4998..000000000 --- a/src/common/highlight/bash.js +++ /dev/null @@ -1,153 +0,0 @@ -/** - * @param {string} value - * @returns {RegExp} - * */ - -/** - * @param {RegExp | string } re - * @returns {string} - */ -function source(re) { - if (!re) return null - if (typeof re === 'string') return re - - return re.source -} - -/** - * @param {...(RegExp | string) } args - * @returns {string} - */ -function concat(...args) { - const joined = args.map((x) => source(x)).join('') - return joined -} - -/* -Language: Bash -Author: vah -Contributrors: Benjamin Pannell -Website: https://www.gnu.org/software/bash/ -Category: common -*/ - -/** @type LanguageFn */ -export default function bash(hljs) { - const VAR = {} - const BRACED_VAR = { - begin: /\$\{/, - end: /\}/, - contains: [ - 'self', - { - begin: /:-/, - contains: [VAR], - }, // default values - ], - } - Object.assign(VAR, { - className: 'variable', - variants: [ - { - begin: concat( - /\$[\w\d#@][\w\d_]*/, - // negative look-ahead tries to avoid matching patterns that are not - // Perl at all like $ident$, @ident@, etc. - `(?![\\w\\d])(?![$])`, - ), - }, - BRACED_VAR, - ], - }) - - const SUBST = { - className: 'subst', - begin: /\$\(/, - end: /\)/, - contains: [hljs.BACKSLASH_ESCAPE], - } - const HERE_DOC = { - begin: /<<-?\s*(?=\w+)/, - starts: { - contains: [ - hljs.END_SAME_AS_BEGIN({ - begin: /(\w+)/, - end: /(\w+)/, - className: 'string', - }), - ], - }, - } - const QUOTE_STRING = { - className: 'string', - begin: /"/, - end: /"/, - contains: [hljs.BACKSLASH_ESCAPE, VAR, SUBST], - } - SUBST.contains.push(QUOTE_STRING) - const ESCAPED_QUOTE = { - className: '', - begin: /\\"/, - } - const APOS_STRING = { - className: 'string', - begin: /'/, - end: /'/, - } - const ARITHMETIC = { - begin: /\$\(\(/, - end: /\)\)/, - contains: [{ begin: /\d+#[0-9a-f]+/, className: 'number' }, hljs.NUMBER_MODE, VAR], - } - const SH_LIKE_SHELLS = ['fish', 'bash', 'zsh', 'sh', 'csh', 'ksh', 'tcsh', 'dash', 'scsh'] - const KNOWN_SHEBANG = hljs.SHEBANG({ - binary: `(${SH_LIKE_SHELLS.join('|')})`, - relevance: 10, - }) - const FUNCTION = { - className: 'function', - begin: /\w[\w\d_]*\s*\(\s*\)\s*\{/, - returnBegin: true, - contains: [hljs.inherit(hljs.TITLE_MODE, { begin: /\w[\w\d_]*/ })], - relevance: 0, - } - - return { - name: 'Bash', - aliases: ['sh', 'zsh'], - keywords: { - $pattern: /\b[a-z._-]+\b/, - keyword: 'if then else elif fi for while in do done case esac function', - literal: 'true false', - built_in: - // Shell built-ins - // http://www.gnu.org/software/bash/manual/html_node/Shell-Builtin-Commands.html - 'break cd continue eval exec exit export getopts hash pwd readonly return shift test times ' + - 'trap umask unset ' + - // Bash built-ins - 'alias bind builtin caller command declare echo enable help let local logout mapfile printf ' + - 'read readarray source type typeset ulimit unalias docker tar wget ' + - // Shell modifiers - 'set shopt ' + - // Zsh built-ins - 'autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles ' + - 'compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate ' + - 'fc fg float functions getcap getln history integer jobs kill limit log noglob popd print ' + - 'pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit ' + - 'unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof ' + - 'zpty zregexparse zsocket zstyle ztcp', - }, - contains: [ - KNOWN_SHEBANG, // to catch known shells and boost relevancy - hljs.SHEBANG(), // to catch unknown shells but still highlight the shebang - FUNCTION, - ARITHMETIC, - hljs.HASH_COMMENT_MODE, - HERE_DOC, - QUOTE_STRING, - ESCAPED_QUOTE, - APOS_STRING, - VAR, - ], - } -} diff --git a/src/common/highlight/bash.ts b/src/common/highlight/bash.ts new file mode 100644 index 000000000..8bcb4ae49 --- /dev/null +++ b/src/common/highlight/bash.ts @@ -0,0 +1,14 @@ +import bash from 'highlight.js/lib/languages/bash' +import { isString } from 'lodash' + +export default (hljs: any) => { + const ret = bash?.(hljs) + if (ret?.keywords?.built_in && isString(ret.keywords.built_in)) { + ret.keywords.built_in = ret.keywords.built_in.replace( + 'read readarray source type typeset ulimit unalias ', + ($0: string) => `${$0}docker tar wget `, + ) + } + + return ret +} diff --git a/src/common/highlight/sql.js b/src/common/highlight/sql.js deleted file mode 100644 index fb70fa2a3..000000000 --- a/src/common/highlight/sql.js +++ /dev/null @@ -1,685 +0,0 @@ -/** - * @param {string} value - * @returns {RegExp} - * */ - -/** - * @param {RegExp | string } re - * @returns {string} - */ -function source(re) { - if (!re) return null - if (typeof re === 'string') return re - - return re.source -} - -/** - * @param {...(RegExp | string) } args - * @returns {string} - */ -function concat(...args) { - const joined = args.map((x) => source(x)).join('') - return joined -} - -/** - * Any of the passed expressions may match - * - * Creates a huge this | this | that | that match - * @param {(RegExp | string)[] } args - * @returns {string} - */ -function either(...args) { - const joined = '(' + args.map((x) => source(x)).join('|') + ')' - return joined -} - -/* - Language: SQL - Website: https://en.wikipedia.org/wiki/SQL - Category: common, database - */ - -function sql(hljs) { - const COMMENT_MODE = hljs.COMMENT('--', '$') - const STRING = { - className: 'string', - variants: [ - { - begin: /'/, - end: /'/, - contains: [{ begin: /''/ }], - }, - ], - } - const QUOTED_IDENTIFIER = { - begin: /"/, - end: /"/, - contains: [{ begin: /""/ }], - } - - const LITERALS = [ - 'true', - 'false', - // Not sure it's correct to call NULL literal, and clauses like IS [NOT] NULL look strange that way. - // "null", - 'unknown', - ] - - const MULTI_WORD_TYPES = ['double precision', 'large object', 'with timezone', 'without timezone'] - - const TYPES = [ - 'bigint', - 'binary', - 'blob', - 'boolean', - 'char', - 'character', - 'clob', - 'date', - 'dec', - 'decfloat', - 'decimal', - 'float', - 'int', - 'integer', - 'interval', - 'nchar', - 'nclob', - 'national', - 'numeric', - 'real', - 'row', - 'smallint', - 'time', - 'timestamp', - 'varchar', - 'varying', // modifier (character varying) - 'varbinary', - ] - - const NON_RESERVED_WORDS = ['add', 'asc', 'collation', 'desc', 'final', 'first', 'last', 'view'] - - // https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#reserved-word - const RESERVED_WORDS = [ - 'abs', - 'acos', - 'all', - 'allocate', - 'alter', - 'and', - 'any', - 'are', - 'array', - 'array_agg', - 'array_max_cardinality', - 'as', - 'asensitive', - 'asin', - 'asymmetric', - 'at', - 'atan', - 'atomic', - 'authorization', - 'avg', - 'begin', - 'begin_frame', - 'begin_partition', - 'between', - 'bigint', - 'binary', - 'blob', - 'boolean', - 'both', - 'by', - 'call', - 'called', - 'cardinality', - 'cascaded', - 'case', - 'cast', - 'ceil', - 'ceiling', - 'char', - 'char_length', - 'character', - 'character_length', - 'check', - 'classifier', - 'clob', - 'close', - 'coalesce', - 'collate', - 'collect', - 'column', - 'commit', - 'condition', - 'connect', - 'constraint', - 'contains', - 'convert', - 'copy', - 'corr', - 'corresponding', - 'cos', - 'cosh', - 'count', - 'covar_pop', - 'covar_samp', - 'create', - 'cross', - 'cube', - 'cume_dist', - 'current', - 'current_catalog', - 'current_date', - 'current_default_transform_group', - 'current_path', - 'current_role', - 'current_row', - 'current_schema', - 'current_time', - 'current_timestamp', - 'current_path', - 'current_role', - 'current_transform_group_for_type', - 'current_user', - 'cursor', - 'cycle', - 'date', - 'day', - 'deallocate', - 'dec', - 'decimal', - 'decfloat', - 'declare', - 'default', - 'define', - 'delete', - 'dense_rank', - 'deref', - 'describe', - 'deterministic', - 'disconnect', - 'distinct', - 'do', - 'double', - 'drop', - 'dynamic', - 'each', - 'element', - 'else', - 'empty', - 'end', - 'end_frame', - 'end_partition', - 'end-exec', - 'equals', - 'escape', - 'every', - 'except', - 'exec', - 'execute', - 'exists', - 'exp', - 'external', - 'extract', - 'false', - 'fetch', - 'filter', - 'first_value', - 'float', - 'floor', - 'for', - 'foreach', - 'foreign', - 'frame_row', - 'free', - 'from', - 'full', - 'function', - 'fusion', - 'get', - 'global', - 'grant', - 'group', - 'grouping', - 'groups', - 'having', - 'hold', - 'hour', - 'identity', - 'in', - 'incase', - 'indicator', - 'initial', - 'inner', - 'inout', - 'insensitive', - 'insert', - 'int', - 'integer', - 'intersect', - 'intersection', - 'interval', - 'into', - 'is', - 'join', - 'json_array', - 'json_arrayagg', - 'json_exists', - 'json_object', - 'json_objectagg', - 'json_query', - 'json_table', - 'json_table_primitive', - 'json_value', - 'lag', - 'language', - 'large', - 'last_value', - 'lateral', - 'lead', - 'leading', - 'left', - 'like', - 'like_regex', - 'listagg', - 'ln', - 'local', - 'localtime', - 'localtimestamp', - 'log', - 'log10', - 'lower', - 'match', - 'match_number', - 'match_recognize', - 'matches', - 'max', - 'member', - 'merge', - 'method', - 'min', - 'minute', - 'mod', - 'modifies', - 'module', - 'month', - 'multiset', - 'national', - 'natural', - 'nchar', - 'nclob', - 'new', - 'no', - 'none', - 'normalize', - 'not', - 'nth_value', - 'ntile', - 'null', - 'nullif', - 'numeric', - 'octet_length', - 'occurrences_regex', - 'of', - 'offset', - 'old', - 'omit', - 'on', - 'one', - 'only', - 'open', - 'or', - 'order', - 'out', - 'outer', - 'over', - 'overlaps', - 'overlay', - 'parameter', - 'partition', - 'pattern', - 'per', - 'percent', - 'percent_rank', - 'percentile_cont', - 'percentile_disc', - 'period', - 'portion', - 'position', - 'position_regex', - 'power', - 'precedes', - 'precision', - 'prepare', - 'primary', - 'procedure', - 'ptf', - 'range', - 'rank', - 'reads', - 'real', - 'recursive', - 'ref', - 'references', - 'referencing', - 'regr_avgx', - 'regr_avgy', - 'regr_count', - 'regr_intercept', - 'regr_r2', - 'regr_slope', - 'regr_sxx', - 'regr_sxy', - 'regr_syy', - 'release', - 'result', - 'return', - 'returns', - 'revoke', - 'right', - 'rollback', - 'rollup', - 'row', - 'row_number', - 'rows', - 'running', - 'savepoint', - 'scope', - 'scroll', - 'search', - 'second', - 'seek', - 'select', - 'sensitive', - 'session_user', - 'set', - 'show', - 'similar', - 'sin', - 'sinh', - 'skip', - 'smallint', - 'some', - 'specific', - 'specifictype', - 'sql', - 'sqlexception', - 'sqlstate', - 'sqlwarning', - 'sqrt', - 'start', - 'static', - 'stddev_pop', - 'stddev_samp', - 'submultiset', - 'subset', - 'substring', - 'substring_regex', - 'succeeds', - 'sum', - 'symmetric', - 'system', - 'system_time', - 'system_user', - 'table', - 'tablesample', - 'tan', - 'tanh', - 'then', - 'time', - 'timestamp', - 'timezone_hour', - 'timezone_minute', - 'to', - 'trailing', - 'translate', - 'translate_regex', - 'translation', - 'treat', - 'trigger', - 'trim', - 'trim_array', - 'true', - 'truncate', - 'uescape', - 'union', - 'unique', - 'unknown', - 'unnest', - 'update ', - 'upper', - 'user', - 'using', - 'value', - 'values', - 'value_of', - 'var_pop', - 'var_samp', - 'varbinary', - 'varchar', - 'varying', - 'versioning', - 'when', - 'whenever', - 'where', - 'width_bucket', - 'window', - 'with', - 'within', - 'without', - 'year', - ] - - // these are reserved words we have identified to be functions - // and should only be highlighted in a dispatch-like context - // ie, array_agg(...), etc. - const RESERVED_FUNCTIONS = [ - 'abs', - 'acos', - 'array_agg', - 'asin', - 'atan', - 'avg', - 'cast', - 'ceil', - 'ceiling', - 'coalesce', - 'corr', - 'cos', - 'cosh', - 'count', - 'covar_pop', - 'covar_samp', - 'cume_dist', - 'dense_rank', - 'deref', - 'element', - 'exp', - 'extract', - 'first_value', - 'floor', - 'json_array', - 'json_arrayagg', - 'json_exists', - 'json_object', - 'json_objectagg', - 'json_query', - 'json_table', - 'json_table_primitive', - 'json_value', - 'lag', - 'last_value', - 'lead', - 'listagg', - 'ln', - 'log', - 'log10', - 'lower', - 'max', - 'min', - 'mod', - 'nth_value', - 'ntile', - 'nullif', - 'percent_rank', - 'percentile_cont', - 'percentile_disc', - 'position', - 'position_regex', - 'power', - 'rank', - 'regr_avgx', - 'regr_avgy', - 'regr_count', - 'regr_intercept', - 'regr_r2', - 'regr_slope', - 'regr_sxx', - 'regr_sxy', - 'regr_syy', - 'row_number', - 'sin', - 'sinh', - 'sqrt', - 'stddev_pop', - 'stddev_samp', - 'substring', - 'substring_regex', - 'sum', - 'tan', - 'tanh', - 'translate', - 'translate_regex', - 'treat', - 'trim', - 'trim_array', - 'unnest', - 'upper', - 'value_of', - 'var_pop', - 'var_samp', - 'width_bucket', - ] - - // these functions can - const POSSIBLE_WITHOUT_PARENS = [ - 'current_catalog', - 'current_date', - 'current_default_transform_group', - 'current_path', - 'current_role', - 'current_schema', - 'current_transform_group_for_type', - 'current_user', - 'session_user', - 'system_time', - 'system_user', - 'current_time', - 'localtime', - 'current_timestamp', - 'localtimestamp', - ] - - // those exist to boost relevance making these very - // "SQL like" keyword combos worth +1 extra relevance - const COMBOS = [ - 'create table', - 'insert into', - 'primary key', - 'foreign key', - 'not null', - 'alter table', - 'add constraint', - 'grouping sets', - 'on overflow', - 'character set', - 'respect nulls', - 'ignore nulls', - 'nulls first', - 'nulls last', - 'depth first', - 'breadth first', - ] - - const FUNCTIONS = RESERVED_FUNCTIONS - - const KEYWORDS = [...RESERVED_WORDS, ...NON_RESERVED_WORDS].filter((keyword) => { - return !RESERVED_FUNCTIONS.includes(keyword) - }) - - const VARIABLE = { - className: 'variable', - begin: /@[a-z0-9]+/, - } - - const OPERATOR = { - className: 'operator', - begin: /[-+*/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?/, - relevance: 0, - } - - const FUNCTION_CALL = { - begin: concat(/\b/, either(...FUNCTIONS), /\s*\(/), - keywords: { - built_in: FUNCTIONS, - }, - } - - // keywords with less than 3 letters are reduced in relevancy - function reduceRelevancy(list, { exceptions, when } = {}) { - const qualifyFn = when - exceptions = exceptions || [] - return list.map((item) => { - if (item.match(/\|\d+$/) || exceptions.includes(item)) { - return item - } else if (qualifyFn(item)) { - return `${item}|0` - } else { - return item - } - }) - } - - return { - name: 'SQL', - case_insensitive: true, - // does not include {} or HTML tags ` x.length < 3 }), - literal: LITERALS, - type: TYPES, - built_in: POSSIBLE_WITHOUT_PARENS, - }, - contains: [ - { - begin: either(...COMBOS), - keywords: { - $pattern: /[\w.]+/, - keyword: KEYWORDS.concat(COMBOS), - literal: LITERALS, - type: TYPES, - }, - }, - { - className: 'type', - begin: either(...MULTI_WORD_TYPES), - }, - FUNCTION_CALL, - VARIABLE, - STRING, - QUOTED_IDENTIFIER, - hljs.C_NUMBER_MODE, - hljs.C_BLOCK_COMMENT_MODE, - COMMENT_MODE, - OPERATOR, - ], - } -} - -export default sql diff --git a/src/common/highlight/sql.ts b/src/common/highlight/sql.ts new file mode 100644 index 000000000..e758b578c --- /dev/null +++ b/src/common/highlight/sql.ts @@ -0,0 +1,12 @@ +import sql from 'highlight.js/lib/languages/sql' + +export default (hljs: any) => { + const ret = sql(hljs) + if (ret?.keywords?.keyword && Array.isArray(ret.keywords.keyword)) { + ret.keywords.keyword.push('do|0', 'foreach', 'incase') + } + if (ret?.contains?.[0]?.keywords?.keyword && Array.isArray(ret.contains[0].keywords.keyword)) { + ret.contains[0].keywords.keyword.push('do', 'foreach', 'incase') + } + return ret +}