Skip to content

Instantly share code, notes, and snippets.

@iarna
Last active May 28, 2018 04:37
Show Gist options
  • Save iarna/a6cc6ef1619c3888b35ca1b79c047ed6 to your computer and use it in GitHub Desktop.
Save iarna/a6cc6ef1619c3888b35ca1b79c047ed6 to your computer and use it in GitHub Desktop.
// 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