+ else
+ log "confusing arg for csi_K: #{direction}"
+ return
+
+ # move lines downwards (arg is how far)
+ csi_L: (lines) ->
+ lines = parseInt @fix_esc_arg lines, '1'
+
+ rearrange = (a) =>
+ return [
+ a[0...@y]..., # keep everything above cursor
+ a[@scroll_bottom - lines + 1 .. @scroll_bottom]..., # we'll clear these shortly
+ a[@y..@scroll_bottom - lines]..., # lines that are moving down
+ a[@scroll_bottom + 1 ... @height]... # rest of screen
+ ]
+ @text = rearrange @text
+ @attributes = rearrange @attributes
+
+ # clear the lines we scrolled off (and put back in as "new")
+ for y in [@y...@y+lines]
+ for x in [0...@width]
+ @text[y][x] = ' '
+ @attributes[y][x] = 0x07
+
+ # move lines upwards (arg is how far)
+ # this obliterates the line under the cursor and arg-1 following it
+ csi_M: (lines) ->
+ lines = parseInt @fix_esc_arg lines, '1'
+
+ rearrange = (a) =>
+ return [
+ a[0 ... @y]..., # keep everything above cursor
+ a[@y + lines .. @scroll_bottom]..., # lines we're moving up
+ a[@y ... @y + lines]..., # recycle these
+ a[@scroll_bottom + 1 ... @height]... # keep the rest
+ ]
+ @text = rearrange @text
+ @attributes = rearrange @attributes
+
+ # clear the lines we're recycling
+ for y in [@scroll_bottom - lines + 1 .. @scroll_bottom]
+ for x in [0...@width]
+ @text[y][x] = ' '
+ @attributes[y][x] = 0x07
+
+ # misc
+ csiq_h: ->
+ args = []
+ for i in arguments
+ arg = @fix_esc_arg i, ''
+ switch arg
+ when '25'
+ @cursor_visible = true
+ when '1049'
+ if @saved_normal_screen?
+ log "ignoring request to switch to the alt screen because we're already on the alt screen"
+ return
+ @saved_normal_screen = x: @x, y: @y, text: @text, attributes: @attributes
+ @text = []
+ @attributes = []
+ for y in [0...@height]
+ @text[y] = []
+ @attributes[y] = []
+ for x in [0...@width]
+ @text[y].push ' '
+ @attributes[y].push 0x07
+ else
+ log "confusing arg for csiq_h: #{arg}"
+ return
+
+ # unmisc
+ csiq_l: ->
+ args = []
+ for i in arguments
+ arg = @fix_esc_arg i, ''
+ switch arg
+ when '25'
+ @cursor_visible = false
+ when '1049'
+ if not @saved_normal_screen?
+ log "ignoring request to switch to the normal screen because we're already on the normal screen"
+ return
+ @x = @saved_normal_screen.x
+ @y = @saved_normal_screen.y
+ @text = @saved_normal_screen.text
+ @attributes = @saved_normal_screen.attributes
+ @saved_normal_screen = null
+ else
+ log "confusing arg for csiq_l: #{arg}"
+ return