(local util (require :lib.util)) (local {: attach-imstate : textbox} (util.require :editor.imstate)) (local View (require :core.view)) (local style (require :core.style)) (local ReplView (View:extend)) (fn ReplView.new [self conn] (ReplView.super.new self) (attach-imstate self) (set self.conn conn) (set self.log []) (set self.cmd "") (set self.scrollheight math.huge) (set self.scrollable true) (set self.pin-to-bottom-y self.scroll.to.y) (self.conn:listen self)) (fn ReplView.try_close [self do_close] (self.conn:unlisten self) (ReplView.super.try_close self do_close)) (fn ReplView.get_scrollable_size [self] self.scrollheight) (fn ReplView.append [self line] (table.insert self.log line)) (fn ReplView.draw-cmd [{: cmd} view x y] (renderer.draw_text style.font cmd x y style.text) (+ (style.font:get_height) style.padding.y)) (fn ReplView.submit [self ?cmd] (local cmd (or ?cmd self.cmd)) (when (= ?cmd nil) (set self.cmd "")) (self:append {:draw #(self.draw-cmd $...) : cmd}) (self.conn:submit cmd)) (fn ReplView.draw [self] (self:draw_background style.background) (self:draw_scrollbar) (var x (- self.position.x self.scroll.x)) (var y (- self.position.y self.scroll.y)) (var rendered-h 0) ; todo: cache sizes and avoid drawing if offscreen? ; note: then offscreen items can't be focussed without further effort ; todo: draw line numbers (each [i line (ipairs self.log)] (let [h (line:draw self x y)] (set y (+ y h)) (set rendered-h (+ rendered-h h)))) (set self.cmd (textbox self :command self.cmd x y self.size.x)) (local pin-to-bottom (>= self.scroll.to.y (- self.scrollheight self.size.y))) (set self.scrollheight (+ rendered-h (style.font:get_height) 4)) (when pin-to-bottom (set self.scroll.to.y (- self.scrollheight self.size.y)))) ReplView