https://github.com/akkartik/mu/blob/main/linux/tile/value.mu
  1 fn render-value-at screen: (addr screen), row: int, col: int, _val: (addr value), top-level?: boolean {
  2   move-cursor screen, row, col
  3   var val/esi: (addr value) <- copy _val
  4   var val-type/ecx: (addr int) <- get val, type
  5   # per-type rendering logic goes here
  6   compare *val-type, 1/string
  7   {
  8     break-if-!=
  9     var val-ah/eax: (addr handle array byte) <- get val, text-data
 10     var val-string/eax: (addr array byte) <- lookup *val-ah
 11     compare val-string, 0
 12     break-if-=
 13     var orig-len/ecx: int <- length val-string
 14     var truncated: (handle array byte)
 15     var truncated-ah/esi: (addr handle array byte) <- address truncated
 16     substring val-string, 0, 0xc, truncated-ah
 17     var truncated-string/eax: (addr array byte) <- lookup *truncated-ah
 18     var len/edx: int <- length truncated-string
 19     start-color screen, 0xf2, 7
 20     print-code-point screen, 0x275d/open-quote
 21     print-string screen, truncated-string
 22     compare len, orig-len
 23     {
 24       break-if-=
 25       print-code-point screen, 0x2026/ellipses
 26     }
 27     print-code-point screen, 0x275e/close-quote
 28     reset-formatting screen
 29     return
 30   }
 31   compare *val-type, 2/array
 32   {
 33     break-if-!=
 34     var val-ah/eax: (addr handle array value) <- get val, array-data
 35     var val-array/eax: (addr array value) <- lookup *val-ah
 36     render-array-at screen, row, col, val-array
 37     return
 38   }
 39   compare *val-type, 3/file
 40   {
 41     break-if-!=
 42     var val-ah/eax: (addr handle buffered-file) <- get val, file-data
 43     var val-file/eax: (addr buffered-file) <- lookup *val-ah
 44     start-color screen, 0, 7
 45     # TODO
 46     print-string screen, " FILE "
 47     return
 48   }
 49   compare *val-type, 4/screen
 50   {
 51     break-if-!=
 52 #?     print-string 0, "render-screen"
 53     var val-ah/eax: (addr handle screen) <- get val, screen-data
 54     var val-screen/eax: (addr screen) <- lookup *val-ah
 55     render-screen screen, row, col, val-screen
 56 #?     print-string 0, "}\n"
 57     return
 58   }
 59   # render ints by default for now
 60   var val-num/eax: (addr float) <- get val, number-data
 61   render-number screen, *val-num, top-level?
 62 }
 63 
 64 # synaesthesia
 65 # TODO: right-justify
 66 fn render-number screen: (addr screen), val: float, top-level?: boolean {
 67   # if we're inside an array, don't color
 68   compare top-level?, 0
 69   {
 70     break-if-!=
 71     print-float-decimal-approximate screen, val, 3
 72     return
 73   }
 74   var val-int/eax: int <- convert val
 75   var bg/eax: int <- hash-color val-int
 76   var fg/ecx: int <- copy 7
 77   {
 78     compare bg, 2
 79     break-if-!=
 80     fg <- copy 0
 81   }
 82   {
 83     compare bg, 3
 84     break-if-!=
 85     fg <- copy 0
 86   }
 87   {
 88     compare bg, 6
 89     break-if-!=
 90     fg <- copy 0
 91   }
 92   start-color screen, fg, bg
 93   print-grapheme screen, 0x20/space
 94   print-float-decimal-approximate screen, val, 3
 95   print-grapheme screen, 0x20/space
 96 }
 97 
 98 fn render-array-at screen: (addr screen), row: int, col: int, _a: (addr array value) {
 99   start-color screen, 0xf2, 7
100   # don't surround in spaces
101   print-grapheme screen, 0x5b/[
102   increment col
103   var a/esi: (addr array value) <- copy _a
104   var max/ecx: int <- length a
105   var i/eax: int <- copy 0
106   {
107     compare i, max
108     break-if->=
109     {
110       compare i, 0
111       break-if-=
112       print-string screen, " "
113     }
114     var off/ecx: (offset value) <- compute-offset a, i
115     var x/ecx: (addr value) <- index a, off
116     render-value-at screen, row, col, x, 0
117     {
118       var w/eax: int <- value-width x, 0
119       add-to col, w
120       increment col
121     }
122     i <- increment
123     loop
124   }
125   print-grapheme screen, 0x5d/]
126 }
127 
128 fn render-screen screen: (addr screen), row: int, col: int, _target-screen: (addr screen) {
129   reset-formatting screen
130   move-cursor screen, row, col
131   var target-screen/esi: (addr screen) <- copy _target-screen
132   var ncols-a/ecx: (addr int) <- get target-screen, num-cols
133   print-upper-border screen, *ncols-a
134   var r/edx: int <- copy 1
135   var nrows-a/ebx: (addr int) <- get target-screen, num-rows
136   {
137     compare r, *nrows-a
138     break-if->
139     increment row  # mutate arg
140     move-cursor screen, row, col
141     print-string screen, " "
142     var c/edi: int <- copy 1
143     {
144       compare c, *ncols-a
145       break-if->
146       print-screen-cell-of-fake-screen screen, target-screen, r, c
147       c <- increment
148       loop
149     }
150     print-string screen, " "
151     r <- increment
152     loop
153   }
154   increment row  # mutate arg
155   move-cursor screen, row, col
156   print-lower-border screen, *ncols-a
157 }
158 
159 fn hash-color val: int -> _/eax: int {
160   var quotient/eax: int <- copy 0
161   var remainder/edx: int <- copy 0
162   quotient, remainder <- integer-divide val, 7  # assumes that 7 is always the background color
163   return remainder
164 }
165 
166 fn print-screen-cell-of-fake-screen screen: (addr screen), _target: (addr screen), _row: int, _col: int {
167   start-color screen, 0, 0xf6
168   var target/esi: (addr screen) <- copy _target
169   var row/ecx: int <- copy _row
170   var col/edx: int <- copy _col
171   # if cursor is at screen-cell, add some fancy
172   {
173     var cursor-row/eax: (addr int) <- get target, cursor-row
174     compare *cursor-row, row
175     break-if-!=
176     var cursor-col/eax: (addr int) <- get target, cursor-col
177     compare *cursor-col, col
178     break-if-!=
179     start-blinking s
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Python: module ranger.gui.widgets.pager</title>
</head><body bgcolor="#f0f0f8">

<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
<tr bgcolor="#7799ee">
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="ranger.html"><font color="#ffffff">ranger</font></a>.<a href="ranger.gui.html"><font color="#ffffff">gui</font></a>.<a href="ranger.gui.widgets.html"><font color="#ffffff">widgets</font></a>.pager</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/hut/ranger/ranger/gui/widgets/pager.py">/home/hut/ranger/ranger/gui/widgets/pager.py</a></font></td></tr></table>
    <p><tt>The&nbsp;pager&nbsp;displays&nbsp;text&nbsp;and&nbsp;allows&nbsp;you&nbsp;to&nbsp;scroll&nbsp;inside&nbsp;it.</tt></p>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#aa55cc">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
    
<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="re.html">re</a><br>
</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ee77aa">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
    
<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><dl>
<dt><font face="helvetica, arial"><a href="ranger.gui.widgets.html#Widget">ranger.gui.widgets.Widget</a>(<a href="ranger.gui.displayable.html#Displayable">ranger.gui.displayable.Displayable</a>)
</font></dt><dd>
<dl>
<dt><font face="helvetica, arial"><a href="ranger.gui.widgets.pager.html#Pager">Pager</a>
</font></dt></dl>
</dd>
</dl>
 <p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ffc8d8">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#000000" face="helvetica, arial"><a name="Pager">class <strong>Pager</strong></a>(<a href="ranger.gui.widgets.html#Widget">ranger.gui.widgets.Widget</a>)</font></td></tr>
    
<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><dl><dt>Method resolution order:</dt>
<dd><a href="ranger.gui.widgets.pager.html#Pager">Pager</a></dd>
<dd><a href="ranger.gui.widgets.html#Widget">ranger.gui.widgets.Widget</a></dd>
<dd><a href="ranger.gui.displayable.html#Displayable">ranger.gui.displayable.Displayable</a></dd>
<dd><a href="ranger.shared.html#EnvironmentAware">ranger.shared.EnvironmentAware</a></dd>
<dd><a href="ranger.shared.html#FileManagerAware">ranger.shared.FileManagerAware</a></dd>
<dd><a href="ranger.shared.html#Awareness">ranger.shared.Awareness</a></dd>
<dd><a href="ranger.gui.curses_shortcuts.html#CursesShortcuts">ranger.gui.curses_shortcuts.CursesShortcuts</a></dd>
<dd><a href="ranger.shared.settings.html#SettingsAware">ranger.shared.settings.SettingsAware</a></dd>
<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
</dl>
<hr>
Methods defined here:<br>
<dl><dt><a name="Pager-__init__"><strong>__init__</strong></a>(self, win, embedded<font color="#909090">=False</font>)</dt></dl>

<dl><dt><a name="Pager-click"><strong>click</strong></a>(self, event)</dt></dl>

<dl><dt><a name="Pager-close"><strong>close</strong></a>(self)</dt></dl>

<dl><dt><a name="Pager-draw"><strong>draw</strong></a>(self)</dt></dl>

<dl><dt><a name="Pager-finalize"><strong>finalize</strong></a>(self)</dt></dl>

<dl><dt><a name="Pager-move"><strong>move</strong></a>(self, narg<font color="#909090">=None</font>, **kw)</dt></dl>

<dl><dt><a name="Pager-open"><strong>open</strong></a>(self)</dt></dl>

<dl><dt><a name="Pager-press"><strong>press</strong></a>(self, key)</dt></dl