Last active
May 28, 2018 04:37
-
-
Save iarna/a6cc6ef1619c3888b35ca1b79c047ed6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// render thread | |
// index | |
// record indexes of natural line breaks | |
// record indexs of wrapped line breaks w/ predefined width | |
// display (line start, #lines, width) | |
const fs = require('fs') | |
let exampleText | |
let lineBreaks = [] | |
// NOTE: Currently can't fill skipped entries in lineBreaks. Should support | |
// this, plus vacating unused areas. Keep n windows alive at any given | |
// time. | |
// other indexes for effecient search | |
// syntax highting is easier, as it can follow the same pattern as newline | |
// finding and save the state of the syntax highight engine for each chunk/line/whatever. | |
// editing recomputes from the previous chunk and continues till the resulting state matches. | |
// def stop when hitting end of display area though, till the user requests more. Everything from that | |
// point on is dirty, till resynchronization occurs. | |
// search and replace is the thing that will be terrible w/o everything in memory. | |
// gap buffers, and other fun | |
//https://joe-editor.sourceforge.io/hacking.html | |
//https://en.wikipedia.org/wiki/Rope_(computer_science) | |
// should get start/end pair as other things, only insist that the window it needs be indexed | |
// should start indexing from nearest previous window, or 0 if there is none. | |
// So indexLines, and separately indexColumns (given line offsets) | |
// todo: Separately need to index characters, turn line into array of characters | |
// similar, toindexText, index line to max cal count. Make sure unicode isn't split, including | |
// combining characters, including zero-width joiners. Know if a characters | |
// is single-width or double-width. | |
// display layer should have special case for emoji on terminals that | |
// display them single-width (eg, emit a space after them) | |
// line splitter is encoding specific. default encodings: hex, unicode. Unicode splits on newline only. | |
// hex splits on fixed length. in hex mode, all characters are double width. | |
function indexText (startLine, endLine) { | |
if (lineBreaks.length >= endLine) return | |
let lineStart = lineBreaks.length ? lineBreaks[lineBreaks.length-1][1] + 1 : 0 | |
let lineCount = 0 | |
const textLength = exampleText.length | |
for (let ii = 0; ii < textLength && lineBreaks.length < endLine; ++ii) { | |
if (exampleText[ii] === 10) { | |
if (lineCount>=startLine) lineBreaks[lineCount] = [lineStart, ii] | |
++lineCount | |
lineStart = ii + 1 | |
} | |
} | |
if (lineBreaks.length >= endLine) return | |
if (lineStart <= exampleText.length) lineBreaks.push([lineStart, exampleText.length +1]) | |
} | |
// editor version would need garbage collector on | |
function display (rowStart, rowCount, colStart, colCount) { | |
console.time('index') | |
indexText(rowStart, rowStart + rowCount) | |
console.timeEnd('index') | |
console.time('render') | |
const win = [] | |
const end = rowStart + rowCount >= lineBreaks.length ? lineBreaks.length : rowStart + rowCount | |
for (let ii = rowStart; ii < end; ++ii) { | |
const lineStart = lineBreaks[ii][0] | |
const lineEnd = lineBreaks[ii][1] | |
const displayStart = lineStart + colStart | |
const displayEnd = lineEnd > displayStart + colCount ? displayStart + colCount : lineEnd | |
if (displayStart > displayEnd) { | |
win.push('') | |
continue | |
} | |
let line = exampleText.slice(displayStart, displayEnd) | |
win.push(line) | |
} | |
console.timeEnd('render') | |
return win | |
} | |
console.time('overall') | |
console.time('readfile') | |
exampleText = fs.readFileSync('/Users/rebecca/code/fetch-fic/working/index/Fanfic.json') | |
console.timeEnd('readfile') | |
console.time('display') | |
console.log(display(4613013, 24, 0, 80).map(_ => _.toString()).join('\n')) | |
console.timeEnd('display') | |
console.timeEnd('overall') | |
console.log(lineBreaks) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment