diff options
-rw-r--r-- | apps/browse.mu | 199 |
1 files changed, 146 insertions, 53 deletions
diff --git a/apps/browse.mu b/apps/browse.mu index 3cffdc4c..353c49b4 100644 --- a/apps/browse.mu +++ b/apps/browse.mu @@ -10,12 +10,15 @@ fn main args: (addr array (addr array byte)) -> exit-status/ebx: int { var filename/eax: (addr array byte) <- first-arg args var file/esi: (addr buffered-file) <- load-file filename enable-screen-grid-mode + enable-keyboard-immediate-mode var nrows/eax: int <- copy 0 var ncols/ecx: int <- copy 0 nrows, ncols <- screen-size - enable-keyboard-immediate-mode + var display-state-storage: display-state + var display-state: (addr display-state) = address display-state-storage + init-display-state display-state, nrows, ncols { - render file, nrows, ncols + render file, display-state var key/eax: byte <- read-key compare key, 0x71 # 'q' loop-if-!= @@ -25,12 +28,143 @@ fn main args: (addr array (addr array byte)) -> exit-status/ebx: int { exit-status <- copy 0 } -type render-state { - current-state: int # enum 0: normal, 1: bold, 2: heading - start-of-line?: boolean - num-hashes-seen?: int +type display-state { + nrows: int # const + ncols: int # const + toprow: int + botrow: int + leftcol: int + rightcol: int + row: int + col: int +} + +fn render in: (addr buffered-file), state: (addr display-state) { + start-drawing state + render-normal in, state +} + +fn render-normal in: (addr buffered-file), state: (addr display-state) { + { + # if done-drawing?(state) break + var done?/eax: boolean <- done-drawing? state + compare done?, 0 + break-if-!= + # + var c/eax: byte <- read-byte-buffered in + # if (c == EOF) break + compare c, 0xffffffff # EOF marker + break-if-= + # if (c == '*') start-bold, render-until-asterisk(in, state), reset + # else if (c == '_') start-bold, render-until-underscore(in, state), reset + # else if (c == '#') compute-color, start color, render-header-line(in, state), reset + # else add-char(state, c) + } +} + +fn render-until-asterisk in: (addr buffered-file), state: (addr display-state) { + { + # if done-drawing?(state) break + var done?/eax: boolean <- done-drawing? state + compare done?, 0 + break-if-!= + # + var c/eax: byte <- read-byte-buffered in + # if (c == EOF) break + compare c, 0xffffffff # EOF marker + break-if-= + # if (c == '*') break + # else add-char(state, c) + } +} + +fn render-until-underscore in: (addr buffered-file), state: (addr display-state) { + { + # if done-drawing?(state) break + var done?/eax: boolean <- done-drawing? state + compare done?, 0 + break-if-!= + # + var c/eax: byte <- read-byte-buffered in + # if (c == EOF) break + compare c, 0xffffffff # EOF marker + break-if-= + # if (c == '_') break + # else add-char(state, c) + } +} + +fn render-header-line in: (addr buffered-file), state: (addr display-state) { + { + # if done-drawing?(state) break + var done?/eax: boolean <- done-drawing? state + compare done?, 0 + break-if-!= + # + var c/eax: byte <- read-byte-buffered in + # if (c == EOF) break + compare c, 0xffffffff # EOF marker + break-if-= + # if (c == '*') break + # else add-char(state, c) + } } +fn init-display-state self: (addr display-state), nrows: int, ncols: int { + # hardcoded parameters: + # top-margin + # page-margin + # text-width + var dest/eax: (addr int) <- copy 0 + # self->nrows = nrows + # self->ncols = ncols + # self->toprow = top-margin + # self->botrow = nrows + # self->leftcol = page-margin + # self->rightcol = self->leftcol + text-width + # start-drawing(self) +} + +fn start-drawing self: (addr display-state) { + # self->row = toprow + # self->col = leftcol +} + +fn add-char self: (addr display-state), c: byte { + # print c + # self->col++ + # if (self->col > self->rightcol) next-line(self) +} + +fn next-line self: (addr display-state) { + # self->row++ + # if (self->row > self->botrow) next-page(self) +} + +fn next-page self: (addr display-state) { + # self->leftcol = self->rightcol + 5 + # self->rightcol = self->leftcol + text-width +} + +fn done-drawing? self: (addr display-state) -> result/eax: boolean { + # self->rightcol >= self->ncols +} + +# screen manipulation: +# properties: width, height +# reset attributes +# clear +# color +# bold +# underline +# print char + +# pages: +# properties: screen, row, col +# methods for new pages +# new page +# new line + # decide how to lay out pages on screen fn render in: (addr buffered-file), nrows: int, ncols: int { # Fit multiple pages on screen on separate columns, each wide enough to read @@ -42,11 +176,6 @@ fn render in: (addr buffered-file), nrows: int, ncols: int { # top-margin # page-margin # text-width - var _r: render-state - var r/edi: (addr render-state) <- address _r - # r->start-of-line? = true - var s/eax: (addr boolean) <- get r, start-of-line? - copy-to *s, 1 # true var toprow/eax: int <- copy 2 # top-margin var botrow/ecx: int <- copy nrows var leftcol/edx: int <- copy 5 # page-margin @@ -56,7 +185,8 @@ fn render in: (addr buffered-file), nrows: int, ncols: int { { compare rightcol, ncols break-if->= - render-page in, toprow, leftcol, botrow, rightcol, r + clear toprow, leftcol, botrow, rightcol + render-page in, toprow, leftcol, botrow, rightcol leftcol <- copy rightcol leftcol <- add 5 # page-margin rightcol <- copy leftcol @@ -65,11 +195,7 @@ fn render in: (addr buffered-file), nrows: int, ncols: int { } } -fn render-page in: (addr buffered-file), toprow: int, leftcol: int, botrow: int, rightcol: int, _r: (addr render-state) { - var r/edi: (addr render-state) <- copy _r - var state/esi: (addr int) <- get r, current-state - clear toprow, leftcol, botrow, rightcol - # render screen rows +fn render-page in: (addr buffered-file), toprow: int, leftcol: int, botrow: int, rightcol: int { var row/ecx: int <- copy toprow $line-loop: { compare row, botrow @@ -102,20 +228,6 @@ $change-state: { copy-to *state, 1 break $change-state } - compare c, 0x23 # '#' - { - break-if-!= - var s/eax: (addr boolean) <- get r, start-of-line? - compare *s, 1 - { - break-if-!= - # r->current-state == 0 && c == '#' && at start of line => count '#'s - var h/eax: (addr int) <- get r, num-hashes-seen? - increment *h - break $change-state - } - break $change-state - } break $change-state } compare *state, 1 # bold @@ -135,9 +247,9 @@ $change-state: { compare c, 0x5f # '_' { break-if-!= - # r->current-state == 1 && c == '_' => print c, then normal text print-byte c col <- increment + # r->current-state == 1 && c == '_' => print c, then normal text reset-formatting start-color 0xec, 7 # 236 = darkish gray copy-to *state, 0 @@ -145,28 +257,9 @@ $change-state: { } break $change-state } - } # $change-state - # update a few attributes of the state based on c without changing the state itself - compare c, 0xa # newline - { - break-if-!= - # c is newline - var s/eax: (addr boolean) <- get r, start-of-line? - copy-to *s, 1 # true - # switch to normal text - reset-formatting - start-color 0xec, 7 # 236 = darkish gray - # no need to print newlines - break $char-loop } - compare c, 0x20 # space - { - break-if-= - # c is not newline or space - var s/eax: (addr boolean) <- get r, start-of-line? - copy-to *s, 0 # false - } - # print c + compare c, 0xa # newline + break-if-= # no need to print newlines print-byte c col <- increment loop |