* Some more progress on MLETV2
This commit is contained in:
parent
807551bca9
commit
30b6cbedfb
|
@ -100,6 +100,8 @@ function Client(input, output) {
|
||||||
var c;
|
var c;
|
||||||
var name;
|
var name;
|
||||||
|
|
||||||
|
console.log(data)
|
||||||
|
|
||||||
if(1 === len) {
|
if(1 === len) {
|
||||||
c = data[0];
|
c = data[0];
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,21 @@ var ansi = require('./ansi_term.js');
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
|
|
||||||
|
var SPECIAL_KEY_MAP_DEFAULT = {
|
||||||
|
lineFeed : [ 'enter' ],
|
||||||
|
exit : [ 'esc' ],
|
||||||
|
backspace : [ 'backspace' ],
|
||||||
|
del : [ 'del' ],
|
||||||
|
tabs : [ 'tab' ],
|
||||||
|
up : [ 'up arrow' ],
|
||||||
|
down : [ 'down arrow' ],
|
||||||
|
end : [ 'end' ],
|
||||||
|
home : [ 'home' ],
|
||||||
|
left : [ 'left arrow' ],
|
||||||
|
right : [ 'right arrow' ],
|
||||||
|
clearLine : [ 'end of medium' ],
|
||||||
|
}
|
||||||
|
|
||||||
exports.MultiLineEditTextView2 = MultiLineEditTextView2;
|
exports.MultiLineEditTextView2 = MultiLineEditTextView2;
|
||||||
|
|
||||||
function MultiLineEditTextView2(options) {
|
function MultiLineEditTextView2(options) {
|
||||||
|
@ -21,6 +36,10 @@ function MultiLineEditTextView2(options) {
|
||||||
options.acceptsInput = true;
|
options.acceptsInput = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!_.isObject(options.specialKeyMap)) {
|
||||||
|
options.specialKeyMap = SPECIAL_KEY_MAP_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
View.call(this, options);
|
View.call(this, options);
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
@ -34,8 +53,18 @@ function MultiLineEditTextView2(options) {
|
||||||
|
|
||||||
this.textLines = [];
|
this.textLines = [];
|
||||||
this.topVisibleIndex = 0;
|
this.topVisibleIndex = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// cursorPos represents zero-based row, col positions
|
||||||
|
// within the editor itself
|
||||||
|
//
|
||||||
this.cursorPos = { col : 0, row : 0 };
|
this.cursorPos = { col : 0, row : 0 };
|
||||||
|
|
||||||
|
this.getTextLinesIndex = function(row) {
|
||||||
|
var index = self.topVisibleIndex + self.cursorPos.row;
|
||||||
|
return index;
|
||||||
|
};
|
||||||
|
|
||||||
this.redrawVisibleArea = function() {
|
this.redrawVisibleArea = function() {
|
||||||
assert(self.topVisibleIndex < self.textLines.length);
|
assert(self.topVisibleIndex < self.textLines.length);
|
||||||
|
|
||||||
|
@ -54,6 +83,7 @@ function MultiLineEditTextView2(options) {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getVisibleText = function(index) {
|
this.getVisibleText = function(index) {
|
||||||
|
index = _.isNumber(index) ? index : self.getTextLinesIndex(self.cursorPos.row);
|
||||||
return self.textLines[index].text.replace(/\t/g, ' ');
|
return self.textLines[index].text.replace(/\t/g, ' ');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -66,17 +96,6 @@ function MultiLineEditTextView2(options) {
|
||||||
return text;
|
return text;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
this.getRenderText = function(text) {
|
|
||||||
text = text.replace(/\t/g, ' ');
|
|
||||||
var remain = self.dimens.width - text.length;
|
|
||||||
if(remain > 0) {
|
|
||||||
text += new Array(remain).join(' ');
|
|
||||||
}
|
|
||||||
return text;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
this.expandTab = function(col, expandChar) {
|
this.expandTab = function(col, expandChar) {
|
||||||
expandChar = expandChar || ' ';
|
expandChar = expandChar || ' ';
|
||||||
var count = self.tabWidth - (col % self.tabWidth);
|
var count = self.tabWidth - (col % self.tabWidth);
|
||||||
|
@ -144,7 +163,7 @@ function MultiLineEditTextView2(options) {
|
||||||
return wrapped;
|
return wrapped;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.insertText = function(text, row, col) {
|
this.insertText = function(text, index, col) {
|
||||||
//
|
//
|
||||||
// Perform the following on |text|:
|
// Perform the following on |text|:
|
||||||
// * Normalize various line feed formats -> \n
|
// * Normalize various line feed formats -> \n
|
||||||
|
@ -159,21 +178,21 @@ function MultiLineEditTextView2(options) {
|
||||||
// Try to handle any possible newline that can be fed to us.
|
// Try to handle any possible newline that can be fed to us.
|
||||||
// See http://stackoverflow.com/questions/5034781/js-regex-to-split-by-line
|
// See http://stackoverflow.com/questions/5034781/js-regex-to-split-by-line
|
||||||
//
|
//
|
||||||
// :TODO: support row/col insertion point
|
// :TODO: support index/col insertion point
|
||||||
|
|
||||||
if(_.isNumber(row)) {
|
if(_.isNumber(index)) {
|
||||||
if(_.isNumber(col)) {
|
if(_.isNumber(col)) {
|
||||||
//
|
//
|
||||||
// Modify text to have information from row
|
// Modify text to have information from index
|
||||||
// before and and after column
|
// before and and after column
|
||||||
//
|
//
|
||||||
// :TODO: Need to clean this string (e.g. collapse tabs)
|
// :TODO: Need to clean this string (e.g. collapse tabs)
|
||||||
text = self.textLines
|
text = self.textLines
|
||||||
|
|
||||||
// :TODO: Remove original line @ row
|
// :TODO: Remove original line @ index
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
row = self.textLines.length;
|
index = self.textLines.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tempLines = text
|
var tempLines = text
|
||||||
|
@ -186,9 +205,9 @@ function MultiLineEditTextView2(options) {
|
||||||
wrapped = self.wordWrapSingleLine(tempLines[i], self.dimens.width);
|
wrapped = self.wordWrapSingleLine(tempLines[i], self.dimens.width);
|
||||||
|
|
||||||
for(var j = 0; j < wrapped.length - 1; ++j) {
|
for(var j = 0; j < wrapped.length - 1; ++j) {
|
||||||
self.textLines.splice(row++, 0, { text : wrapped[j] } );
|
self.textLines.splice(index++, 0, { text : wrapped[j] } );
|
||||||
}
|
}
|
||||||
self.textLines.splice(row++, 0, { text : wrapped[wrapped.length - 1], eol : true });
|
self.textLines.splice(index++, 0, { text : wrapped[wrapped.length - 1], eol : true });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -202,14 +221,27 @@ function MultiLineEditTextView2(options) {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.cursorUp = function() {
|
this.cursorUp = function() {
|
||||||
console.log('up')
|
if(self.cursorPos.row > 0) {
|
||||||
|
self.cursorPos.row--;
|
||||||
|
self.client.term.write(ansi.up());
|
||||||
|
|
||||||
|
// :TODO: self.makeTabAdjustment('up')
|
||||||
|
} else if(self.topVisibleIndex > 0) {
|
||||||
|
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.cursorDown = function() {
|
this.cursorDown = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.cursorLeft = function() {
|
this.cursorLeft = function() {
|
||||||
|
if(self.cursorPos.col > 0) {
|
||||||
|
self.cursorPos.col--;
|
||||||
|
self.client.term.write(ansi.left());
|
||||||
|
// :TODO: handle landing on a tab
|
||||||
|
} else {
|
||||||
|
// :TODO: goto previous line if possible and scroll if needed
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.cursorRight = function() {
|
this.cursorRight = function() {
|
||||||
|
@ -217,12 +249,31 @@ function MultiLineEditTextView2(options) {
|
||||||
if(self.cursorPos.col < colEnd) {
|
if(self.cursorPos.col < colEnd) {
|
||||||
self.cursorPos.col++;
|
self.cursorPos.col++;
|
||||||
self.client.term.write(ansi.right());
|
self.client.term.write(ansi.right());
|
||||||
|
|
||||||
|
// :TODO: handle landing on a tab
|
||||||
} else {
|
} else {
|
||||||
// :TODO: goto next line; scroll if needed, etc.
|
// :TODO: goto next line; scroll if needed, etc.
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.cursorHome = function() {
|
this.cursorHome = function() {
|
||||||
|
var firstNonWhitespace = self.getVisibleText().search(/\S/);
|
||||||
|
if(-1 !== firstNonWhitespace) {
|
||||||
|
self.cursorPos.col = firstNonWhitespace;
|
||||||
|
} else {
|
||||||
|
self.cursorPos.col = 0;
|
||||||
|
}
|
||||||
|
console.log(self.getVisibleText())
|
||||||
|
self.moveClientCusorToCursorPos();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.cursorEnd = function() {
|
||||||
|
self.cursorPos.col = Math.max(self.getVisibleText().length - 1, 0);
|
||||||
|
self.moveClientCusorToCursorPos();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.cursorStartOfText = function() {
|
||||||
self.topVisibleIndex = 0;
|
self.topVisibleIndex = 0;
|
||||||
self.cursorPos = { row : 0, col : 0 };
|
self.cursorPos = { row : 0, col : 0 };
|
||||||
|
|
||||||
|
@ -230,18 +281,15 @@ function MultiLineEditTextView2(options) {
|
||||||
self.moveClientCusorToCursorPos();
|
self.moveClientCusorToCursorPos();
|
||||||
};
|
};
|
||||||
|
|
||||||
this.cursorEnd = function() {
|
this.cursorEndOfText = function() {
|
||||||
self.topVisibleIndex = Math.max(self.textLines.length - self.dimens.height, 0);
|
self.topVisibleIndex = Math.max(self.textLines.length - self.dimens.height, 0);
|
||||||
var row = (self.textLines.length - self.topVisibleIndex) - 1;
|
self.cursorPos.row = (self.textLines.length - self.topVisibleIndex) - 1;
|
||||||
|
self.cursorPos.col = self.getVisibleText().length; // uses row set above
|
||||||
self.cursorPos = {
|
|
||||||
row : row,
|
|
||||||
col : self.getVisibleText(row).length
|
|
||||||
};
|
|
||||||
|
|
||||||
self.redraw();
|
self.redraw();
|
||||||
self.moveClientCusorToCursorPos();
|
self.moveClientCusorToCursorPos();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
require('util').inherits(MultiLineEditTextView2, View);
|
require('util').inherits(MultiLineEditTextView2, View);
|
||||||
|
@ -265,11 +313,37 @@ MultiLineEditTextView2.prototype.onSpecialKeyPress = function(keyName) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
console.log(keyName);
|
||||||
|
|
||||||
|
// :TODO: Determine CTRL-* keys for various things
|
||||||
|
// See http://www.bbsdocumentary.com/library/PROGRAMS/GRAPHICS/ANSI/bansi.txt
|
||||||
|
// http://wiki.synchro.net/howto:editor:slyedit#edit_mode
|
||||||
|
// http://sublime-text-unofficial-documentation.readthedocs.org/en/latest/reference/keyboard_shortcuts_win.html
|
||||||
|
|
||||||
|
/* Mystic
|
||||||
|
[^B] Reformat Paragraph [^O] Show this help file
|
||||||
|
[^I] Insert tab space [^Q] Enter quote mode
|
||||||
|
[^K] Cut current line of text [^V] Toggle insert/overwrite
|
||||||
|
[^U] Paste previously cut text [^Y] Delete current line
|
||||||
|
|
||||||
|
|
||||||
|
BASIC MOVEMENT COMMANDS
|
||||||
|
|
||||||
|
UP/^E LEFT/^S PGUP/^R HOME/^F
|
||||||
|
DOWN/^X RIGHT/^D PGDN/^C END/^G
|
||||||
|
*/
|
||||||
|
|
||||||
[ 'up', 'down', 'left', 'right', 'home', 'end' ].forEach(function key(arrowKey) {
|
[ 'up', 'down', 'left', 'right', 'home', 'end' ].forEach(function key(arrowKey) {
|
||||||
if(self.isSpecialKeyMapped(arrowKey, keyName)) {
|
if(self.isSpecialKeyMapped(arrowKey, keyName)) {
|
||||||
self['cursor' + arrowKey.substring(0,1).toUpperCase() + arrowKey.substring(1)]();
|
self['cursor' + arrowKey.substring(0,1).toUpperCase() + arrowKey.substring(1)]();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
MultiLineEditTextView2.super_.prototype.onSpecialKeyPress.call(this, keyName);
|
// TEMP HACK FOR TESTING -----
|
||||||
|
if(self.isSpecialKeyMapped('lineFeed', keyName)) {
|
||||||
|
//self.cursorStartOfText();
|
||||||
|
self.cursorEndOfText();
|
||||||
|
}
|
||||||
|
|
||||||
|
//MultiLineEditTextView2.super_.prototype.onSpecialKeyPress.call(this, keyName);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue