|
|
|
@ -49,20 +49,29 @@ class FindBar extends Component {
|
|
|
|
|
return result.charAt(0).toUpperCase() + result.slice(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Generates a regexp and splits a token and param details for a command
|
|
|
|
|
compileCommand(command) {
|
|
|
|
|
let regexp = '';
|
|
|
|
|
let param;
|
|
|
|
|
let param = null;
|
|
|
|
|
|
|
|
|
|
const matcher = /\(:([a-zA-Z_$][a-zA-Z0-9_$]*)(?:(?: as )(.*))?\)/g;
|
|
|
|
|
const match = matcher.exec(command.pattern);
|
|
|
|
|
const token = command.pattern.slice(0, match.index) || command.token;
|
|
|
|
|
regexp += this._escapeRegExp(command.pattern.slice(0, match.index));
|
|
|
|
|
const matchIndex = match ? match.index : command.pattern.length;
|
|
|
|
|
|
|
|
|
|
if (match[1]) {
|
|
|
|
|
const token = command.pattern.slice(0, matchIndex) || command.token;
|
|
|
|
|
regexp += this._escapeRegExp(command.pattern.slice(0, matchIndex));
|
|
|
|
|
|
|
|
|
|
if (match && match[1]) {
|
|
|
|
|
regexp += '(.*)';
|
|
|
|
|
param = { name:match[1], display:match[2] || this._camelCaseToSpace(match[1]) };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
console.log(Object.assign({}, command, {
|
|
|
|
|
regexp,
|
|
|
|
|
token,
|
|
|
|
|
param
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
return Object.assign({}, command, {
|
|
|
|
|
regexp,
|
|
|
|
|
token,
|
|
|
|
@ -70,6 +79,8 @@ class FindBar extends Component {
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check if the entered string matches any command.
|
|
|
|
|
// adds a scope (so user can type param value) and dispatches action for fully matched commands
|
|
|
|
|
matchCommand() {
|
|
|
|
|
const string = this.state.activeScope ? this.state.activeScope + this.state.value : this.state.value;
|
|
|
|
|
let match;
|
|
|
|
@ -78,18 +89,27 @@ class FindBar extends Component {
|
|
|
|
|
return match;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const param = match[1] && match[1].trim();
|
|
|
|
|
const paramName = command.param ? command.param.name : null;
|
|
|
|
|
const enteredParamValue = command.param && match[1] ? match[1].trim() : null;
|
|
|
|
|
|
|
|
|
|
if (!command) {
|
|
|
|
|
// No matched command
|
|
|
|
|
return null;
|
|
|
|
|
} else if (command && !param) {
|
|
|
|
|
} else if (command.param && !enteredParamValue) {
|
|
|
|
|
// Partial Match
|
|
|
|
|
// Command was partially matched: It requires a param, but param wasn't entered
|
|
|
|
|
// Set a scope so user can fill the param
|
|
|
|
|
this.setState({
|
|
|
|
|
value: '',
|
|
|
|
|
activeScope: command.token,
|
|
|
|
|
placeholder: command.param.display
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
this.props.dispatch(runCommand(command.token, command.param.name, param));
|
|
|
|
|
// Match
|
|
|
|
|
// Command was matched and either it doesn't require a param or it's required param was entered
|
|
|
|
|
// Dispatch action
|
|
|
|
|
const payload = paramName ? { [paramName]: enteredParamValue } : null;
|
|
|
|
|
this.props.dispatch(runCommand(command.token, payload));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -102,10 +122,18 @@ class FindBar extends Component {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
handleChange(event) {
|
|
|
|
|
this.setState({
|
|
|
|
|
value: event.target.value,
|
|
|
|
|
getSuggestions() {
|
|
|
|
|
return this._getSuggestions(this.state.value, this.state.activeScope, this._compiledCommands);
|
|
|
|
|
}
|
|
|
|
|
// Memoized version
|
|
|
|
|
_getSuggestions(value, scope, commands) {
|
|
|
|
|
if (scope) return []; // No autocomplete for scoped input
|
|
|
|
|
const results = fuzzy.filter(value, commands, {
|
|
|
|
|
//pre: '<strong>',
|
|
|
|
|
//post: '</strong>',
|
|
|
|
|
extract: el => el.token
|
|
|
|
|
});
|
|
|
|
|
return results.slice(0, 5).map(result => result.original);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
handleKeyDown(event) {
|
|
|
|
@ -171,6 +199,12 @@ class FindBar extends Component {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
handleChange(event) {
|
|
|
|
|
this.setState({
|
|
|
|
|
value: event.target.value,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
handleInputBlur() {
|
|
|
|
|
if (this._ignoreBlur) return;
|
|
|
|
|
this.setState({
|
|
|
|
@ -189,20 +223,6 @@ class FindBar extends Component {
|
|
|
|
|
this.setState({ isOpen: true });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_getSuggestions(value, scope, commands) {
|
|
|
|
|
if (scope) return []; // TODO: Prepare for multiple params & search suggestions
|
|
|
|
|
const results = fuzzy.filter(value, commands, {
|
|
|
|
|
//pre: '<strong>',
|
|
|
|
|
//post: '</strong>',
|
|
|
|
|
extract: el => el.token
|
|
|
|
|
});
|
|
|
|
|
return results.slice(0, 5).map(result => result.original);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getSuggestions() {
|
|
|
|
|
return this._getSuggestions(this.state.value, this.state.activeScope, this._compiledCommands);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
highlightCommandFromMouse(index) {
|
|
|
|
|
this.setState({ highlightedIndex: index });
|
|
|
|
|
}
|
|
|
|
|