Basic function kinda works
This commit is contained in:
@@ -2,4 +2,4 @@ from hissp.reader import transpile
|
|||||||
transpile(__package__, "livesort", "test_livesort")
|
transpile(__package__, "livesort", "test_livesort")
|
||||||
del transpile
|
del transpile
|
||||||
|
|
||||||
from livesort_hssp.livesort import livesort, render
|
from livesort_hssp.livesort import Livesort
|
||||||
|
|||||||
@@ -1,44 +1,72 @@
|
|||||||
(hissp.basic.._macro_.prelude)
|
(hissp.basic.._macro_.prelude)
|
||||||
|
|
||||||
(defmacro setq (symbol value)
|
|
||||||
"lol this isn't even my lisp"
|
|
||||||
`(setitem (locals) (quote ,symbol) ,value))
|
|
||||||
|
|
||||||
(define livesort
|
(deftype Livesort ()
|
||||||
(lambda (next-line ; iterable function
|
__init__
|
||||||
print ; function to write output
|
(lambda (self
|
||||||
height ; window/screen height in lines
|
next-line ; iterable function yielding lines of text
|
||||||
width ; window/screen width in characters
|
print ; function to write output
|
||||||
)
|
height ; window/screen height in lines
|
||||||
(let (lines (list) ; sorted lines
|
width ; window/screen width in characters
|
||||||
cursor 0 ; line number to keep on screen and highlight
|
)
|
||||||
quitting? False ; set flag to exit loop
|
(attach self next-line print height width :
|
||||||
)
|
lines (list) ; sorted input lines
|
||||||
;; the cursor is thought to exist between line `cursor` and `cursor - 1`
|
screen (list (mul height '(None))))
|
||||||
(any-for line next-line
|
None) ; __init__ required to return `None`
|
||||||
(let (lineno (bisect..bisect lines line))
|
|
||||||
(unless (gt lineno cursor)
|
|
||||||
(setq cursor (add cursor 1)))
|
|
||||||
(.insert lines lineno line)
|
|
||||||
(print (.format "c{}" (render lines cursor height width))))
|
|
||||||
quitting?))))
|
|
||||||
|
|
||||||
(define render
|
sortline
|
||||||
(lambda (lines ; sequence of sorted lines
|
(lambda (self line)
|
||||||
cursor ; line to keep on-screen
|
"Insort a line and update the cursor position"
|
||||||
height ; window height
|
(when (.strip line)
|
||||||
width ; and width
|
(let (lineno (bisect..bisect self.lines line))
|
||||||
)
|
;; Normally would use `..insort` but there's going to be more
|
||||||
(.join "\n"
|
(.insert self.lines lineno line))))
|
||||||
(map (lambda (line) (getitem line (slice 0 width)))
|
|
||||||
(getitem lines
|
|
||||||
(let (r (ifloordiv height 2))
|
|
||||||
(slice (max 0 (sub cursor r))
|
|
||||||
(min (len lines) (add cursor r)))))))))
|
|
||||||
|
|
||||||
|
render
|
||||||
|
(lambda (self)
|
||||||
|
"Produce a list of the lines which should be visible, cropped to `width`"
|
||||||
|
(list (map (lambda (line) (getitem line (slice None self.width)))
|
||||||
|
(getitem self.lines (slice None self.height)))))
|
||||||
|
|
||||||
|
display
|
||||||
|
(lambda (self)
|
||||||
|
"Compare `(self.render)` to `self.screen` and return a string that
|
||||||
|
will update the display."
|
||||||
|
(let (output (list)
|
||||||
|
lines (self.render)
|
||||||
|
changed? (list))
|
||||||
|
(.append output "[H") ; Home cursor
|
||||||
|
(any-for lineno (range self.height)
|
||||||
|
(let (line (if-else (lt lineno (len lines))
|
||||||
|
(getitem lines lineno)
|
||||||
|
""))
|
||||||
|
(unless (eq line (getitem self.screen lineno))
|
||||||
|
(setitem self.screen lineno line)
|
||||||
|
(.append changed? line)
|
||||||
|
;; ^[[K to erase any characters that follow on this line
|
||||||
|
(.append output (.format "{}[K"
|
||||||
|
(.rstrip line (chr 0x0a)))))
|
||||||
|
(.append output (chr 0x0a))) ; Move to beginning of next line
|
||||||
|
False)
|
||||||
|
;; If something changed, don't bother outputting the last cursor
|
||||||
|
;; movement code. If nothing changed, don't bother outputting
|
||||||
|
;; anything.
|
||||||
|
(if-else changed?
|
||||||
|
(.join "" (getitem output (slice None -1)))
|
||||||
|
"")))
|
||||||
|
|
||||||
|
livesort
|
||||||
|
(lambda (self)
|
||||||
|
"Process every input line, updating screen each line"
|
||||||
|
(any-for line self.next-line
|
||||||
|
(.sortline self line)
|
||||||
|
(.print self (.display self))
|
||||||
|
False)))
|
||||||
|
|
||||||
(when (eq __name__ '__main__)
|
(when (eq __name__ '__main__)
|
||||||
(livesort sys..stdin
|
(.livesort (Livesort sys..stdin
|
||||||
sys..stdout.write
|
(lambda (data)
|
||||||
(int (|| (os..getenv 'LINES) "24"))
|
(sys..stdout.write data)
|
||||||
(int (|| (os..getenv 'COLUMNS) "80"))))
|
(sys..stdout.flush))
|
||||||
|
(int (|| (os..getenv 'LINES) "24"))
|
||||||
|
(int (|| (os..getenv 'COLUMNS) "80")))))
|
||||||
|
|||||||
@@ -1,8 +1,63 @@
|
|||||||
(hissp.basic.._macro_.prelude)
|
(hissp.basic.._macro_.prelude)
|
||||||
|
|
||||||
(deftype TestLivesort (unittest..TestCase)
|
(deftype TestLivesort (unittest..TestCase)
|
||||||
|
setUp
|
||||||
|
(lambda (self)
|
||||||
|
(attach self :
|
||||||
|
input-buf (list)
|
||||||
|
output-buf (list)
|
||||||
|
ls (livesort_hssp.livesort..Livesort self.input-buf
|
||||||
|
self.output-buf.append
|
||||||
|
4
|
||||||
|
8)))
|
||||||
|
|
||||||
|
tearDown
|
||||||
|
(lambda (self)
|
||||||
|
(delattr self 'ls)
|
||||||
|
(delattr self 'output-buf)
|
||||||
|
(delattr self 'input-buf))
|
||||||
|
|
||||||
|
test_Livesort
|
||||||
|
(lambda (self)
|
||||||
|
(cascade self
|
||||||
|
(.assertEqual self.ls.next-line self.input-buf)
|
||||||
|
(.assertEqual self.ls.print self.output-buf.append)
|
||||||
|
(.assertEqual self.ls.height 4)
|
||||||
|
(.assertEqual self.ls.width 8)
|
||||||
|
(.assertFalse self.ls.lines)
|
||||||
|
(.assertTrue self.ls.screen))
|
||||||
|
(any-for line self.ls.screen
|
||||||
|
(not (self.assertEqual None line))))
|
||||||
|
|
||||||
|
test_sortline
|
||||||
|
(lambda (self)
|
||||||
|
(self.assertFalse self.ls.lines)
|
||||||
|
(self.ls.sortline "line 2")
|
||||||
|
(self.assertEqual self.ls.lines (list '(.#"line 2")))
|
||||||
|
(self.ls.sortline "line 1")
|
||||||
|
(self.assertEqual self.ls.lines (list '(.#"line 1" .#"line 2"))))
|
||||||
|
|
||||||
test_render
|
test_render
|
||||||
(lambda (self)
|
(lambda (self)
|
||||||
(.assertEqual self "----" (livesort_hssp..render '(.#"-----") 0 4 4))))
|
(self.ls.sortline "line 1")
|
||||||
|
(self.assertEqual (self.ls.render)
|
||||||
|
(list '(.#"line 1"))))
|
||||||
|
|
||||||
(when (eq __name__ '__main__) (hissp.reader..transpile __package__ 'test_livesort))
|
test_display
|
||||||
|
(lambda (self)
|
||||||
|
;; I got fed up trying to write this sensibly, will go away after refacor
|
||||||
|
(self.assertEqual "[H[K
|
||||||
|
[K
|
||||||
|
[K
|
||||||
|
[K" (self.ls.display))
|
||||||
|
(self.ls.sortline "line 1")
|
||||||
|
(self.assertEqual "[Hline 1[K
|
||||||
|
|
||||||
|
|
||||||
|
" (self.ls.display)))
|
||||||
|
|
||||||
|
test_livesort ; note (unfortunate) capitalization
|
||||||
|
(lambda (self)
|
||||||
|
(self.input-buf.append "line 1")
|
||||||
|
(self.ls.livesort)
|
||||||
|
_#(self.assertEqual self.output-buf (list '(.#"line 1")))))
|
||||||
|
|||||||
Reference in New Issue
Block a user