From: Jason Woofenden Date: Thu, 31 Jan 2013 03:33:10 +0000 (-0500) Subject: csi_H, csi_K, better csi args cleaning/defaults X-Git-Tag: v1.0~31 X-Git-Url: https://jasonwoof.com/gitweb/?p=watch-my-terminal.git;a=commitdiff_plain;h=bd8f5b58663dd5870827c1d0dfa4f8eff8f6a5f0 csi_H, csi_K, better csi args cleaning/defaults --- diff --git a/server.coffee b/server.coffee index 61d3647..d66b6cd 100644 --- a/server.coffee +++ b/server.coffee @@ -37,7 +37,7 @@ terminal = require('./terminal.coffee') # SETTINGS app.listen(9293) -term = terminal.new(105, 66) +term = terminal.new(104, 66) sockets = [] diff --git a/terminal.coffee b/terminal.coffee index 75afdc5..b66bf00 100644 --- a/terminal.coffee +++ b/terminal.coffee @@ -19,7 +19,7 @@ class Terminal @a = 0x000007 # cursor attributes @partial = '' @resize width, height - + resize: (width, height) -> # FIXME: write a version that retains some of the data @width = width @@ -50,12 +50,7 @@ class Terminal else @update_sequence_then_text parts[i] return - - clear_rest_of_line: -> - for i in [@x...@width] - @text[@y][i] = ' ' - @attributes[@y][i] = @a - + add_new_line: -> # clear top line for i in [0...@width] @@ -68,7 +63,7 @@ class Terminal @attributes.push(tmp) # slide cursor up with rest of text @y -= 1 - + wrap_to_next_line: -> if @y is @height - 1 @add_new_line() @@ -100,22 +95,60 @@ class Terminal if @x is @width @wrap_to_next_line() return - + set_attribute_bits: (mask, value) -> @a = (@a & ~mask) | value - csi_m: default: "0", go: -> + # we're supposed to ignore leeding zeros, and while we're at it, lets swap + # in the default for blank or missing values + fix_esc_arg: (value, deef_alt) -> + if value? and value != '' + while value[0] is '0' and value.length > 1 + value = value.substr 1 + return value + else + return deef_alt + + # clear (some or all of) current line + csi_K: (direction) -> + switch @fix_esc_arg direction, '0' + when '0' # erase to right + for i in [@x...@width] + @text[@y][i] = ' ' + @attributes[@y][i] = @a + when '1' # erase to left + for i in [0...@x] + @text[@y][i] = ' ' + @attributes[@y][i] = @a + when '0' # erase whole line + for i in [0...@width] + @text[@y][i] = ' ' + @attributes[@y][i] = @a + + # set cursor position (one based) + csi_H: (row, column) -> + row = 0 + @fix_esc_arg row, 1 + column = 0 + @fix_esc_arg column, 1 + # convert to 0 base + column -= 1 + if 0 <= column < @width + @x = column + else + console.log "tried to move cursor to invalid column: #{column}" + row -= 1 + if 0 <= row < @height + @y = row + else + console.log "tried to move cursor to invalid row: #{row}" + + # set color, bold, underline, etc + csi_m: -> args = [] for i in arguments - args.push i + args.push @fix_esc_arg i, 0 while args.length > 0 - fixed = args.shift() - while fixed[0] is '0' - fixed = fixed.substr 1 - if fixed is '' - fixed = '0' - switch fixed + switch args.shift() # remove all style/color when '0' @@ -130,7 +163,7 @@ class Terminal @set_attribute_bits 0x40000, 0x40000 when '8' # invisible @set_attribute_bits 0x80000, 0x80000 - + # disable style attributes when '22' # not bold... according to a page @set_attribute_bits 0x10000, 0 @@ -243,12 +276,11 @@ class Terminal # str is the whole escape sequence (minus the esc[ prefix) update_sequence: (str) -> command = @["csi_#{str.substr str.length - 1}"] - return unless command? + if not command? + console.log "Unrecognized sequence: ESC[#{str}" + return args = str.substr(0, str.length - 1).split ';' - for i in [0...args.length] - if args[i] is '' - args[i] = command.default - command.go.call this, args... + command.call this, args... update_sequence_then_text: (str) -> len = @escape_sequence_length str