From 7aa2a2d07d6ea4f916a54f584bae98a4220fc67c Mon Sep 17 00:00:00 2001 From: Snehil Shah Date: Sat, 1 Jun 2024 10:05:02 +0000 Subject: [PATCH 01/33] feat: add APIs to programmatically control syntax-highlighter Signed-off-by: Snehil Shah --- lib/node_modules/@stdlib/repl/lib/main.js | 273 ++++++++++++++++++ .../@stdlib/repl/lib/syntax_highlighter.js | 137 ++++++++- 2 files changed, 409 insertions(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/repl/lib/main.js b/lib/node_modules/@stdlib/repl/lib/main.js index d812cf445cef..056c0e8c889e 100644 --- a/lib/node_modules/@stdlib/repl/lib/main.js +++ b/lib/node_modules/@stdlib/repl/lib/main.js @@ -30,6 +30,7 @@ var logger = require( 'debug' ); var inherit = require( '@stdlib/utils/inherit' ); var isString = require( '@stdlib/assert/is-string' ).isPrimitive; var isNumber = require( '@stdlib/assert/is-number' ).isPrimitive; +var isObject = require( '@stdlib/assert/is-object' ); var isFunction = require( '@stdlib/assert/is-function' ); var isConfigurableProperty = require( '@stdlib/assert/is-configurable-property' ); var hasOwnProp = require( '@stdlib/assert/has-own-property' ); @@ -782,6 +783,278 @@ setNonEnumerableReadOnly( REPL.prototype, 'clearUserDocs', function clearUserDoc return this; }); +/** +* Gets all available themes in the syntax-highlighter. +* +* @name getThemes +* @memberof REPL.prototype +* @type {Function} +* @returns {Array} array of all theme names +* +* @example +* var debug = require( '@stdlib/streams/node/debug-sink' ); +* +* // Create a new REPL: +* var repl = new REPL({ +* 'output': debug() +* }); +* +* // ... +* +* // Fetch all themes: +* repl.getThemes(); +* +* // ... +* +* // Close the REPL: +* repl.close(); +*/ +setNonEnumerableReadOnly( REPL.prototype, 'getThemes', function getThemes() { + return this._syntaxHighlighter.getThemes(); +}); + +/** +* Sets the current theme in the syntax-highlighter. +* +* @name setTheme +* @memberof REPL.prototype +* @type {Function} +* @param {string} theme - theme name +* @throws {TypeError} argument must be a string +* +* @example +* var debug = require( '@stdlib/streams/node/debug-sink' ); +* +* // Create a new REPL: +* var repl = new REPL({ +* 'output': debug() +* }); +* +* // ... +* +* // Fetch all themes: +* repl.setTheme( 'myTheme' ); +* +* // ... +* +* // Close the REPL: +* repl.close(); +*/ +setNonEnumerableReadOnly( REPL.prototype, 'setTheme', function setTheme( theme ) { + if ( !isString( theme ) ) { + throw new TypeError( format( 'invalid argument. First argument must be a string. Value: `%s`.', theme ) ); + } + this._syntaxHighlighter.setTheme( theme ); +}); + +/** +* Gets the current theme in the syntax-highlighter. +* +* @name getTheme +* @memberof REPL.prototype +* @type {Function} +* @returns {string} theme name +* +* @example +* var debug = require( '@stdlib/streams/node/debug-sink' ); +* +* // Create a new REPL: +* var repl = new REPL({ +* 'output': debug() +* }); +* +* // ... +* +* // Get current theme: +* repl.getTheme(); +* +* // ... +* +* // Close the REPL: +* repl.close(); +*/ +setNonEnumerableReadOnly( REPL.prototype, 'getTheme', function getTheme() { + return this._syntaxHighlighter.getTheme(); +}); + +/** +* Gets the theme's color configuration in the syntax-highlighter. +* +* @name getThemeConfig +* @memberof REPL.prototype +* @type {Function} +* @param {string} theme - theme name +* @throws {TypeError} argument must be a string +* @returns {Object} theme object +* +* @example +* var debug = require( '@stdlib/streams/node/debug-sink' ); +* +* // Create a new REPL: +* var repl = new REPL({ +* 'output': debug() +* }); +* +* // ... +* +* // Get theme object: +* repl.getThemeConfig( 'myTheme' ); +* +* // ... +* +* // Close the REPL: +* repl.close(); +*/ +setNonEnumerableReadOnly( REPL.prototype, 'getThemeConfig', function getThemeConfig( theme ) { + if ( !isString( theme ) ) { + throw new TypeError( format( 'invalid argument. First argument must be a string. Value: `%s`.', theme ) ); + } + return this._syntaxHighlighter.getThemeConfig( theme ); +}); + +/** +* Gets the default theme's name from the syntax-highlighter. +* +* @name getDefaultTheme +* @memberof REPL.prototype +* @type {Function} +* @returns {string} default theme name +* +* @example +* var debug = require( '@stdlib/streams/node/debug-sink' ); +* +* // Create a new REPL: +* var repl = new REPL({ +* 'output': debug() +* }); +* +* // ... +* +* // Get default theme name: +* repl.getDefaultTheme(); +* +* // ... +* +* // Close the REPL: +* repl.close(); +*/ +setNonEnumerableReadOnly( REPL.prototype, 'getDefaultTheme', function getDefaultTheme() { + return this._syntaxHighlighter.getDefaultTheme(); +}); + +/** +* Sets the default color theme in the syntax-highlighter. +* +* @name setDefaultTheme +* @memberof REPL.prototype +* @type {Function} +* @param {string} theme - theme name +* @throws {TypeError} argument must be a string +* @returns {void} +* +* @example +* var debug = require( '@stdlib/streams/node/debug-sink' ); +* +* // Create a new REPL: +* var repl = new REPL({ +* 'output': debug() +* }); +* +* // ... +* +* // Set default theme: +* repl.setDefaultTheme( 'myTheme' ); +* +* // ... +* +* // Close the REPL: +* repl.close(); +*/ +setNonEnumerableReadOnly( REPL.prototype, 'setDefaultTheme', function setDefaultTheme( theme ) { + if ( !isString( theme ) ) { + throw new TypeError( format( 'invalid argument. First argument must be a string. Value: `%s`.', theme ) ); + } + this._syntaxHighlighter.setDefaultTheme( theme ); +}); + +/** +* Adds a theme to the syntax-highlighter. +* +* @name addTheme +* @memberof REPL.prototype +* @type {Function} +* @param {string} name - theme name +* @param {Object} theme - theme object +* @throws {TypeError} first argument must be a string +* @throws {TypeError} second argument must be an object +* @returns {void} +* +* @example +* var debug = require( '@stdlib/streams/node/debug-sink' ); +* +* // Create a new REPL: +* var repl = new REPL({ +* 'output': debug() +* }); +* +* // ... +* +* // Add a user-defined theme: +* repl.addTheme( 'myTheme', { +* 'keyword': 'red', +* 'variable': 'green' +* }); +* +* // ... +* +* // Close the REPL: +* repl.close(); +*/ +setNonEnumerableReadOnly( REPL.prototype, 'addTheme', function addTheme( name, theme ) { + if ( !isString( name ) ) { + throw new TypeError( format( 'invalid argument. First argument must be a string. Value: `%s`.', name ) ); + } + if ( !isObject( theme ) ) { + throw new TypeError( format( 'invalid argument. Second argument must be an object. Value: `%s`.', theme ) ); + } + this._syntaxHighlighter.addTheme( theme ); +}); + +/** +* Deletes a theme from the syntax-highlighter. +* +* @name deleteTheme +* @memberof REPL.prototype +* @type {Function} +* @param {string} name - theme name +* @throws {TypeError} first argument must be a string +* @returns {void} +* +* @example +* var debug = require( '@stdlib/streams/node/debug-sink' ); +* +* // Create a new REPL: +* var repl = new REPL({ +* 'output': debug() +* }); +* +* // ... +* +* // Delete an existing theme: +* repl.deleteTheme( 'myTheme' ); +* +* // ... +* +* // Close the REPL: +* repl.close(); +*/ +setNonEnumerableReadOnly( REPL.prototype, 'deleteTheme', function deleteTheme( name ) { + if ( !isString( name ) ) { + throw new TypeError( format( 'invalid argument. First argument must be a string. Value: `%s`.', name ) ); + } + this._syntaxHighlighter.deleteTheme( name ); +}); + /** * Loads and evaluates a JavaScript file line-by-line. * diff --git a/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js b/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js index 0fb92b3de858..88d178cbdca9 100644 --- a/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js +++ b/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js @@ -24,7 +24,11 @@ var readline = require( 'readline' ); var logger = require( 'debug' ); +var format = require( '@stdlib/string/format' ); var setNonEnumerableReadOnly = require( '@stdlib/utils/define-nonenumerable-read-only-property' ); +var objectKeys = require( '@stdlib/utils/keys' ); +var omit = require( '@stdlib/utils/omit' ); +var contains = require('@stdlib/array/base/assert/contains'); var tokenizer = require( './tokenizer.js' ); var THEMES = require( './themes.js' ); var ANSI = require( './ansi_colors.js' ); @@ -82,6 +86,15 @@ function SyntaxHighlighter( repl, ostream ) { // Initialize a buffer to cache the highlighted line: this._highlightedLine = ''; + // Initialize an object storing all available themes: + this._themes = THEMES; + + // Initialize a variable storing the current theme: + this._theme = 'default'; + + // Initialize a variable storing the default theme: + this._defaultTheme = 'default'; + return this; } @@ -100,7 +113,7 @@ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, '_highlightLine', functio var highlightedLine = ''; var resetCode = ANSI[ 'reset' ]; var colorCode; - var colors = THEMES[ 'default' ]; + var colors = this._themes[ this._theme ]; var offset = 0; var token; var i; @@ -125,6 +138,128 @@ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, '_highlightLine', functio return highlightedLine; }); +/** +* Gets all available theme names. +* +* @name getThemes +* @memberof SyntaxHighlighter.prototype +* @type {Function} +* @returns {Array} array of all theme names +*/ +setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'getThemes', function getThemes() { + return objectKeys( this._themes ); +}); + +/** +* Sets the current color theme. +* +* @name setTheme +* @memberof SyntaxHighlighter.prototype +* @type {Function} +* @param {string} theme - theme name +* @throws {Error} argument must be an existing theme +*/ +setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'setTheme', function setTheme( theme ) { + if ( !contains( objectKeys( this._themes ), theme ) ) { + throw new Error( format( 'invalid argument. First argument must be an existing theme name. Value: `%s`.', theme ) ); + } + this._highlightedLine = ''; + this._theme = theme; +}); + +/** +* Gets current theme name. +* +* @name getTheme +* @memberof SyntaxHighlighter.prototype +* @type {Function} +* @returns {Object} theme name +*/ +setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'getTheme', function getTheme() { + return this._theme; +}); + +/** +* Gets a theme's colors configuration. +* +* @name getThemeConfig +* @memberof SyntaxHighlighter.prototype +* @type {Function} +* @param {string} theme - theme name +* @throws {Error} must provide an existing theme name +* @returns {Object} theme object +*/ +setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'getThemeConfig', function getThemeConfig( theme ) { + if ( !contains( objectKeys( this._themes ), theme ) ) { + throw new Error( format( 'invalid argument. First argument must be an existing theme name. Value: `%s`.', theme ) ); + } + return this._themes[ theme ]; +}); + +/** +* Gets the default color theme name. +* +* @name getDefaultTheme +* @memberof SyntaxHighlighter.prototype +* @type {Function} +* @returns {string} default theme name +*/ +setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'getDefaultTheme', function getDefaultTheme() { + return this._defaultTheme; +}); + +/** +* Sets the default color theme. +* +* @name setDefaultTheme +* @memberof SyntaxHighlighter.prototype +* @type {Function} +* @param {string} theme - theme name +* @throws {Error} argument must be an existing theme +*/ +setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'setDefaultTheme', function setDefaultTheme( theme ) { + if ( !contains( objectKeys( this._themes ), theme ) ) { + throw new Error( format( 'invalid argument. First argument must be an existing theme name. Value: `%s`.', theme ) ); + } + this._defaultTheme = theme; +}); + +/** +* Adds a new color theme. +* +* @name addTheme +* @memberof SyntaxHighlighter.prototype +* @type {Function} +* @param {Object} theme - theme object +*/ +setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'addTheme', function addTheme( name, theme ) { + this._themes[ name ] = theme; +}); + +/** +* Deletes a color theme. +* +* @name deleteTheme +* @memberof SyntaxHighlighter.prototype +* @type {Function} +* @param {Object} theme - theme name +* @throws {Error} must provide an existing theme name +* @throws {Error} must provide a theme other than the default theme +*/ +setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'deleteTheme', function deleteTheme( theme ) { + if ( !contains( objectKeys( this._themes ), theme ) ) { + throw new Error( format( 'invalid argument. First argument must be an existing theme name. Value: `%s`.', theme ) ); + } + if ( theme === this._defaultTheme ) { + throw new Error( format( 'invalid argument. First argument cannot be the default theme. Value: `%s`.', theme ) ); + } + if ( theme === this._theme ) { + this._highlightedLine = ''; + this._theme = this._defaultTheme; + } + this._themes = omit( this._themes, theme ); +}); + /** * Callback for handling a "keypress" event. * From 31b51342b298ee88f4fd9f4cb1aaeb8028922e08 Mon Sep 17 00:00:00 2001 From: Snehil Shah Date: Sat, 1 Jun 2024 11:13:37 +0000 Subject: [PATCH 02/33] feat: add REPL commands to control syntax-highlighting Signed-off-by: Snehil Shah --- lib/node_modules/@stdlib/repl/lib/commands.js | 10 +++ .../@stdlib/repl/lib/commands/add_theme.js | 73 +++++++++++++++ .../repl/lib/commands/default_theme.js | 73 +++++++++++++++ .../@stdlib/repl/lib/commands/delete_theme.js | 71 +++++++++++++++ .../@stdlib/repl/lib/commands/get_theme.js | 74 ++++++++++++++++ .../@stdlib/repl/lib/commands/theme.js | 88 +++++++++++++++++++ .../@stdlib/repl/lib/help_text.js | 6 ++ 7 files changed, 395 insertions(+) create mode 100644 lib/node_modules/@stdlib/repl/lib/commands/add_theme.js create mode 100644 lib/node_modules/@stdlib/repl/lib/commands/default_theme.js create mode 100644 lib/node_modules/@stdlib/repl/lib/commands/delete_theme.js create mode 100644 lib/node_modules/@stdlib/repl/lib/commands/get_theme.js create mode 100644 lib/node_modules/@stdlib/repl/lib/commands/theme.js diff --git a/lib/node_modules/@stdlib/repl/lib/commands.js b/lib/node_modules/@stdlib/repl/lib/commands.js index f5ceec95d5b6..cc45566bebfc 100644 --- a/lib/node_modules/@stdlib/repl/lib/commands.js +++ b/lib/node_modules/@stdlib/repl/lib/commands.js @@ -20,6 +20,7 @@ // MODULES // +var onAddTheme = require( './commands/add_theme.js' ); var onAlias2Pkg = require( './commands/alias2pkg.js' ); var onAlias2Related = require( './commands/alias2related.js' ); var onAns = require( './commands/ans.js' ); @@ -35,12 +36,15 @@ var onContributors = require( './commands/contributor.js' ); var onCopyright = require( './commands/copyright.js' ); var onCredits = require( './commands/credits.js' ); var onCurrentWorkspace = require( './commands/current_workspace.js' ); +var onDefaultTheme = require( './commands/default_theme.js' ); +var onDeleteTheme = require( './commands/delete_theme.js' ); var onDeleteWorkspace = require( './commands/delete_workspace.js' ); var onDeeprerequire = require( './commands/deeprerequire.js' ); var onDonate = require( './commands/donate.js' ); var onDone = require( './commands/__done__.js' ); var onEvalin = require( './commands/evalin.js' ); var onExample = require( './commands/example.js' ); +var onGetTheme = require( './commands/get_theme.js' ); var onHelp = require( './commands/help.js' ); var onInfo = require( './commands/info.js' ); var isWorkspace = require( './commands/is_workspace.js' ); @@ -57,6 +61,7 @@ var onRerequire = require( './commands/rerequire.js' ); var onRerun = require( './commands/rerun.js' ); var onReset = require( './commands/reset.js' ); var onSettings = require( './commands/settings.js' ); +var onTheme = require( './commands/theme.js' ); var onTutorial = require( './commands/tutorial.js' ); var onUserDoc = require( './commands/user_doc.js' ); var onVars = require( './commands/vars.js' ); @@ -90,6 +95,7 @@ function commands( repl ) { // Define a list of REPL-specific commands (NOTE: keep in alphabetical order): cmds = []; cmds.push( [ '__done__', onDone( repl ), false ] ); + cmds.push( [ 'addTheme', onAddTheme( repl ), false ] ); cmds.push( [ 'alias2pkg', onAlias2Pkg( repl ), false ] ); cmds.push( [ 'alias2related', onAlias2Related( repl, cmds ), false ] ); cmds.push( [ 'ans', onAns( repl ), true ] ); @@ -105,11 +111,14 @@ function commands( repl ) { cmds.push( [ 'copyright', onCopyright( repl ), false ] ); cmds.push( [ 'credits', onCredits( repl ), false ] ); cmds.push( [ 'currentWorkspace', onCurrentWorkspace( repl ), true ] ); + cmds.push( [ 'defaultTheme', onDefaultTheme( repl ), false ] ); + cmds.push( [ 'deleteTheme', onDeleteTheme( repl ), false ] ); cmds.push( [ 'deleteWorkspace', onDeleteWorkspace( repl ), false ] ); cmds.push( [ 'deeprerequire', onDeeprerequire( repl ), false ] ); cmds.push( [ 'donate', onDonate( repl ), false ] ); cmds.push( [ 'evalin', onEvalin( repl, cmds ), false ] ); cmds.push( [ 'example', onExample( repl, cmds ), false ] ); + cmds.push( [ 'getTheme', onGetTheme( repl ), false ] ); cmds.push( [ 'help', onHelp( repl, cmds ), false ] ); cmds.push( [ 'info', onInfo( repl, cmds ), false ] ); cmds.push( [ 'isKeyword', isKeyword( repl ), false ] ); @@ -126,6 +135,7 @@ function commands( repl ) { cmds.push( [ 'rerun', onRerun( repl ), false ] ); cmds.push( [ 'reset', onReset( repl ), false ] ); cmds.push( [ 'settings', onSettings( repl ), false ] ); + cmds.push( [ 'theme', onTheme( repl ), false ] ); cmds.push( [ 'tutorial', onTutorial( repl ), false ] ); cmds.push( [ 'userDoc', onUserDoc( repl ), false ] ); cmds.push( [ 'vars', onVars( repl ), false ] ); diff --git a/lib/node_modules/@stdlib/repl/lib/commands/add_theme.js b/lib/node_modules/@stdlib/repl/lib/commands/add_theme.js new file mode 100644 index 000000000000..2b4c036118ac --- /dev/null +++ b/lib/node_modules/@stdlib/repl/lib/commands/add_theme.js @@ -0,0 +1,73 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable no-underscore-dangle */ + +'use strict'; + +// MODULES // + +var format = require( '@stdlib/string/format' ); +var log = require( './../log.js' ); + + +// MAIN // + +/** +* Returns a callback to be invoked upon calling the `addTheme` command. +* +* @private +* @param {REPL} repl - REPL instance +* @returns {Function} callback +*/ +function command( repl ) { + return onCommand; + + /** + * Adds a color theme to the syntax-highlighter. + * + * @private + * @param {string} [name] - theme name + * @param {Object} [theme] - theme object + * @returns {void} + */ + function onCommand() { + var theme; + var nargs; + var name; + + nargs = arguments.length; + if ( nargs < 2 ) { + repl._ostream.write( 'Error: invalid operation. Provide a theme to add.\n' ); + return; + } + name = arguments[ 0 ]; + theme = arguments[ 1 ]; + try { + repl.addTheme( name, theme ); + } catch ( err ) { + repl._ostream.write( format( 'Error: %s\n', err.message ) ); + } + log( repl, format( '\nSuccessfully added theme `%s`.', name ) ); + } +} + + +// EXPORTS // + +module.exports = command; diff --git a/lib/node_modules/@stdlib/repl/lib/commands/default_theme.js b/lib/node_modules/@stdlib/repl/lib/commands/default_theme.js new file mode 100644 index 000000000000..6eda2e3084fd --- /dev/null +++ b/lib/node_modules/@stdlib/repl/lib/commands/default_theme.js @@ -0,0 +1,73 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable no-underscore-dangle */ + +'use strict'; + +// MODULES // + +var format = require( '@stdlib/string/format' ); +var log = require( './../log.js' ); + + +// MAIN // + +/** +* Returns a callback to be invoked upon calling the `defaultTheme` command. +* +* @private +* @param {REPL} repl - REPL instance +* @returns {Function} callback +*/ +function command( repl ) { + return onCommand; + + /** + * Gets (and sets) the default color theme for syntax-highlighting. + * + * @private + * @param {string} [name] - theme name + * @returns {void} + */ + function onCommand() { + var theme; + var nargs; + var name; + + nargs = arguments.length; + if ( nargs === 0 ) { + theme = repl.getDefaultTheme(); + log( repl, format( 'Default theme: `%s`', theme ) ); + return; + } + name = arguments[ 0 ]; + try { + repl.setDefaultTheme( name ); + } catch ( err ) { + repl._ostream.write( format( 'Error: %s\n', err.message ) ); + return; + } + log( repl, format( '\nSuccessfully updated default theme to `%s`.', name ) ); + } +} + + +// EXPORTS // + +module.exports = command; diff --git a/lib/node_modules/@stdlib/repl/lib/commands/delete_theme.js b/lib/node_modules/@stdlib/repl/lib/commands/delete_theme.js new file mode 100644 index 000000000000..b53e2c60a96c --- /dev/null +++ b/lib/node_modules/@stdlib/repl/lib/commands/delete_theme.js @@ -0,0 +1,71 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable no-underscore-dangle */ + +'use strict'; + +// MODULES // + +var format = require( '@stdlib/string/format' ); +var log = require( './../log.js' ); + + +// MAIN // + +/** +* Returns a callback to be invoked upon calling the `deleteTheme` command. +* +* @private +* @param {REPL} repl - REPL instance +* @returns {Function} callback +*/ +function command( repl ) { + return onCommand; + + /** + * Deletes a color theme from the syntax-highlighter. + * + * @private + * @param {string} [name] - theme name + * @returns {void} + */ + function onCommand() { + var nargs; + var name; + + nargs = arguments.length; + if ( nargs === 0 ) { + repl._ostream.write( 'Error: invalid operation. Provide a theme name to delete.\n' ); + return; + } + name = arguments[ 0 ]; + try { + repl.deleteTheme( name ); + } catch ( err ) { + repl._ostream.write( format( 'Error: %s\n', err.message ) ); + return; + } + log( repl, format( '\nSuccessfully deleted theme `%s`.', name ) ); + } +} + + +// EXPORTS // + +module.exports = command; diff --git a/lib/node_modules/@stdlib/repl/lib/commands/get_theme.js b/lib/node_modules/@stdlib/repl/lib/commands/get_theme.js new file mode 100644 index 000000000000..5d060a737860 --- /dev/null +++ b/lib/node_modules/@stdlib/repl/lib/commands/get_theme.js @@ -0,0 +1,74 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable no-underscore-dangle */ + +'use strict'; + +// MODULES // + +var format = require( '@stdlib/string/format' ); +var log = require( './../log.js' ); + + +// MAIN // + +/** +* Returns a callback to be invoked upon calling the `getTheme` command. +* +* @private +* @param {REPL} repl - REPL instance +* @returns {Function} callback +*/ +function command( repl ) { + return onCommand; + + /** + * Gets the color configuration of a theme from the syntax-highlighter. + * + * @private + * @param {string} [name] - theme name + * @returns {void} + */ + function onCommand() { + var theme; + var nargs; + var name; + + nargs = arguments.length; + + // If no theme name given, get the current theme... + if ( nargs === 0 ) { + name = repl.getTheme(); + } else { + name = arguments[ 0 ]; + } + try { + theme = repl.getThemeConfig( name ); + } catch ( err ) { + repl._ostream.write( format( 'Error: %s\n', err.message ) ); + return; + } + log( repl, JSON.stringify( theme, null, 2 ) ); + } +} + + +// EXPORTS // + +module.exports = command; diff --git a/lib/node_modules/@stdlib/repl/lib/commands/theme.js b/lib/node_modules/@stdlib/repl/lib/commands/theme.js new file mode 100644 index 000000000000..8c4d1a51d2a3 --- /dev/null +++ b/lib/node_modules/@stdlib/repl/lib/commands/theme.js @@ -0,0 +1,88 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* eslint-disable no-underscore-dangle */ + +'use strict'; + +// MODULES // + +var format = require( '@stdlib/string/format' ); +var log = require( './../log.js' ); + + +// MAIN // + +/** +* Returns a callback to be invoked upon calling the `theme` command. +* +* @private +* @param {REPL} repl - REPL instance +* @returns {Function} callback +*/ +function command( repl ) { + return onCommand; + + /** + * Gets (and sets) the color theme(s) for syntax-highlighting. + * + * @private + * @param {string} [name] - theme name + * @returns {void} + */ + function onCommand() { + var themes; + var theme; + var nargs; + var name; + var i; + + nargs = arguments.length; + + // If no theme name given, display current and available themes: + if ( nargs === 0 ) { + themes = repl.getThemes(); + theme = repl.getTheme(); + if ( themes.length === 0 ) { + repl._ostream.write( 'No themes available.' ); + return; + } + repl._ostream.write( format( 'Current theme: `%s`.\n', theme ) ); + repl._ostream.write( format( 'Available themes: `%s`', themes[ 0 ] ) ); + for ( i = 1; i < themes.length; i++ ) { + repl._ostream.write( format( ' ,`%s`', themes[ i ] ) ); + } + repl._ostream.write( '.\n' ); + return; + } + // Set theme: + name = arguments[ 0 ]; + try { + repl.setTheme( name ); + } catch ( err ) { + repl._ostream.write( format( 'Error: %s\n', err.message ) ); + return; + } + log( repl, format( '\nSuccessfully updated theme to `%s`.', name ) ); + } +} + + +// EXPORTS // + +module.exports = command; diff --git a/lib/node_modules/@stdlib/repl/lib/help_text.js b/lib/node_modules/@stdlib/repl/lib/help_text.js index 2daf600c19b5..0367347655cd 100644 --- a/lib/node_modules/@stdlib/repl/lib/help_text.js +++ b/lib/node_modules/@stdlib/repl/lib/help_text.js @@ -65,6 +65,12 @@ var MSG = [ ' deeprerequire() Re-import a module and its dependencies.', ' load() Load and evaluate a JavaScript file line-by-line.', '', + ' theme([name]) List, get and set color themes.', + ' defaultTheme([name]) Get and set the default color theme.', + ' addTheme(name,value) Add a new color theme.', + ' deleteTheme(name) Delete a specified theme.', + ' getTheme([name]) Get the current (or a specified) color theme palette.', + '', ' save() Save previous commands to a specified file.', ' saveStart() Start saving commands to a specified file.', ' saveStop() Stop saving commands.', From 685843398c0f6a8023c85afb49259261914d9370 Mon Sep 17 00:00:00 2001 From: Snehil Shah Date: Sat, 1 Jun 2024 11:28:32 +0000 Subject: [PATCH 03/33] feat: add setting to enable/disable syntax-highlighting Signed-off-by: Snehil Shah --- lib/node_modules/@stdlib/repl/lib/main.js | 13 +++++-- lib/node_modules/@stdlib/repl/lib/settings.js | 4 ++ .../@stdlib/repl/lib/syntax_highlighter.js | 38 +++++++++++++++++-- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/lib/node_modules/@stdlib/repl/lib/main.js b/lib/node_modules/@stdlib/repl/lib/main.js index 056c0e8c889e..adb73e9e886d 100644 --- a/lib/node_modules/@stdlib/repl/lib/main.js +++ b/lib/node_modules/@stdlib/repl/lib/main.js @@ -145,6 +145,7 @@ function REPL( options ) { opts.isTTY = ( opts.isTTY === void 0 ) ? opts.output.isTTY : opts.isTTY; opts.settings.autoPage = ( opts.settings.autoPage === void 0 ) ? opts.isTTY : opts.settings.autoPage; // eslint-disable-line max-len opts.settings.completionPreviews = ( opts.settings.completionPreviews === void 0 ) ? opts.isTTY : opts.settings.completionPreviews; // eslint-disable-line max-len + opts.settings.syntaxHighlighting = ( opts.settings.syntaxHighlighting === void 0 ) ? opts.isTTY : opts.settings.syntaxHighlighting; // eslint-disable-line max-len debug( 'Options: %s', JSON.stringify({ 'input': '', @@ -273,7 +274,7 @@ function REPL( options ) { setNonEnumerableReadOnly( this, '_previewCompleter', new PreviewCompleter( this._rli, this._completer, this._ostream, this._settings.completionPreviews ) ); // Initialize a syntax-highlighter: - setNonEnumerableReadOnly( this, '_syntaxHighlighter', new SyntaxHighlighter( this, this._ostream ) ); + setNonEnumerableReadOnly( this, '_syntaxHighlighter', new SyntaxHighlighter( this, this._ostream, this._settings.syntaxHighlighting ) ); // Cache a reference to the private readline interface `ttyWrite` to allow calling the method when wanting default behavior: setNonEnumerableReadOnly( this, '_ttyWrite', this._rli._ttyWrite ); @@ -349,9 +350,7 @@ function REPL( options ) { if ( autoClosed ) { self._previewCompleter.clear(); } - if ( self._isTTY ) { - self._syntaxHighlighter.onKeypress(); - } + self._syntaxHighlighter.onKeypress(); self._previewCompleter.onKeypress( data, key ); } @@ -1485,6 +1484,12 @@ setNonEnumerableReadOnly( REPL.prototype, 'settings', function settings() { } else { this._ostream.disablePaging(); } + } else if ( name === 'syntaxHighlighting' ) { + if ( value ) { + this._syntaxHighlighter.enable(); + } else { + this._syntaxHighlighter.disable(); + } } return this; diff --git a/lib/node_modules/@stdlib/repl/lib/settings.js b/lib/node_modules/@stdlib/repl/lib/settings.js index b60354e6e6eb..cfd992926893 100644 --- a/lib/node_modules/@stdlib/repl/lib/settings.js +++ b/lib/node_modules/@stdlib/repl/lib/settings.js @@ -43,6 +43,10 @@ var SETTINGS = { 'completionPreviews': { 'desc': 'Enable the display of completion previews for auto-completion.', 'type': 'boolean' + }, + 'syntaxHighlighting': { + 'desc': 'Enable syntax highlighting of the input.', + 'type': 'boolean' } }; diff --git a/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js b/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js index 88d178cbdca9..a63519efed83 100644 --- a/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js +++ b/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js @@ -63,14 +63,18 @@ function tokenComparator( a, b ) { * @constructor * @param {REPL} repl - REPL instance * @param {WritableStream} ostream - writable stream +* @param {boolean} enabled - boolean indicating whether the syntax-highlighter should be initially enabled * @returns {SyntaxHighlighter} syntax-highlighter instance */ -function SyntaxHighlighter( repl, ostream ) { +function SyntaxHighlighter( repl, ostream, enabled ) { if ( !( this instanceof SyntaxHighlighter ) ) { - return new SyntaxHighlighter( repl, ostream ); + return new SyntaxHighlighter( repl, ostream, enabled ); } debug( 'Creating a new syntax-highlighter' ); + // Initialize a flag indicating whether the preview completer is enabled: + this._enabled = enabled; + // Cache a reference to the provided REPL instance: this._repl = repl; @@ -260,6 +264,32 @@ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'deleteTheme', function d this._themes = omit( this._themes, theme ); }); +/** +* Disables the syntax-highlighter. +* +* @name disable +* @memberof SyntaxHighlighter.prototype +* @type {Function} +* @returns {SyntaxHighlighter} syntax-highlighter instance +*/ +setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'disable', function disable() { + this._enabled = false; + return this; +}); + +/** +* Enables the syntax-highlighter. +* +* @name enable +* @memberof SyntaxHighlighter.prototype +* @type {Function} +* @returns {SyntaxHighlighter} syntax-highlighter instance +*/ +setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'enable', function enable() { + this._enabled = true; + return this; +}); + /** * Callback for handling a "keypress" event. * @@ -274,11 +304,13 @@ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'onKeypress', function on var highlightedLine; var tokens; + if ( !this._enabled ) { + return; + } if ( !this._rli.line ) { debug( 'Empty line detected. Skipping highlighting...' ); return; } - // If no line change is detected, use the highlighted line from cache... if ( this._line === this._rli.line ) { debug( 'No line change detected. Using cache...' ); From 0c3e6d349627d5e8290af9397826a1fca15a47d8 Mon Sep 17 00:00:00 2001 From: Snehil Shah Date: Sat, 1 Jun 2024 11:40:44 +0000 Subject: [PATCH 04/33] test: fix failing tests Signed-off-by: Snehil Shah --- .../test/integration/test.auto_close_pairs.js | 3 ++- .../integration/test.auto_delete_pairs.js | 3 ++- .../repl/test/integration/test.auto_page.js | 1 + .../integration/test.completion_previews.js | 24 ++++++++++++------- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/lib/node_modules/@stdlib/repl/test/integration/test.auto_close_pairs.js b/lib/node_modules/@stdlib/repl/test/integration/test.auto_close_pairs.js index 2da94b404aab..6a69fdcc52e2 100644 --- a/lib/node_modules/@stdlib/repl/test/integration/test.auto_close_pairs.js +++ b/lib/node_modules/@stdlib/repl/test/integration/test.auto_close_pairs.js @@ -144,7 +144,8 @@ function defaultSettings() { 'autoClosePairs': false, 'autoDeletePairs': false, 'autoPage': false, - 'completionPreviews': false + 'completionPreviews': false, + 'syntaxHighlighting': false }; } diff --git a/lib/node_modules/@stdlib/repl/test/integration/test.auto_delete_pairs.js b/lib/node_modules/@stdlib/repl/test/integration/test.auto_delete_pairs.js index 14b6b6548e84..dd9a8397820b 100644 --- a/lib/node_modules/@stdlib/repl/test/integration/test.auto_delete_pairs.js +++ b/lib/node_modules/@stdlib/repl/test/integration/test.auto_delete_pairs.js @@ -112,7 +112,8 @@ function defaultSettings() { 'autoClosePairs': false, 'autoDeletePairs': false, 'autoPage': false, - 'completionPreviews': false + 'completionPreviews': false, + 'syntaxHighlighting': false }; } diff --git a/lib/node_modules/@stdlib/repl/test/integration/test.auto_page.js b/lib/node_modules/@stdlib/repl/test/integration/test.auto_page.js index 7c677d25fa4b..63703e1a5cec 100644 --- a/lib/node_modules/@stdlib/repl/test/integration/test.auto_page.js +++ b/lib/node_modules/@stdlib/repl/test/integration/test.auto_page.js @@ -59,6 +59,7 @@ function defaultSettings() { 'autoDeletePairs': false, 'autoClosePairs': false, 'completionPreviews': false, + 'syntaxHighlighting': false, 'autoPage': true }; } diff --git a/lib/node_modules/@stdlib/repl/test/integration/test.completion_previews.js b/lib/node_modules/@stdlib/repl/test/integration/test.completion_previews.js index 8aad9ca7dffe..caa0c7d262b2 100644 --- a/lib/node_modules/@stdlib/repl/test/integration/test.completion_previews.js +++ b/lib/node_modules/@stdlib/repl/test/integration/test.completion_previews.js @@ -45,7 +45,8 @@ tape( 'a REPL instance supports displaying a completion preview of user-defined opts = { 'input': istream, 'settings': { - 'autoPage': false + 'autoPage': false, + 'syntaxHighlighting': false } }; r = repl( opts, onClose ); @@ -88,7 +89,8 @@ tape( 'a REPL instance supports displaying a completion preview for common prefi opts = { 'input': istream, 'settings': { - 'autoPage': false + 'autoPage': false, + 'syntaxHighlighting': false } }; r = repl( opts, onClose ); @@ -132,7 +134,8 @@ tape( 'a REPL instance supports displaying a completion preview for recognized i opts = { 'input': istream, 'settings': { - 'autoPage': false + 'autoPage': false, + 'syntaxHighlighting': false } }; r = repl( opts, onClose ); @@ -175,7 +178,8 @@ tape( 'a REPL instance supports displaying a completion preview when a cursor is opts = { 'input': istream, 'settings': { - 'autoPage': false + 'autoPage': false, + 'syntaxHighlighting': false } }; r = repl( opts, onClose ); @@ -227,7 +231,8 @@ tape( 'a REPL instance supports auto-completing a completion candidate by moving opts = { 'input': istream, 'settings': { - 'autoPage': false + 'autoPage': false, + 'syntaxHighlighting': false } }; r = repl( opts, onClose ); @@ -278,7 +283,8 @@ tape( 'a REPL instance supports auto-completing a completion preview and executi 'inputPrompt': '> ', 'outputPrompt': '', 'settings': { - 'autoPage': false + 'autoPage': false, + 'syntaxHighlighting': false } }; r = repl( opts, onClose ); @@ -330,7 +336,8 @@ tape( 'a REPL instance does not display a completion preview when no completion opts = { 'input': istream, 'settings': { - 'autoPage': false + 'autoPage': false, + 'syntaxHighlighting': false } }; r = repl( opts, onClose ); @@ -387,7 +394,8 @@ tape( 'a REPL instance does not display a completion preview once a user enters 'inputPrompt': '> ', 'outputPrompt': '', 'settings': { - 'autoPage': false + 'autoPage': false, + 'syntaxHighlighting': false } }; r = repl( opts, onClose ); From d5a00a8a324665fc8413624bb8bc6088a19daa1a Mon Sep 17 00:00:00 2001 From: Snehil Shah Date: Sat, 1 Jun 2024 12:06:55 +0000 Subject: [PATCH 05/33] feat: add options for syntax-highlighting upon REPL startup Signed-off-by: Snehil Shah --- lib/node_modules/@stdlib/repl/lib/main.js | 23 ++++++++++++++++--- lib/node_modules/@stdlib/repl/lib/validate.js | 12 ++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/lib/node_modules/@stdlib/repl/lib/main.js b/lib/node_modules/@stdlib/repl/lib/main.js index adb73e9e886d..d84eba01bd12 100644 --- a/lib/node_modules/@stdlib/repl/lib/main.js +++ b/lib/node_modules/@stdlib/repl/lib/main.js @@ -30,10 +30,11 @@ var logger = require( 'debug' ); var inherit = require( '@stdlib/utils/inherit' ); var isString = require( '@stdlib/assert/is-string' ).isPrimitive; var isNumber = require( '@stdlib/assert/is-number' ).isPrimitive; -var isObject = require( '@stdlib/assert/is-object' ); +var isPlainObject = require( '@stdlib/assert/is-plain-object' ); var isFunction = require( '@stdlib/assert/is-function' ); var isConfigurableProperty = require( '@stdlib/assert/is-configurable-property' ); var hasOwnProp = require( '@stdlib/assert/has-own-property' ); +var objectKeys = require( '@stdlib/utils/keys' ); var setNonEnumerable = require( '@stdlib/utils/define-nonenumerable-property' ); var setNonEnumerableReadOnly = require( '@stdlib/utils/define-nonenumerable-read-only-property' ); var setReadOnly = require( '@stdlib/utils/define-read-only-property' ); @@ -91,6 +92,8 @@ var debug = logger( 'repl' ); * @param {boolean} [options.isTTY] - boolean indicating whether the input and output streams should be treated like a TTY (terminal) and whether the REPL should use ANSI/VT100 escape codes when writing to the output stream * @param {string} [options.welcome] - welcome message * @param {NonNegativeInteger} [options.padding=1] - number of empty lines between successive commands +* @param {Object} [options.themes] - table mapping of color themes to load for syntax-highlighting +* @param {string} [options.defaultTheme] - name of the default theme to use for syntax-highlighting * @param {string} [options.load] - file path specifying a JavaScript file to load and evaluate line-by-line (e.g., a previous REPL history file) * @param {string} [options.save] - file path specifying where to save REPL command history * @param {string} [options.log] - file path specifying where to save REPL commands and printed output @@ -123,9 +126,11 @@ var debug = logger( 'repl' ); */ function REPL( options ) { var ostream; + var themes; var opts; var self; var err; + var i; if ( !( this instanceof REPL ) ) { if ( arguments.length ) { @@ -304,6 +309,18 @@ function REPL( options ) { // TODO: check whether to synchronously initialize a REPL log file + // Check whether to load user-defined themes upon startup... + if ( opts.themes ) { + themes = objectKeys( opts.themes ); + for ( i = 0; i < themes.length; i++ ) { + this.addTheme( themes[ i ], opts.themes[ themes[ i ] ] ); + } + } + // Check whether to set a default theme upon startup... + if ( opts.defaultTheme ) { + this.setTheme( opts.defaultTheme ); + this.setDefaultTheme( opts.defaultTheme ); + } // Check whether to load and execute a JavaScript file (e.g., prior REPL history) upon startup... if ( opts.load ) { this.load( opts.load ); @@ -1013,10 +1030,10 @@ setNonEnumerableReadOnly( REPL.prototype, 'addTheme', function addTheme( name, t if ( !isString( name ) ) { throw new TypeError( format( 'invalid argument. First argument must be a string. Value: `%s`.', name ) ); } - if ( !isObject( theme ) ) { + if ( !isPlainObject( theme ) ) { throw new TypeError( format( 'invalid argument. Second argument must be an object. Value: `%s`.', theme ) ); } - this._syntaxHighlighter.addTheme( theme ); + this._syntaxHighlighter.addTheme( name, theme ); }); /** diff --git a/lib/node_modules/@stdlib/repl/lib/validate.js b/lib/node_modules/@stdlib/repl/lib/validate.js index adaeee1a68f3..8a2f9cffbd01 100644 --- a/lib/node_modules/@stdlib/repl/lib/validate.js +++ b/lib/node_modules/@stdlib/repl/lib/validate.js @@ -107,6 +107,18 @@ function validate( opts, options ) { return new TypeError( format( 'invalid option. `%s` option must be a string. Option: `%s`.', 'welcome', options.welcome ) ); } } + if ( hasOwnProp( options, 'themes' ) ) { + opts.themes = options.themes; + if ( !isPlainObject( options.themes ) ) { + return new TypeError( format( 'invalid option. `%s` option must be an object. Option: `%s`.', 'themes', options.themes ) ); + } + } + if ( hasOwnProp( options, 'defaultTheme' ) ) { + opts.defaultTheme = options.defaultTheme; + if ( !isString( options.defaultTheme ) ) { + return new TypeError( format( 'invalid option. `%s` option must be a string. Option: `%s`.', 'defaultTheme', options.defaultTheme ) ); + } + } if ( hasOwnProp( options, 'save' ) ) { opts.save = options.save; if ( !isString( options.save ) ) { From 56c30bf95a8c3f760f05521743d978221dd421ae Mon Sep 17 00:00:00 2001 From: Snehil Shah Date: Sun, 2 Jun 2024 10:32:45 +0000 Subject: [PATCH 06/33] refactor: update API and command signatures Signed-off-by: Snehil Shah --- lib/node_modules/@stdlib/repl/lib/commands.js | 8 +- .../@stdlib/repl/lib/commands/add_theme.js | 1 + .../@stdlib/repl/lib/commands/get_theme.js | 4 +- .../{default_theme.js => rename_theme.js} | 24 +-- .../@stdlib/repl/lib/commands/theme.js | 88 --------- .../@stdlib/repl/lib/commands/themes.js | 66 +++++++ .../@stdlib/repl/lib/help_text.js | 12 +- lib/node_modules/@stdlib/repl/lib/main.js | 180 +++++------------- lib/node_modules/@stdlib/repl/lib/settings.js | 8 + .../@stdlib/repl/lib/syntax_highlighter.js | 42 ++-- lib/node_modules/@stdlib/repl/lib/validate.js | 6 - 11 files changed, 168 insertions(+), 271 deletions(-) rename lib/node_modules/@stdlib/repl/lib/commands/{default_theme.js => rename_theme.js} (68%) delete mode 100644 lib/node_modules/@stdlib/repl/lib/commands/theme.js create mode 100644 lib/node_modules/@stdlib/repl/lib/commands/themes.js diff --git a/lib/node_modules/@stdlib/repl/lib/commands.js b/lib/node_modules/@stdlib/repl/lib/commands.js index cc45566bebfc..6d843e9a2369 100644 --- a/lib/node_modules/@stdlib/repl/lib/commands.js +++ b/lib/node_modules/@stdlib/repl/lib/commands.js @@ -36,7 +36,6 @@ var onContributors = require( './commands/contributor.js' ); var onCopyright = require( './commands/copyright.js' ); var onCredits = require( './commands/credits.js' ); var onCurrentWorkspace = require( './commands/current_workspace.js' ); -var onDefaultTheme = require( './commands/default_theme.js' ); var onDeleteTheme = require( './commands/delete_theme.js' ); var onDeleteWorkspace = require( './commands/delete_workspace.js' ); var onDeeprerequire = require( './commands/deeprerequire.js' ); @@ -56,12 +55,13 @@ var onPager = require( './commands/pager.js' ); var onPresentationStart = require( './commands/presentation_start.js' ); var onPresentationStop = require( './commands/presentation_stop.js' ); var onQuit = require( './commands/quit.js' ); +var onRenameTheme = require( './commands/rename_theme.js' ); var onRenameWorkspace = require( './commands/rename_workspace.js' ); var onRerequire = require( './commands/rerequire.js' ); var onRerun = require( './commands/rerun.js' ); var onReset = require( './commands/reset.js' ); var onSettings = require( './commands/settings.js' ); -var onTheme = require( './commands/theme.js' ); +var onThemes = require( './commands/themes.js' ); var onTutorial = require( './commands/tutorial.js' ); var onUserDoc = require( './commands/user_doc.js' ); var onVars = require( './commands/vars.js' ); @@ -111,7 +111,6 @@ function commands( repl ) { cmds.push( [ 'copyright', onCopyright( repl ), false ] ); cmds.push( [ 'credits', onCredits( repl ), false ] ); cmds.push( [ 'currentWorkspace', onCurrentWorkspace( repl ), true ] ); - cmds.push( [ 'defaultTheme', onDefaultTheme( repl ), false ] ); cmds.push( [ 'deleteTheme', onDeleteTheme( repl ), false ] ); cmds.push( [ 'deleteWorkspace', onDeleteWorkspace( repl ), false ] ); cmds.push( [ 'deeprerequire', onDeeprerequire( repl ), false ] ); @@ -130,12 +129,13 @@ function commands( repl ) { cmds.push( [ 'presentationStart', onPresentationStart( repl ), false ] ); cmds.push( [ 'presentationStop', onPresentationStop( repl ), false ] ); cmds.push( [ 'quit', onQuit( repl ), false ] ); + cmds.push( [ 'renameTheme', onRenameTheme( repl ), false ] ); cmds.push( [ 'renameWorkspace', onRenameWorkspace( repl ), false ] ); cmds.push( [ 'rerequire', onRerequire( repl ), false ] ); cmds.push( [ 'rerun', onRerun( repl ), false ] ); cmds.push( [ 'reset', onReset( repl ), false ] ); cmds.push( [ 'settings', onSettings( repl ), false ] ); - cmds.push( [ 'theme', onTheme( repl ), false ] ); + cmds.push( [ 'themes', onThemes( repl ), false ] ); cmds.push( [ 'tutorial', onTutorial( repl ), false ] ); cmds.push( [ 'userDoc', onUserDoc( repl ), false ] ); cmds.push( [ 'vars', onVars( repl ), false ] ); diff --git a/lib/node_modules/@stdlib/repl/lib/commands/add_theme.js b/lib/node_modules/@stdlib/repl/lib/commands/add_theme.js index 2b4c036118ac..eea130ca5e9c 100644 --- a/lib/node_modules/@stdlib/repl/lib/commands/add_theme.js +++ b/lib/node_modules/@stdlib/repl/lib/commands/add_theme.js @@ -62,6 +62,7 @@ function command( repl ) { repl.addTheme( name, theme ); } catch ( err ) { repl._ostream.write( format( 'Error: %s\n', err.message ) ); + return; } log( repl, format( '\nSuccessfully added theme `%s`.', name ) ); } diff --git a/lib/node_modules/@stdlib/repl/lib/commands/get_theme.js b/lib/node_modules/@stdlib/repl/lib/commands/get_theme.js index 5d060a737860..cf74f63afb91 100644 --- a/lib/node_modules/@stdlib/repl/lib/commands/get_theme.js +++ b/lib/node_modules/@stdlib/repl/lib/commands/get_theme.js @@ -54,12 +54,12 @@ function command( repl ) { // If no theme name given, get the current theme... if ( nargs === 0 ) { - name = repl.getTheme(); + name = repl.settings( 'theme' ); } else { name = arguments[ 0 ]; } try { - theme = repl.getThemeConfig( name ); + theme = repl.getTheme( name ); } catch ( err ) { repl._ostream.write( format( 'Error: %s\n', err.message ) ); return; diff --git a/lib/node_modules/@stdlib/repl/lib/commands/default_theme.js b/lib/node_modules/@stdlib/repl/lib/commands/rename_theme.js similarity index 68% rename from lib/node_modules/@stdlib/repl/lib/commands/default_theme.js rename to lib/node_modules/@stdlib/repl/lib/commands/rename_theme.js index 6eda2e3084fd..cb703386462a 100644 --- a/lib/node_modules/@stdlib/repl/lib/commands/default_theme.js +++ b/lib/node_modules/@stdlib/repl/lib/commands/rename_theme.js @@ -29,7 +29,7 @@ var log = require( './../log.js' ); // MAIN // /** -* Returns a callback to be invoked upon calling the `defaultTheme` command. +* Returns a callback to be invoked upon calling the `renameTheme` command. * * @private * @param {REPL} repl - REPL instance @@ -39,31 +39,33 @@ function command( repl ) { return onCommand; /** - * Gets (and sets) the default color theme for syntax-highlighting. + * Renames a color theme in the syntax-highlighter. * * @private - * @param {string} [name] - theme name + * @param {string} [oldName] - old theme name + * @param {string} [newName] - new theme name * @returns {void} */ function onCommand() { - var theme; + var oldName; + var newName; var nargs; - var name; nargs = arguments.length; - if ( nargs === 0 ) { - theme = repl.getDefaultTheme(); - log( repl, format( 'Default theme: `%s`', theme ) ); + + if ( nargs < 2 ) { + repl._ostream.write( 'Error: invalid operation. Provide the existing and new theme names to rename.' ); return; } - name = arguments[ 0 ]; + oldName = arguments[ 0 ]; + newName = arguments[ 1 ]; try { - repl.setDefaultTheme( name ); + repl.renameTheme( oldName, newName ); } catch ( err ) { repl._ostream.write( format( 'Error: %s\n', err.message ) ); return; } - log( repl, format( '\nSuccessfully updated default theme to `%s`.', name ) ); + log( repl, format( 'Successfully named theme `%s` to `%s`.', oldName, newName ) ); } } diff --git a/lib/node_modules/@stdlib/repl/lib/commands/theme.js b/lib/node_modules/@stdlib/repl/lib/commands/theme.js deleted file mode 100644 index 8c4d1a51d2a3..000000000000 --- a/lib/node_modules/@stdlib/repl/lib/commands/theme.js +++ /dev/null @@ -1,88 +0,0 @@ -/** -* @license Apache-2.0 -* -* Copyright (c) 2024 The Stdlib Authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -/* eslint-disable no-underscore-dangle */ - -'use strict'; - -// MODULES // - -var format = require( '@stdlib/string/format' ); -var log = require( './../log.js' ); - - -// MAIN // - -/** -* Returns a callback to be invoked upon calling the `theme` command. -* -* @private -* @param {REPL} repl - REPL instance -* @returns {Function} callback -*/ -function command( repl ) { - return onCommand; - - /** - * Gets (and sets) the color theme(s) for syntax-highlighting. - * - * @private - * @param {string} [name] - theme name - * @returns {void} - */ - function onCommand() { - var themes; - var theme; - var nargs; - var name; - var i; - - nargs = arguments.length; - - // If no theme name given, display current and available themes: - if ( nargs === 0 ) { - themes = repl.getThemes(); - theme = repl.getTheme(); - if ( themes.length === 0 ) { - repl._ostream.write( 'No themes available.' ); - return; - } - repl._ostream.write( format( 'Current theme: `%s`.\n', theme ) ); - repl._ostream.write( format( 'Available themes: `%s`', themes[ 0 ] ) ); - for ( i = 1; i < themes.length; i++ ) { - repl._ostream.write( format( ' ,`%s`', themes[ i ] ) ); - } - repl._ostream.write( '.\n' ); - return; - } - // Set theme: - name = arguments[ 0 ]; - try { - repl.setTheme( name ); - } catch ( err ) { - repl._ostream.write( format( 'Error: %s\n', err.message ) ); - return; - } - log( repl, format( '\nSuccessfully updated theme to `%s`.', name ) ); - } -} - - -// EXPORTS // - -module.exports = command; diff --git a/lib/node_modules/@stdlib/repl/lib/commands/themes.js b/lib/node_modules/@stdlib/repl/lib/commands/themes.js new file mode 100644 index 000000000000..69e2497068b4 --- /dev/null +++ b/lib/node_modules/@stdlib/repl/lib/commands/themes.js @@ -0,0 +1,66 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var format = require( '@stdlib/string/format' ); +var log = require( './../log.js' ); + + +// MAIN // + +/** +* Returns a callback to be invoked upon calling the `themes` command. +* +* @private +* @param {REPL} repl - REPL instance +* @returns {Function} callback +*/ +function command( repl ) { + return onCommand; + + /** + * Gets available color themes for syntax-highlighting. + * + * @private + * @returns {void} + */ + function onCommand() { + var output; + var themes; + var i; + + themes = repl.themes(); + if ( themes.length === 0 ) { + log( repl, 'No available themes.' ); + } + output = format( 'Available themes: `%s`', themes[ 0 ] ); + for ( i = 1; i < themes.length; i++ ) { + output += format( ' ,`%s`', themes[ i ] ); + } + output += '.'; + log( repl, output ); + } +} + + +// EXPORTS // + +module.exports = command; diff --git a/lib/node_modules/@stdlib/repl/lib/help_text.js b/lib/node_modules/@stdlib/repl/lib/help_text.js index 0367347655cd..9ca8a970b0c0 100644 --- a/lib/node_modules/@stdlib/repl/lib/help_text.js +++ b/lib/node_modules/@stdlib/repl/lib/help_text.js @@ -53,6 +53,12 @@ var MSG = [ ' renameWorkspace() Rename a specified workspace.', ' currentWorkspace Return the name of the current workspace.', '', + ' themes() List available color themes.', + ' addTheme(name,value) Add a new color theme.', + ' deleteTheme(name) Delete a specified color theme.', + ' renameTheme(old,new) Rename a specified color theme', + ' getTheme([name]) Get the current (or a specified) color theme palette.', + '', ' assignin() Assign a value to a workspace variable.', ' assignfrom() Read in a value from another workspace.', '', @@ -65,12 +71,6 @@ var MSG = [ ' deeprerequire() Re-import a module and its dependencies.', ' load() Load and evaluate a JavaScript file line-by-line.', '', - ' theme([name]) List, get and set color themes.', - ' defaultTheme([name]) Get and set the default color theme.', - ' addTheme(name,value) Add a new color theme.', - ' deleteTheme(name) Delete a specified theme.', - ' getTheme([name]) Get the current (or a specified) color theme palette.', - '', ' save() Save previous commands to a specified file.', ' saveStart() Start saving commands to a specified file.', ' saveStop() Stop saving commands.', diff --git a/lib/node_modules/@stdlib/repl/lib/main.js b/lib/node_modules/@stdlib/repl/lib/main.js index d84eba01bd12..87620f213e76 100644 --- a/lib/node_modules/@stdlib/repl/lib/main.js +++ b/lib/node_modules/@stdlib/repl/lib/main.js @@ -93,7 +93,6 @@ var debug = logger( 'repl' ); * @param {string} [options.welcome] - welcome message * @param {NonNegativeInteger} [options.padding=1] - number of empty lines between successive commands * @param {Object} [options.themes] - table mapping of color themes to load for syntax-highlighting -* @param {string} [options.defaultTheme] - name of the default theme to use for syntax-highlighting * @param {string} [options.load] - file path specifying a JavaScript file to load and evaluate line-by-line (e.g., a previous REPL history file) * @param {string} [options.save] - file path specifying where to save REPL command history * @param {string} [options.log] - file path specifying where to save REPL commands and printed output @@ -151,6 +150,8 @@ function REPL( options ) { opts.settings.autoPage = ( opts.settings.autoPage === void 0 ) ? opts.isTTY : opts.settings.autoPage; // eslint-disable-line max-len opts.settings.completionPreviews = ( opts.settings.completionPreviews === void 0 ) ? opts.isTTY : opts.settings.completionPreviews; // eslint-disable-line max-len opts.settings.syntaxHighlighting = ( opts.settings.syntaxHighlighting === void 0 ) ? opts.isTTY : opts.settings.syntaxHighlighting; // eslint-disable-line max-len + opts.settings.theme = ( opts.settings.theme === void 0 ) ? 'default' : opts.settings.theme; + opts.settings.defaultTheme = ( opts.settings.defaultTheme === void 0 ) ? 'default' : opts.settings.defaultTheme; debug( 'Options: %s', JSON.stringify({ 'input': '', @@ -317,9 +318,13 @@ function REPL( options ) { } } // Check whether to set a default theme upon startup... - if ( opts.defaultTheme ) { - this.setTheme( opts.defaultTheme ); - this.setDefaultTheme( opts.defaultTheme ); + if ( opts.settings.defaultTheme !== 'default' ) { + this._syntaxHighlighter.setTheme( opts.defaultTheme ); + this.settings( 'defaultTheme', opts.defaultTheme ); + } + // Check whether to set a current theme upon startup... + if ( opts.settings.theme !== 'default' ) { + this.settings( 'theme', opts.settings.theme ); } // Check whether to load and execute a JavaScript file (e.g., prior REPL history) upon startup... if ( opts.load ) { @@ -802,7 +807,7 @@ setNonEnumerableReadOnly( REPL.prototype, 'clearUserDocs', function clearUserDoc /** * Gets all available themes in the syntax-highlighter. * -* @name getThemes +* @name themes * @memberof REPL.prototype * @type {Function} * @returns {Array} array of all theme names @@ -818,87 +823,23 @@ setNonEnumerableReadOnly( REPL.prototype, 'clearUserDocs', function clearUserDoc * // ... * * // Fetch all themes: -* repl.getThemes(); +* repl.themes(); * * // ... * * // Close the REPL: * repl.close(); */ -setNonEnumerableReadOnly( REPL.prototype, 'getThemes', function getThemes() { +setNonEnumerableReadOnly( REPL.prototype, 'themes', function themes() { return this._syntaxHighlighter.getThemes(); }); /** -* Sets the current theme in the syntax-highlighter. -* -* @name setTheme -* @memberof REPL.prototype -* @type {Function} -* @param {string} theme - theme name -* @throws {TypeError} argument must be a string -* -* @example -* var debug = require( '@stdlib/streams/node/debug-sink' ); -* -* // Create a new REPL: -* var repl = new REPL({ -* 'output': debug() -* }); -* -* // ... -* -* // Fetch all themes: -* repl.setTheme( 'myTheme' ); -* -* // ... -* -* // Close the REPL: -* repl.close(); -*/ -setNonEnumerableReadOnly( REPL.prototype, 'setTheme', function setTheme( theme ) { - if ( !isString( theme ) ) { - throw new TypeError( format( 'invalid argument. First argument must be a string. Value: `%s`.', theme ) ); - } - this._syntaxHighlighter.setTheme( theme ); -}); - -/** -* Gets the current theme in the syntax-highlighter. +* Gets a theme's color configuration from the syntax-highlighter. * * @name getTheme * @memberof REPL.prototype * @type {Function} -* @returns {string} theme name -* -* @example -* var debug = require( '@stdlib/streams/node/debug-sink' ); -* -* // Create a new REPL: -* var repl = new REPL({ -* 'output': debug() -* }); -* -* // ... -* -* // Get current theme: -* repl.getTheme(); -* -* // ... -* -* // Close the REPL: -* repl.close(); -*/ -setNonEnumerableReadOnly( REPL.prototype, 'getTheme', function getTheme() { - return this._syntaxHighlighter.getTheme(); -}); - -/** -* Gets the theme's color configuration in the syntax-highlighter. -* -* @name getThemeConfig -* @memberof REPL.prototype -* @type {Function} * @param {string} theme - theme name * @throws {TypeError} argument must be a string * @returns {Object} theme object @@ -914,14 +855,14 @@ setNonEnumerableReadOnly( REPL.prototype, 'getTheme', function getTheme() { * // ... * * // Get theme object: -* repl.getThemeConfig( 'myTheme' ); +* repl.getTheme( 'myTheme' ); * * // ... * * // Close the REPL: * repl.close(); */ -setNonEnumerableReadOnly( REPL.prototype, 'getThemeConfig', function getThemeConfig( theme ) { +setNonEnumerableReadOnly( REPL.prototype, 'getTheme', function getTheme( theme ) { if ( !isString( theme ) ) { throw new TypeError( format( 'invalid argument. First argument must be a string. Value: `%s`.', theme ) ); } @@ -929,43 +870,15 @@ setNonEnumerableReadOnly( REPL.prototype, 'getThemeConfig', function getThemeCon }); /** -* Gets the default theme's name from the syntax-highlighter. -* -* @name getDefaultTheme -* @memberof REPL.prototype -* @type {Function} -* @returns {string} default theme name -* -* @example -* var debug = require( '@stdlib/streams/node/debug-sink' ); -* -* // Create a new REPL: -* var repl = new REPL({ -* 'output': debug() -* }); -* -* // ... -* -* // Get default theme name: -* repl.getDefaultTheme(); -* -* // ... -* -* // Close the REPL: -* repl.close(); -*/ -setNonEnumerableReadOnly( REPL.prototype, 'getDefaultTheme', function getDefaultTheme() { - return this._syntaxHighlighter.getDefaultTheme(); -}); - -/** -* Sets the default color theme in the syntax-highlighter. +* Adds a theme to the syntax-highlighter. * -* @name setDefaultTheme +* @name addTheme * @memberof REPL.prototype * @type {Function} -* @param {string} theme - theme name -* @throws {TypeError} argument must be a string +* @param {string} name - theme name +* @param {Object} theme - theme object +* @throws {TypeError} first argument must be a string +* @throws {TypeError} second argument must be an object * @returns {void} * * @example @@ -978,31 +891,37 @@ setNonEnumerableReadOnly( REPL.prototype, 'getDefaultTheme', function getDefault * * // ... * -* // Set default theme: -* repl.setDefaultTheme( 'myTheme' ); +* // Add a user-defined theme: +* repl.addTheme( 'myTheme', { +* 'keyword': 'red', +* 'variable': 'green' +* }); * * // ... * * // Close the REPL: * repl.close(); */ -setNonEnumerableReadOnly( REPL.prototype, 'setDefaultTheme', function setDefaultTheme( theme ) { - if ( !isString( theme ) ) { - throw new TypeError( format( 'invalid argument. First argument must be a string. Value: `%s`.', theme ) ); +setNonEnumerableReadOnly( REPL.prototype, 'addTheme', function addTheme( name, theme ) { + if ( !isString( name ) ) { + throw new TypeError( format( 'invalid argument. First argument must be a string. Value: `%s`.', name ) ); + } + if ( !isPlainObject( theme ) ) { + throw new TypeError( format( 'invalid argument. Second argument must be an object. Value: `%s`.', theme ) ); } - this._syntaxHighlighter.setDefaultTheme( theme ); + this._syntaxHighlighter.addTheme( name, theme ); }); /** -* Adds a theme to the syntax-highlighter. +* Renames a theme in the syntax-highlighter. * -* @name addTheme +* @name renameTheme * @memberof REPL.prototype * @type {Function} -* @param {string} name - theme name -* @param {Object} theme - theme object +* @param {string} oldName - old theme name +* @param {string} newName - new theme name * @throws {TypeError} first argument must be a string -* @throws {TypeError} second argument must be an object +* @throws {TypeError} second argument must be a string * @returns {void} * * @example @@ -1015,25 +934,22 @@ setNonEnumerableReadOnly( REPL.prototype, 'setDefaultTheme', function setDefault * * // ... * -* // Add a user-defined theme: -* repl.addTheme( 'myTheme', { -* 'keyword': 'red', -* 'variable': 'green' -* }); +* // Rename an existing theme: +* repl.renameTheme( 'myTheme', 'yourTheme' ); * * // ... * * // Close the REPL: * repl.close(); */ -setNonEnumerableReadOnly( REPL.prototype, 'addTheme', function addTheme( name, theme ) { - if ( !isString( name ) ) { - throw new TypeError( format( 'invalid argument. First argument must be a string. Value: `%s`.', name ) ); +setNonEnumerableReadOnly( REPL.prototype, 'renameTheme', function renameTheme( oldName, newName ) { + if ( !isString( oldName ) ) { + throw new TypeError( format( 'invalid argument. First argument must be a string. Value: `%s`.', oldName ) ); } - if ( !isPlainObject( theme ) ) { - throw new TypeError( format( 'invalid argument. Second argument must be an object. Value: `%s`.', theme ) ); + if ( !isString( newName ) ) { + throw new TypeError( format( 'invalid argument. Second argument must be a string. Value: `%s`.', newName ) ); } - this._syntaxHighlighter.addTheme( name, theme ); + this._syntaxHighlighter.renameTheme( oldName, newName ); }); /** @@ -1507,6 +1423,10 @@ setNonEnumerableReadOnly( REPL.prototype, 'settings', function settings() { } else { this._syntaxHighlighter.disable(); } + } else if ( name === 'theme' ) { + this._syntaxHighlighter.setTheme( value ); + } else if ( name === 'defaultTheme' ) { + this._syntaxHighlighter.setDefaultTheme( value ); } return this; diff --git a/lib/node_modules/@stdlib/repl/lib/settings.js b/lib/node_modules/@stdlib/repl/lib/settings.js index cfd992926893..76290be4ecc6 100644 --- a/lib/node_modules/@stdlib/repl/lib/settings.js +++ b/lib/node_modules/@stdlib/repl/lib/settings.js @@ -47,6 +47,14 @@ var SETTINGS = { 'syntaxHighlighting': { 'desc': 'Enable syntax highlighting of the input.', 'type': 'boolean' + }, + 'theme': { + 'desc': 'Set the color theme for syntax-highlighting.', + 'type': 'string' + }, + 'defaultTheme': { + 'desc': 'Set the default color theme for syntax-highlighting.', + 'type': 'string' } }; diff --git a/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js b/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js index a63519efed83..15b764fd1e88 100644 --- a/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js +++ b/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js @@ -171,18 +171,6 @@ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'setTheme', function setT this._theme = theme; }); -/** -* Gets current theme name. -* -* @name getTheme -* @memberof SyntaxHighlighter.prototype -* @type {Function} -* @returns {Object} theme name -*/ -setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'getTheme', function getTheme() { - return this._theme; -}); - /** * Gets a theme's colors configuration. * @@ -200,18 +188,6 @@ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'getThemeConfig', functio return this._themes[ theme ]; }); -/** -* Gets the default color theme name. -* -* @name getDefaultTheme -* @memberof SyntaxHighlighter.prototype -* @type {Function} -* @returns {string} default theme name -*/ -setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'getDefaultTheme', function getDefaultTheme() { - return this._defaultTheme; -}); - /** * Sets the default color theme. * @@ -240,6 +216,24 @@ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'addTheme', function addT this._themes[ name ] = theme; }); +/** +* Renames a color theme. +* +* @name renameTheme +* @memberof SyntaxHighlighter.prototype +* @type {Function} +* @param {string} oldName - old theme name +* @param {string} newName - new theme name +* @throws {Error} first argument must be an existing theme name +*/ +setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'renameTheme', function renameTheme( oldName, newName ) { + if ( !contains( objectKeys( this._themes ), oldName ) ) { + throw new Error( format( 'invalid argument. First argument must be an existing theme name. Value: `%s`.', oldName ) ); + } + this._themes[ newName ] = this._themes[ oldName ]; + this._themes = omit( this._themes, oldName ); +}); + /** * Deletes a color theme. * diff --git a/lib/node_modules/@stdlib/repl/lib/validate.js b/lib/node_modules/@stdlib/repl/lib/validate.js index 8a2f9cffbd01..11ce529317d8 100644 --- a/lib/node_modules/@stdlib/repl/lib/validate.js +++ b/lib/node_modules/@stdlib/repl/lib/validate.js @@ -113,12 +113,6 @@ function validate( opts, options ) { return new TypeError( format( 'invalid option. `%s` option must be an object. Option: `%s`.', 'themes', options.themes ) ); } } - if ( hasOwnProp( options, 'defaultTheme' ) ) { - opts.defaultTheme = options.defaultTheme; - if ( !isString( options.defaultTheme ) ) { - return new TypeError( format( 'invalid option. `%s` option must be a string. Option: `%s`.', 'defaultTheme', options.defaultTheme ) ); - } - } if ( hasOwnProp( options, 'save' ) ) { opts.save = options.save; if ( !isString( options.save ) ) { From f466ab3b545e3751c3c241e99e638d6c8792f6d1 Mon Sep 17 00:00:00 2001 From: Snehil Shah Date: Sun, 2 Jun 2024 12:45:04 +0000 Subject: [PATCH 07/33] refactor: move `await` keyword to a control keyword Following IDE conventions like VSCode Signed-off-by: Snehil Shah --- lib/node_modules/@stdlib/repl/lib/tokenizer.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/node_modules/@stdlib/repl/lib/tokenizer.js b/lib/node_modules/@stdlib/repl/lib/tokenizer.js index aeee8b29da04..41f16968341b 100644 --- a/lib/node_modules/@stdlib/repl/lib/tokenizer.js +++ b/lib/node_modules/@stdlib/repl/lib/tokenizer.js @@ -16,7 +16,7 @@ * limitations under the License. */ -/* eslint-disable max-lines-per-function */ +/* eslint-disable max-lines-per-function, id-length */ 'use strict'; @@ -34,10 +34,12 @@ var commands = require( './commands.js' ); // VARIABLES // var COMMANDS = commands(); +var isUnrecognizedKeyword = contains.factory( [ 'async', 'let' ] ); var isControlKeyword = contains.factory( [ 'if', 'else', 'switch', 'case', 'catch', 'finally', 'try', 'return', 'break', 'continue' ] ); +var isUnrecognizedControlKeyword = contains.factory( [ 'await' ] ); var isSpecialIdentifier = contains.factory( [ 'this', 'super' ] ); var isReservedLiteral = contains.factory( [ 'null', 'true', 'false' ] ); -var isUnrecognizedKeyword = contains.factory( [ 'async', 'await', 'let' ] ); +var isUnrecognizedReservedLiteral = contains.factory( [ 'undefined' ] ); var isStringTokenType = contains.factory( [ 'string', 'template' ] ); var isLiteralType = contains.factory( [ 'string', 'boolean', 'number' ] ); var isReservedName = contains.factory( [ 'undefined', 'async', 'await', 'let' ] ); @@ -104,7 +106,7 @@ function tokenizer( line, context ) { if ( token.start === token.end ) { return; } - if ( token.type.isLoop || isControlKeyword( token.type.keyword ) ) { + if ( token.type.isLoop || isControlKeyword( token.type.keyword ) || ( token.type.label === 'name' && isUnrecognizedControlKeyword( token.value ) ) ) { // Control flow keywords - `for`, `while`, `do`, `if`, `else` etc: token.type = 'control'; tokens.push( token ); @@ -198,11 +200,11 @@ function tokenizer( line, context ) { return true; } // Ignore node if it is an unrecognized `keyword`: - if ( isUnrecognizedKeyword( node.name ) ) { + if ( isUnrecognizedKeyword( node.name ) || isUnrecognizedControlKeyword( node.name ) ) { // eslint-disable-line max-len return true; } // If node is an unrecognized `literal`, push it as a token: - if ( node.name === 'undefined' ) { + if ( isUnrecognizedReservedLiteral( node.name ) ) { tokens.push({ 'value': node.name, 'type': 'literal', From 1fd60701e6e6b91c15ff9468769f16e6e6c435ad Mon Sep 17 00:00:00 2001 From: Snehil Shah Date: Sun, 2 Jun 2024 13:09:43 +0000 Subject: [PATCH 08/33] fix: resolve `null` try parameters crashing the REPL Found the bug when testing against `try{} catch` as `resolveLocalScopes` was returning null nodes. This is not specific to the syntax highlighter but specific to the function. You can also reproduce the bug by turning off the syntax highlighter and clicking TAB after writing the above expression Signed-off-by: Snehil Shah --- lib/node_modules/@stdlib/repl/lib/resolve_local_scopes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/repl/lib/resolve_local_scopes.js b/lib/node_modules/@stdlib/repl/lib/resolve_local_scopes.js index 7ec3cdaff12d..a4f1b314c133 100644 --- a/lib/node_modules/@stdlib/repl/lib/resolve_local_scopes.js +++ b/lib/node_modules/@stdlib/repl/lib/resolve_local_scopes.js @@ -223,7 +223,7 @@ function resolveScopes( ast ) { * @param {Array} parents - array of parent AST nodes */ function TryStatement( node ) { - if ( node.handler ) { + if ( node.handler && node.handler.param ) { node.handler.locals = node.handler.locals || []; appendUnique( node.handler.locals, node.handler.param.name ); appendUnique( declarations, node.handler.param ); From f8c10a41ffe116ac22b12afb1a43a01ecd0dc196 Mon Sep 17 00:00:00 2001 From: Snehil Shah Date: Sun, 2 Jun 2024 14:07:46 +0000 Subject: [PATCH 09/33] fix: don't throw error if a node doesn't match a declaration When writing an expression like (4) => , it was throwing an error as the declaration pattern was of type `Literal` and the default case was raising an error. Signed-off-by: Snehil Shah --- lib/node_modules/@stdlib/repl/lib/resolve_local_scopes.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/node_modules/@stdlib/repl/lib/resolve_local_scopes.js b/lib/node_modules/@stdlib/repl/lib/resolve_local_scopes.js index a4f1b314c133..1a0be6bcafb6 100644 --- a/lib/node_modules/@stdlib/repl/lib/resolve_local_scopes.js +++ b/lib/node_modules/@stdlib/repl/lib/resolve_local_scopes.js @@ -21,7 +21,6 @@ // MODULES // var walk = require( 'acorn-walk' ).ancestor; -var format = require( '@stdlib/string/format' ); var appendUnique = require( './append_unique.js' ); var isScope = require( './is_scope.js' ); var isBlockScope = require( './is_block_scope.js' ); @@ -129,7 +128,7 @@ function resolveScopes( ast ) { break; default: - throw new Error( format( 'internal error. Unrecognized pattern type: `%s`.', node.type ) ); + break; } } From 5c9b7f6b579cde4ada4e1e738e78375cb44da9a6 Mon Sep 17 00:00:00 2001 From: Snehil Shah Date: Sun, 2 Jun 2024 14:40:56 +0000 Subject: [PATCH 10/33] fix: handle member expressions like `foo['bar']` Signed-off-by: Snehil Shah --- .../@stdlib/repl/lib/tokenizer.js | 55 ++++++++++++------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/lib/node_modules/@stdlib/repl/lib/tokenizer.js b/lib/node_modules/@stdlib/repl/lib/tokenizer.js index 41f16968341b..4d63bdfc6e99 100644 --- a/lib/node_modules/@stdlib/repl/lib/tokenizer.js +++ b/lib/node_modules/@stdlib/repl/lib/tokenizer.js @@ -305,28 +305,43 @@ function tokenizer( line, context ) { // Fetch properties from context: property = properties.next(); while ( !property.done ) { - obj = obj[ property.value.name ]; - if ( !obj ) { - // Property not found in context: - break; + // Case: 'bar' in `foo['bar']` - property already pushed as a string token. Ignore... + if ( property.value.type === 'Literal' ) { + obj = obj[ property.value.value ]; + if ( !obj ) { + // Property not found in context: + break; + } + property = properties.next(); + continue; } - // Push token if property exists in context: - if ( isLiteralType( typeof obj ) ) { - tokens.push({ - 'value': property.value.name, - 'type': 'variable', - 'start': property.value.start, - 'end': property.value.end - }); - } else { - tokens.push({ - 'value': property.value.name, - 'type': typeof obj, - 'start': property.value.start, - 'end': property.value.end - }); + // Case: `foo.bar`: + if ( property.value.type === 'Identifier' ) { + obj = obj[ property.value.name ]; + if ( !obj ) { + // Property not found in context: + break; + } + // Push token if property exists in context: + if ( isLiteralType( typeof obj ) ) { + tokens.push({ + 'value': property.value.name, + 'type': 'variable', + 'start': property.value.start, + 'end': property.value.end + }); + } else { + tokens.push({ + 'value': property.value.name, + 'type': typeof obj, + 'start': property.value.start, + 'end': property.value.end + }); + } + property = properties.next(); + continue; } - property = properties.next(); + break; } /** From 3e7d7ba454de99094bd0a06c47aaac444798ce28 Mon Sep 17 00:00:00 2001 From: Snehil Shah Date: Sun, 2 Jun 2024 14:49:03 +0000 Subject: [PATCH 11/33] test: add tests for the syntax highlighter Signed-off-by: Snehil Shah --- .../syntax-highlighting/comments.json | 7 + .../syntax-highlighting/control_keywords.json | 7 + .../declaration_names.json | 7 + .../syntax-highlighting/functions.json | 7 + .../syntax-highlighting/keywords.json | 7 + .../syntax-highlighting/local_scopes.json | 7 + .../member_expressions.json | 8 + .../syntax-highlighting/numeric_literals.json | 7 + .../fixtures/syntax-highlighting/objects.json | 7 + .../syntax-highlighting/operators.json | 7 + .../syntax-highlighting/punctuation.json | 7 + .../fixtures/syntax-highlighting/regexp.json | 7 + .../reserved_literals.json | 7 + .../special_identifiers.json | 7 + .../syntax-highlighting/string_literals.json | 7 + .../syntax-highlighting/variables.json | 7 + .../integration/test.syntax_highlighting.js | 203 ++++++++++++++++++ 17 files changed, 316 insertions(+) create mode 100644 lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/comments.json create mode 100644 lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/control_keywords.json create mode 100644 lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/declaration_names.json create mode 100644 lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/functions.json create mode 100644 lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/keywords.json create mode 100644 lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/local_scopes.json create mode 100644 lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/member_expressions.json create mode 100644 lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/numeric_literals.json create mode 100644 lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/objects.json create mode 100644 lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/operators.json create mode 100644 lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/punctuation.json create mode 100644 lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/regexp.json create mode 100644 lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/reserved_literals.json create mode 100644 lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/special_identifiers.json create mode 100644 lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/string_literals.json create mode 100644 lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/variables.json create mode 100644 lib/node_modules/@stdlib/repl/test/integration/test.syntax_highlighting.js diff --git a/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/comments.json b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/comments.json new file mode 100644 index 000000000000..aa8f8d24fe92 --- /dev/null +++ b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/comments.json @@ -0,0 +1,7 @@ +{ + "expression": "var a; // This is a comment", + "expected": "var a; \u001b[31m// This is a comment\u001b[0m", + "theme": { + "comment": "red" + } +} diff --git a/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/control_keywords.json b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/control_keywords.json new file mode 100644 index 000000000000..7baaf3f80329 --- /dev/null +++ b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/control_keywords.json @@ -0,0 +1,7 @@ +{ + "expression": "async function foo(a) { if (a) { return a; } else { try { switch(a) { case 0: return await Promise.resolve(a); } } catch (e) { return e; } } }", + "expected": "async function foo(a) { \u001b[31mif\u001b[0m (a) { \u001b[31mreturn\u001b[0m a; } \u001b[31melse\u001b[0m { \u001b[31mtry\u001b[0m { \u001b[31mswitch\u001b[0m(a) { \u001b[31mcase\u001b[0m 0: \u001b[31mreturn\u001b[0m \u001b[31mawait\u001b[0m Promise.resolve(a); } } \u001b[31mcatch\u001b[0m (e) { \u001b[31mreturn\u001b[0m e; } } }", + "theme": { + "control": "red" + } +} diff --git a/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/declaration_names.json b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/declaration_names.json new file mode 100644 index 000000000000..cde8e9e830f9 --- /dev/null +++ b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/declaration_names.json @@ -0,0 +1,7 @@ +{ + "expression": "let a; function b(x) => 4; class d", + "expected": "let \u001b[31ma\u001b[0m; function \u001b[31mb\u001b[0m(\u001b[31mx\u001b[0m) => 4; class \u001b[31md\u001b[0m", + "theme": { + "name": "red" + } +} diff --git a/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/functions.json b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/functions.json new file mode 100644 index 000000000000..ba51fbf2d81a --- /dev/null +++ b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/functions.json @@ -0,0 +1,7 @@ +{ + "expression": "var a = () => true;\na", + "expected": "\u001b[31ma\u001b[0m", + "theme": { + "function": "red" + } +} diff --git a/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/keywords.json b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/keywords.json new file mode 100644 index 000000000000..a7e63fe12d7a --- /dev/null +++ b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/keywords.json @@ -0,0 +1,7 @@ +{ + "expression": "var a = 4; const b = 5; let a = async () => {}; function foo() { return a; } class", + "expected": "\u001b[31mvar\u001b[0m a = 4; \u001b[31mconst\u001b[0m b = 5; \u001b[31mlet\u001b[0m a = \u001b[31masync\u001b[0m () => {}; \u001b[31mfunction\u001b[0m foo() { return a; } \u001b[31mclass\u001b[0m", + "theme": { + "keyword": "red" + } +} diff --git a/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/local_scopes.json b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/local_scopes.json new file mode 100644 index 000000000000..99977d66bfc0 --- /dev/null +++ b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/local_scopes.json @@ -0,0 +1,7 @@ +{ + "expression": "let a = 4; a", + "expected": "let a = 4; \u001b[31ma\u001b[0m", + "theme": { + "variable": "red" + } +} diff --git a/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/member_expressions.json b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/member_expressions.json new file mode 100644 index 000000000000..64bff84df0c7 --- /dev/null +++ b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/member_expressions.json @@ -0,0 +1,8 @@ +{ + "expression": "var foo = { 'bar': { 'func': function() { return true; } } };\nfoo['bar'].func()", + "expected": "\u001b[31mfoo\u001b[0m['bar'].\u001b[33mfunc\u001b[0m()", + "theme": { + "object": "red", + "function": "yellow" + } +} diff --git a/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/numeric_literals.json b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/numeric_literals.json new file mode 100644 index 000000000000..ffdf0d779db5 --- /dev/null +++ b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/numeric_literals.json @@ -0,0 +1,7 @@ +{ + "expression": "34 + 45.78", + "expected": "\u001b[31m34\u001b[0m + \u001b[31m45.78\u001b[0m", + "theme": { + "number": "red" + } +} diff --git a/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/objects.json b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/objects.json new file mode 100644 index 000000000000..798e65412f21 --- /dev/null +++ b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/objects.json @@ -0,0 +1,7 @@ +{ + "expression": "var a = { 'b': 4 };\na", + "expected": "\u001b[31ma\u001b[0m", + "theme": { + "object": "red" + } +} diff --git a/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/operators.json b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/operators.json new file mode 100644 index 000000000000..fe63210b66e1 --- /dev/null +++ b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/operators.json @@ -0,0 +1,7 @@ +{ + "expression": "var a = 5 + 10 * 2 / (4 - 2) == 15 && 10 > 5 || 5 < 10; var b = 5; b++", + "expected": "var a \u001b[31m=\u001b[0m 5 \u001b[31m+\u001b[0m 10 \u001b[31m*\u001b[0m 2 \u001b[31m/\u001b[0m (4 \u001b[31m-\u001b[0m 2) \u001b[31m==\u001b[0m 15 \u001b[31m&&\u001b[0m 10 \u001b[31m>\u001b[0m 5 \u001b[31m||\u001b[0m 5 \u001b[31m<\u001b[0m 10; var b \u001b[31m=\u001b[0m 5; b\u001b[31m++\u001b[0m", + "theme": { + "operator": "red" + } +} diff --git a/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/punctuation.json b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/punctuation.json new file mode 100644 index 000000000000..4023f7697d4d --- /dev/null +++ b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/punctuation.json @@ -0,0 +1,7 @@ +{ + "expression": "let obj = {a: 1, b: 2}; let func = (x) => x * 2; let ternary = [1, 2] ? true : false", + "expected": "let obj = \u001b[31m{\u001b[0ma\u001b[31m:\u001b[0m 1\u001b[31m,\u001b[0m b\u001b[31m:\u001b[0m 2\u001b[31m}\u001b[0m\u001b[31m;\u001b[0m let func = \u001b[31m(\u001b[0mx\u001b[31m)\u001b[0m \u001b[31m=>\u001b[0m x * 2\u001b[31m;\u001b[0m let ternary = \u001b[31m[\u001b[0m1\u001b[31m,\u001b[0m 2\u001b[31m]\u001b[0m \u001b[31m?\u001b[0m true \u001b[31m:\u001b[0m false", + "theme": { + "punctuation": "red" + } +} diff --git a/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/regexp.json b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/regexp.json new file mode 100644 index 000000000000..1df483bc8c0b --- /dev/null +++ b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/regexp.json @@ -0,0 +1,7 @@ +{ + "expression": "/\\d+/g;", + "expected": "\u001b[31m/\\d+/g\u001b[0m;", + "theme": { + "regexp": "red" + } +} diff --git a/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/reserved_literals.json b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/reserved_literals.json new file mode 100644 index 000000000000..97a9ac2bbb84 --- /dev/null +++ b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/reserved_literals.json @@ -0,0 +1,7 @@ +{ + "expression": "let a = true; let b = false; let c = null; let d = undefined;", + "expected": "let a = \u001b[31mtrue\u001b[0m; let b = \u001b[31mfalse\u001b[0m; let c = \u001b[31mnull\u001b[0m; let d = \u001b[31mundefined\u001b[0m;", + "theme": { + "literal": "red" + } +} diff --git a/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/special_identifiers.json b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/special_identifiers.json new file mode 100644 index 000000000000..cf2308dc5efb --- /dev/null +++ b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/special_identifiers.json @@ -0,0 +1,7 @@ +{ + "expression": "class Foo { constructor() { this.a = 1; } } class Bar extends Foo { constructor() { super(); this.b = 2; } }", + "expected": "class Foo { constructor() { \u001b[31mthis\u001b[0m.a = 1; } } class Bar extends Foo { constructor() { \u001b[31msuper\u001b[0m(); \u001b[31mthis\u001b[0m.b = 2; } }", + "theme": { + "specialIdentifier": "red" + } +} diff --git a/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/string_literals.json b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/string_literals.json new file mode 100644 index 000000000000..7b50dba3d4e6 --- /dev/null +++ b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/string_literals.json @@ -0,0 +1,7 @@ +{ + "expression": "var a = 'hello'; var b = `2 + 2 = ${4} haha`;", + "expected": "var a = \u001b[31m'hello'\u001b[0m; var b = `\u001b[31m2 + 2 = \u001b[0m${4}\u001b[31m haha\u001b[0m`;", + "theme": { + "string": "red" + } +} diff --git a/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/variables.json b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/variables.json new file mode 100644 index 000000000000..2f2df467c0d1 --- /dev/null +++ b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/variables.json @@ -0,0 +1,7 @@ +{ + "expression": "var a = true;\na", + "expected": "\u001b[31ma\u001b[0m", + "theme": { + "variable": "red" + } +} diff --git a/lib/node_modules/@stdlib/repl/test/integration/test.syntax_highlighting.js b/lib/node_modules/@stdlib/repl/test/integration/test.syntax_highlighting.js new file mode 100644 index 000000000000..71ca8dfc16d9 --- /dev/null +++ b/lib/node_modules/@stdlib/repl/test/integration/test.syntax_highlighting.js @@ -0,0 +1,203 @@ +/** +* @license Apache-2.0 +* +* Copyright (c) 2024 The Stdlib Authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +'use strict'; + +// MODULES // + +var resolve = require( 'path' ).resolve; +var tape = require( 'tape' ); +var DebugStream = require( '@stdlib/streams/node/debug' ); +var replace = require( '@stdlib/string/replace' ); +var readDir = require( '@stdlib/fs/read-dir' ).sync; +var format = require( '@stdlib/string/format' ); +var repl = require( './fixtures/repl.js' ); + + +// VARIABLES // + +var RE_JSON = /\.json$/; + +var FIXTURES_DIR = resolve( __dirname, 'fixtures', 'syntax-highlighting' ); +var FIXTURES_FILES = filter( readDir( FIXTURES_DIR ) ); + + +// FUNCTIONS // + +/** +* Filters a list of files for those having a `*.json` file extension. +* +* @private +* @param {Array} list - file list +* @returns {Array} filtered list +*/ +function filter( list ) { + var out; + var i; + + out = []; + for ( i = 0; i < list.length; i++ ) { + if ( RE_JSON.test( list[ i ] ) ) { + out.push( list[ i ] ); + } + } + return out; +} + +/** +* Returns default settings. +* +* @private +* @returns {Object} default settings +*/ +function defaultSettings() { + return { + 'autoClosePairs': false, + 'autoDeletePairs': false, + 'autoPage': false, + 'completionPreviews': false, + 'syntaxHighlighting': true + }; +} + +/** +* Asserts that a provided expression triggers expected syntax highlighting. +* +* @private +* @param {Object} t - test object +* @param {Object} fixture - fixture object +* @param {string} fixture.expression - expression string +* @param {string} fixture.expected - expected/highlighted string +* @param {Object} fixture.theme - test theme +* @param {Function} done - callback to invoke upon completion +*/ +function assert( t, fixture, done ) { + var expression; + var expected; + var istream; + var opts; + var r; + + istream = new DebugStream({ + 'name': 'repl-input-stream' + }); + opts = { + 'input': istream, + 'inputPrompt': '', + 'quiet': true, + 'settings': defaultSettings() + }; + r = repl( opts, onClose ); + + // Load test theme: + r.addTheme( 'test', fixture.theme ); + r.settings( 'theme', 'test' ); + + // Get expression and expected strings: + expression = fixture.expression; + expected = fixture.expected; + + // Emulate the presence of an existing expression: + istream.write( expression ); + + // Close the input stream: + istream.end(); + + // Close the REPL: + r.close(); + + function onClose( error, data ) { + var actual; + if ( error ) { + t.fail( error.message ); + return; + } + actual = data[ data.length - 1 ]; + t.strictEqual( actual, expected, 'returns expected value' ); + done(); + } +} + +/** +* Generates a test name from a fixture file name. +* +* @private +* @param {string} msg - test description +* @param {string} filename - file name +* @returns {string} test name +*/ +function testName( msg, filename ) { + var str = replace( filename, RE_JSON, '' ); + str = replace( str, '_', ' ' ); + return format( '%s (%s)', msg, str ); +} + +/** +* Returns a test function for testing against a specified fixture file. +* +* @private +* @param {string} fpath - fixture file path +* @param {Function} assert - assertion function +* @returns {Function} test function +*/ +function testFcn( fpath, assert ) { + return test; + + function test( t ) { + var fixture = require( fpath ); // eslint-disable-line stdlib/no-dynamic-require + assert( t, fixture, done ); + + function done() { + t.end(); + } + } +} + +/** +* Run tests against test fixtures. +* +* @private +* @param {string} msg - test description +* @param {string} dir - fixtures directory +* @param {Array} fixtures - list of fixtures +* @param {Function} assert - assert function +*/ +function test( msg, dir, fixtures, assert ) { + var fpath; + var f; + var t; + var i; + + for ( i = 0; i < fixtures.length; i++ ) { + f = fixtures[ i ]; + t = testName( msg, f ); + fpath = resolve( dir, f ); + tape( t, testFcn( fpath, assert ) ); + } +} + + +// TESTS // + +tape( 'main export is a function', function test( t ) { + t.ok( true, __filename ); + t.strictEqual( typeof repl, 'function', 'main export is a function' ); + t.end(); +}); + +test( 'a REPL instance supports syntax highlighting of the input', FIXTURES_DIR, FIXTURES_FILES, assert ); From 570f24ecfcbd957ab215f394cf298fe524552bbf Mon Sep 17 00:00:00 2001 From: Snehil Shah Date: Sun, 2 Jun 2024 14:59:23 +0000 Subject: [PATCH 12/33] refactor: clean code logic Signed-off-by: Snehil Shah --- .../@stdlib/repl/lib/syntax_highlighter.js | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js b/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js index 15b764fd1e88..8983f76589ef 100644 --- a/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js +++ b/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js @@ -295,7 +295,6 @@ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'enable', function enable * @returns {void} */ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'onKeypress', function onKeypress() { - var highlightedLine; var tokens; if ( !this._enabled ) { @@ -305,11 +304,8 @@ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'onKeypress', function on debug( 'Empty line detected. Skipping highlighting...' ); return; } - // If no line change is detected, use the highlighted line from cache... - if ( this._line === this._rli.line ) { - debug( 'No line change detected. Using cache...' ); - highlightedLine = this._highlightedLine; - } else { + // If line change is detected, tokenize & highlight the line. Use cache if no line change is detected... + if ( this._line !== this._rli.line ) { // Update line buffer: this._line = this._rli.line; @@ -322,16 +318,13 @@ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'onKeypress', function on } // Highlight: debug( '%d tokens found. Highlighting...', tokens.length ); - highlightedLine = this._highlightLine( this._line, tokens ); - - // Cache the newly highlighted line: - this._highlightedLine = highlightedLine; + this._highlightedLine = this._highlightLine( this._line, tokens ); } // Replace: debug( 'Replacing current line with the highlighted line...' ); readline.moveCursor( this._ostream, -1 * this._rli.cursor, 0 ); readline.clearLine( this._ostream, 1 ); - this._ostream.write( highlightedLine ); + this._ostream.write( this._highlightedLine ); readline.moveCursor( this._ostream, this._rli.cursor - this._line.length, 0 ); // eslint-disable-line max-len }); From 7f31a89730888b114828768f8358f0ee1d59d732 Mon Sep 17 00:00:00 2001 From: Snehil Shah Date: Sun, 2 Jun 2024 15:28:56 +0000 Subject: [PATCH 13/33] docs: document added prototype methods and settings Signed-off-by: Snehil Shah --- lib/node_modules/@stdlib/repl/README.md | 143 ++++++++++++++++++ lib/node_modules/@stdlib/repl/lib/defaults.js | 11 +- lib/node_modules/@stdlib/repl/lib/main.js | 6 +- 3 files changed, 156 insertions(+), 4 deletions(-) diff --git a/lib/node_modules/@stdlib/repl/README.md b/lib/node_modules/@stdlib/repl/README.md index 3e7f7bfb3947..d0d03a1460fb 100644 --- a/lib/node_modules/@stdlib/repl/README.md +++ b/lib/node_modules/@stdlib/repl/README.md @@ -71,6 +71,7 @@ The function accepts the following `options`: - **outputPrompt**: output prompt. If the output prompt includes the character sequence `%d`, the output prompt includes line numbers. Default: `'Out[%d]: '`. - **welcome**: welcome message. - **padding**: number of empty lines between consecutive commands. Default: `1`. +- **themes**: table mapping of color themes to load for syntax-highlighting - **load**: file path specifying a JavaScript file to load and evaluate line-by-line (e.g., a previous REPL history file). - **save**: file path specifying where to save REPL command history. - **log**: file path specifying where to save REPL commands and printed output. @@ -83,6 +84,28 @@ The function supports specifying the following settings: - **autoDeletePairs**: boolean indicating whether to automatically delete adjacent matching brackets, parentheses, and quotes. Default: `true`. - **autoPage**: boolean indicating whether to automatically page return values having a display size exceeding the visible screen. When streams are TTY, the default is `true`; otherwise, the default is `false`. - **completionPreviews**: boolean indicating whether to display completion previews for auto-completion. When streams are TTY, the default is `true`; otherwise, the default is `false`. +- **syntaxHighlighting**: boolean indicating whether to enable syntax highlighting of the input. When streams are TTY, the default is `true`; otherwise, the default is `false`. +- **theme**: theme to set upon REPL startup. Default: `default`. +- **defaultTheme**: default theme to set upon REPL startup. Default: `default`. + +#### REPL.prototype.viewport() + +Returns the REPL viewport. + +```javascript +var debug = require( '@stdlib/streams/node/debug-sink' ); + +// Create a new REPL: +var repl = new REPL({ + 'output': debug() +}); + +// Query the REPL viewport: +var v = repl.viewport(); + +// Close the REPL: +repl.close(); +``` #### REPL.prototype.createContext() @@ -176,6 +199,126 @@ repl.clearUserDocs(); repl.close(); ``` +#### Repl.prototype.themes() + +Returns all available themes in the syntax-highlighter. + +```javascript +var debug = require( '@stdlib/streams/node/debug-sink' ); + +// Create a new REPL: +var repl = new REPL({ + 'output': debug() +}); + +// ... + +// Fetch all available themes: +repl.themes(); + +// ... + +// Close the REPL: +repl.close(); +``` + +#### Repl.prototype.getTheme() + +Returns all available themes in the syntax-highlighter. + +```javascript +var debug = require( '@stdlib/streams/node/debug-sink' ); + +// Create a new REPL: +var repl = new REPL({ + 'output': debug() +}); + +// ... + +// Fetch all available themes: +repl.themes(); + +// ... + +// Close the REPL: +repl.close(); +``` + +#### Repl.prototype.addTheme() + +Adds a color theme to the syntax-highlighter. + +```javascript +var debug = require( '@stdlib/streams/node/debug-sink' ); + +// Create a new REPL: +var repl = new REPL({ + 'output': debug() +}); + +// ... + +// Add a user-defined theme: +repl.addTheme( 'myTheme', { + 'keyword': 'red', + 'variable': 'green' + + // ... +}); + +// ... + +// Close the REPL: +repl.close(); +``` + +#### Repl.prototype.deleteTheme() + +Deletes a specified theme from the syntax-highlighter. + +```javascript +var debug = require( '@stdlib/streams/node/debug-sink' ); + +// Create a new REPL: +var repl = new REPL({ + 'output': debug() +}); + +// ... + +// Delete an existing theme: +repl.deleteTheme( 'myTheme' ); + +// ... + +// Close the REPL: +repl.close(); +``` + +#### Repl.prototype.renameTheme() + +Renames a specified theme in the syntax-highlighter. + +```javascript +var debug = require( '@stdlib/streams/node/debug-sink' ); + +// Create a new REPL: +var repl = new REPL({ + 'output': debug() +}); + +// ... + +// Rename an existing theme: +repl.renameTheme( 'myTheme', 'yourTheme' ); + +// ... + +// Close the REPL: +repl.close(); +``` + #### REPL.prototype.load( fpath, clbk ) Loads and evaluates a JavaScript file line-by-line. diff --git a/lib/node_modules/@stdlib/repl/lib/defaults.js b/lib/node_modules/@stdlib/repl/lib/defaults.js index 52ea52ee72bc..9b76e412d121 100644 --- a/lib/node_modules/@stdlib/repl/lib/defaults.js +++ b/lib/node_modules/@stdlib/repl/lib/defaults.js @@ -90,7 +90,16 @@ function defaults() { 'autoPage': void 0, // Flag indicating whether to enable the display of completion previews for auto-completion (note: default depends on whether TTY): - 'completionPreviews': void 0 + 'completionPreviews': void 0, + + // Flag indicating whether to enable syntax highlighting of the input (note: default depends on whether TTY): + 'syntaxHighlighting': void 0, + + // Theme for syntax highlighting: + 'theme': 'default', + + // Default theme for syntax highlighting: + 'defaultTheme': 'default' } }; } diff --git a/lib/node_modules/@stdlib/repl/lib/main.js b/lib/node_modules/@stdlib/repl/lib/main.js index 87620f213e76..40fbf90794da 100644 --- a/lib/node_modules/@stdlib/repl/lib/main.js +++ b/lib/node_modules/@stdlib/repl/lib/main.js @@ -150,8 +150,6 @@ function REPL( options ) { opts.settings.autoPage = ( opts.settings.autoPage === void 0 ) ? opts.isTTY : opts.settings.autoPage; // eslint-disable-line max-len opts.settings.completionPreviews = ( opts.settings.completionPreviews === void 0 ) ? opts.isTTY : opts.settings.completionPreviews; // eslint-disable-line max-len opts.settings.syntaxHighlighting = ( opts.settings.syntaxHighlighting === void 0 ) ? opts.isTTY : opts.settings.syntaxHighlighting; // eslint-disable-line max-len - opts.settings.theme = ( opts.settings.theme === void 0 ) ? 'default' : opts.settings.theme; - opts.settings.defaultTheme = ( opts.settings.defaultTheme === void 0 ) ? 'default' : opts.settings.defaultTheme; debug( 'Options: %s', JSON.stringify({ 'input': '', @@ -822,7 +820,7 @@ setNonEnumerableReadOnly( REPL.prototype, 'clearUserDocs', function clearUserDoc * * // ... * -* // Fetch all themes: +* // Fetch all available themes: * repl.themes(); * * // ... @@ -895,6 +893,8 @@ setNonEnumerableReadOnly( REPL.prototype, 'getTheme', function getTheme( theme ) * repl.addTheme( 'myTheme', { * 'keyword': 'red', * 'variable': 'green' +* +* // ... * }); * * // ... From 028f4775172b3117d652b26501af5a10764a4c15 Mon Sep 17 00:00:00 2001 From: Snehil Shah Date: Sun, 2 Jun 2024 23:40:32 +0000 Subject: [PATCH 14/33] test: update test case Signed-off-by: Snehil Shah --- .../fixtures/syntax-highlighting/member_expressions.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/member_expressions.json b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/member_expressions.json index 64bff84df0c7..ff25cfed3efc 100644 --- a/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/member_expressions.json +++ b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/member_expressions.json @@ -1,8 +1,9 @@ { "expression": "var foo = { 'bar': { 'func': function() { return true; } } };\nfoo['bar'].func()", - "expected": "\u001b[31mfoo\u001b[0m['bar'].\u001b[33mfunc\u001b[0m()", + "expected": "\u001b[31mfoo\u001b[0m[\u001b[32m'bar'\u001b[0m].\u001b[33mfunc\u001b[0m()", "theme": { "object": "red", - "function": "yellow" + "function": "yellow", + "string": "green" } } From 7c99ef73eaf1c45050e105f1abf0c36fd08a9d7a Mon Sep 17 00:00:00 2001 From: Snehil Shah Date: Mon, 3 Jun 2024 00:17:58 +0000 Subject: [PATCH 15/33] fix: handle recursive `MemberExpressions` Signed-off-by: Snehil Shah --- .../@stdlib/repl/lib/tokenizer.js | 24 ++++++++++++++++--- .../member_expressions.json | 6 ++--- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/lib/node_modules/@stdlib/repl/lib/tokenizer.js b/lib/node_modules/@stdlib/repl/lib/tokenizer.js index 4d63bdfc6e99..dba128a31486 100644 --- a/lib/node_modules/@stdlib/repl/lib/tokenizer.js +++ b/lib/node_modules/@stdlib/repl/lib/tokenizer.js @@ -264,8 +264,10 @@ function tokenizer( line, context ) { * * @private * @param {Object} node - AST node + * @param {boolean} compute - boolean indicating whether to compute the `MemberExpression` + * @returns {void|*} computed value of the `MemberExpression` if compute is true */ - function resolveMemberExpression( node ) { + function resolveMemberExpression( node, compute ) { var properties = linkedList(); var property; var locals; @@ -293,7 +295,6 @@ function tokenizer( line, context ) { if ( contains( locals, property.value.name ) ) { return; } - // Enter object's namespace: obj = context; properties = properties.iterator(); @@ -315,13 +316,17 @@ function tokenizer( line, context ) { property = properties.next(); continue; } - // Case: `foo.bar`: + // Case: `foo.bar` - resolve property and push it as a token... if ( property.value.type === 'Identifier' ) { obj = obj[ property.value.name ]; if ( !obj ) { // Property not found in context: break; } + if ( compute ) { + property = properties.next(); + continue; + } // Push token if property exists in context: if ( isLiteralType( typeof obj ) ) { tokens.push({ @@ -341,8 +346,21 @@ function tokenizer( line, context ) { property = properties.next(); continue; } + // Case: `foo[a.b].bar` - recursively compute the internal `MemberExpression`... + if ( property.value.type === 'MemberExpression' ) { + obj = obj[ resolveMemberExpression( property.value, true ) ]; + if ( !obj ) { + // Property not found in context: + break; + } + property = properties.next(); + continue; + } break; } + if ( compute ) { + return obj; + } /** * Resolves members of the `MemberExpression` node. diff --git a/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/member_expressions.json b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/member_expressions.json index ff25cfed3efc..bfab779ea350 100644 --- a/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/member_expressions.json +++ b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/member_expressions.json @@ -1,9 +1,9 @@ { - "expression": "var foo = { 'bar': { 'func': function() { return true; } } };\nfoo['bar'].func()", - "expected": "\u001b[31mfoo\u001b[0m[\u001b[32m'bar'\u001b[0m].\u001b[33mfunc\u001b[0m()", + "expression": "var a = { 'b': 'bar' }; var foo = { 'bar': { 'func': function() { return true; } } };\nfoo[a.b].func()", + "expected": "\u001b[31mfoo\u001b[0m[\u001b[31ma\u001b[0m.\u001b[32mb\u001b[0m].\u001b[33mfunc\u001b[0m()", "theme": { "object": "red", "function": "yellow", - "string": "green" + "variable": "green" } } From 1b79a3c6781524e22d70ca879acc06b6b72e54f8 Mon Sep 17 00:00:00 2001 From: Snehil Shah Date: Mon, 3 Jun 2024 02:44:08 +0000 Subject: [PATCH 16/33] refactor: clean code logic Signed-off-by: Snehil Shah --- .../@stdlib/repl/lib/tokenizer.js | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/lib/node_modules/@stdlib/repl/lib/tokenizer.js b/lib/node_modules/@stdlib/repl/lib/tokenizer.js index dba128a31486..311aed4e2b64 100644 --- a/lib/node_modules/@stdlib/repl/lib/tokenizer.js +++ b/lib/node_modules/@stdlib/repl/lib/tokenizer.js @@ -323,25 +323,23 @@ function tokenizer( line, context ) { // Property not found in context: break; } - if ( compute ) { - property = properties.next(); - continue; - } - // Push token if property exists in context: - if ( isLiteralType( typeof obj ) ) { - tokens.push({ - 'value': property.value.name, - 'type': 'variable', - 'start': property.value.start, - 'end': property.value.end - }); - } else { - tokens.push({ - 'value': property.value.name, - 'type': typeof obj, - 'start': property.value.start, - 'end': property.value.end - }); + if ( !compute ) { + // Push token if property exists in context: + if ( isLiteralType( typeof obj ) ) { + tokens.push({ + 'value': property.value.name, + 'type': 'variable', + 'start': property.value.start, + 'end': property.value.end + }); + } else { + tokens.push({ + 'value': property.value.name, + 'type': typeof obj, + 'start': property.value.start, + 'end': property.value.end + }); + } } property = properties.next(); continue; From 765c19bc801658edddb5820f9d4429deba745c94 Mon Sep 17 00:00:00 2001 From: Snehil Shah Date: Mon, 3 Jun 2024 02:46:51 +0000 Subject: [PATCH 17/33] fix: correct string formatting Signed-off-by: Snehil Shah --- lib/node_modules/@stdlib/repl/lib/commands/themes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/repl/lib/commands/themes.js b/lib/node_modules/@stdlib/repl/lib/commands/themes.js index 69e2497068b4..17eb019bdd69 100644 --- a/lib/node_modules/@stdlib/repl/lib/commands/themes.js +++ b/lib/node_modules/@stdlib/repl/lib/commands/themes.js @@ -53,7 +53,7 @@ function command( repl ) { } output = format( 'Available themes: `%s`', themes[ 0 ] ); for ( i = 1; i < themes.length; i++ ) { - output += format( ' ,`%s`', themes[ i ] ); + output += format( ', `%s`', themes[ i ] ); } output += '.'; log( repl, output ); From 4480879e9da0b788aa41aa32c401955690017972 Mon Sep 17 00:00:00 2001 From: Snehil Shah Date: Mon, 3 Jun 2024 07:10:38 +0000 Subject: [PATCH 18/33] fix: ignore placeholder nodes Signed-off-by: Snehil Shah --- lib/node_modules/@stdlib/repl/lib/tokenizer.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/node_modules/@stdlib/repl/lib/tokenizer.js b/lib/node_modules/@stdlib/repl/lib/tokenizer.js index 311aed4e2b64..d630a917c1c4 100644 --- a/lib/node_modules/@stdlib/repl/lib/tokenizer.js +++ b/lib/node_modules/@stdlib/repl/lib/tokenizer.js @@ -306,6 +306,10 @@ function tokenizer( line, context ) { // Fetch properties from context: property = properties.next(); while ( !property.done ) { + // Ignore placeholder nodes: + if ( property.value.start === property.value.end ) { + return; + } // Case: 'bar' in `foo['bar']` - property already pushed as a string token. Ignore... if ( property.value.type === 'Literal' ) { obj = obj[ property.value.value ]; From 0ea6e2e6d3f77fb6be9aed5b0f341f18ed00f61d Mon Sep 17 00:00:00 2001 From: Snehil Shah Date: Tue, 4 Jun 2024 06:50:22 +0000 Subject: [PATCH 19/33] fix: setting themes during startup Signed-off-by: Snehil Shah --- lib/node_modules/@stdlib/repl/lib/main.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/lib/node_modules/@stdlib/repl/lib/main.js b/lib/node_modules/@stdlib/repl/lib/main.js index 40fbf90794da..0651a2288be7 100644 --- a/lib/node_modules/@stdlib/repl/lib/main.js +++ b/lib/node_modules/@stdlib/repl/lib/main.js @@ -315,15 +315,10 @@ function REPL( options ) { this.addTheme( themes[ i ], opts.themes[ themes[ i ] ] ); } } - // Check whether to set a default theme upon startup... - if ( opts.settings.defaultTheme !== 'default' ) { - this._syntaxHighlighter.setTheme( opts.defaultTheme ); - this.settings( 'defaultTheme', opts.defaultTheme ); - } - // Check whether to set a current theme upon startup... - if ( opts.settings.theme !== 'default' ) { - this.settings( 'theme', opts.settings.theme ); - } + // Set the default and current theme for syntax-highlighting... + this.settings( 'defaultTheme', opts.settings.defaultTheme ); + this.settings( 'theme', opts.settings.theme ); + // Check whether to load and execute a JavaScript file (e.g., prior REPL history) upon startup... if ( opts.load ) { this.load( opts.load ); From de9e1e87e115a9db0eb1aa2afca29b169fbb0da2 Mon Sep 17 00:00:00 2001 From: Snehil Shah Date: Tue, 4 Jun 2024 18:29:00 +0000 Subject: [PATCH 20/33] docs: keep it consistent Signed-off-by: Snehil Shah --- lib/node_modules/@stdlib/repl/README.md | 8 ++++---- lib/node_modules/@stdlib/repl/lib/help_text.js | 4 ++-- lib/node_modules/@stdlib/repl/lib/main.js | 5 ++++- lib/node_modules/@stdlib/repl/lib/settings.js | 4 ++-- lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js | 2 +- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/lib/node_modules/@stdlib/repl/README.md b/lib/node_modules/@stdlib/repl/README.md index d0d03a1460fb..0fd3633177e9 100644 --- a/lib/node_modules/@stdlib/repl/README.md +++ b/lib/node_modules/@stdlib/repl/README.md @@ -71,7 +71,7 @@ The function accepts the following `options`: - **outputPrompt**: output prompt. If the output prompt includes the character sequence `%d`, the output prompt includes line numbers. Default: `'Out[%d]: '`. - **welcome**: welcome message. - **padding**: number of empty lines between consecutive commands. Default: `1`. -- **themes**: table mapping of color themes to load for syntax-highlighting +- **themes**: table mapping of color themes to load for syntax highlighting. - **load**: file path specifying a JavaScript file to load and evaluate line-by-line (e.g., a previous REPL history file). - **save**: file path specifying where to save REPL command history. - **log**: file path specifying where to save REPL commands and printed output. @@ -85,8 +85,8 @@ The function supports specifying the following settings: - **autoPage**: boolean indicating whether to automatically page return values having a display size exceeding the visible screen. When streams are TTY, the default is `true`; otherwise, the default is `false`. - **completionPreviews**: boolean indicating whether to display completion previews for auto-completion. When streams are TTY, the default is `true`; otherwise, the default is `false`. - **syntaxHighlighting**: boolean indicating whether to enable syntax highlighting of the input. When streams are TTY, the default is `true`; otherwise, the default is `false`. -- **theme**: theme to set upon REPL startup. Default: `default`. -- **defaultTheme**: default theme to set upon REPL startup. Default: `default`. +- **theme**: initial color theme for syntax highlighting. Default: `default`. +- **defaultTheme**: default theme for syntax highlighting. Default: `default`. #### REPL.prototype.viewport() @@ -224,7 +224,7 @@ repl.close(); #### Repl.prototype.getTheme() -Returns all available themes in the syntax-highlighter. +Returns a theme's color palette from the syntax-highlighter. ```javascript var debug = require( '@stdlib/streams/node/debug-sink' ); diff --git a/lib/node_modules/@stdlib/repl/lib/help_text.js b/lib/node_modules/@stdlib/repl/lib/help_text.js index 9ca8a970b0c0..309deaa33210 100644 --- a/lib/node_modules/@stdlib/repl/lib/help_text.js +++ b/lib/node_modules/@stdlib/repl/lib/help_text.js @@ -56,8 +56,8 @@ var MSG = [ ' themes() List available color themes.', ' addTheme(name,value) Add a new color theme.', ' deleteTheme(name) Delete a specified color theme.', - ' renameTheme(old,new) Rename a specified color theme', - ' getTheme([name]) Get the current (or a specified) color theme palette.', + ' renameTheme(old,new) Rename a specified color theme.', + ' getTheme([name]) Get the current (or a specified) theme\'s color palette.', '', ' assignin() Assign a value to a workspace variable.', ' assignfrom() Read in a value from another workspace.', diff --git a/lib/node_modules/@stdlib/repl/lib/main.js b/lib/node_modules/@stdlib/repl/lib/main.js index 0651a2288be7..d1297f7a782a 100644 --- a/lib/node_modules/@stdlib/repl/lib/main.js +++ b/lib/node_modules/@stdlib/repl/lib/main.js @@ -102,6 +102,9 @@ var debug = logger( 'repl' ); * @param {boolean} [options.settings.autoDeletePairs=true] - boolean indicating whether to automatically delete adjacent matching brackets, parentheses, and quotes * @param {boolean} [options.settings.autoPage] - boolean indicating whether to automatically page return values requiring a display size exceeding the visible screen * @param {boolean} [options.settings.completionPreviews] - boolean indicating whether to enable completion previews for auto-completion +* @param {boolean} [options.settings.syntaxHighlighting] - boolean indicating whether to enable syntax highlighting of the input +* @param {string} [options.settings.theme] - initial color theme for syntax highlighting +* @param {string} [options.settings.defaultTheme] - default color theme for syntax highlighting * @throws {Error} must provide valid options * @returns {REPL} REPL instance * @@ -828,7 +831,7 @@ setNonEnumerableReadOnly( REPL.prototype, 'themes', function themes() { }); /** -* Gets a theme's color configuration from the syntax-highlighter. +* Gets a theme's color palette from the syntax-highlighter. * * @name getTheme * @memberof REPL.prototype diff --git a/lib/node_modules/@stdlib/repl/lib/settings.js b/lib/node_modules/@stdlib/repl/lib/settings.js index 76290be4ecc6..7e38fbe61dd2 100644 --- a/lib/node_modules/@stdlib/repl/lib/settings.js +++ b/lib/node_modules/@stdlib/repl/lib/settings.js @@ -49,11 +49,11 @@ var SETTINGS = { 'type': 'boolean' }, 'theme': { - 'desc': 'Set the color theme for syntax-highlighting.', + 'desc': 'Set the color theme for syntax highlighting.', 'type': 'string' }, 'defaultTheme': { - 'desc': 'Set the default color theme for syntax-highlighting.', + 'desc': 'Set the default color theme for syntax highlighting.', 'type': 'string' } }; diff --git a/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js b/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js index 8983f76589ef..3d826e14ce9d 100644 --- a/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js +++ b/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js @@ -172,7 +172,7 @@ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'setTheme', function setT }); /** -* Gets a theme's colors configuration. +* Gets a theme's colors palette. * * @name getThemeConfig * @memberof SyntaxHighlighter.prototype From 802d6028f65fef37dcf949f42b0a07b805e02e9e Mon Sep 17 00:00:00 2001 From: Snehil Shah Date: Tue, 4 Jun 2024 18:30:36 +0000 Subject: [PATCH 21/33] refactor: return theme object in `getTheme` command Signed-off-by: Snehil Shah --- lib/node_modules/@stdlib/repl/lib/commands/get_theme.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/node_modules/@stdlib/repl/lib/commands/get_theme.js b/lib/node_modules/@stdlib/repl/lib/commands/get_theme.js index cf74f63afb91..2a4c186339f8 100644 --- a/lib/node_modules/@stdlib/repl/lib/commands/get_theme.js +++ b/lib/node_modules/@stdlib/repl/lib/commands/get_theme.js @@ -23,7 +23,6 @@ // MODULES // var format = require( '@stdlib/string/format' ); -var log = require( './../log.js' ); // MAIN // @@ -43,7 +42,7 @@ function command( repl ) { * * @private * @param {string} [name] - theme name - * @returns {void} + * @returns {Object|void} theme object */ function onCommand() { var theme; @@ -64,7 +63,7 @@ function command( repl ) { repl._ostream.write( format( 'Error: %s\n', err.message ) ); return; } - log( repl, JSON.stringify( theme, null, 2 ) ); + return theme; } } From 4e2af9a501ef81faa84d4d2ffe185d9e779982a1 Mon Sep 17 00:00:00 2001 From: Snehil Shah Date: Wed, 5 Jun 2024 14:20:12 +0000 Subject: [PATCH 22/33] fix: suggestions Signed-off-by: Snehil Shah --- lib/node_modules/@stdlib/repl/README.md | 157 ++++++++++++++++-- .../@stdlib/repl/lib/commands/add_theme.js | 19 +-- .../@stdlib/repl/lib/commands/delete_theme.js | 15 +- .../@stdlib/repl/lib/commands/get_theme.js | 7 +- .../@stdlib/repl/lib/commands/rename_theme.js | 20 +-- .../@stdlib/repl/lib/commands/themes.js | 25 +-- lib/node_modules/@stdlib/repl/lib/defaults.js | 7 +- .../@stdlib/repl/lib/help_text.js | 2 +- lib/node_modules/@stdlib/repl/lib/main.js | 56 +++++-- lib/node_modules/@stdlib/repl/lib/settings.js | 8 +- .../@stdlib/repl/lib/syntax_highlighter.js | 36 ++-- lib/node_modules/@stdlib/repl/lib/themes.js | 2 +- .../syntax-highlighting/functions.json | 2 +- .../reserved_literals.json | 4 +- 14 files changed, 215 insertions(+), 145 deletions(-) diff --git a/lib/node_modules/@stdlib/repl/README.md b/lib/node_modules/@stdlib/repl/README.md index 0fd3633177e9..f5e0a6a02052 100644 --- a/lib/node_modules/@stdlib/repl/README.md +++ b/lib/node_modules/@stdlib/repl/README.md @@ -71,7 +71,7 @@ The function accepts the following `options`: - **outputPrompt**: output prompt. If the output prompt includes the character sequence `%d`, the output prompt includes line numbers. Default: `'Out[%d]: '`. - **welcome**: welcome message. - **padding**: number of empty lines between consecutive commands. Default: `1`. -- **themes**: table mapping of color themes to load for syntax highlighting. +- **themes**: table containing color themes for syntax highlighting. - **load**: file path specifying a JavaScript file to load and evaluate line-by-line (e.g., a previous REPL history file). - **save**: file path specifying where to save REPL command history. - **log**: file path specifying where to save REPL commands and printed output. @@ -84,9 +84,8 @@ The function supports specifying the following settings: - **autoDeletePairs**: boolean indicating whether to automatically delete adjacent matching brackets, parentheses, and quotes. Default: `true`. - **autoPage**: boolean indicating whether to automatically page return values having a display size exceeding the visible screen. When streams are TTY, the default is `true`; otherwise, the default is `false`. - **completionPreviews**: boolean indicating whether to display completion previews for auto-completion. When streams are TTY, the default is `true`; otherwise, the default is `false`. -- **syntaxHighlighting**: boolean indicating whether to enable syntax highlighting of the input. When streams are TTY, the default is `true`; otherwise, the default is `false`. -- **theme**: initial color theme for syntax highlighting. Default: `default`. -- **defaultTheme**: default theme for syntax highlighting. Default: `default`. +- **syntaxHighlighting**: boolean indicating whether to enable syntax highlighting of entered input expressions. When streams are TTY, the default is `true`; otherwise, the default is `false`. +- **theme**: initial color theme for syntax highlighting. Default: `stdlib-ansi-basic`. #### REPL.prototype.viewport() @@ -176,7 +175,7 @@ repl.clearHistory(); repl.close(); ``` -#### Repl.prototype.clearUserDocs() +#### REPL.prototype.clearUserDocs() Clears user-defined documentation. @@ -199,9 +198,9 @@ repl.clearUserDocs(); repl.close(); ``` -#### Repl.prototype.themes() +#### REPL.prototype.themes() -Returns all available themes in the syntax-highlighter. +Returns a list of all available themes for syntax highlighting. ```javascript var debug = require( '@stdlib/streams/node/debug-sink' ); @@ -214,7 +213,8 @@ var repl = new REPL({ // ... // Fetch all available themes: -repl.themes(); +var themes = repl.themes(); +// returns [...] // ... @@ -222,9 +222,9 @@ repl.themes(); repl.close(); ``` -#### Repl.prototype.getTheme() +#### REPL.prototype.getTheme() -Returns a theme's color palette from the syntax-highlighter. +Returns a theme's color palette for syntax highlighting. ```javascript var debug = require( '@stdlib/streams/node/debug-sink' ); @@ -236,8 +236,14 @@ var repl = new REPL({ // ... -// Fetch all available themes: -repl.themes(); +// Add a user-defined theme: +repl.addTheme( 'myTheme', { + 'keyword': 'red' +}); + +// Get a theme's color palette: +var theme = repl.getTheme( 'myTheme' ); +// returns { 'keyword': 'red' } // ... @@ -245,9 +251,9 @@ repl.themes(); repl.close(); ``` -#### Repl.prototype.addTheme() +#### REPL.prototype.addTheme() -Adds a color theme to the syntax-highlighter. +Adds a syntax highlighting theme. ```javascript var debug = require( '@stdlib/streams/node/debug-sink' ); @@ -273,7 +279,25 @@ repl.addTheme( 'myTheme', { repl.close(); ``` -#### Repl.prototype.deleteTheme() +The syntax-highlighter supports the following tokens and ANSI color names: + +- **keyword**: keywords. eg: `var`, `function`, `let`, `const`, `in`, `class` etc. +- **control**: control flow keywords. eg: `if`, `else`, `try`, `catch`, `return` etc. +- **specialIdentifier**: special identifiers. eg: `this`, `super` etc. +- **string**: string and template literals. +- **number**: numeric literals. +- **literal**: reserved literals. eg: `true`, `false`, `null`, `undefined` etc. +- **regexp**: regular expressions. +- **command**: built-in REPL commands. +- **function**: function identifiers. +- **object**: object identifiers. +- **variable**: literal identifiers. +- **name**: variable names. +- **comment**: line comments. +- **punctuation**: punctuation symbols. eg: `;`, `[`, `{`, `,`, `?` etc. +- **operator**: operator symbols. eg: `+`, `-`, `*`, `=`, `++`, `>=`, `&&` etc. + +#### REPL.prototype.deleteTheme() Deletes a specified theme from the syntax-highlighter. @@ -287,7 +311,15 @@ var repl = new REPL({ // ... -// Delete an existing theme: +// Add a user-defined theme: +repl.addTheme( 'myTheme', { + 'keyword': 'red', + 'variable': 'green' + + // ... +}); + +// Delete the added theme: repl.deleteTheme( 'myTheme' ); // ... @@ -296,7 +328,7 @@ repl.deleteTheme( 'myTheme' ); repl.close(); ``` -#### Repl.prototype.renameTheme() +#### REPL.prototype.renameTheme() Renames a specified theme in the syntax-highlighter. @@ -310,7 +342,15 @@ var repl = new REPL({ // ... -// Rename an existing theme: +// Add a user-defined theme: +repl.addTheme( 'myTheme', { + 'keyword': 'red', + 'variable': 'green' + + // ... +}); + +// Rename the added theme: repl.renameTheme( 'myTheme', 'yourTheme' ); // ... @@ -529,6 +569,19 @@ repl.close(); REPL instances support the following commands... +#### addTheme( name, theme ) + +Adds a syntax highlighting color theme. + +```text +// Add color theme: +In [1]: addTheme( 'myTheme', { 'keyword': 'red' } ) + +// Check updated list of themes: +In [2]: themes() +Out[2]: [ 'stdlib-ansi-basic', 'myTheme' ] +``` + #### alias2pkg( arg ) Returns the package name associated with a provided alias or class instance. @@ -740,6 +793,26 @@ In [1]: currentWorkspace Out[1]: 'base' ``` +#### deleteTheme( name ) + +Deletes a syntax highlighting color theme. + +```text +// Add a color theme: +In [1]: addTheme( 'myTheme', { 'keyword': 'red' } ) + +// Check list of themes: +In [2]: themes() +Out[2]: [ 'stdlib-ansi-basic', 'myTheme' ] + +// Delete the added theme: +In [3]: deleteTheme( 'myTheme' ) + +// Check updated list of themes: +In [4]: themes() +Out[4]: [ 'stdlib-ansi-basic' ] +``` + #### deeprerequire( id ) Re-imports a module, JSON, or local file and all of its associated module dependencies. @@ -838,6 +911,21 @@ In [1]: example( base.sin ) **Note**: only direct instances of documented built-in constructors are supported. +#### getTheme( \[name] ) + +Returns a syntax highlighting color theme. + +```text +// Add a color theme: +In [1]: addTheme( 'myTheme', { 'keyword': 'red' } ) + +// Get the color theme: +In [2]: getTheme( 'myTheme' ) +Out[2]: { 'keyword': 'red' } +``` + +**Note**: if no theme name is provided, the current theme is returned. + #### help( \[arg] ) Prints help text. @@ -1019,6 +1107,26 @@ Exits the REPL. In [1]: quit() ``` +#### renameTheme( oldName, newName ) + +Renames a syntax highlighting color theme. + +```text +// Add a color theme: +In [1]: addTheme( 'myTheme', { 'keyword': 'red' } ) + +// Check list of themes: +In [2]: themes() +Out[2]: [ 'stdlib-ansi-basic', 'myTheme' ] + +// Rename the added theme: +In [3]: getTheme( 'myTheme', 'yourTheme' ) + +// Check updated list of themes: +In [4]: themes() +Out[4]: [ 'stdlib-ansi-basic', 'yourTheme' ] +``` + #### renameWorkspace( oldName, newName ) Renames a workspace. @@ -1202,6 +1310,19 @@ To update a specific setting, provide a `value` argument. In [1]: settings( 'autoClosePairs', false ) ``` +#### themes() + +Returns a list of all available syntax highlighting color themes. + +```text +// Add a color theme: +In [1]: addTheme( 'myTheme', { 'keyword': 'red' } ) + +// Check list of themes: +In [2]: themes() +Out[2]: [ 'stdlib-ansi-basic', 'myTheme' ] +``` + #### tutorial( \[name, \[options]] ) Starts a tutorial. diff --git a/lib/node_modules/@stdlib/repl/lib/commands/add_theme.js b/lib/node_modules/@stdlib/repl/lib/commands/add_theme.js index eea130ca5e9c..b978ab7ab810 100644 --- a/lib/node_modules/@stdlib/repl/lib/commands/add_theme.js +++ b/lib/node_modules/@stdlib/repl/lib/commands/add_theme.js @@ -39,25 +39,14 @@ function command( repl ) { return onCommand; /** - * Adds a color theme to the syntax-highlighter. + * Adds a syntax highlighting color theme. * * @private - * @param {string} [name] - theme name - * @param {Object} [theme] - theme object + * @param {string} name - theme name + * @param {Object} theme - theme object * @returns {void} */ - function onCommand() { - var theme; - var nargs; - var name; - - nargs = arguments.length; - if ( nargs < 2 ) { - repl._ostream.write( 'Error: invalid operation. Provide a theme to add.\n' ); - return; - } - name = arguments[ 0 ]; - theme = arguments[ 1 ]; + function onCommand( name, theme ) { try { repl.addTheme( name, theme ); } catch ( err ) { diff --git a/lib/node_modules/@stdlib/repl/lib/commands/delete_theme.js b/lib/node_modules/@stdlib/repl/lib/commands/delete_theme.js index b53e2c60a96c..73227328398f 100644 --- a/lib/node_modules/@stdlib/repl/lib/commands/delete_theme.js +++ b/lib/node_modules/@stdlib/repl/lib/commands/delete_theme.js @@ -39,22 +39,13 @@ function command( repl ) { return onCommand; /** - * Deletes a color theme from the syntax-highlighter. + * Deletes a syntax highlighting color theme. * * @private - * @param {string} [name] - theme name + * @param {string} name - theme name * @returns {void} */ - function onCommand() { - var nargs; - var name; - - nargs = arguments.length; - if ( nargs === 0 ) { - repl._ostream.write( 'Error: invalid operation. Provide a theme name to delete.\n' ); - return; - } - name = arguments[ 0 ]; + function onCommand( name ) { try { repl.deleteTheme( name ); } catch ( err ) { diff --git a/lib/node_modules/@stdlib/repl/lib/commands/get_theme.js b/lib/node_modules/@stdlib/repl/lib/commands/get_theme.js index 2a4c186339f8..3ebda3bca6c4 100644 --- a/lib/node_modules/@stdlib/repl/lib/commands/get_theme.js +++ b/lib/node_modules/@stdlib/repl/lib/commands/get_theme.js @@ -38,7 +38,7 @@ function command( repl ) { return onCommand; /** - * Gets the color configuration of a theme from the syntax-highlighter. + * Returns a syntax highlighting color theme. * * @private * @param {string} [name] - theme name @@ -46,13 +46,10 @@ function command( repl ) { */ function onCommand() { var theme; - var nargs; var name; - nargs = arguments.length; - // If no theme name given, get the current theme... - if ( nargs === 0 ) { + if ( arguments.length === 0 ) { name = repl.settings( 'theme' ); } else { name = arguments[ 0 ]; diff --git a/lib/node_modules/@stdlib/repl/lib/commands/rename_theme.js b/lib/node_modules/@stdlib/repl/lib/commands/rename_theme.js index cb703386462a..43e702a526c5 100644 --- a/lib/node_modules/@stdlib/repl/lib/commands/rename_theme.js +++ b/lib/node_modules/@stdlib/repl/lib/commands/rename_theme.js @@ -39,26 +39,14 @@ function command( repl ) { return onCommand; /** - * Renames a color theme in the syntax-highlighter. + * Renames a syntax highlighting color theme. * * @private - * @param {string} [oldName] - old theme name - * @param {string} [newName] - new theme name + * @param {string} oldName - old theme name + * @param {string} newName - new theme name * @returns {void} */ - function onCommand() { - var oldName; - var newName; - var nargs; - - nargs = arguments.length; - - if ( nargs < 2 ) { - repl._ostream.write( 'Error: invalid operation. Provide the existing and new theme names to rename.' ); - return; - } - oldName = arguments[ 0 ]; - newName = arguments[ 1 ]; + function onCommand( oldName, newName ) { try { repl.renameTheme( oldName, newName ); } catch ( err ) { diff --git a/lib/node_modules/@stdlib/repl/lib/commands/themes.js b/lib/node_modules/@stdlib/repl/lib/commands/themes.js index 17eb019bdd69..698c71413e74 100644 --- a/lib/node_modules/@stdlib/repl/lib/commands/themes.js +++ b/lib/node_modules/@stdlib/repl/lib/commands/themes.js @@ -18,12 +18,6 @@ 'use strict'; -// MODULES // - -var format = require( '@stdlib/string/format' ); -var log = require( './../log.js' ); - - // MAIN // /** @@ -37,26 +31,13 @@ function command( repl ) { return onCommand; /** - * Gets available color themes for syntax-highlighting. + * Returns a list of available syntax highlighting color themes. * * @private - * @returns {void} + * @returns {Array} list of available themes */ function onCommand() { - var output; - var themes; - var i; - - themes = repl.themes(); - if ( themes.length === 0 ) { - log( repl, 'No available themes.' ); - } - output = format( 'Available themes: `%s`', themes[ 0 ] ); - for ( i = 1; i < themes.length; i++ ) { - output += format( ', `%s`', themes[ i ] ); - } - output += '.'; - log( repl, output ); + return repl.themes(); } } diff --git a/lib/node_modules/@stdlib/repl/lib/defaults.js b/lib/node_modules/@stdlib/repl/lib/defaults.js index 9b76e412d121..8f07cbe2b011 100644 --- a/lib/node_modules/@stdlib/repl/lib/defaults.js +++ b/lib/node_modules/@stdlib/repl/lib/defaults.js @@ -92,14 +92,11 @@ function defaults() { // Flag indicating whether to enable the display of completion previews for auto-completion (note: default depends on whether TTY): 'completionPreviews': void 0, - // Flag indicating whether to enable syntax highlighting of the input (note: default depends on whether TTY): + // Flag indicating whether to enable syntax highlighting (note: default depends on whether TTY): 'syntaxHighlighting': void 0, // Theme for syntax highlighting: - 'theme': 'default', - - // Default theme for syntax highlighting: - 'defaultTheme': 'default' + 'theme': 'stdlib-ansi-basic' } }; } diff --git a/lib/node_modules/@stdlib/repl/lib/help_text.js b/lib/node_modules/@stdlib/repl/lib/help_text.js index 309deaa33210..10737246d93c 100644 --- a/lib/node_modules/@stdlib/repl/lib/help_text.js +++ b/lib/node_modules/@stdlib/repl/lib/help_text.js @@ -57,7 +57,7 @@ var MSG = [ ' addTheme(name,value) Add a new color theme.', ' deleteTheme(name) Delete a specified color theme.', ' renameTheme(old,new) Rename a specified color theme.', - ' getTheme([name]) Get the current (or a specified) theme\'s color palette.', + ' getTheme([name]) Return the current (or a specified) theme\'s color palette.', '', ' assignin() Assign a value to a workspace variable.', ' assignfrom() Read in a value from another workspace.', diff --git a/lib/node_modules/@stdlib/repl/lib/main.js b/lib/node_modules/@stdlib/repl/lib/main.js index d1297f7a782a..b2f16c01629d 100644 --- a/lib/node_modules/@stdlib/repl/lib/main.js +++ b/lib/node_modules/@stdlib/repl/lib/main.js @@ -102,9 +102,8 @@ var debug = logger( 'repl' ); * @param {boolean} [options.settings.autoDeletePairs=true] - boolean indicating whether to automatically delete adjacent matching brackets, parentheses, and quotes * @param {boolean} [options.settings.autoPage] - boolean indicating whether to automatically page return values requiring a display size exceeding the visible screen * @param {boolean} [options.settings.completionPreviews] - boolean indicating whether to enable completion previews for auto-completion -* @param {boolean} [options.settings.syntaxHighlighting] - boolean indicating whether to enable syntax highlighting of the input +* @param {boolean} [options.settings.syntaxHighlighting] - boolean indicating whether to enable syntax highlighting * @param {string} [options.settings.theme] - initial color theme for syntax highlighting -* @param {string} [options.settings.defaultTheme] - default color theme for syntax highlighting * @throws {Error} must provide valid options * @returns {REPL} REPL instance * @@ -318,8 +317,7 @@ function REPL( options ) { this.addTheme( themes[ i ], opts.themes[ themes[ i ] ] ); } } - // Set the default and current theme for syntax-highlighting... - this.settings( 'defaultTheme', opts.settings.defaultTheme ); + // Set the syntax highlighting theme... this.settings( 'theme', opts.settings.theme ); // Check whether to load and execute a JavaScript file (e.g., prior REPL history) upon startup... @@ -801,12 +799,12 @@ setNonEnumerableReadOnly( REPL.prototype, 'clearUserDocs', function clearUserDoc }); /** -* Gets all available themes in the syntax-highlighter. +* Returns a list of all available themes for syntax highlighting. * * @name themes * @memberof REPL.prototype * @type {Function} -* @returns {Array} array of all theme names +* @returns {Array} list of all theme names * * @example * var debug = require( '@stdlib/streams/node/debug-sink' ); @@ -831,13 +829,14 @@ setNonEnumerableReadOnly( REPL.prototype, 'themes', function themes() { }); /** -* Gets a theme's color palette from the syntax-highlighter. +* Returns a theme's color palette for syntax highlighting. * * @name getTheme * @memberof REPL.prototype * @type {Function} * @param {string} theme - theme name -* @throws {TypeError} argument must be a string +* @throws {TypeError} must provide a string +* @throws {Error} must provide an existing theme name * @returns {Object} theme object * * @example @@ -850,7 +849,12 @@ setNonEnumerableReadOnly( REPL.prototype, 'themes', function themes() { * * // ... * -* // Get theme object: +* // Add a user-defined theme: +* repl.addTheme( 'myTheme', { +* 'keyword': 'red' +* }); +* +* // Get a theme's color palette: * repl.getTheme( 'myTheme' ); * * // ... @@ -866,7 +870,7 @@ setNonEnumerableReadOnly( REPL.prototype, 'getTheme', function getTheme( theme ) }); /** -* Adds a theme to the syntax-highlighter. +* Adds a syntax highlighting theme. * * @name addTheme * @memberof REPL.prototype @@ -911,7 +915,7 @@ setNonEnumerableReadOnly( REPL.prototype, 'addTheme', function addTheme( name, t }); /** -* Renames a theme in the syntax-highlighter. +* Renames a specified theme in the syntax-highlighter.. * * @name renameTheme * @memberof REPL.prototype @@ -920,6 +924,8 @@ setNonEnumerableReadOnly( REPL.prototype, 'addTheme', function addTheme( name, t * @param {string} newName - new theme name * @throws {TypeError} first argument must be a string * @throws {TypeError} second argument must be a string +* @throws {Error} first argument must be an existing theme name +* @throws {Error} first argument must not be the default theme name * @returns {void} * * @example @@ -932,7 +938,15 @@ setNonEnumerableReadOnly( REPL.prototype, 'addTheme', function addTheme( name, t * * // ... * -* // Rename an existing theme: +* // Add a user-defined theme: +* repl.addTheme( 'myTheme', { +* 'keyword': 'red', +* 'variable': 'green' +* +* // ... +* }); + +* // Rename the added theme: * repl.renameTheme( 'myTheme', 'yourTheme' ); * * // ... @@ -951,13 +965,15 @@ setNonEnumerableReadOnly( REPL.prototype, 'renameTheme', function renameTheme( o }); /** -* Deletes a theme from the syntax-highlighter. +* Deletes a specified theme from the syntax-highlighter. * * @name deleteTheme * @memberof REPL.prototype * @type {Function} * @param {string} name - theme name -* @throws {TypeError} first argument must be a string +* @throws {TypeError} must provide a string +* @throws {Error} must provide an existing theme name +* @throws {Error} must not provide the default theme * @returns {void} * * @example @@ -970,7 +986,15 @@ setNonEnumerableReadOnly( REPL.prototype, 'renameTheme', function renameTheme( o * * // ... * -* // Delete an existing theme: +* // Add a user-defined theme: +* repl.addTheme( 'myTheme', { +* 'keyword': 'red', +* 'variable': 'green' +* +* // ... +* }); +* +* // Delete the added theme: * repl.deleteTheme( 'myTheme' ); * * // ... @@ -1423,8 +1447,6 @@ setNonEnumerableReadOnly( REPL.prototype, 'settings', function settings() { } } else if ( name === 'theme' ) { this._syntaxHighlighter.setTheme( value ); - } else if ( name === 'defaultTheme' ) { - this._syntaxHighlighter.setDefaultTheme( value ); } return this; diff --git a/lib/node_modules/@stdlib/repl/lib/settings.js b/lib/node_modules/@stdlib/repl/lib/settings.js index 7e38fbe61dd2..abfb131a0d26 100644 --- a/lib/node_modules/@stdlib/repl/lib/settings.js +++ b/lib/node_modules/@stdlib/repl/lib/settings.js @@ -45,15 +45,11 @@ var SETTINGS = { 'type': 'boolean' }, 'syntaxHighlighting': { - 'desc': 'Enable syntax highlighting of the input.', + 'desc': 'Enable syntax highlighting.', 'type': 'boolean' }, 'theme': { - 'desc': 'Set the color theme for syntax highlighting.', - 'type': 'string' - }, - 'defaultTheme': { - 'desc': 'Set the default color theme for syntax highlighting.', + 'desc': 'Set the syntax highlighting theme.', 'type': 'string' } }; diff --git a/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js b/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js index 3d826e14ce9d..5ca3488ccf9e 100644 --- a/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js +++ b/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js @@ -37,6 +37,7 @@ var ANSI = require( './ansi_colors.js' ); // VARIABLES // var debug = logger( 'repl:syntax-highlighter' ); +var DEFAULT_THEME = 'stdlib-ansi-basic'; // FUNCTIONS // @@ -94,10 +95,7 @@ function SyntaxHighlighter( repl, ostream, enabled ) { this._themes = THEMES; // Initialize a variable storing the current theme: - this._theme = 'default'; - - // Initialize a variable storing the default theme: - this._defaultTheme = 'default'; + this._theme = ''; return this; } @@ -143,7 +141,7 @@ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, '_highlightLine', functio }); /** -* Gets all available theme names. +* Returns a list of available theme names. * * @name getThemes * @memberof SyntaxHighlighter.prototype @@ -172,7 +170,7 @@ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'setTheme', function setT }); /** -* Gets a theme's colors palette. +* Returns a theme's colors palette. * * @name getThemeConfig * @memberof SyntaxHighlighter.prototype @@ -188,22 +186,6 @@ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'getThemeConfig', functio return this._themes[ theme ]; }); -/** -* Sets the default color theme. -* -* @name setDefaultTheme -* @memberof SyntaxHighlighter.prototype -* @type {Function} -* @param {string} theme - theme name -* @throws {Error} argument must be an existing theme -*/ -setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'setDefaultTheme', function setDefaultTheme( theme ) { - if ( !contains( objectKeys( this._themes ), theme ) ) { - throw new Error( format( 'invalid argument. First argument must be an existing theme name. Value: `%s`.', theme ) ); - } - this._defaultTheme = theme; -}); - /** * Adds a new color theme. * @@ -227,10 +209,16 @@ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'addTheme', function addT * @throws {Error} first argument must be an existing theme name */ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'renameTheme', function renameTheme( oldName, newName ) { + if ( oldName === DEFAULT_THEME ) { + throw new Error( format( 'invalid argument. First argument must be not be the default theme name. Value: `%s`.', oldName ) ); + } if ( !contains( objectKeys( this._themes ), oldName ) ) { throw new Error( format( 'invalid argument. First argument must be an existing theme name. Value: `%s`.', oldName ) ); } this._themes[ newName ] = this._themes[ oldName ]; + if ( oldName === this._theme ) { + this._repl.settings( 'theme', newName ); + } this._themes = omit( this._themes, oldName ); }); @@ -248,12 +236,12 @@ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'deleteTheme', function d if ( !contains( objectKeys( this._themes ), theme ) ) { throw new Error( format( 'invalid argument. First argument must be an existing theme name. Value: `%s`.', theme ) ); } - if ( theme === this._defaultTheme ) { + if ( theme === DEFAULT_THEME ) { throw new Error( format( 'invalid argument. First argument cannot be the default theme. Value: `%s`.', theme ) ); } if ( theme === this._theme ) { this._highlightedLine = ''; - this._theme = this._defaultTheme; + this._repl.settings( 'theme', DEFAULT_THEME ); } this._themes = omit( this._themes, theme ); }); diff --git a/lib/node_modules/@stdlib/repl/lib/themes.js b/lib/node_modules/@stdlib/repl/lib/themes.js index 5840be5cb198..e49e4f1198be 100644 --- a/lib/node_modules/@stdlib/repl/lib/themes.js +++ b/lib/node_modules/@stdlib/repl/lib/themes.js @@ -28,7 +28,7 @@ * @type {Object} */ var THEMES = { - 'default': { + 'stdlib-ansi-basic': { // Keywords: 'control': 'magenta', 'keyword': 'blue', diff --git a/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/functions.json b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/functions.json index ba51fbf2d81a..be9648b077cf 100644 --- a/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/functions.json +++ b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/functions.json @@ -1,5 +1,5 @@ { - "expression": "var a = () => true;\na", + "expression": "function a() {};\na", "expected": "\u001b[31ma\u001b[0m", "theme": { "function": "red" diff --git a/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/reserved_literals.json b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/reserved_literals.json index 97a9ac2bbb84..1fd1250b8674 100644 --- a/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/reserved_literals.json +++ b/lib/node_modules/@stdlib/repl/test/integration/fixtures/syntax-highlighting/reserved_literals.json @@ -1,6 +1,6 @@ { - "expression": "let a = true; let b = false; let c = null; let d = undefined;", - "expected": "let a = \u001b[31mtrue\u001b[0m; let b = \u001b[31mfalse\u001b[0m; let c = \u001b[31mnull\u001b[0m; let d = \u001b[31mundefined\u001b[0m;", + "expression": "var a = true; var b = false; var c = null; var d = undefined;", + "expected": "var a = \u001b[31mtrue\u001b[0m; var b = \u001b[31mfalse\u001b[0m; var c = \u001b[31mnull\u001b[0m; var d = \u001b[31mundefined\u001b[0m;", "theme": { "literal": "red" } From 7bc6f929410cf21e63773e8b7ca034bc8d3405dd Mon Sep 17 00:00:00 2001 From: Athan Date: Fri, 7 Jun 2024 15:40:24 -0700 Subject: [PATCH 23/33] Apply suggestions from code review Signed-off-by: Athan --- lib/node_modules/@stdlib/repl/README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/node_modules/@stdlib/repl/README.md b/lib/node_modules/@stdlib/repl/README.md index f5e0a6a02052..3a0f0ea09d21 100644 --- a/lib/node_modules/@stdlib/repl/README.md +++ b/lib/node_modules/@stdlib/repl/README.md @@ -279,14 +279,14 @@ repl.addTheme( 'myTheme', { repl.close(); ``` -The syntax-highlighter supports the following tokens and ANSI color names: +The syntax-highlighter supports the following tokens and associated theme fields: -- **keyword**: keywords. eg: `var`, `function`, `let`, `const`, `in`, `class` etc. -- **control**: control flow keywords. eg: `if`, `else`, `try`, `catch`, `return` etc. -- **specialIdentifier**: special identifiers. eg: `this`, `super` etc. +- **keyword**: keywords (e.g., `var`, `function`, `let`, `const`, `in`, and `class`). +- **control**: control flow keywords (e.g., `if`, `else`, `try`, `catch`, and `return`). +- **specialIdentifier**: special identifiers (e.g., `this` and `super`). - **string**: string and template literals. - **number**: numeric literals. -- **literal**: reserved literals. eg: `true`, `false`, `null`, `undefined` etc. +- **literal**: reserved literals (e.g., `true`, `false`, `null`, and `undefined`). - **regexp**: regular expressions. - **command**: built-in REPL commands. - **function**: function identifiers. @@ -294,8 +294,8 @@ The syntax-highlighter supports the following tokens and ANSI color names: - **variable**: literal identifiers. - **name**: variable names. - **comment**: line comments. -- **punctuation**: punctuation symbols. eg: `;`, `[`, `{`, `,`, `?` etc. -- **operator**: operator symbols. eg: `+`, `-`, `*`, `=`, `++`, `>=`, `&&` etc. +- **punctuation**: punctuation symbols (e.g., `;`, `[`, `{`, `,`, and `?`). +- **operator**: operator symbols (e.g., `+`, `-`, `*`, `=`, `++`, `>=`, and `&&`). #### REPL.prototype.deleteTheme() From 7c7dbeb86d393230e0fe18bd59d5924567fd1cf1 Mon Sep 17 00:00:00 2001 From: Athan Date: Fri, 7 Jun 2024 15:42:13 -0700 Subject: [PATCH 24/33] Apply suggestions from code review Signed-off-by: Athan --- lib/node_modules/@stdlib/repl/lib/commands/get_theme.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/repl/lib/commands/get_theme.js b/lib/node_modules/@stdlib/repl/lib/commands/get_theme.js index 3ebda3bca6c4..05ce9a763f38 100644 --- a/lib/node_modules/@stdlib/repl/lib/commands/get_theme.js +++ b/lib/node_modules/@stdlib/repl/lib/commands/get_theme.js @@ -42,7 +42,7 @@ function command( repl ) { * * @private * @param {string} [name] - theme name - * @returns {Object|void} theme object + * @returns {(Object|void)} theme object */ function onCommand() { var theme; From 3f7d8859dc3df00b3e6dac8a71d150f8a23c5216 Mon Sep 17 00:00:00 2001 From: Athan Date: Fri, 7 Jun 2024 15:44:18 -0700 Subject: [PATCH 25/33] Apply suggestions from code review Signed-off-by: Athan --- lib/node_modules/@stdlib/repl/lib/commands/themes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/repl/lib/commands/themes.js b/lib/node_modules/@stdlib/repl/lib/commands/themes.js index 698c71413e74..d3e1177da7a8 100644 --- a/lib/node_modules/@stdlib/repl/lib/commands/themes.js +++ b/lib/node_modules/@stdlib/repl/lib/commands/themes.js @@ -34,7 +34,7 @@ function command( repl ) { * Returns a list of available syntax highlighting color themes. * * @private - * @returns {Array} list of available themes + * @returns {Array} list of available themes */ function onCommand() { return repl.themes(); From 3d80c69a3a1e15c060026ec711dfe743bbf9d2ec Mon Sep 17 00:00:00 2001 From: Athan Date: Fri, 7 Jun 2024 15:51:55 -0700 Subject: [PATCH 26/33] Apply suggestions from code review Signed-off-by: Athan --- lib/node_modules/@stdlib/repl/lib/main.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/node_modules/@stdlib/repl/lib/main.js b/lib/node_modules/@stdlib/repl/lib/main.js index b2f16c01629d..c415c36c9391 100644 --- a/lib/node_modules/@stdlib/repl/lib/main.js +++ b/lib/node_modules/@stdlib/repl/lib/main.js @@ -92,7 +92,7 @@ var debug = logger( 'repl' ); * @param {boolean} [options.isTTY] - boolean indicating whether the input and output streams should be treated like a TTY (terminal) and whether the REPL should use ANSI/VT100 escape codes when writing to the output stream * @param {string} [options.welcome] - welcome message * @param {NonNegativeInteger} [options.padding=1] - number of empty lines between successive commands -* @param {Object} [options.themes] - table mapping of color themes to load for syntax-highlighting +* @param {Object} [options.themes] - table containing color themes for syntax highlighting * @param {string} [options.load] - file path specifying a JavaScript file to load and evaluate line-by-line (e.g., a previous REPL history file) * @param {string} [options.save] - file path specifying where to save REPL command history * @param {string} [options.log] - file path specifying where to save REPL commands and printed output @@ -310,7 +310,7 @@ function REPL( options ) { // TODO: check whether to synchronously initialize a REPL log file - // Check whether to load user-defined themes upon startup... + // Add any provided user-defined themes... if ( opts.themes ) { themes = objectKeys( opts.themes ); for ( i = 0; i < themes.length; i++ ) { @@ -817,7 +817,8 @@ setNonEnumerableReadOnly( REPL.prototype, 'clearUserDocs', function clearUserDoc * // ... * * // Fetch all available themes: -* repl.themes(); +* var theme = repl.themes(); +* // returns [...] * * // ... * @@ -855,7 +856,8 @@ setNonEnumerableReadOnly( REPL.prototype, 'themes', function themes() { * }); * * // Get a theme's color palette: -* repl.getTheme( 'myTheme' ); +* var o = repl.getTheme( 'myTheme' ); +* // returns { 'keyword': 'red' } * * // ... * @@ -915,7 +917,7 @@ setNonEnumerableReadOnly( REPL.prototype, 'addTheme', function addTheme( name, t }); /** -* Renames a specified theme in the syntax-highlighter.. +* Renames a specified syntax highlighting theme. * * @name renameTheme * @memberof REPL.prototype @@ -965,7 +967,7 @@ setNonEnumerableReadOnly( REPL.prototype, 'renameTheme', function renameTheme( o }); /** -* Deletes a specified theme from the syntax-highlighter. +* Deletes a specified syntax highlighting theme. * * @name deleteTheme * @memberof REPL.prototype From 8938c74b2cb8f0b53b989253353d1d7e820ec0cd Mon Sep 17 00:00:00 2001 From: Athan Date: Fri, 7 Jun 2024 16:03:29 -0700 Subject: [PATCH 27/33] Apply suggestions from code review Signed-off-by: Athan --- lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js | 3 +-- lib/node_modules/@stdlib/repl/lib/tokenizer.js | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js b/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js index 5ca3488ccf9e..90fe9ab3df27 100644 --- a/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js +++ b/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js @@ -146,7 +146,7 @@ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, '_highlightLine', functio * @name getThemes * @memberof SyntaxHighlighter.prototype * @type {Function} -* @returns {Array} array of all theme names +* @returns {Array} array of all theme names */ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'getThemes', function getThemes() { return objectKeys( this._themes ); @@ -292,7 +292,6 @@ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'onKeypress', function on debug( 'Empty line detected. Skipping highlighting...' ); return; } - // If line change is detected, tokenize & highlight the line. Use cache if no line change is detected... if ( this._line !== this._rli.line ) { // Update line buffer: this._line = this._rli.line; diff --git a/lib/node_modules/@stdlib/repl/lib/tokenizer.js b/lib/node_modules/@stdlib/repl/lib/tokenizer.js index d630a917c1c4..21ecef7d7d4f 100644 --- a/lib/node_modules/@stdlib/repl/lib/tokenizer.js +++ b/lib/node_modules/@stdlib/repl/lib/tokenizer.js @@ -265,7 +265,7 @@ function tokenizer( line, context ) { * @private * @param {Object} node - AST node * @param {boolean} compute - boolean indicating whether to compute the `MemberExpression` - * @returns {void|*} computed value of the `MemberExpression` if compute is true + * @returns {(void|*)} computed value of the `MemberExpression` if compute is true */ function resolveMemberExpression( node, compute ) { var properties = linkedList(); From 7de50f521826f5e2862cf631c82f842e18b5db20 Mon Sep 17 00:00:00 2001 From: Athan Date: Fri, 7 Jun 2024 16:05:51 -0700 Subject: [PATCH 28/33] Apply suggestions from code review Signed-off-by: Athan --- lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js b/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js index 90fe9ab3df27..b00e605de6c2 100644 --- a/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js +++ b/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js @@ -170,7 +170,7 @@ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'setTheme', function setT }); /** -* Returns a theme's colors palette. +* Returns a theme's color palette. * * @name getThemeConfig * @memberof SyntaxHighlighter.prototype From 3798c6572bc264e5ff2c534fd7867dccc72d6ed6 Mon Sep 17 00:00:00 2001 From: Athan Date: Fri, 7 Jun 2024 16:10:02 -0700 Subject: [PATCH 29/33] Apply suggestions from code review Signed-off-by: Athan --- lib/node_modules/@stdlib/repl/lib/main.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/node_modules/@stdlib/repl/lib/main.js b/lib/node_modules/@stdlib/repl/lib/main.js index c415c36c9391..d5fc46caddf4 100644 --- a/lib/node_modules/@stdlib/repl/lib/main.js +++ b/lib/node_modules/@stdlib/repl/lib/main.js @@ -818,7 +818,6 @@ setNonEnumerableReadOnly( REPL.prototype, 'clearUserDocs', function clearUserDoc * * // Fetch all available themes: * var theme = repl.themes(); -* // returns [...] * * // ... * @@ -857,7 +856,6 @@ setNonEnumerableReadOnly( REPL.prototype, 'themes', function themes() { * * // Get a theme's color palette: * var o = repl.getTheme( 'myTheme' ); -* // returns { 'keyword': 'red' } * * // ... * From ba7ac55371664be73d2f0f075d00fe954a6dbfdc Mon Sep 17 00:00:00 2001 From: Snehil Shah Date: Sat, 8 Jun 2024 04:27:22 +0000 Subject: [PATCH 30/33] fix: suggestions Signed-off-by: Snehil Shah --- lib/node_modules/@stdlib/repl/README.md | 8 ++++---- .../@stdlib/repl/lib/commands/rename_theme.js | 2 +- .../@stdlib/repl/lib/syntax_highlighter.js | 12 ++++++------ 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/node_modules/@stdlib/repl/README.md b/lib/node_modules/@stdlib/repl/README.md index 3a0f0ea09d21..206a2b19097f 100644 --- a/lib/node_modules/@stdlib/repl/README.md +++ b/lib/node_modules/@stdlib/repl/README.md @@ -222,7 +222,7 @@ var themes = repl.themes(); repl.close(); ``` -#### REPL.prototype.getTheme() +#### REPL.prototype.getTheme( name ) Returns a theme's color palette for syntax highlighting. @@ -251,7 +251,7 @@ var theme = repl.getTheme( 'myTheme' ); repl.close(); ``` -#### REPL.prototype.addTheme() +#### REPL.prototype.addTheme( name, theme ) Adds a syntax highlighting theme. @@ -297,7 +297,7 @@ The syntax-highlighter supports the following tokens and associated theme fields - **punctuation**: punctuation symbols (e.g., `;`, `[`, `{`, `,`, and `?`). - **operator**: operator symbols (e.g., `+`, `-`, `*`, `=`, `++`, `>=`, and `&&`). -#### REPL.prototype.deleteTheme() +#### REPL.prototype.deleteTheme( name ) Deletes a specified theme from the syntax-highlighter. @@ -328,7 +328,7 @@ repl.deleteTheme( 'myTheme' ); repl.close(); ``` -#### REPL.prototype.renameTheme() +#### REPL.prototype.renameTheme( oldName, newName ) Renames a specified theme in the syntax-highlighter. diff --git a/lib/node_modules/@stdlib/repl/lib/commands/rename_theme.js b/lib/node_modules/@stdlib/repl/lib/commands/rename_theme.js index 43e702a526c5..04685fd3ed0a 100644 --- a/lib/node_modules/@stdlib/repl/lib/commands/rename_theme.js +++ b/lib/node_modules/@stdlib/repl/lib/commands/rename_theme.js @@ -53,7 +53,7 @@ function command( repl ) { repl._ostream.write( format( 'Error: %s\n', err.message ) ); return; } - log( repl, format( 'Successfully named theme `%s` to `%s`.', oldName, newName ) ); + log( repl, format( '\nSuccessfully named theme `%s` to `%s`.', oldName, newName ) ); } } diff --git a/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js b/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js index b00e605de6c2..ff3ca44325d9 100644 --- a/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js +++ b/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js @@ -28,7 +28,7 @@ var format = require( '@stdlib/string/format' ); var setNonEnumerableReadOnly = require( '@stdlib/utils/define-nonenumerable-read-only-property' ); var objectKeys = require( '@stdlib/utils/keys' ); var omit = require( '@stdlib/utils/omit' ); -var contains = require('@stdlib/array/base/assert/contains'); +var hasOwnProp = require( '@stdlib/assert/has-own-property' ); var tokenizer = require( './tokenizer.js' ); var THEMES = require( './themes.js' ); var ANSI = require( './ansi_colors.js' ); @@ -162,7 +162,7 @@ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'getThemes', function get * @throws {Error} argument must be an existing theme */ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'setTheme', function setTheme( theme ) { - if ( !contains( objectKeys( this._themes ), theme ) ) { + if ( !hasOwnProp( this._themes, theme ) ) { throw new Error( format( 'invalid argument. First argument must be an existing theme name. Value: `%s`.', theme ) ); } this._highlightedLine = ''; @@ -180,7 +180,7 @@ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'setTheme', function setT * @returns {Object} theme object */ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'getThemeConfig', function getThemeConfig( theme ) { - if ( !contains( objectKeys( this._themes ), theme ) ) { + if ( !hasOwnProp( this._themes, theme ) ) { throw new Error( format( 'invalid argument. First argument must be an existing theme name. Value: `%s`.', theme ) ); } return this._themes[ theme ]; @@ -212,7 +212,7 @@ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'renameTheme', function r if ( oldName === DEFAULT_THEME ) { throw new Error( format( 'invalid argument. First argument must be not be the default theme name. Value: `%s`.', oldName ) ); } - if ( !contains( objectKeys( this._themes ), oldName ) ) { + if ( !hasOwnProp( this._themes, oldName ) ) { throw new Error( format( 'invalid argument. First argument must be an existing theme name. Value: `%s`.', oldName ) ); } this._themes[ newName ] = this._themes[ oldName ]; @@ -233,11 +233,11 @@ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'renameTheme', function r * @throws {Error} must provide a theme other than the default theme */ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'deleteTheme', function deleteTheme( theme ) { - if ( !contains( objectKeys( this._themes ), theme ) ) { + if ( !hasOwnProp( this._themes, theme ) ) { throw new Error( format( 'invalid argument. First argument must be an existing theme name. Value: `%s`.', theme ) ); } if ( theme === DEFAULT_THEME ) { - throw new Error( format( 'invalid argument. First argument cannot be the default theme. Value: `%s`.', theme ) ); + throw new Error( format( 'invalid argument. First argument must not be the default theme. Value: `%s`.', theme ) ); } if ( theme === this._theme ) { this._highlightedLine = ''; From 81bdca731370c25d3f0be337f3f7619c7f6be60d Mon Sep 17 00:00:00 2001 From: Athan Date: Sat, 8 Jun 2024 03:59:33 -0700 Subject: [PATCH 31/33] Apply suggestions from code review Signed-off-by: Athan --- lib/node_modules/@stdlib/repl/lib/commands/rename_theme.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/repl/lib/commands/rename_theme.js b/lib/node_modules/@stdlib/repl/lib/commands/rename_theme.js index 04685fd3ed0a..81b6182829a9 100644 --- a/lib/node_modules/@stdlib/repl/lib/commands/rename_theme.js +++ b/lib/node_modules/@stdlib/repl/lib/commands/rename_theme.js @@ -53,7 +53,7 @@ function command( repl ) { repl._ostream.write( format( 'Error: %s\n', err.message ) ); return; } - log( repl, format( '\nSuccessfully named theme `%s` to `%s`.', oldName, newName ) ); + log( repl, format( '\nSuccessfully renamed theme from `%s` to `%s`.', oldName, newName ) ); } } From 6ea845f4e5d042e2e249424afe0fdf70e52d8eba Mon Sep 17 00:00:00 2001 From: Athan Date: Sat, 8 Jun 2024 04:02:34 -0700 Subject: [PATCH 32/33] Apply suggestions from code review Signed-off-by: Athan --- lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js b/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js index ff3ca44325d9..838834c374f8 100644 --- a/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js +++ b/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js @@ -237,7 +237,7 @@ setNonEnumerableReadOnly( SyntaxHighlighter.prototype, 'deleteTheme', function d throw new Error( format( 'invalid argument. First argument must be an existing theme name. Value: `%s`.', theme ) ); } if ( theme === DEFAULT_THEME ) { - throw new Error( format( 'invalid argument. First argument must not be the default theme. Value: `%s`.', theme ) ); + throw new Error( format( 'invalid argument. First argument must not be the default theme name. Value: `%s`.', theme ) ); } if ( theme === this._theme ) { this._highlightedLine = ''; From 6913e06b3397404f57431c4d80811d764c2dc5fb Mon Sep 17 00:00:00 2001 From: Athan Date: Sat, 8 Jun 2024 04:05:05 -0700 Subject: [PATCH 33/33] Apply suggestions from code review Signed-off-by: Athan --- lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js b/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js index 838834c374f8..901e15d105aa 100644 --- a/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js +++ b/lib/node_modules/@stdlib/repl/lib/syntax_highlighter.js @@ -95,7 +95,7 @@ function SyntaxHighlighter( repl, ostream, enabled ) { this._themes = THEMES; // Initialize a variable storing the current theme: - this._theme = ''; + this._theme = DEFAULT_THEME; return this; }