diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2021-06-05 09:35:37 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2021-06-05 09:35:37 -0700 |
commit | 3d4e1b8b28368aaddb38e7948163d18c123dfe2b (patch) | |
tree | e90c04dc4ac6707f638e376f558539a475dfe1a0 | |
parent | 5a066f8ddaeb9e22891c67217642e7900c4eeb20 (diff) | |
download | mu-3d4e1b8b28368aaddb38e7948163d18c123dfe2b.tar.gz |
working on jumping to word at cursor
I had a nice clean definition for word-at-cursor, but it's wrong and I'm going to have to mangle it.
-rw-r--r-- | mu-init.subx | 1 | ||||
-rw-r--r-- | shell/environment.mu | 45 | ||||
-rw-r--r-- | shell/gap-buffer.mu | 239 |
3 files changed, 284 insertions, 1 deletions
diff --git a/mu-init.subx b/mu-init.subx index 5cc2d083..c1c6b435 100644 --- a/mu-init.subx +++ b/mu-init.subx @@ -14,7 +14,6 @@ Entry: bd/copy-to-ebp 0/imm32 # #? (main 0 0 Primary-bus-secondary-drive) -#? (test-run-preserves-trace-view-on-rerun) # always first run tests (run-tests) (num-test-failures) # => eax diff --git a/shell/environment.mu b/shell/environment.mu index 1545f0ff..6f0718b1 100644 --- a/shell/environment.mu +++ b/shell/environment.mu @@ -117,6 +117,18 @@ fn edit-environment _self: (addr environment), key: grapheme, data-disk: (addr d compare key, 7/ctrl-g break-if-!= var cursor-in-function-modal-a/eax: (addr boolean) <- get self, cursor-in-function-modal? + compare *cursor-in-function-modal-a, 0/false + break-if-!= + # look for a word to prepopulate the modal + var current-word-storage: (stream byte 0x40) + var current-word/edi: (addr stream byte) <- address current-word-storage + word-at-cursor self, current-word + var partial-function-name-ah/eax: (addr handle gap-buffer) <- get self, partial-function-name + var partial-function-name/eax: (addr gap-buffer) <- lookup *partial-function-name-ah + clear-gap-buffer partial-function-name + load-gap-buffer-from-stream partial-function-name, current-word + # enable the modal + var cursor-in-function-modal-a/eax: (addr boolean) <- get self, cursor-in-function-modal? copy-to *cursor-in-function-modal-a, 1/true return } @@ -186,6 +198,39 @@ fn edit-environment _self: (addr environment), key: grapheme, data-disk: (addr d edit-sandbox sandbox, key, globals, data-disk, 1/tweak-real-screen } +fn word-at-cursor _self: (addr environment), out: (addr stream byte) { + var self/esi: (addr environment) <- copy _self + var cursor-in-function-modal-a/eax: (addr boolean) <- get self, cursor-in-function-modal? + compare *cursor-in-function-modal-a, 0/false + { + break-if-= + # cursor in function modal + return + } + var cursor-in-globals-a/edx: (addr boolean) <- get self, cursor-in-globals? + compare *cursor-in-globals-a, 0/false + { + break-if-= + # cursor in some function editor + var globals/eax: (addr global-table) <- get self, globals + var cursor-index-addr/ecx: (addr int) <- get globals, cursor-index + var cursor-index/ecx: int <- copy *cursor-index-addr + var globals-data-ah/eax: (addr handle array global) <- get globals, data + var globals-data/eax: (addr array global) <- lookup *globals-data-ah + var cursor-offset/ecx: (offset global) <- compute-offset globals-data, cursor-index + var curr-global/eax: (addr global) <- index globals-data, cursor-offset + var curr-global-data-ah/eax: (addr handle gap-buffer) <- get curr-global, input + var curr-global-data/eax: (addr gap-buffer) <- lookup *curr-global-data-ah + word-at-gap curr-global-data, out + return + } + # cursor in sandbox + var sandbox/ecx: (addr sandbox) <- get self, sandbox + var sandbox-data-ah/eax: (addr handle gap-buffer) <- get sandbox, data + var sandbox-data/eax: (addr gap-buffer) <- lookup *sandbox-data-ah + word-at-gap sandbox-data, out +} + fn render-function-modal screen: (addr screen), _self: (addr environment) { var self/esi: (addr environment) <- copy _self var width/eax: int <- copy 0 diff --git a/shell/gap-buffer.mu b/shell/gap-buffer.mu index c2f9b3b2..9b4c4faf 100644 --- a/shell/gap-buffer.mu +++ b/shell/gap-buffer.mu @@ -134,6 +134,245 @@ fn emit-stack-from-top _self: (addr grapheme-stack), out: (addr stream byte) { } } +fn word-at-gap _self: (addr gap-buffer), out: (addr stream byte) { + var self/esi: (addr gap-buffer) <- copy _self + clear-stream out + var left/ecx: (addr grapheme-stack) <- get self, left + var left-index/eax: int <- top-most-word left + emit-stack-from-index left, left-index, out + draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen "|" 7/fg 0/bg + var right/ecx: (addr grapheme-stack) <- get self, right + var right-index/eax: int <- top-most-word right + draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, right-index, 4/fg 0/bg + emit-stack-to-index right, right-index, out +} + +fn test-word-at-gap-single-word-with-gap-at-end { + var _g: gap-buffer + var g/esi: (addr gap-buffer) <- address _g + initialize-gap-buffer-with g, "abc" + # gap is at end (right is empty) + var out-storage: (stream byte 0x10) + var out/eax: (addr stream byte) <- address out-storage + word-at-gap g, out + check-stream-equal out, "abc", "F - test-word-at-gap-single-word-with-gap-at-end" +} + +fn test-word-at-gap-single-word-with-gap-at-start { + var _g: gap-buffer + var g/esi: (addr gap-buffer) <- address _g + initialize-gap-buffer-with g, "abc" + gap-to-start g + # + var out-storage: (stream byte 0x10) + var out/eax: (addr stream byte) <- address out-storage + word-at-gap g, out + check-stream-equal out, "abc", "F - test-word-at-gap-single-word-with-gap-at-start" +} + +fn test-word-at-gap-multiple-words-with-gap-at-non-word-grapheme-at-end { + var _g: gap-buffer + var g/esi: (addr gap-buffer) <- address _g + initialize-gap-buffer-with g, "abc " + # gap is at end (right is empty) + var out-storage: (stream byte 0x10) + var out/eax: (addr stream byte) <- address out-storage + word-at-gap g, out + check-stream-equal out, "", "F - test-word-at-gap-multiple-words-with-gap-at-non-word-grapheme-at-end" +} + +fn test-word-at-gap-multiple-words-with-gap-at-non-word-grapheme-at-start { + var _g: gap-buffer + var g/esi: (addr gap-buffer) <- address _g + initialize-gap-buffer-with g, " abc" + gap-to-start g + # + var out-storage: (stream byte 0x10) + var out/eax: (addr stream byte) <- address out-storage + word-at-gap g, out + rewind-stream out + draw-stream-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, out, 5/fg 0/bg + check-stream-equal out, "", "F - test-word-at-gap-multiple-words-with-gap-at-non-word-grapheme-at-start" +} + +fn test-word-at-gap-multiple-words-with-gap-at-end { + var _g: gap-buffer + var g/esi: (addr gap-buffer) <- address _g + initialize-gap-buffer-with g, "a bc d" + # gap is at end (right is empty) + var out-storage: (stream byte 0x10) + var out/eax: (addr stream byte) <- address out-storage + word-at-gap g, out + check-stream-equal out, "d", "F - test-word-at-gap-multiple-words-with-gap-at-end" +} + +fn test-word-at-gap-multiple-words-with-gap-at-initial-word { + var _g: gap-buffer + var g/esi: (addr gap-buffer) <- address _g + initialize-gap-buffer-with g, "a bc d" + gap-to-start g + # + var out-storage: (stream byte 0x10) + var out/eax: (addr stream byte) <- address out-storage + word-at-gap g, out + check-stream-equal out, "a", "F - test-word-at-gap-multiple-words-with-gap-at-initial-word" +} + +fn test-word-at-gap-multiple-words-with-gap-at-final-word { + var _g: gap-buffer + var g/esi: (addr gap-buffer) <- address _g + initialize-gap-buffer-with g, "a bc d" + var dummy/eax: grapheme <- gap-left g + # gap is at final word + var out-storage: (stream byte 0x10) + var out/eax: (addr stream byte) <- address out-storage + word-at-gap g, out + check-stream-equal out, "d", "F - test-word-at-gap-multiple-words-with-gap-at-final-word" +} + +fn test-word-at-gap-multiple-words-with-gap-at-final-non-word { + var _g: gap-buffer + var g/esi: (addr gap-buffer) <- address _g + initialize-gap-buffer-with g, "abc " + var dummy/eax: grapheme <- gap-left g + # gap is at final word + var out-storage: (stream byte 0x10) + var out/eax: (addr stream byte) <- address out-storage + word-at-gap g, out + check-stream-equal out, "", "F - test-word-at-gap-multiple-words-with-gap-at-final-non-word" +} + +fn top-most-word _self: (addr grapheme-stack) -> _/eax: int { + var self/esi: (addr grapheme-stack) <- copy _self + var data-ah/edi: (addr handle array grapheme) <- get self, data + var _data/eax: (addr array grapheme) <- lookup *data-ah + var data/edi: (addr array grapheme) <- copy _data + var top-addr/ecx: (addr int) <- get self, top + var i/ebx: int <- copy *top-addr + i <- decrement + { + compare i, 0 + break-if-< + var g/edx: (addr grapheme) <- index data, i + { + var foo/eax: int <- copy *g + draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, foo, 7/fg 0/bg + } + var is-word?/eax: boolean <- is-ascii-word-grapheme? *g + { + var foo/eax: int <- copy is-word? + draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, foo, 1/fg 0/bg + } + compare is-word?, 0/false + break-if-= + i <- decrement + loop + } + i <- increment + return i +} + +fn bottom-most-word _self: (addr grapheme-stack) -> _/eax: int { + var self/esi: (addr grapheme-stack) <- copy _self + var data-ah/edi: (addr handle array grapheme) <- get self, data + var _data/eax: (addr array grapheme) <- lookup *data-ah + var data/edi: (addr array grapheme) <- copy _data + var top-addr/ecx: (addr int) <- get self, top + var i/ebx: int <- copy 0 + { + compare i, *top-addr + break-if->= + var g/edx: (addr grapheme) <- index data, i + { + var foo/eax: int <- copy *g + draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, foo, 4/fg 0/bg + } + var is-word?/eax: boolean <- is-ascii-word-grapheme? *g + compare is-word?, 0/false + break-if-= + i <- decrement + loop + } + return i +} + +fn emit-stack-from-index _self: (addr grapheme-stack), start: int, out: (addr stream byte) { + var self/esi: (addr grapheme-stack) <- copy _self + var data-ah/edi: (addr handle array grapheme) <- get self, data + var _data/eax: (addr array grapheme) <- lookup *data-ah + var data/edi: (addr array grapheme) <- copy _data + var top-addr/ecx: (addr int) <- get self, top + var i/eax: int <- copy start + { + compare i, *top-addr + break-if->= + var g/edx: (addr grapheme) <- index data, i + write-grapheme out, *g + i <- increment + loop + } +} + +fn emit-stack-to-index _self: (addr grapheme-stack), end: int, out: (addr stream byte) { + var self/esi: (addr grapheme-stack) <- copy _self + var data-ah/edi: (addr handle array grapheme) <- get self, data + var _data/eax: (addr array grapheme) <- lookup *data-ah + var data/edi: (addr array grapheme) <- copy _data + var top-addr/ecx: (addr int) <- get self, top + var i/eax: int <- copy *top-addr + draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, i, 3/fg 0/bg + i <- decrement + { + compare i, 0 + break-if-< + compare i, end + break-if-< + var g/edx: (addr grapheme) <- index data, i + write-grapheme out, *g + i <- decrement + loop + } +} + +fn is-ascii-word-grapheme? g: grapheme -> _/eax: boolean { + compare g, 0x21/! + { + break-if-!= + return 1/true + } + compare g, 0x3f/? + { + break-if-!= + return 1/true + } + compare g, 0x41/A + { + break-if->= + return 0/false + } + compare g, 0x5a/Z + { + break-if->= + return 1/true + } + compare g, 0x5f/_ + { + break-if-!= + return 1/true + } + compare g, 0x61/a + { + break-if->= + return 0/false + } + compare g, 0x7a/z + { + break-if->= + return 1/true + } + return 0/false +} + # We implicitly render everything editable in a single color, and assume the # cursor is a single other color. fn render-gap-buffer-wrapping-right-then-down screen: (addr screen), _gap: (addr gap-buffer), xmin: int, ymin: int, xmax: int, ymax: int, render-cursor?: boolean, color: int, background-color: int -> _/eax: int, _/ecx: int { |