diff --git a/core/fse.js b/core/fse.js index 3996a174..bd08ad96 100644 --- a/core/fse.js +++ b/core/fse.js @@ -607,8 +607,13 @@ function FullScreenEditorModule(options) { // ...should not be too bad to do at all // ...probably do want quote markers in place here though, e.g. " Nu> Said some things" // ...this could be handled via message.getQuoteLines(...) => [] - - self.viewControllers.quoteBuilder.getView(3).setItems(['Someone said some shit', 'then they said more shit', 'and what not...', 'hurp durp']); + //self.viewControllers.quoteBuilder.getView(3).setItems(['Someone said some shit', 'then they said more shit', 'and what not...', 'hurp durp']); + var quoteView = self.viewControllers.quoteBuilder.getView(3); + var quoteWidth = quoteView.dimens.width; + console.log(quoteWidth) + var quoteLines = self.replyToMessage.getQuoteLines(quoteWidth); + console.log(quoteLines) + quoteView.setItems(quoteLines); callback(null); }, function setViewFocus(callback) { diff --git a/core/message.js b/core/message.js index 66543bcf..32000c8b 100644 --- a/core/message.js +++ b/core/message.js @@ -2,6 +2,7 @@ 'use strict'; var msgDb = require('./database.js').dbs.message; +var wordWrapText = require('./word_wrap.js').wordWrapText; var uuid = require('node-uuid'); var async = require('async'); @@ -241,4 +242,29 @@ Message.prototype.persist = function(cb) { }); } ); -}; \ No newline at end of file +}; + +Message.prototype.getQuoteLines = function(width) { + var quoteLines = []; + + var origLines = this.message + .replace(/\b/g, '') + .split(/\r\n|[\n\v\f\r\x85\u2028\u2029]/g); + + var wrapOpts = { + width : width, + tabHandling : 'expand', + tabWidth : 4, + }; + + var wrapped; + var quotePrefix = 'Nu> '; // :TODO: build FTN style quote prefix + + for(var i = 0; i < origLines.length; ++i) { + wrapped = wordWrapText(quotePrefix + origLines[i], wrapOpts).wrapped; + + Array.prototype.push.apply(quoteLines, wrapped); + } + + return quoteLines; +}; diff --git a/core/multi_line_edit_text_view.js b/core/multi_line_edit_text_view.js index 8e4b0972..c9e66fc5 100644 --- a/core/multi_line_edit_text_view.js +++ b/core/multi_line_edit_text_view.js @@ -6,6 +6,7 @@ var miscUtil = require('./misc_util.js'); var strUtil = require('./string_util.js'); var ansi = require('./ansi_term.js'); var colorCodes = require('./color_codes.js'); +var wordWrapText = require('./word_wrap.js').wordWrapText; var assert = require('assert'); var _ = require('lodash'); @@ -492,84 +493,16 @@ function MultiLineEditTextView(options) { }; this.wordWrapSingleLine = function(s, tabHandling, width) { - tabHandling = tabHandling || 'expandTabs'; if(!_.isNumber(width)) { width = self.dimens.width; } - // - // Notes - // * Sublime Text 3 for example considers spaces after a word - // part of said word. For example, "word " would be wraped - // in it's entirity. - // - // * Tabs in Sublime Text 3 are also treated as a word, so, e.g. - // "\t" may resolve to " " and must fit within the space. - // - // * If a word is ultimately too long to fit, break it up until it does. - // - // RegExp below is JavaScript '\s' minus the '\t' - // - var re = new RegExp( - '\t|[ \f\n\r\v​\u00a0\u1680​\u180e\u2000​\u2001\u2002​\u2003\u2004\u2005\u2006​' + - '\u2007\u2008​\u2009\u200a​\u2028\u2029​\u202f\u205f​\u3000]', 'g'); - var m; - var wordStart = 0; - var results = { wrapped : [ '' ] }; - var i = 0; - var word; - var wordLen; - - function addWord() { - word.match(new RegExp('.{0,' + width + '}', 'g')).forEach(function wrd(w) { - wordLen = self.getStringLength(w); - - if(results.wrapped[i].length + w.length > width) { - //if(results.wrapped[i].length + wordLen > width) { - if(0 === i) { - results.firstWrapRange = { start : wordStart, end : wordStart + w.length }; - //results.firstWrapRange = { start : wordStart, end : wordStart + wordLen }; - } - results.wrapped[++i] = w; - } else { - results.wrapped[i] += w; - } + return wordWrapText( + s, { + width : width, + tabHandling : tabHandling || 'expand', + tabWidth : self.tabWidth, }); - } - - while((m = re.exec(s)) !== null) { - word = s.substring(wordStart, re.lastIndex - 1); - - switch(m[0].charAt(0)) { - case ' ' : - word += m[0]; - break; - - case '\t' : - // - // Expand tab given position - // - // Nice info here: http://c-for-dummies.com/blog/?p=424 - // - if('expandTabs' === tabHandling) { - word += self.expandTab(results.wrapped[i].length + word.length, '\t') + '\t'; - } else { - word += m[0]; - } - break; - } - - addWord(); - wordStart = re.lastIndex + m[0].length - 1; - } - - // - // Remainder - // - word = s.substring(wordStart); - addWord(); - - return results; }; // :TODO: rename to insertRawText() @@ -1059,7 +992,7 @@ MultiLineEditTextView.prototype.setFocus = function(focused) { MultiLineEditTextView.prototype.setText = function(text) { //text = require('fs').readFileSync('/home/nuskooler/Downloads/test_text.txt', { encoding : 'utf-8'}); - //this.textLines = [ ]; + this.textLines = [ ]; this.insertRawText(text); if(this.isEditMode()) { diff --git a/core/word_wrap.js b/core/word_wrap.js new file mode 100644 index 00000000..98b9257e --- /dev/null +++ b/core/word_wrap.js @@ -0,0 +1,105 @@ +/* jslint node: true */ +'use strict'; + +var assert = require('assert'); +var _ = require('lodash'); + +exports.wordWrapText = wordWrapText; + +function wordWrapText(text, options) { + // + // options.*: + // width : word wrap width + // tabHandling : expand (default=expand) + // tabWidth : tab width if tabHandling is 'expand' (default=4) + // + assert(_.isObject(options), 'Missing options!'); + assert(_.isNumber(options.width), 'Missing options.width!'); + + options.tabHandling = options.tabHandling || 'expand'; + + if(!_.isNumber(options.tabWidth)) { + options.tabWidth = 4; + } + + // + // Notes + // * Sublime Text 3 for example considers spaces after a word + // part of said word. For example, "word " would be wraped + // in it's entirity. + // + // * Tabs in Sublime Text 3 are also treated as a word, so, e.g. + // "\t" may resolve to " " and must fit within the space. + // + // * If a word is ultimately too long to fit, break it up until it does. + // + // RegExp below is JavaScript '\s' minus the '\t' + // + var re = new RegExp( + '\t|[ \f\n\r\v​\u00a0\u1680​\u180e\u2000​\u2001\u2002​\u2003\u2004\u2005\u2006​' + + '\u2007\u2008​\u2009\u200a​\u2028\u2029​\u202f\u205f​\u3000]', 'g'); + var m; + var wordStart = 0; + var results = { wrapped : [ '' ] }; + var i = 0; + var word; + var wordLen; + + function expandTab(col) { + var remainWidth = options.tabWidth - (col % options.tabWidth); + return new Array(remainWidth).join('\t'); + } + + // :TODO: support wrapping pipe code text (e.g. ignore color codes, expand MCI codes) + + function addWord() { + word.match(new RegExp('.{0,' + options.width + '}', 'g')).forEach(function wrd(w) { + //wordLen = self.getStringLength(w); + + if(results.wrapped[i].length + w.length > options.width) { + //if(results.wrapped[i].length + wordLen > width) { + if(0 === i) { + results.firstWrapRange = { start : wordStart, end : wordStart + w.length }; + //results.firstWrapRange = { start : wordStart, end : wordStart + wordLen }; + } + results.wrapped[++i] = w; + } else { + results.wrapped[i] += w; + } + }); + } + + while((m = re.exec(text)) !== null) { + word = text.substring(wordStart, re.lastIndex - 1); + + switch(m[0].charAt(0)) { + case ' ' : + word += m[0]; + break; + + case '\t' : + // + // Expand tab given position + // + // Nice info here: http://c-for-dummies.com/blog/?p=424 + // + if('expand' === options.tabHandling) { + word += expandTab(results.wrapped[i].length + word.length) + '\t'; + } else { + word += m[0]; + } + break; + } + + addWord(); + wordStart = re.lastIndex + m[0].length - 1; + } + + // + // Remainder + // + word = text.substring(wordStart); + addWord(); + + return results; +} \ No newline at end of file