mirror of
https://github.com/NuSkooler/enigma-bbs.git
synced 2025-06-06 12:47:13 +02:00
Added ERC Module
This commit is contained in:
parent
b6cada6f3c
commit
be6af161ec
4 changed files with 318 additions and 58 deletions
|
@ -34,7 +34,7 @@ var _ = require('lodash');
|
|||
//
|
||||
// Editors - BBS
|
||||
// * https://github.com/M-griffin/Enthral/blob/master/src/msg_fse.cpp
|
||||
//
|
||||
//
|
||||
//
|
||||
// Editors - Other
|
||||
// * http://joe-editor.sourceforge.net/
|
||||
|
@ -55,12 +55,12 @@ var _ = require('lodash');
|
|||
|
||||
//
|
||||
// To-Do
|
||||
//
|
||||
//
|
||||
// * Index pos % for emit scroll events
|
||||
// * Some of this shoudl be async'd where there is lots of processing (e.g. word wrap)
|
||||
// * Fix backspace when col=0 (e.g. bs to prev line)
|
||||
// * Add back word delete
|
||||
// *
|
||||
// *
|
||||
|
||||
|
||||
var SPECIAL_KEY_MAP_DEFAULT = {
|
||||
|
@ -114,6 +114,11 @@ function MultiLineEditTextView(options) {
|
|||
this.topVisibleIndex = 0;
|
||||
this.mode = options.mode || 'edit'; // edit | preview | read-only
|
||||
|
||||
if (this.mode == 'edit') {
|
||||
this.autoScroll = options.autoScroll || 'true';
|
||||
} else {
|
||||
this.autoScroll = options.autoScroll || 'false';
|
||||
}
|
||||
//
|
||||
// cursorPos represents zero-based row, col positions
|
||||
// within the editor itself
|
||||
|
@ -179,7 +184,7 @@ function MultiLineEditTextView(options) {
|
|||
|
||||
this.eraseRows = function(startRow, endRow) {
|
||||
self.client.term.rawWrite(self.getSGRFor('text') + ansi.hideCursor());
|
||||
|
||||
|
||||
var absPos = self.getAbsolutePosition(startRow, 0);
|
||||
var absPosEnd = self.getAbsolutePosition(endRow, 0);
|
||||
var eraseFiller = new Array(self.dimens.width).join(' ');
|
||||
|
@ -216,7 +221,7 @@ function MultiLineEditTextView(options) {
|
|||
if(!_.isNumber(index)) {
|
||||
index = self.getTextLinesIndex();
|
||||
}
|
||||
return self.textLines[index].text.replace(/\t/g, ' ');
|
||||
return self.textLines[index].text.replace(/\t/g, ' ');
|
||||
};
|
||||
|
||||
this.getText = function(index) {
|
||||
|
@ -266,19 +271,19 @@ function MultiLineEditTextView(options) {
|
|||
}
|
||||
return lines;
|
||||
};
|
||||
|
||||
|
||||
this.getOutputText = function(startIndex, endIndex, eolMarker) {
|
||||
let lines = self.getTextLines(startIndex, endIndex);
|
||||
let text = '';
|
||||
var re = new RegExp('\\t{1,' + (self.tabWidth) + '}', 'g');
|
||||
|
||||
|
||||
lines.forEach(line => {
|
||||
text += line.text.replace(re, '\t');
|
||||
if(eolMarker && line.eol) {
|
||||
text += eolMarker;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
|
@ -302,7 +307,7 @@ function MultiLineEditTextView(options) {
|
|||
/*
|
||||
this.editTextAtPosition = function(editAction, text, index, col) {
|
||||
switch(editAction) {
|
||||
case 'insert' :
|
||||
case 'insert' :
|
||||
self.insertCharactersInText(text, index, col);
|
||||
break;
|
||||
|
||||
|
@ -329,7 +334,7 @@ function MultiLineEditTextView(options) {
|
|||
newLines[newLines.length - 1].eol = true;
|
||||
|
||||
Array.prototype.splice.apply(
|
||||
self.textLines,
|
||||
self.textLines,
|
||||
[ index, (nextEolIndex - index) + 1 ].concat(newLines));
|
||||
|
||||
return wrapped.firstWrapRange;
|
||||
|
@ -337,7 +342,7 @@ function MultiLineEditTextView(options) {
|
|||
|
||||
this.removeCharactersFromText = function(index, col, operation, count) {
|
||||
if('right' === operation) {
|
||||
self.textLines[index].text =
|
||||
self.textLines[index].text =
|
||||
self.textLines[index].text.slice(col, count) +
|
||||
self.textLines[index].text.slice(col + count);
|
||||
|
||||
|
@ -354,11 +359,11 @@ function MultiLineEditTextView(options) {
|
|||
} else if ('backspace' === operation) {
|
||||
// :TODO: method for splicing text
|
||||
self.textLines[index].text =
|
||||
self.textLines[index].text.slice(0, col - (count - 1)) +
|
||||
self.textLines[index].text.slice(0, col - (count - 1)) +
|
||||
self.textLines[index].text.slice(col + 1);
|
||||
|
||||
self.cursorPos.col -= (count - 1);
|
||||
|
||||
|
||||
self.updateTextWordWrap(index);
|
||||
self.redrawRows(self.cursorPos.row, self.dimens.height);
|
||||
|
||||
|
@ -405,9 +410,9 @@ function MultiLineEditTextView(options) {
|
|||
|
||||
this.insertCharactersInText = function(c, index, col) {
|
||||
self.textLines[index].text = [
|
||||
self.textLines[index].text.slice(0, col),
|
||||
c,
|
||||
self.textLines[index].text.slice(col)
|
||||
self.textLines[index].text.slice(0, col),
|
||||
c,
|
||||
self.textLines[index].text.slice(col)
|
||||
].join('');
|
||||
|
||||
//self.cursorPos.col++;
|
||||
|
@ -443,13 +448,13 @@ function MultiLineEditTextView(options) {
|
|||
//
|
||||
absPos = self.getAbsolutePosition(self.cursorPos.row, self.cursorPos.col);
|
||||
self.client.term.write(
|
||||
ansi.hideCursor() +
|
||||
self.getSGRFor('text') +
|
||||
ansi.hideCursor() +
|
||||
self.getSGRFor('text') +
|
||||
self.getRenderText(index).slice(self.cursorPos.col - c.length) +
|
||||
ansi.goto(absPos.row, absPos.col) +
|
||||
ansi.showCursor(), false
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.getRemainingTabWidth = function(col) {
|
||||
|
@ -541,7 +546,7 @@ function MultiLineEditTextView(options) {
|
|||
.split(/\r\n|[\n\v\f\r\x85\u2028\u2029]/g);
|
||||
|
||||
var wrapped;
|
||||
|
||||
|
||||
for(var i = 0; i < text.length; ++i) {
|
||||
wrapped = self.wordWrapSingleLine(
|
||||
text[i], // input
|
||||
|
@ -556,7 +561,7 @@ function MultiLineEditTextView(options) {
|
|||
};
|
||||
|
||||
this.getAbsolutePosition = function(row, col) {
|
||||
return {
|
||||
return {
|
||||
row : self.position.row + row,
|
||||
col : self.position.col + col,
|
||||
};
|
||||
|
@ -610,7 +615,7 @@ function MultiLineEditTextView(options) {
|
|||
|
||||
this.keyPressDown = function() {
|
||||
var lastVisibleRow = Math.min(
|
||||
self.dimens.height,
|
||||
self.dimens.height,
|
||||
(self.textLines.length - self.topVisibleIndex)) - 1;
|
||||
|
||||
if(self.cursorPos.row < lastVisibleRow) {
|
||||
|
@ -714,7 +719,7 @@ function MultiLineEditTextView(options) {
|
|||
var nextEolIndex = self.getNextEndOfLineIndex(index);
|
||||
var text = self.getContiguousText(index, nextEolIndex);
|
||||
var newLines = self.wordWrapSingleLine(text.slice(self.cursorPos.col), 'tabsIntact').wrapped;
|
||||
|
||||
|
||||
newLines.unshift( { text : text.slice(0, self.cursorPos.col), eol : true } );
|
||||
for(var i = 1; i < newLines.length; ++i) {
|
||||
newLines[i] = { text : newLines[i] };
|
||||
|
@ -722,7 +727,7 @@ function MultiLineEditTextView(options) {
|
|||
newLines[newLines.length - 1].eol = true;
|
||||
|
||||
Array.prototype.splice.apply(
|
||||
self.textLines,
|
||||
self.textLines,
|
||||
[ index, (nextEolIndex - index) + 1 ].concat(newLines));
|
||||
|
||||
// redraw from current row to end of visible area
|
||||
|
@ -844,9 +849,9 @@ function MultiLineEditTextView(options) {
|
|||
self.client.term.rawWrite(ansi.left(move));
|
||||
break;
|
||||
|
||||
case 'up' :
|
||||
case 'up' :
|
||||
case 'down' :
|
||||
//
|
||||
//
|
||||
// Jump to the tabstop nearest the cursor
|
||||
//
|
||||
var newCol = self.tabStops.reduce(function r(prev, curr) {
|
||||
|
@ -890,7 +895,7 @@ function MultiLineEditTextView(options) {
|
|||
this.cursorBeginOfNextLine = function() {
|
||||
// e.g. when scrolling right past eol
|
||||
var linesBelow = self.getRemainingLinesBelowRow();
|
||||
|
||||
|
||||
if(linesBelow > 0) {
|
||||
var lastVisibleRow = Math.min(self.dimens.height, self.textLines.length) - 1;
|
||||
if(self.cursorPos.row < lastVisibleRow) {
|
||||
|
@ -1007,9 +1012,9 @@ MultiLineEditTextView.prototype.setText = function(text) {
|
|||
MultiLineEditTextView.prototype.addText = function(text) {
|
||||
this.insertRawText(text);
|
||||
|
||||
if(this.isEditMode()) {
|
||||
if(this.autoScroll) {
|
||||
this.cursorEndOfDocument();
|
||||
} else if(this.isPreviewMode()) {
|
||||
} else {
|
||||
this.cursorStartOfDocument();
|
||||
}
|
||||
};
|
||||
|
@ -1027,7 +1032,7 @@ MultiLineEditTextView.prototype.setPropertyValue = function(propName, value) {
|
|||
};
|
||||
|
||||
var HANDLED_SPECIAL_KEYS = [
|
||||
'up', 'down', 'left', 'right',
|
||||
'up', 'down', 'left', 'right',
|
||||
'home', 'end',
|
||||
'page up', 'page down',
|
||||
'line feed',
|
||||
|
@ -1045,7 +1050,7 @@ MultiLineEditTextView.prototype.onKeyPress = function(ch, key) {
|
|||
var self = this;
|
||||
var handled;
|
||||
|
||||
if(key) {
|
||||
if(key) {
|
||||
HANDLED_SPECIAL_KEYS.forEach(function aKey(specialKey) {
|
||||
if(self.isKeyMapped(specialKey, key.name)) {
|
||||
|
||||
|
@ -1068,6 +1073,22 @@ MultiLineEditTextView.prototype.onKeyPress = function(ch, key) {
|
|||
}
|
||||
};
|
||||
|
||||
MultiLineEditTextView.prototype.scrollUp = function() {
|
||||
this.scrollDocumentUp();
|
||||
}
|
||||
|
||||
MultiLineEditTextView.prototype.scrollDown = function() {
|
||||
this.scrollDocumentDown();
|
||||
}
|
||||
|
||||
MultiLineEditTextView.prototype.deleteLine = function(line) {
|
||||
this.textLines.splice(line, 1);
|
||||
}
|
||||
|
||||
MultiLineEditTextView.prototype.getLineCount = function() {
|
||||
return this.textLines.length;
|
||||
}
|
||||
|
||||
MultiLineEditTextView.prototype.getTextEditMode = function() {
|
||||
return this.overtypeMode ? 'overtype' : 'insert';
|
||||
};
|
||||
|
@ -1075,11 +1096,10 @@ MultiLineEditTextView.prototype.getTextEditMode = function() {
|
|||
MultiLineEditTextView.prototype.getEditPosition = function() {
|
||||
var currentIndex = this.getTextLinesIndex() + 1;
|
||||
|
||||
return {
|
||||
row : this.getTextLinesIndex(this.cursorPos.row),
|
||||
return {
|
||||
row : this.getTextLinesIndex(this.cursorPos.row),
|
||||
col : this.cursorPos.col,
|
||||
percent : Math.floor(((currentIndex / this.textLines.length) * 100)),
|
||||
below : this.getRemainingLinesBelowRow(),
|
||||
};
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue