1 # Some useful helpers for dealing with text (arrays of characters) 2 3 def equal a:text, b:text -> result:bool [ 4 local-scope 5 load-inputs 6 an:num, bn:num <- deaddress a, b 7 address-equal?:boolean <- equal an, bn 8 return-if address-equal?, true 9 return-unless a, false 10 return-unless b, false 11 a-len:num <- length *a 12 b-len:num <- length *b 13 # compare lengths 14 trace 99, [text-equal], [comparing lengths] 15 length-equal?:bool <- equal a-len, b-len 16 return-unless length-equal?, false 17 # compare each corresponding character 18 trace 99, [text-equal], [comparing characters] 19 i:num <- copy 0 20 { 21 done?:bool <- greater-or-equal i, a-len 22 break-if done? 23 a2:char <- index *a, i 24 b2:char <- index *b, i 25 chars-match?:bool <- equal a2, b2 26 return-unless chars-match?, false 27 i <- add i, 1 28 loop 29 } 30 return true 31 ] 32 33 scenario text-equal-reflexive [ 34 local-scope 35 x:text <- new [abc] 36 run [ 37 10:bool/raw <- equal x, x 38 ] 39 memory-should-contain [ 40 10 <- 1 # x == x for all x 41 ] 42 ] 43 44 scenario text-equal-identical [ 45 local-scope 46 x:text <- new [abc] 47 y:text <- new [abc] 48 run [ 49 10:bool/raw <- equal x, y 50 ] 51 memory-should-contain [ 52 10 <- 1 # abc == abc 53 ] 54 ] 55 56 scenario text-equal-distinct-lengths [ 57 local-scope 58 x:text <- new [abc] 59 y:text <- new [abcd] 60 run [ 61 10:bool/raw <- equal x, y 62 ] 63 memory-should-contain [ 64 10 <- 0 # abc != abcd 65 ] 66 trace-should-contain [ 67 text-equal: comparing lengths 68 ] 69 trace-should-not-contain [ 70 text-equal: comparing characters 71 ] 72 ] 73 74 scenario text-equal-with-empty [ 75 local-scope 76 x:text <- new [] 77 y:text <- new [abcd] 78 run [ 79 10:bool/raw <- equal x, y 80 ] 81 memory-should-contain [ 82 10 <- 0 # "" != abcd 83 ] 84 ] 85 86 scenario text-equal-with-null [ 87 local-scope 88 x:text <- new [abcd] 89 y:text <- copy null 90 run [ 91 10:bool/raw <- equal x, null 92 11:bool/raw <- equal null, x 93 12:bool/raw <- equal x, y 94 13:bool/raw <- equal y, x 95 14:bool/raw <- equal y, y 96 ] 97 memory-should-contain [ 98 10 <- 0 99 11 <- 0 100 12 <- 0 101 13 <- 0 102 14 <- 1 103 ] 104 check-trace-count-for-label 0, [error] 105 ] 106 107 scenario text-equal-common-lengths-but-distinct [ 108 local-scope 109 x:text <- new [abc] 110 y:text <- new [abd] 111 run [ 112 10:bool/raw <- equal x, y 113 ] 114 memory-should-contain [ 115 10 <- 0 # abc != abd 116 ] 117 ] 118 119 # A new type to help incrementally construct texts. 120 container buffer:_elem [ 121 length:num 122 data:&:@:_elem 123 ] 124 125 def new-buffer capacity:num -> result:&:buffer:_elem [ 126 local-scope 127 load-inputs 128 result <- new {(buffer _elem): type} 129 *result <- put *result, length:offset, 0 130 { 131 break-if capacity 132 # capacity not provided 133 capacity <- copy 10 134 } 135 data:&:@:_elem <- new _elem:type, capacity 136 *result <- put *result, data:offset, data 137 return result 138 ] 139 140 def grow-buffer buf:&:buffer:_elem -> buf:&:buffer:_elem [ 141 local-scope 142 load-inputs 143 # double buffer size 144 olddata:&:@:_elem <- get *buf, data:offset 145 oldlen:num <- length *olddata 146 newlen:num <- multiply oldlen, 2 147 newdata:&:@:_elem <- new _elem:type, newlen 148 *buf <- put *buf, data:offset, newdata 149 # copy old contents 150 i:num <- copy 0 151 { 152 done?:bool <- greater-or-equal i, oldlen 153 break-if done? 154 src:_elem <- index *olddata, i 155 *newdata <- put-index *newdata, i, src 156 i <- add i, 1 157 loop 158 } 159 ] 160 161 def buffer-full? in:&:buffer:_elem -> result:bool [ 162 local-scope 163 load-inputs 164 len:num <- get *in, length:offset 165 s:&:@:_elem <- get *in, data:offset 166 capacity:num <- length *s 167 result <- greater-or-equal len, capacity 168 ] 169 170 # most broadly applicable definition of append to a buffer 171 def append buf:&:buffer:_elem, x:_elem -> buf:&:buffer:_elem [ 172 local-scope 173 load-inputs 174 len:num <- get *buf, length:offset 175 { 176 # grow buffer if necessary 177 full?:bool <- buffer-full? buf 178 break-unless full? 179 buf <- grow-buffer buf 180 } 181 s:&:@:_elem <- get *buf, data:offset 182 *s <- put-index *s, len, x 183 len <- add len, 1 184 *buf <- put *buf, length:offset, len 185 ] 186 187 # most broadly applicable definition of append to a buffer of characters: just 188 # call to-text 189 def append buf:&:buffer:char, x:_elem -> buf:&:buffer:char [ 190 local-scope 191 load-inputs 192 text:text <- to-text x 193 buf <- append buf, text 194 ] 195 196 # specialization for characters that is backspace-aware 197 def append buf:&:buffer:char, c:char -> buf:&:buffer:char [ 198 local-scope 199 load-inputs 200 len:num <- get *buf, length:offset 201 { 202 # backspace? just drop last character if it exists and return 203 backspace?:bool <- equal c, 8/backspace 204 break-unless backspace? 205 empty?:bool <- lesser-or-equal len, 0 206 return-if empty? 207 len <- subtract len, 1 208 *buf <- put *buf, length:offset, len 209 return 210 } 211 { 212 # grow buffer if necessary 213 full?:bool <- buffer-full? buf 214 break-unless full? 215 buf <- grow-buffer buf 216 } 217 s:text <- get *buf, data:offset 218 *s <- put-index *s, len, c 219 len <- add len, 1 220 *buf <- put *buf, length:offset, len 221 ] 222 223 def append buf:&:buffer:_elem, t:&:@:_elem -> buf:&:buffer:_elem [ 224 local-scope 225 load-inputs 226 len:num <- length *t 227 i:num <- copy 0 228 { 229 done?:bool <- greater-or-equal i, len 230 break-if done? 231 x:_elem <- index *t, i 232 buf <- append buf, x 233 i <- add i, 1 234 loop 235 } 236 ] 237 238 scenario append-to-empty-buffer [ 239 local-scope 240 x:&:buffer:char <- new-buffer 241 run [ 242 c:char <- copy 97/a 243 x <- append x, c 244 10:num/raw <- get *x, length:offset 245 s:text <- get *x, data:offset 246 11:char/raw <- index *s, 0 247 12:char/raw <- index *s, 1 248 ] 249 memory-should-contain [ 250 10 <- 1 # buffer length 251 11 <- 97 # a 252 12 <- 0 # rest of buffer is empty 253 ] 254 ] 255 256 scenario append-to-buffer [ 257 local-scope 258 x:&:buffer:char <- new-buffer 259 c:char <- copy 97/a 260 x <- append x, c 261 run [ 262 c <- copy 98/b 263 x <- append x, c 264 10:num/raw <- get *x, length:offset 265 s:text <- get *x, data:offset 266 11:char/raw <- index *s, 0 267 12:char/raw <- index *s, 1 268 13:char/raw <- index *s, 2 269 ] 270 memory-should-contain [ 271 10 <- 2 # buffer length 272 11 <- 97 # a 273 12 <- 98 # b 274 13 <- 0 # rest of buffer is empty 275 ] 276 ] 277 278 scenario append-grows-buffer [ 279 local-scope 280 x:&:buffer:char <- new-buffer 3 281 s1:text <- get *x, data:offset 282 x <- append x, [abc] # buffer is now full 283 s2:text <- get *x, data:offset 284 run [ 285 10:bool/raw <- equal s1, s2 286 11:@:char/raw <- copy *s2 287 +buffer-filled 288 c:char <- copy 100/d 289 x <- append x, c 290 s3:text <- get *x, data:offset 291 20:bool/raw <- equal s1, s3 292 21:num/raw <- get *x, length:offset 293 30:@:char/raw <- copy *s3 294 ] 295 memory-should-contain [ 296 # before +buffer-filled 297 10 <- 1 # no change in data pointer after original append 298 11 <- 3 # size of data 299 12 <- 97 # data 300 13 <- 98 301 14 <- 99 302 # in the end 303 20 <- 0 # data pointer has grown after second append 304 21 <- 4 # final length 305 30 <- 6 # but data's capacity has doubled 306 31 <- 97 # data 307 32 <- 98 308 33 <- 99 309 34 <- 100 310 35 <- 0 311 36 <- 0 312 ] 313 ] 314 315 scenario buffer-append-handles-backspace [ 316 local-scope 317 x:&:buffer:char <- new-buffer 318 x <- append x, [ab] 319 run [ 320 c:char <- copy 8/backspace 321 x <- append x, c 322 s:text <- buffer-to-array x 323 10:@:char/raw <- copy *s 324 ] 325 memory-should-contain [ 326 10 <- 1 # length 327 11 <- 97 # contents 328 12 <- 0 329 ] 330 ] 331 332 scenario append-to-buffer-of-non-characters [ 333 local-scope 334 x:&:buffer:text <- new-buffer 1/capacity 335 # no errors 336 ] 337 338 def buffer-to-array in:&:buffer:_elem -> result:&:@:_elem [ 339 local-scope 340 load-inputs 341<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html><head><title>Python: module ranger.gui.ui</title> </head><body bgcolor="#f0f0f8"> <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading"> <tr bgcolor="#7799ee"> <td valign=bottom> <br> <font color="#ffffff" face="helvetica, arial"> <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>.ui</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/ui.py">/home/hut/ranger/ranger/gui/ui.py</a></font></td></tr></table> <p><tt># Copyright (C) 2009, 2010 Roman Zimbelmann <romanz@lavabit.com><br> #<br> # This program is free software: you can redistribute it and/or modify<br> # it under the terms of the GNU General Public License as published by<br> # the Free Software Foundation, either version 3 of the License, or<br> # (at your option) any later version.<br> #<br> # This program is distributed in the hope that it will be useful,<br> # but WITHOUT ANY WARRANTY; without even the implied warranty of<br> # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br> # GNU General Public License for more details.<br> #<br> # You should have received a copy of the GNU General Public License<br> # along with this program. If not, see <<a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>>.</tt></p> <p> <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> <tr bgcolor="#aa55cc"> <td colspan=3 valign=bottom> <br> <font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr> <tr><td bgcolor="#aa55cc"><tt> </tt></td><td> </td> <td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="_curses.html">_curses</a><br> <a href="curses.html">curses</a><br> </td><td width="25%" valign=top><a href="os.html">os</a><br> <a href="socket.html">socket</a><br> </td><td width="25%" valign=top><a href="sys.html">sys</a><br> </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> <br> <font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr> <tr><td bgcolor="#ee77aa"><tt> </tt></td><td> </td> <td width="100%"><dl> <dt><font face="helvetica, arial"><a href="ranger.gui.displayable.html#DisplayableContainer">ranger.gui.displayable.DisplayableContainer</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.ui.html#UI">UI</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> <br> <font color="#000000" face="helvetica, arial"><a name="UI">class <strong>UI</strong></a>(<a href="ranger.gui.displayable.html#DisplayableContainer">ranger.gui.displayable.DisplayableContainer</a>)</font></td></tr> <tr><td bgcolor="#ffc8d8"><tt> </tt></td><td> </td> <td width="100%"><dl><dt>Method resolution order:</dt> <dd><a href="ranger.gui.ui.html#UI">UI</a></dd> <dd><a href="ranger.gui.displayable.html#DisplayableContainer">ranger.gui.displayable.DisplayableContainer</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="UI-__init__"><strong>__init__</strong></a>(self, commandlist<font color="#909090">=None</font>, env<font color="#909090">=None</font>, fm<font color="#909090">=None</font>)</dt></dl> <dl><dt><a name="UI-destroy"><strong>destroy</strong></a>(self)</dt><dd><tt>Destroy all widgets and turn off curses</tt></dd></dl> <dl><dt><a name="UI-draw"><strong>draw</strong></a>(self)</dt><dd><tt>Draw all objects in the container</tt></dd></dl> <dl><dt><a name="UI-finalize"><strong>finalize</strong></a>(self)</dt><dd><tt>Finalize every object in container and refresh the window</tt></dd></dl> <dl><dt><a name="UI-get_next_key"><strong>get_next_key</strong></a>(self)</dt><dd><tt>Waits for key input and returns the pressed key</tt></dd></dl> <dl><dt><a name="UI-handle_key"><strong>handle_key</strong></a>(self, key)</dt><dd><tt>Handles key input</tt></dd></dl> <dl><dt><a name="UI-handle_mouse"><strong>handle_mouse</strong></a>(self)</dt><dd><tt>Handles mouse input</tt></dd></dl> <dl><dt><a name="UI-initialize"><strong>initialize</strong></a>(self)</dt><dd><tt>initialize curses, then call setup (at the first time) and resize.</tt></dd></dl> <dl><dt><a name="UI-redraw"><strong>redraw</strong></a>(self)</dt><dd><tt>Redraw all widgets</tt></dd></dl> <dl><dt><a name="UI-redraw_window"><strong>redraw_window</strong></a>(self)</dt><dd><tt>Redraw the window. This only calls self.<strong>win</strong>.redrawwin().</tt></dd></dl> <dl><dt><a name="UI-set_load_mode"><strong>set_load_mode</strong></a>(self, boolean)</dt></dl> <dl><dt><a name="UI-setup"><strong>setup</strong></a>(self)</dt><dd><tt>Called after an <a href="#UI-initialize">initialize</a>() call.<br> Override this!</tt></dd></dl> <dl><dt><a name="UI-suspend"><strong>suspend</strong></a>(self)</dt><dd><tt>Turn off curses</tt></dd></dl> <dl><dt><a name="UI-update_size"><strong>update_size</strong></a>(self)</dt><dd><tt>Update self.<strong>env</strong>.termsize.<br> Extend this method to resize all widgets!</tt></dd></dl> <hr> Data and other attributes defined here:<br> <dl><dt><strong>is_set_up</strong> = False</dl> <dl><dt><strong>load_mode</strong> = False</dl> <dl><dt><strong>mousemask</strong> = 268435455</dl> <hr> Methods inherited from <a href="ranger.gui.displayable.html#DisplayableContainer">ranger.gui.displayable.DisplayableContainer</a>:<br> <dl><dt><a name="UI-add_child"><strong>add_child</strong></a>(self, obj)</dt><dd><tt>Add the objects to the container.</tt></dd></dl> <dl><dt><a name="UI-click"><strong>click</strong></a>(self, event)</dt><dd><tt>Recursively called on objects in container</tt></dd></dl> <dl><dt><a name="UI-poke"><strong>poke</strong></a>(self)</dt><dd><tt>Recursively called on objects in container</tt></dd></dl> <dl><dt><a name="UI-press"><strong>press</strong></a>(self, key)</dt><dd><tt>Recursively called on objects in container</tt></dd></dl> <dl><dt><a name="UI-remove_child"><strong>remove_child</strong></a>(self, obj)</dt><dd><tt>Remove the object from the container.</tt></dd></dl> <hr> Methods inherited from <a href="ranger.gui.displayable.html#Displayable">ranger.gui.displayable.Displayable</a>:<br> <dl><dt><a name="UI-__bool__"><strong>__bool__</strong></a> = __nonzero__(self)</dt><dd><tt>Always True</tt></dd></dl> <dl><dt><a name="UI-__contains__"><strong>__contains__</strong></a>(self, item)</dt><dd><tt>Is item inside the boundaries?<br> item can be an iterable like [y, x] or an object with x and y methods.</tt></dd></dl> <dl><dt><a name="UI-__nonzero__"><strong>__nonzero__</strong></a>(self)</dt><dd><tt>Always True</tt></dd></dl> <dl><dt><a name="UI-__str__"><strong>__str__</strong></a>(self)</dt></dl> <dl><dt><a name="UI-contains_point"><strong>contains_point</strong></a>(self, y, x)</dt><dd><tt>Test whether the point (with absolute coordinates) lies<br> within the boundaries of this object.</tt></dd></dl> <dl><dt><a name="UI-resize"><strong>resize</strong></a>(self, y, x, hei<font color="#909090">=None</font>, wid<font color="#909090">=None</font>)</dt><dd><tt>Resize the widget</tt></dd></dl> <hr> Data and other attributes inherited from <a href="ranger.shared.html#EnvironmentAware">ranger.shared.EnvironmentAware</a>:<br> <dl><dt><strong>env</strong> = None</dl> <hr> Data and other attributes inherited from <a href="ranger.shared.html#FileManagerAware">ranger.shared.FileManagerAware</a>:<br> <dl><dt><strong>fm</strong> = None</dl> <hr> Data descriptors inherited from <a href="ranger.shared.html#Awareness">ranger.shared.Awareness</a>:<br> <dl><dt><strong>__dict__</strong></dt> <dd><tt>dictionary for instance variables (if defined)</tt></dd> </dl> <dl><dt><strong>__weakref__</strong></dt> <dd><tt>list of weak references to the object (if defined)</tt></dd> </dl> <hr> Methods inherited from <a href="ranger.gui.curses_shortcuts.html#CursesShortcuts">ranger.gui.curses_shortcuts.CursesShortcuts</a>:<br> <dl><dt><a name="UI-addnstr"><strong>addnstr</strong></a>(self, *args)</dt></dl> <dl><dt><a name="UI-addstr"><strong>addstr</strong></a>(self, *args)</dt></dl> <dl><dt><a name="UI-color"><strong>color</strong></a>(self, *keys)</dt><dd><tt>Change the colors from now on.</tt></dd></dl> <dl><dt><a name="UI-color_at"><strong>color_at</strong></a>(self, y, x, wid, *keys)</dt><dd><tt>Change the colors at the specified position</tt></dd></dl> <dl><dt><a name="UI-color_reset"><strong>color_reset</strong></a>(self)</dt><dd><tt>Change the colors to the default colors</tt></dd></dl> <hr> Data and other attributes inherited from <a href="ranger.shared.settings.html#SettingsAware">ranger.shared.settings.SettingsAware</a>:<br> <dl><dt><strong>settings</strong> = {}</dl> </td></tr></table></td></tr></table><p> <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> <tr bgcolor="#55aa55"> <td colspan=3 valign=bottom> <br> <font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr> <tr><td bgcolor="#55aa55"><tt> </tt></td><td> </td> <td width="100%"><strong>TERMINALS_WITH_TITLE</strong> = ('xterm', 'xterm-256color', 'rxvt', 'rxvt-256color', 'rxvt-unicode', 'aterm', 'Eterm', 'screen', 'screen-256color')</td></tr></table> </body></html>