Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 52 additions & 14 deletions packages/browser-repl/src/components/editor.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,22 @@ describe('<Editor />', () => {
return aceEditor.instance().editor as any;
};

const execCommandBoundTo = (aceEditor: any, key: string): void => {
const execCommandBoundTo = (
aceEditor: any,
key: { win: string; mac: string }
): void => {
const commands = Object.values(aceEditor.commands.commands);
const command: any = commands.find(({ bindKey }) => {
const command: any = commands.find(({ name, bindKey }) => {
if (!bindKey) {
return false;
}

if (typeof bindKey === 'string') {
return key === bindKey;
if (name === 'gotoline') {
// Ignore gotoline - our command overrides.
return false;
}

const { win, mac } = bindKey as {win: string; mac: string};
return win === key && mac === key;
const { win, mac } = bindKey as { win: string; mac: string };
return win === key.win && mac === key.mac;
});

if (!command) {
Expand Down Expand Up @@ -58,7 +61,24 @@ describe('<Editor />', () => {
const aceEditor = getAceEditorInstance(wrapper);
expect(spy).not.to.have.been.called;

execCommandBoundTo(aceEditor, 'Return');
execCommandBoundTo(aceEditor, {
win: 'Return',
mac: 'Return'
});
expect(spy).to.have.been.calledOnce;
});

it('calls onClearCommand when command/ctrl+L is pressed', () => {
const spy = sinon.spy();
const wrapper = mount(<Editor onClearCommand={spy} />);

const aceEditor = getAceEditorInstance(wrapper);

expect(spy).not.to.have.been.called;
execCommandBoundTo(aceEditor, {
win: 'Ctrl-L',
mac: 'Command-L'
});
expect(spy).to.have.been.calledOnce;
});

Expand All @@ -69,7 +89,10 @@ describe('<Editor />', () => {
const aceEditor = getAceEditorInstance(wrapper);

expect(spy).not.to.have.been.called;
execCommandBoundTo(aceEditor, 'Up');
execCommandBoundTo(aceEditor, {
win: 'Up',
mac: 'Up'
});
expect(spy).to.have.been.calledOnce;
});

Expand All @@ -82,7 +105,10 @@ describe('<Editor />', () => {
aceEditor.moveCursorToPosition({ row: 1, column: 0 });
aceEditor.clearSelection();

execCommandBoundTo(aceEditor, 'Up');
execCommandBoundTo(aceEditor, {
win: 'Up',
mac: 'Up'
});
expect(spy).not.to.have.been.called;
});

Expand All @@ -96,7 +122,10 @@ describe('<Editor />', () => {
aceEditor.clearSelection();

expect(spy).not.to.have.been.called;
execCommandBoundTo(aceEditor, 'Down');
execCommandBoundTo(aceEditor, {
win: 'Down',
mac: 'Down'
});
expect(spy).to.have.been.calledOnce;
});

Expand All @@ -107,7 +136,10 @@ describe('<Editor />', () => {
const aceEditor = getAceEditorInstance(wrapper);
aceEditor.setValue('row 0\nrow 1');

execCommandBoundTo(aceEditor, 'Down');
execCommandBoundTo(aceEditor, {
win: 'Down',
mac: 'Down'
});
expect(spy).not.to.have.been.called;
});

Expand All @@ -119,7 +151,10 @@ describe('<Editor />', () => {
aceEditor.setValue('text');
aceEditor.selectAll();

execCommandBoundTo(aceEditor, 'Up');
execCommandBoundTo(aceEditor, {
win: 'Up',
mac: 'Up'
});
expect(spy).not.to.have.been.called;
});

Expand All @@ -131,7 +166,10 @@ describe('<Editor />', () => {
aceEditor.setValue('text');
aceEditor.selectAll();

execCommandBoundTo(aceEditor, 'Down');
execCommandBoundTo(aceEditor, {
win: 'Down',
mac: 'Down'
});
expect(spy).not.to.have.been.called;
});

Expand Down
23 changes: 10 additions & 13 deletions packages/browser-repl/src/components/editor.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import AceEditor from 'react-ace';
import { Autocompleter } from '@mongosh/browser-runtime-core';
import { AceAutocompleterAdapter } from './ace-autocompleter-adapter';
Expand All @@ -11,35 +10,26 @@ import './ace-theme';
import ace from 'brace';
const tools = ace.acequire('ace/ext/language_tools');

const noop = (): void => {
//
};
const noop = (): void => {};

interface EditorProps {
onEnter?(): void | Promise<void>;
onArrowUpOnFirstLine?(): void | Promise<void>;
onArrowDownOnLastLine?(): void | Promise<void>;
onChange?(value: string): void | Promise<void>;
onClearCommand?(): void | Promise<void>;
autocompleter?: Autocompleter;
setInputRef?(ref): void;
value?: string;
}

export class Editor extends Component<EditorProps> {
static propTypes = {
onEnter: PropTypes.func,
onArrowUpOnFirstLine: PropTypes.func,
onArrowDownOnLastLine: PropTypes.func,
onChange: PropTypes.func,
setInputRef: PropTypes.func,
value: PropTypes.string
};

static defaultProps = {
onEnter: noop,
onArrowUpOnFirstLine: noop,
onArrowDownOnLastLine: noop,
onChange: noop,
onClearCommand: noop,
value: ''
};

Expand All @@ -60,6 +50,8 @@ export class Editor extends Component<EditorProps> {
};

render(): JSX.Element {
const { onClearCommand } = this.props;

return (<AceEditor
showPrintMargin={false}
showGutter={false}
Expand Down Expand Up @@ -114,6 +106,11 @@ export class Editor extends Component<EditorProps> {

this.props.onArrowDownOnLastLine();
}
},
{
name: 'clearShell',
bindKey: { win: 'Ctrl-L', mac: 'Command-L' },
exec: onClearCommand
}
]}
width="100%"
Expand Down
22 changes: 8 additions & 14 deletions packages/browser-repl/src/components/shell-input.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { Editor } from './editor';
import { Autocompleter } from '@mongosh/browser-runtime-core';
Expand All @@ -9,9 +8,10 @@ import Icon from '@leafygreen-ui/icon';
const styles = require('./shell-input.less');

interface ShellInputProps {
onInput?(code: string): void | Promise<void>;
history?: readonly string[];
autocompleter?: Autocompleter;
history?: readonly string[];
onClearCommand?(): void | Promise<void>;
onInput?(code: string): void | Promise<void>;
setInputRef?(ref): void;
}

Expand All @@ -20,13 +20,6 @@ interface ShellInputState {
}

export class ShellInput extends Component<ShellInputProps, ShellInputState> {
static propTypes = {
onInput: PropTypes.func,
history: PropTypes.arrayOf(PropTypes.string),
autocompleter: PropTypes.object,
setInputRef: PropTypes.func
};

readonly state: ShellInputState = {
currentValue: ''
};
Expand Down Expand Up @@ -116,13 +109,14 @@ export class ShellInput extends Component<ShellInputProps, ShellInputState> {
/>);

const editor = (<Editor
value={this.state.currentValue}
onChange={this.onChange}
onEnter={this.onEnter}
autocompleter={this.props.autocompleter}
onArrowUpOnFirstLine={this.historyBack}
onArrowDownOnLastLine={this.historyNext}
autocompleter={this.props.autocompleter}
onChange={this.onChange}
onEnter={this.onEnter}
onClearCommand={this.props.onClearCommand}
setInputRef={this.props.setInputRef}
value={this.state.currentValue}
/>);

const className = classnames(styles['shell-input']);
Expand Down
27 changes: 10 additions & 17 deletions packages/browser-repl/src/components/shell.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { ShellInput } from './shell-input';
import { ShellOutput, ShellOutputEntry } from './shell-output';
Expand Down Expand Up @@ -72,22 +71,6 @@ const noop = (): void => {
* The browser-repl Shell component
*/
export class Shell extends Component<ShellProps, ShellState> {
static propTypes = {
runtime: PropTypes.shape({
evaluate: PropTypes.func.isRequired
}).isRequired,
onOutputChanged: PropTypes.func,
onHistoryChanged: PropTypes.func,
redactInfo: PropTypes.bool,
maxOutputLength: PropTypes.number,
maxHistoryLength: PropTypes.number,
initialOutput: PropTypes.arrayOf(PropTypes.shape({
format: PropTypes.string.isRequired,
value: PropTypes.any.isRequired
})),
initialHistory: PropTypes.arrayOf(PropTypes.string)
};

static defaultProps = {
onHistoryChanged: noop,
onOutputChanged: noop,
Expand Down Expand Up @@ -162,6 +145,15 @@ export class Shell extends Component<ShellProps, ShellState> {
return output;
}

private onClearCommand = (): void => {
const output = [];

Object.freeze(output);

this.setState({ output });
this.props.onOutputChanged(output);
};

private onInput = async(code: string): Promise<void> => {
const inputLine: ShellOutputEntry = {
format: 'input',
Expand Down Expand Up @@ -212,6 +204,7 @@ export class Shell extends Component<ShellProps, ShellState> {
</div>
<div ref={(el): void => { this.shellInputElement = el; }}>
<ShellInput
onClearCommand={this.onClearCommand}
onInput={this.onInput}
history={this.state.history}
autocompleter={this.props.runtime}
Expand Down
16 changes: 8 additions & 8 deletions packages/cli-repl/src/completer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,6 @@ const BASE_COMPLETIONS = EXPRESSION_OPERATORS.concat(

const MATCH_COMPLETIONS = QUERY_OPERATORS.concat(BSON_TYPES);

const SHELL_COMPLETIONS = shellSignatures.ShellApi.attributes;
const COLL_COMPLETIONS = shellSignatures.Collection.attributes;
const DB_COMPLETIONS = shellSignatures.Database.attributes;
const AGG_CURSOR_COMPLETIONS = shellSignatures.AggregationCursor.attributes;
const COLL_CURSOR_COMPLETIONS = shellSignatures.Cursor.attributes;
const RS_COMPLETIONS = shellSignatures.ReplicaSet.attributes;
const SHARD_COMPLETE = shellSignatures.Shard.attributes;

/**
* The proect stage operator.
*/
Expand All @@ -42,6 +34,14 @@ const GROUP = '$group';
* @returns {array} Matching Completions, Current User Input.
*/
function completer(mdbVersion: string, line: string): [string[], string] {
const SHELL_COMPLETIONS = shellSignatures.ShellApi.attributes;
const COLL_COMPLETIONS = shellSignatures.Collection.attributes;
const DB_COMPLETIONS = shellSignatures.Database.attributes;
const AGG_CURSOR_COMPLETIONS = shellSignatures.AggregationCursor.attributes;
const COLL_CURSOR_COMPLETIONS = shellSignatures.Cursor.attributes;
const RS_COMPLETIONS = shellSignatures.ReplicaSet.attributes;
const SHARD_COMPLETE = shellSignatures.Shard.attributes;

// keep initial line param intact to always return in return statement
// check for contents of line with:
const splitLine = line.split('.');
Expand Down
Loading