Hy version kind of works
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
import hy
|
||||||
|
from livesort_hy.livesort import Livesort
|
||||||
|
# This allows `unittest.main` to discover these tests
|
||||||
|
from livesort_hy.test_livesort import TestLivesort
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
(import [bisect [bisect]])
|
||||||
|
|
||||||
|
(defclass Livesort []
|
||||||
|
(defn __init__ [self
|
||||||
|
next-line ; iterable function yielding lines of text
|
||||||
|
print ; function to write output
|
||||||
|
height ; window/screen height in lines
|
||||||
|
width ; window/screen width in characters
|
||||||
|
]
|
||||||
|
(setv self.next-line next-line
|
||||||
|
self.print print
|
||||||
|
self.height height
|
||||||
|
self.width width
|
||||||
|
self.lines (list)
|
||||||
|
self.screen (* height [None])))
|
||||||
|
(defn sortline [self line]
|
||||||
|
"Insort a line"
|
||||||
|
(when (line.strip)
|
||||||
|
;; Normally would use `insort` but there's going to be more
|
||||||
|
(self.lines.insert (bisect self.lines line) line)))
|
||||||
|
(defn render [self]
|
||||||
|
"Produce a list of the lines which should be visible, cropped to `width`"
|
||||||
|
(list (map (fn [line] (cut line 0 self.width))
|
||||||
|
(cut self.lines 0 self.height))))
|
||||||
|
(defn display [self]
|
||||||
|
"Compare `(self.render)` to `self.screen` and return a string that
|
||||||
|
will update the display."
|
||||||
|
(setv output (list)
|
||||||
|
lines (self.render)
|
||||||
|
changed? False)
|
||||||
|
(output.append "[H") ; Home cursor
|
||||||
|
(for [lineno (range self.height)]
|
||||||
|
(setv line (if (< lineno (len lines)) (get lines lineno) ""))
|
||||||
|
(unless (= line (get self.screen lineno))
|
||||||
|
(setv (get self.screen lineno) line
|
||||||
|
changed? True)
|
||||||
|
;; ^[[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
|
||||||
|
;; if something changed, don't bother outputting the last cursor
|
||||||
|
;; movement code. If nothing changed, don't bother outputting
|
||||||
|
;; anything.
|
||||||
|
(if changed? (.join "" (cut output 0 -1)) ""))
|
||||||
|
(defn livesort [self]
|
||||||
|
"Process every input line, updating screen each line"
|
||||||
|
(for [line self.next-line]
|
||||||
|
(.sortline self line)
|
||||||
|
(.print self (.display self)))))
|
||||||
|
|
||||||
|
(defmain
|
||||||
|
()
|
||||||
|
(import sys os)
|
||||||
|
(.livesort
|
||||||
|
(Livesort sys.stdin
|
||||||
|
(fn [data] (sys.stdout.write data) (sys.stdout.flush))
|
||||||
|
(int (or (os.getenv "LINES") "24"))
|
||||||
|
(int (or (os.getenv "COLUMNS") "80")))))
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
(import [livesort_hy [Livesort]])
|
||||||
|
(import unittest)
|
||||||
|
|
||||||
|
|
||||||
|
(defclass TestLivesort [unittest.TestCase]
|
||||||
|
(defn setUp [self]
|
||||||
|
(setv self.input-buf (list)
|
||||||
|
self.output-buf (list)
|
||||||
|
self.ls (Livesort self.input-buf self.output-buf.append 4 8)))
|
||||||
|
|
||||||
|
(defn tearDown [self]
|
||||||
|
(del self.ls
|
||||||
|
self.output-buf
|
||||||
|
self.input-buf))
|
||||||
|
|
||||||
|
(defn test_Livesort [self]
|
||||||
|
(self.assertEqual self.ls.next-line self.input-buf)
|
||||||
|
(self.assertEqual self.ls.print self.output-buf.append)
|
||||||
|
(self.assertEqual self.ls.height 4)
|
||||||
|
(self.assertEqual self.ls.width 8)
|
||||||
|
(self.assertFalse self.ls.lines)
|
||||||
|
(self.assertTrue self.ls.screen)
|
||||||
|
(for [line self.ls.screen]
|
||||||
|
(self.assertEqual None line)))
|
||||||
|
|
||||||
|
(defn test_sortline [self]
|
||||||
|
(self.assertFalse self.ls.lines)
|
||||||
|
(self.ls.sortline "line 2")
|
||||||
|
(self.assertEqual self.ls.lines ["line 2"])
|
||||||
|
(self.ls.sortline "line 1")
|
||||||
|
(self.assertEqual self.ls.lines ["line 1" "line 2"]))
|
||||||
|
|
||||||
|
(defn test_render [self]
|
||||||
|
(self.ls.sortline "line 1")
|
||||||
|
(self.assertEqual (self.ls.render)
|
||||||
|
["line 1"]))
|
||||||
|
|
||||||
|
(defn test_display [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)))
|
||||||
|
|
||||||
|
;; note (unfortunate) capitalization
|
||||||
|
(defn test_livesort [self]
|
||||||
|
(self.input-buf.append "line 1")
|
||||||
|
(self.ls.livesort)))
|
||||||
Reference in New Issue
Block a user