Skip to content

Commit

Permalink
Terminal history support (#161)
Browse files Browse the repository at this point in the history
  • Loading branch information
cheton committed Jun 11, 2017
1 parent 4e6c151 commit d8a0c8d
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 9 deletions.
68 changes: 68 additions & 0 deletions src/web/widgets/Console/History.js
@@ -0,0 +1,68 @@
class History {
maxLength = Infinity;
history = []; // A circular history array if a maximum length is given
start = 0; // The start position for the history array
index = -1; // Current index of the history array

constructor(maxLength) {
maxLength = Number(maxLength) || 0;
if (maxLength > 0) {
this.maxLength = maxLength;
}
}
current() {
if (this.history.length === 0) {
return undefined;
}

const index = (this.start + this.index) % this.history.length;
return this.history[index];
}
forward() {
if ((this.history.length === 0) || (this.index + 1 >= this.history.length)) {
return undefined;
}

++this.index;
const index = (this.start + this.index) % this.history.length;
return this.history[index];
}
back() {
if ((this.history.length === 0) || (this.index - 1 < 0)) {
return undefined;
}

--this.index;
const index = (this.start + this.index) % this.history.length;
return this.history[index];
}
go(n) {
if (this.history.length === 0) {
return undefined;
}
n = Number(n) || 0;
this.index = Math.min(Math.max(0, this.index + n), this.history.length - 1);
const index = (this.start + this.index) % this.history.length;
return this.history[index];
}
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
// S x x x x x x x x x >> x S x x x x x x x x
push(data) {
if (this.history.length < this.maxLength) {
if (this.index + 1 >= this.history.length) {
++this.index;
}
this.history.push(data);
} else {
this.history[this.start] = data;
this.start = (this.start + 1) % this.history.length;
if (this.index > 0) {
--this.index;
}
}

return data;
}
}

export default History;
42 changes: 33 additions & 9 deletions src/web/widgets/Console/Terminal.jsx
@@ -1,11 +1,12 @@
import includes from 'lodash/includes';
import classNames from 'classnames';
import { code } from 'keycode';
//import { code } from 'keycode';
import PropTypes from 'prop-types';
import React, { PureComponent } from 'react';
import ReactDOM from 'react-dom';
import Xterm from 'xterm';
import fit from 'xterm/lib/addons/fit/fit';
import History from './History';
import log from '../../lib/log';
import styles from './index.styl';

Expand All @@ -26,6 +27,8 @@ class Terminal extends PureComponent {
tabStopWidth: 4,
onData: () => {}
};
history = new History(1000);
historyCommand = '';

eventHandler = {
onResize: (size) => {
Expand All @@ -38,19 +41,22 @@ class Terminal extends PureComponent {
return (key, event) => {
const { onData } = this.props;
const term = this.term;
const nonPrintable = (event.altKey || event.altGraphKey || event.ctrlKey || event.metaKey);
const nonPrintableKey = (event.altKey || event.altGraphKey || event.ctrlKey || event.metaKey);

// Enter
if (event.keyCode === code.enter) {
if (event.key === 'Enter') {
if (buffer.length > 0) {
this.history.push(buffer);
}
buffer += key;
onData(buffer);
buffer = '';
term.writeln('');
return;
}

// Delete
if (event.keyCode === code.backspace) {
// Backspace
if (event.key === 'Backspace') {
let line = term.lines.get(term.ybase + term.y);
let x = term.x;
if (line && x > 0) {
Expand All @@ -72,17 +78,35 @@ class Terminal extends PureComponent {
return;
}

// Non-printable character (e.g. ctrl-x)
if (nonPrintable) {
// Non-printable keys (e.g. ctrl-x)
if (nonPrintableKey) {
onData(buffer);
buffer = '';

onData(key);
return;
}

// Up, Right, Down, Left
if (includes([code.up, code.right, code.down, code.left], event.keyCode)) {
// Left, Right
if (includes(['ArrowLeft', 'ArrowRight'], event.key)) {
return;
}

// Up, Down
if (includes(['ArrowUp', 'ArrowDown'], event.key)) {
if (event.key === 'ArrowUp') {
if (!this.historyCommand) {
this.historyCommand = this.history.current() || '';
} else if (this.history.index > 0) {
this.historyCommand = this.history.back() || '';
}
} else if (event.key === 'ArrowDown') {
this.historyCommand = this.history.forward() || '';
}

term.eraseLine(term.y);
term.x = 0;
term.write(this.historyCommand);
return;
}

Expand Down

0 comments on commit d8a0c8d

Please sign in to comment.