JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
add cursor incrementals movement: csi_[ABCD]
[watch-my-terminal.git] / client.coffee
1 $ ->
2         timeout = (ms, f) -> setTimeout(f, ms)
3         term = null
4         palette = [
5                 # normal colours
6                 '2e3436',
7                 'cc0000',
8                 '4e9a06',
9                 'c4a000',
10                 '3465a4',
11                 '75507b',
12                 '06989a',
13                 'd3d7cf',
14
15                 # brighter versions (for bold, and 16-color sequences)
16                 '555753',
17                 'ef2929',
18                 '8ae234',
19                 'fce94f',
20                 '729fcf',
21                 'ad7fa8',
22                 '34e2e2',
23                 'eeeeec',
24
25                 # 256 colors
26                 '000000', '00005f', '000087', '0000af', '0000d7', '0000ff', '005f00', '005f5f',
27                 '005f87', '005faf', '005fd7', '005fff', '008700', '00875f', '008787', '0087af',
28                 '0087d7', '0087ff', '00af00', '00af5f', '00af87', '00afaf', '00afd7', '00afff',
29                 '00d700', '00d75f', '00d787', '00d7af', '00d7d7', '00d7ff', '00ff00', '00ff5f',
30                 '00ff87', '00ffaf', '00ffd7', '00ffff', '5f0000', '5f005f', '5f0087', '5f00af',
31                 '5f00d7', '5f00ff', '5f5f00', '5f5f5f', '5f5f87', '5f5faf', '5f5fd7', '5f5fff',
32                 '5f8700', '5f875f', '5f8787', '5f87af', '5f87d7', '5f87ff', '5faf00', '5faf5f',
33                 '5faf87', '5fafaf', '5fafd7', '5fafff', '5fd700', '5fd75f', '5fd787', '5fd7af',
34                 '5fd7d7', '5fd7ff', '5fff00', '5fff5f', '5fff87', '5fffaf', '5fffd7', '5fffff',
35                 '870000', '87005f', '870087', '8700af', '8700d7', '8700ff', '875f00', '875f5f',
36                 '875f87', '875faf', '875fd7', '875fff', '878700', '87875f', '878787', '8787af',
37                 '8787d7', '8787ff', '87af00', '87af5f', '87af87', '87afaf', '87afd7', '87afff',
38                 '87d700', '87d75f', '87d787', '87d7af', '87d7d7', '87d7ff', '87ff00', '87ff5f',
39                 '87ff87', '87ffaf', '87ffd7', '87ffff', 'af0000', 'af005f', 'af0087', 'af00af',
40                 'af00d7', 'af00ff', 'af5f00', 'af5f5f', 'af5f87', 'af5faf', 'af5fd7', 'af5fff',
41                 'af8700', 'af875f', 'af8787', 'af87af', 'af87d7', 'af87ff', 'afaf00', 'afaf5f',
42                 'afaf87', 'afafaf', 'afafd7', 'afafff', 'afd700', 'afd75f', 'afd787', 'afd7af',
43                 'afd7d7', 'afd7ff', 'afff00', 'afff5f', 'afff87', 'afffaf', 'afffd7', 'afffff',
44                 'd70000', 'd7005f', 'd70087', 'd700af', 'd700d7', 'd700ff', 'd75f00', 'd75f5f',
45                 'd75f87', 'd75faf', 'd75fd7', 'd75fff', 'd78700', 'd7875f', 'd78787', 'd787af',
46                 'd787d7', 'd787ff', 'd7af00', 'd7af5f', 'd7af87', 'd7afaf', 'd7afd7', 'd7afff',
47                 'd7d700', 'd7d75f', 'd7d787', 'd7d7af', 'd7d7d7', 'd7d7ff', 'd7ff00', 'd7ff5f',
48                 'd7ff87', 'd7ffaf', 'd7ffd7', 'd7ffff', 'ff0000', 'ff005f', 'ff0087', 'ff00af',
49                 'ff00d7', 'ff00ff', 'ff5f00', 'ff5f5f', 'ff5f87', 'ff5faf', 'ff5fd7', 'ff5fff',
50                 'ff8700', 'ff875f', 'ff8787', 'ff87af', 'ff87d7', 'ff87ff', 'ffaf00', 'ffaf5f',
51                 'ffaf87', 'ffafaf', 'ffafd7', 'ffafff', 'ffd700', 'ffd75f', 'ffd787', 'ffd7af',
52                 'ffd7d7', 'ffd7ff', 'ffff00', 'ffff5f', 'ffff87', 'ffffaf', 'ffffd7', 'ffffff',
53                 '080808', '121212', '1c1c1c', '262626', '303030', '3a3a3a', '444444', '4e4e4e',
54                 '585858', '626262', '6c6c6c', '767676', '808080', '8a8a8a', '949494', '9e9e9e',
55                 'a8a8a8', 'b2b2b2', 'bcbcbc', 'c6c6c6', 'd0d0d0', 'dadada', 'e4e4e4', 'eeeeee'
56         ]
57
58         $body = $('body')
59         $body.css backgroundColor: "##{palette[0]}", color: "##{palette[7]}"
60
61         socket = io.connect('http://localhost')
62
63         color_to_css = (i) ->
64                 # handle inverse bit
65                 if i & 0x080000
66                         index = ((i >> 8) & 0xff)
67                 else
68                         index = (i & 0xff)
69
70                 # lighten the basic 8 colors when they're bold
71                 if ((i & 0x10000) and index < 8)
72                         index += 8
73                 return 'color: #' + palette[index] + '; '
74
75         bg_color_to_css = (i) ->
76                 # xor the inverse bit, to get color_to_css to use the bg color
77                 return 'background-' + color_to_css(i ^ 0x080000)
78
79         stylize = (txt, style) ->
80                 if (txt.length == 0 or style == 0x000007)
81                         return txt
82                 css = ''
83                 css += 'font-weight: bold; ' if style & 0x010000
84                 css += 'text-decoration: underline; ' if style & 0x020000
85                 css += 'font-style: italic; ' if style & 0x200000 # italic
86                 css += 'opacity: 0; ' if style & 0x100000 # invisible
87                 css += color_to_css(style) if ((style & 0x0800ff) isnt 0x07)
88                 css += bg_color_to_css(style) if (style & 0x08ff00)
89                 return $('<span style="'+css+'"></span>').text(txt)
90
91         redraw_wait = false
92         redraw_again = false
93         redraw_now = ->
94                 $body.children().remove()
95                 for i in [0...term.text.length]
96                         div = $('<div>')
97                         txt = ''
98                         a = 0x000007
99                         for j in [0...term.text[i].length]
100                                 if (term.attributes[i][j] isnt a)
101                                         if (txt.length)
102                                                 div.append(stylize(txt, a))
103                                                 txt = ''
104                                         a = term.attributes[i][j]
105                                 txt += term.text[i][j]
106                         if txt.length
107                                 div.append(stylize(txt, a))
108                         $body.append(div)
109
110         # limit to 50fps
111         redraw = ->
112                 if (redraw_wait)
113                         redraw_again = true
114                 else
115                         redraw_now()
116                         redraw_wait = true
117                         redraw_again = false
118                         timeout 20, ->
119                                 redraw_wait = false
120                                 if (redraw_again)
121                                         redraw_again = false
122                                         redraw()
123
124         update = (data) ->
125                 if (term)
126                         term.update(data)
127                         redraw()
128
129         socket.on 'data', (data) ->
130                 update(data)
131
132         socket.on 'init', (v) ->
133                 term = terminal.new(v.width, v.height)
134                 term.x = v.x
135                 term.y = v.y
136                 term.a = v.a
137                 term.text = v.text
138                 term.attributes = v.attributes
139                 redraw()