├── .gitignore ├── .luacheckrc ├── .luacov ├── BUGS.md ├── LICENSE.md ├── README.md ├── examples ├── echo_input.lua └── terminfo.lua ├── spec └── tparm_spec.lua └── tui ├── filters.lua ├── init.lua ├── terminfo.lua ├── tparm.lua ├── tput.lua └── util.lua /.gitignore: -------------------------------------------------------------------------------- 1 | /luacov.report.out 2 | /luacov.stats.out 3 | -------------------------------------------------------------------------------- /.luacheckrc: -------------------------------------------------------------------------------- 1 | std = "min" 2 | files["spec"] = { 3 | std = "+busted"; 4 | } 5 | -------------------------------------------------------------------------------- /.luacov: -------------------------------------------------------------------------------- 1 | return { 2 | statsfile = "luacov.stats.out"; 3 | reportfile = "luacov.report.out"; 4 | deletestats = true; 5 | include = { 6 | "/tui/[^/]+$"; 7 | }; 8 | exclude = { 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /BUGS.md: -------------------------------------------------------------------------------- 1 | ## rxvt-unicode (urxvt) 2 | 3 | - Shift + various keys send invalid CSI sequences, e.g. 4 | 5 | - Shift+Delete sends "\27[3$" 6 | - Shift+F11 and Shift+F12 (i.e. F23 and F24) come through as "\27[23$" and "\27[24$", which are unterminated CSI sequences. 7 | 8 | - In X10 mouse reporting mode, going past Cx=255 the escape sequence ends early (I expect they just see the wrapped-around Cx value as a NUL byte that ends the string) 9 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016-2019 Daurnimator 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # lua-tui 2 | 3 | A library for doing things with terminals 4 | 5 | ## Status 6 | 7 | This was a weekend project. You probably shouldn't use it in any projects. 8 | 9 | 10 | ## Components 11 | 12 | ### tui.filters 13 | 14 | Tells you how long a potentially unread escape sequence will be. 15 | 16 | Filters get a `peek` function that they use to lookahead on an input stream. 17 | 18 | 19 | ### tui.terminfo 20 | 21 | Parser for terminfo files 22 | 23 | 24 | ### tui.tput 25 | 26 | `init` and `reset` functions 27 | 28 | 29 | ## Useful links 30 | 31 | - http://invisible-island.net/xterm/ctlseqs/ctlseqs.html 32 | -------------------------------------------------------------------------------- /examples/echo_input.lua: -------------------------------------------------------------------------------- 1 | local tui = require "tui" 2 | local tui_util = require "tui.util" 3 | 4 | tui_util.atexit(function() 5 | io.stdout:write("\27[?1002;1003l") -- Turn all mouse reporting off 6 | os.execute("stty sane") 7 | end) 8 | 9 | os.execute("stty raw opost -echo") 10 | assert(io.stdout:write( 11 | "\27[?1002h", -- Turn on click + drag mouse movement reporting 12 | "\27[?1003h" -- Turn on *all* mouse movement reporting (some terms don't support, e.g. tmux) 13 | )) 14 | assert(io.stdout:flush()) 15 | 16 | print('Quit with "q"') 17 | repeat 18 | local c = tui.getnext() 19 | local mouse_offset = c:match("\27%[M()") or c:match("\155M()") 20 | if mouse_offset then 21 | -- The low two bits of C b encode button information: 0=MB1 pressed, 1=MB2 pressed, 2=MB3 pressed, 3=release. 22 | -- The next three bits encode the modifiers which were down when the button was pressed and are added together: 23 | -- 4=Shift, 8=Meta, 16=Control. 24 | -- On button-motion events, xterm adds 32 to the event code (the third character, C b ) 25 | -- Wheel mice may return buttons 4 and 5. Those buttons are represented by the same event codes as buttons 1 and 2 respectively, 26 | -- except that 64 is added to the event code. 27 | local cb = c:byte(mouse_offset) 28 | local button = cb % 4 29 | local shift = math.floor(cb / 4) % 2 ~= 0 30 | local meta = math.floor(cb / 8) % 2 ~= 0 31 | local ctrl = math.floor(cb / 16) % 2 ~= 0 32 | local button_change = math.floor(cb / 32) % 2 ~= 0 33 | local wheel = math.floor(cb / 64) % 2 ~= 0 34 | local extra = math.floor(cb / 128) % 2 ~= 0 35 | local b 36 | if wheel and button_change then 37 | if button == 0 then 38 | b = "scrollup" 39 | elseif button == 1 then 40 | b = "scrolldown" 41 | else 42 | error("UNKNOWN") 43 | end 44 | elseif button == 3 then 45 | if button_change then 46 | -- yes it's ambiguous *which* button was released 47 | b = "release" 48 | else 49 | b = "move" 50 | end 51 | else 52 | if button == 0 then 53 | b = "left" 54 | elseif button == 1 then 55 | b = "middle" 56 | elseif button == 2 then 57 | b = "right" 58 | end 59 | if not button_change then 60 | b = b .. "+drag" 61 | end 62 | end 63 | if shift then 64 | b = "shift-" .. b 65 | end 66 | if meta then 67 | b = "meta-" .. b 68 | end 69 | if ctrl then 70 | b = "ctrl-" .. b 71 | end 72 | if extra then 73 | b = b .. "+extra" 74 | end 75 | 76 | -- C x and C y are the x and y coordinates of the mouse event, encoded as in X10 mode. 77 | -- local cx, cy = utf8.codepoint(c, mouse_offset+1, -1) 78 | local cx, cy = string.byte(c, mouse_offset+1, -1) 79 | cx = cx - 32 80 | cy = cy - 32 81 | print("MOUSE", b, cx, cy, "BYTES:", c:byte(1,-1)) 82 | else 83 | print("INPUT", string.format("%q", c):gsub("\\\n", "\\n"), "BYTES:", c:byte(1,-1)) 84 | end 85 | until c == "q" 86 | -------------------------------------------------------------------------------- /examples/terminfo.lua: -------------------------------------------------------------------------------- 1 | local tui_terminfo = require "tui.terminfo" 2 | 3 | local caps, names 4 | if arg[1] and arg[1]:match("/") then 5 | caps, names = assert(tui_terminfo.open(arg[1])) 6 | else 7 | caps, names = assert(tui_terminfo.find(arg[1])) 8 | end 9 | 10 | print(names[#names]) 11 | local lines = {} 12 | for k, v in pairs(caps) do 13 | if type(v) == "string" then 14 | v = string.format("%q", v):gsub("\n", "\\n") 15 | else 16 | v = tostring(v) 17 | end 18 | lines[#lines+1] = string.format("\t%s: %s\n", k, v) 19 | end 20 | table.sort(lines) 21 | print(table.concat(lines)) 22 | -------------------------------------------------------------------------------- /spec/tparm_spec.lua: -------------------------------------------------------------------------------- 1 | describe("tparm", function() 2 | local tparm = require "tui.tparm".tparm 3 | it("empty string", function() 4 | assert.same("", tparm("")) 5 | end) 6 | it("normal string with no specifiers", function() 7 | assert.same("\27foo\n", tparm("\27foo\n")) 8 | end) 9 | it("%%", function() 10 | assert.same("foo%bar", tparm("foo%%bar")) 11 | end) 12 | it("simple push + printf", function() 13 | assert.same("\27[1A", tparm("\27[%p1%dA", 1)) 14 | end) 15 | it("if/then/elseif/else", function() 16 | local str = "%?%p1%{7}%>%t\27[48;5;%p1%dm%e\27[4%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m%;" 17 | --[[ 18 | %?%p1%{7}%>%t 19 | \27[48;5;%p1%dm 20 | %e 21 | \27[4 22 | %?%p1%{1}%=%t 23 | 4 24 | %e%p1%{3}%=%t 25 | 6 26 | %e%p1%{4}%=%t 27 | 1 28 | %e%p1%{6}%=%t 29 | 3 30 | %e 31 | %p1%d 32 | %; 33 | m 34 | %; 35 | ]] 36 | assert.same("\27[40m", tparm(str, 0)) 37 | assert.same("\27[44m", tparm(str, 1)) 38 | assert.same("\27[42m", tparm(str, 2)) 39 | assert.same("\27[46m", tparm(str, 3)) 40 | assert.same("\27[41m", tparm(str, 4)) 41 | assert.same("\27[45m", tparm(str, 5)) 42 | assert.same("\27[43m", tparm(str, 6)) 43 | assert.same("\27[47m", tparm(str, 7)) 44 | assert.same("\27[48;5;8m", tparm(str, 8)) 45 | assert.same("\27[48;5;9m", tparm(str, 9)) 46 | end) 47 | end) 48 | -------------------------------------------------------------------------------- /tui/filters.lua: -------------------------------------------------------------------------------- 1 | local function SS2(peek) 2 | local c = peek(1) 3 | if c == "\27" then 4 | if peek(2) == "N" then 5 | return 3 6 | end 7 | elseif c == "\142" then 8 | return 2 9 | end 10 | end 11 | 12 | local function SS3(peek) 13 | local c = peek(1) 14 | if c == "\27" then 15 | if peek(2) == "O" then 16 | return 3 17 | end 18 | elseif c == "\143" then 19 | return 2 20 | end 21 | end 22 | 23 | local function CSI(peek) 24 | local c = peek(1) 25 | local pos 26 | if c == "\27" then 27 | if peek(2) == "[" then 28 | pos = 3 29 | else 30 | return 31 | end 32 | elseif c == "\155" then 33 | pos = 2 34 | else 35 | return 36 | end 37 | -- Read whole CSI sequence 38 | --[[ from ECMA-048: 39 | The format of a control sequence is 'CSI P ... P I ... I F' where 40 | - P ... P are parameter bytes, which, if present, consist of bit combinations from 03/00 to 03/15 41 | - I ... I are intermediate bytes, which, if present, consist of bit combinations from 02/00 to 02/15 42 | Together with the Final Byte F they identify the control function 43 | - F is the final byte; it consists of a bit combination from 04/00 to 07/14 44 | ]] 45 | c = peek(pos) 46 | while c and c:match("[\48-\63]") do 47 | pos = pos + 1 48 | c = peek(pos) 49 | end 50 | while c and c:match("[\32-\47]") do 51 | pos = pos + 1 52 | c = peek(pos) 53 | end 54 | if c and c:match("[\64-\126]") then 55 | return pos 56 | end 57 | -- not valid CSI code... 58 | end 59 | 60 | local function OSC(peek) 61 | local c = peek(1) 62 | local pos 63 | if c == "\27" then 64 | if peek(2) == "]" then 65 | pos = 3 66 | else 67 | return 68 | end 69 | elseif c == "\157" then 70 | pos = 2 71 | else 72 | return 73 | end 74 | repeat 75 | c = peek(pos) 76 | if c == "\27" then 77 | if peek(pos+1) == "\\" then 78 | return pos+1 79 | end 80 | elseif c == "\156" or c == "\7" then -- OSC can be terminated by BEL in xterm 81 | return pos 82 | end 83 | pos = pos + 1 84 | until not c 85 | end 86 | 87 | local function peek_for_st(peek, pos) 88 | repeat 89 | local c = peek(pos) 90 | if c == "\27" then 91 | if peek(pos+1) == "\\" then 92 | return pos+1 93 | end 94 | elseif c == "\156" then 95 | return pos 96 | end 97 | pos = pos + 1 98 | until not c 99 | end 100 | 101 | local function DCS(peek) 102 | local c = peek(1) 103 | local pos 104 | if c == "\27" then 105 | if peek(2) == "P" then 106 | pos = 3 107 | else 108 | return 109 | end 110 | elseif c == "\144" then 111 | pos = 2 112 | else 113 | return 114 | end 115 | return peek_for_st(peek, pos) 116 | end 117 | 118 | local function SOS(peek) 119 | local c = peek(1) 120 | local pos 121 | if c == "\27" then 122 | if peek(2) == "X" then 123 | pos = 3 124 | else 125 | return 126 | end 127 | elseif c == "\152" then 128 | pos = 2 129 | else 130 | return 131 | end 132 | return peek_for_st(peek, pos) 133 | end 134 | 135 | local function PM(peek) 136 | local c = peek(1) 137 | local pos 138 | if c == "\27" then 139 | if peek(2) == "^" then 140 | pos = 3 141 | else 142 | return 143 | end 144 | elseif c == "\158" then 145 | pos = 2 146 | else 147 | return 148 | end 149 | return peek_for_st(peek, pos) 150 | end 151 | 152 | local function APC(peek) 153 | local c = peek(1) 154 | local pos 155 | if c == "\27" then 156 | if peek(2) == "_" then 157 | pos = 3 158 | else 159 | return 160 | end 161 | elseif c == "\159" then 162 | pos = 2 163 | else 164 | return 165 | end 166 | return peek_for_st(peek, pos) 167 | end 168 | 169 | -- this doesn't block U+D800 through U+DFFF 170 | local function multibyte_UTF8(peek) 171 | local c1 = peek(1) 172 | if c1 == nil then return end 173 | local b1 = c1:byte() 174 | if b1 >= 194 and b1 <= 244 then 175 | local c2 = peek(2) 176 | if c2 == nil then return end 177 | local b2 = c2:byte() 178 | if b2 >= 128 and b2 < 192 then 179 | if b1 < 224 then 180 | return 2 181 | else 182 | local c3 = peek(3) 183 | if c3 == nil then return end 184 | local b3 = c3:byte() 185 | if b3 >= 128 and b3 < 192 then 186 | if b1 < 240 then 187 | return 3 188 | else 189 | local c4 = peek(4) 190 | if c4 == nil then return end 191 | local b4 = c4:byte() 192 | if b4 >= 128 and b4 < 192 then 193 | return 4 194 | end 195 | end 196 | end 197 | end 198 | end 199 | end 200 | end 201 | 202 | local function mouse(peek) 203 | local c = peek(1) 204 | local pos 205 | if c == "\27" then 206 | if peek(2) == "[" then 207 | pos = 3 208 | else 209 | return 210 | end 211 | elseif c == "\155" then 212 | pos = 2 213 | else 214 | return 215 | end 216 | if peek(pos) == "M" then 217 | -- The low two bits of C b encode button information: 0=MB1 pressed, 1=MB2 pressed, 2=MB3 pressed, 3=release. 218 | -- The next three bits encode the modifiers which were down when the button was pressed and are added together: 4=Shift, 8=Meta, 16=Control. 219 | -- On button-motion events, xterm adds 32 to the event code (the third character, C b ) 220 | -- Wheel mice may return buttons 4 and 5. Those buttons are represented by the same event codes as buttons 1 and 2 respectively, except that 64 is added to the event code. 221 | -- C x and C y are the x and y coordinates of the mouse event, encoded as in X10 mode. 222 | return pos + 3 223 | end 224 | end 225 | 226 | -- Filter that fixes linux virtual console bugs 227 | local function linux_quirks(peek) 228 | -- bug in F1-F5 keys 229 | if peek(1) == "\27" and peek(2) == "[" and peek(3) == "[" then 230 | local c = peek(4) 231 | if c == "A" or c == "B" or c == "C" or c == "D" or c == "E" then 232 | return 4 233 | end 234 | end 235 | -- bug is an unterminated OSC: P n rr gg bb 236 | if peek(1) == "\27" and peek(2) == "]" and peek(3) == "P" then 237 | return 9 238 | end 239 | end 240 | 241 | local function make_chain(tbl) 242 | return function(peek) 243 | for _, v in ipairs(tbl) do 244 | local len = v(peek) 245 | if len then 246 | return len 247 | end 248 | end 249 | end 250 | end 251 | 252 | local default_chain = make_chain { 253 | -- Always before CSI 254 | mouse; 255 | -- These can be in any order 256 | SS2; 257 | SS3; 258 | CSI; 259 | OSC; 260 | DCS; 261 | SOS; 262 | PM; 263 | APC; 264 | -- Should be before ESC but after CSI and OSC 265 | linux_quirks; 266 | } 267 | 268 | return { 269 | multibyte_UTF8 = multibyte_UTF8; 270 | mouse = mouse; 271 | SS2 = SS2; 272 | SS3 = SS3; 273 | CSI = CSI; 274 | OSC = OSC; 275 | DCS = DCS; 276 | SOS = SOS; 277 | PM = PM; 278 | APC = APC; 279 | linux_quirks = linux_quirks; 280 | 281 | make_chain = make_chain; 282 | default_chain = default_chain; 283 | } 284 | -------------------------------------------------------------------------------- /tui/init.lua: -------------------------------------------------------------------------------- 1 | local tui_filters = require "tui.filters" 2 | 3 | local function fd_to_getter(fd, filter) 4 | local readahead = "" 5 | local function fill(chars) 6 | local need_more = chars - #readahead 7 | if need_more > 0 then 8 | local data, err, errno = fd:read(need_more) 9 | if not data then 10 | return nil, err, errno 11 | end 12 | readahead = readahead .. data 13 | end 14 | return true 15 | end 16 | local function peek(char) 17 | local ok, err, errno = fill(char) 18 | if not ok then 19 | return nil, err, errno 20 | end 21 | return readahead:sub(char, char) 22 | end 23 | local function take(chars) 24 | local ok, err, errno = fill(chars) 25 | if not ok then 26 | return nil, err, errno 27 | end 28 | local r = readahead:sub(1, chars) 29 | readahead = readahead:sub(chars+1) 30 | return r 31 | end 32 | return function() 33 | local a, err, errno = take(filter(peek) or 1) 34 | if a and a == "\27" then 35 | -- if result is a 'loose' escape, then tie it to the next sequence 36 | local b = take(filter(peek) or 1) 37 | if b then 38 | return a .. b 39 | end 40 | end 41 | return a, err, errno 42 | end 43 | end 44 | 45 | local default_getnext = fd_to_getter(io.stdin, tui_filters.default_chain) 46 | 47 | return { 48 | getnext = default_getnext; 49 | } 50 | -------------------------------------------------------------------------------- /tui/terminfo.lua: -------------------------------------------------------------------------------- 1 | -- Compiled format documented in man 5 term 2 | 3 | local sunpack = string.unpack or require "compat53.string".unpack 4 | 5 | -- Arrays taken from term.h 6 | 7 | local Booleans = {} 8 | local Numbers = {} 9 | local Strings = {} 10 | 11 | Booleans[0] = "auto_left_margin" 12 | Booleans[1] = "auto_right_margin" 13 | Booleans[2] = "no_esc_ctlc" 14 | Booleans[3] = "ceol_standout_glitch" 15 | Booleans[4] = "eat_newline_glitch" 16 | Booleans[5] = "erase_overstrike" 17 | Booleans[6] = "generic_type" 18 | Booleans[7] = "hard_copy" 19 | Booleans[8] = "has_meta_key" 20 | Booleans[9] = "has_status_line" 21 | Booleans[10] = "insert_null_glitch" 22 | Booleans[11] = "memory_above" 23 | Booleans[12] = "memory_below" 24 | Booleans[13] = "move_insert_mode" 25 | Booleans[14] = "move_standout_mode" 26 | Booleans[15] = "over_strike" 27 | Booleans[16] = "status_line_esc_ok" 28 | Booleans[17] = "dest_tabs_magic_smso" 29 | Booleans[18] = "tilde_glitch" 30 | Booleans[19] = "transparent_underline" 31 | Booleans[20] = "xon_xoff" 32 | Booleans[21] = "needs_xon_xoff" 33 | Booleans[22] = "prtr_silent" 34 | Booleans[23] = "hard_cursor" 35 | Booleans[24] = "non_rev_rmcup" 36 | Booleans[25] = "no_pad_char" 37 | Booleans[26] = "non_dest_scroll_region" 38 | Booleans[27] = "can_change" 39 | Booleans[28] = "back_color_erase" 40 | Booleans[29] = "hue_lightness_saturation" 41 | Booleans[30] = "col_addr_glitch" 42 | Booleans[31] = "cr_cancels_micro_mode" 43 | Booleans[32] = "has_print_wheel" 44 | Booleans[33] = "row_addr_glitch" 45 | Booleans[34] = "semi_auto_right_margin" 46 | Booleans[35] = "cpi_changes_res" 47 | Booleans[36] = "lpi_changes_res" 48 | Numbers[0] = "columns" 49 | Numbers[1] = "init_tabs" 50 | Numbers[2] = "lines" 51 | Numbers[3] = "lines_of_memory" 52 | Numbers[4] = "magic_cookie_glitch" 53 | Numbers[5] = "padding_baud_rate" 54 | Numbers[6] = "virtual_terminal" 55 | Numbers[7] = "width_status_line" 56 | Numbers[8] = "num_labels" 57 | Numbers[9] = "label_height" 58 | Numbers[10] = "label_width" 59 | Numbers[11] = "max_attributes" 60 | Numbers[12] = "maximum_windows" 61 | Numbers[13] = "max_colors" 62 | Numbers[14] = "max_pairs" 63 | Numbers[15] = "no_color_video" 64 | Numbers[16] = "buffer_capacity" 65 | Numbers[17] = "dot_vert_spacing" 66 | Numbers[18] = "dot_horz_spacing" 67 | Numbers[19] = "max_micro_address" 68 | Numbers[20] = "max_micro_jump" 69 | Numbers[21] = "micro_col_size" 70 | Numbers[22] = "micro_line_size" 71 | Numbers[23] = "number_of_pins" 72 | Numbers[24] = "output_res_char" 73 | Numbers[25] = "output_res_line" 74 | Numbers[26] = "output_res_horz_inch" 75 | Numbers[27] = "output_res_vert_inch" 76 | Numbers[28] = "print_rate" 77 | Numbers[29] = "wide_char_size" 78 | Numbers[30] = "buttons" 79 | Numbers[31] = "bit_image_entwining" 80 | Numbers[32] = "bit_image_type" 81 | Strings[0] = "back_tab" 82 | Strings[1] = "bell" 83 | Strings[2] = "carriage_return" 84 | Strings[3] = "change_scroll_region" 85 | Strings[4] = "clear_all_tabs" 86 | Strings[5] = "clear_screen" 87 | Strings[6] = "clr_eol" 88 | Strings[7] = "clr_eos" 89 | Strings[8] = "column_address" 90 | Strings[9] = "command_character" 91 | Strings[10] = "cursor_address" 92 | Strings[11] = "cursor_down" 93 | Strings[12] = "cursor_home" 94 | Strings[13] = "cursor_invisible" 95 | Strings[14] = "cursor_left" 96 | Strings[15] = "cursor_mem_address" 97 | Strings[16] = "cursor_normal" 98 | Strings[17] = "cursor_right" 99 | Strings[18] = "cursor_to_ll" 100 | Strings[19] = "cursor_up" 101 | Strings[20] = "cursor_visible" 102 | Strings[21] = "delete_character" 103 | Strings[22] = "delete_line" 104 | Strings[23] = "dis_status_line" 105 | Strings[24] = "down_half_line" 106 | Strings[25] = "enter_alt_charset_mode" 107 | Strings[26] = "enter_blink_mode" 108 | Strings[27] = "enter_bold_mode" 109 | Strings[28] = "enter_ca_mode" 110 | Strings[29] = "enter_delete_mode" 111 | Strings[30] = "enter_dim_mode" 112 | Strings[31] = "enter_insert_mode" 113 | Strings[32] = "enter_secure_mode" 114 | Strings[33] = "enter_protected_mode" 115 | Strings[34] = "enter_reverse_mode" 116 | Strings[35] = "enter_standout_mode" 117 | Strings[36] = "enter_underline_mode" 118 | Strings[37] = "erase_chars" 119 | Strings[38] = "exit_alt_charset_mode" 120 | Strings[39] = "exit_attribute_mode" 121 | Strings[40] = "exit_ca_mode" 122 | Strings[41] = "exit_delete_mode" 123 | Strings[42] = "exit_insert_mode" 124 | Strings[43] = "exit_standout_mode" 125 | Strings[44] = "exit_underline_mode" 126 | Strings[45] = "flash_screen" 127 | Strings[46] = "form_feed" 128 | Strings[47] = "from_status_line" 129 | Strings[48] = "init_1string" 130 | Strings[49] = "init_2string" 131 | Strings[50] = "init_3string" 132 | Strings[51] = "init_file" 133 | Strings[52] = "insert_character" 134 | Strings[53] = "insert_line" 135 | Strings[54] = "insert_padding" 136 | Strings[55] = "key_backspace" 137 | Strings[56] = "key_catab" 138 | Strings[57] = "key_clear" 139 | Strings[58] = "key_ctab" 140 | Strings[59] = "key_dc" 141 | Strings[60] = "key_dl" 142 | Strings[61] = "key_down" 143 | Strings[62] = "key_eic" 144 | Strings[63] = "key_eol" 145 | Strings[64] = "key_eos" 146 | Strings[65] = "key_f0" 147 | Strings[66] = "key_f1" 148 | Strings[67] = "key_f10" 149 | Strings[68] = "key_f2" 150 | Strings[69] = "key_f3" 151 | Strings[70] = "key_f4" 152 | Strings[71] = "key_f5" 153 | Strings[72] = "key_f6" 154 | Strings[73] = "key_f7" 155 | Strings[74] = "key_f8" 156 | Strings[75] = "key_f9" 157 | Strings[76] = "key_home" 158 | Strings[77] = "key_ic" 159 | Strings[78] = "key_il" 160 | Strings[79] = "key_left" 161 | Strings[80] = "key_ll" 162 | Strings[81] = "key_npage" 163 | Strings[82] = "key_ppage" 164 | Strings[83] = "key_right" 165 | Strings[84] = "key_sf" 166 | Strings[85] = "key_sr" 167 | Strings[86] = "key_stab" 168 | Strings[87] = "key_up" 169 | Strings[88] = "keypad_local" 170 | Strings[89] = "keypad_xmit" 171 | Strings[90] = "lab_f0" 172 | Strings[91] = "lab_f1" 173 | Strings[92] = "lab_f10" 174 | Strings[93] = "lab_f2" 175 | Strings[94] = "lab_f3" 176 | Strings[95] = "lab_f4" 177 | Strings[96] = "lab_f5" 178 | Strings[97] = "lab_f6" 179 | Strings[98] = "lab_f7" 180 | Strings[99] = "lab_f8" 181 | Strings[100] = "lab_f9" 182 | Strings[101] = "meta_off" 183 | Strings[102] = "meta_on" 184 | Strings[103] = "newline" 185 | Strings[104] = "pad_char" 186 | Strings[105] = "parm_dch" 187 | Strings[106] = "parm_delete_line" 188 | Strings[107] = "parm_down_cursor" 189 | Strings[108] = "parm_ich" 190 | Strings[109] = "parm_index" 191 | Strings[110] = "parm_insert_line" 192 | Strings[111] = "parm_left_cursor" 193 | Strings[112] = "parm_right_cursor" 194 | Strings[113] = "parm_rindex" 195 | Strings[114] = "parm_up_cursor" 196 | Strings[115] = "pkey_key" 197 | Strings[116] = "pkey_local" 198 | Strings[117] = "pkey_xmit" 199 | Strings[118] = "print_screen" 200 | Strings[119] = "prtr_off" 201 | Strings[120] = "prtr_on" 202 | Strings[121] = "repeat_char" 203 | Strings[122] = "reset_1string" 204 | Strings[123] = "reset_2string" 205 | Strings[124] = "reset_3string" 206 | Strings[125] = "reset_file" 207 | Strings[126] = "restore_cursor" 208 | Strings[127] = "row_address" 209 | Strings[128] = "save_cursor" 210 | Strings[129] = "scroll_forward" 211 | Strings[130] = "scroll_reverse" 212 | Strings[131] = "set_attributes" 213 | Strings[132] = "set_tab" 214 | Strings[133] = "set_window" 215 | Strings[134] = "tab" 216 | Strings[135] = "to_status_line" 217 | Strings[136] = "underline_char" 218 | Strings[137] = "up_half_line" 219 | Strings[138] = "init_prog" 220 | Strings[139] = "key_a1" 221 | Strings[140] = "key_a3" 222 | Strings[141] = "key_b2" 223 | Strings[142] = "key_c1" 224 | Strings[143] = "key_c3" 225 | Strings[144] = "prtr_non" 226 | Strings[145] = "char_padding" 227 | Strings[146] = "acs_chars" 228 | Strings[147] = "plab_norm" 229 | Strings[148] = "key_btab" 230 | Strings[149] = "enter_xon_mode" 231 | Strings[150] = "exit_xon_mode" 232 | Strings[151] = "enter_am_mode" 233 | Strings[152] = "exit_am_mode" 234 | Strings[153] = "xon_character" 235 | Strings[154] = "xoff_character" 236 | Strings[155] = "ena_acs" 237 | Strings[156] = "label_on" 238 | Strings[157] = "label_off" 239 | Strings[158] = "key_beg" 240 | Strings[159] = "key_cancel" 241 | Strings[160] = "key_close" 242 | Strings[161] = "key_command" 243 | Strings[162] = "key_copy" 244 | Strings[163] = "key_create" 245 | Strings[164] = "key_end" 246 | Strings[165] = "key_enter" 247 | Strings[166] = "key_exit" 248 | Strings[167] = "key_find" 249 | Strings[168] = "key_help" 250 | Strings[169] = "key_mark" 251 | Strings[170] = "key_message" 252 | Strings[171] = "key_move" 253 | Strings[172] = "key_next" 254 | Strings[173] = "key_open" 255 | Strings[174] = "key_options" 256 | Strings[175] = "key_previous" 257 | Strings[176] = "key_print" 258 | Strings[177] = "key_redo" 259 | Strings[178] = "key_reference" 260 | Strings[179] = "key_refresh" 261 | Strings[180] = "key_replace" 262 | Strings[181] = "key_restart" 263 | Strings[182] = "key_resume" 264 | Strings[183] = "key_save" 265 | Strings[184] = "key_suspend" 266 | Strings[185] = "key_undo" 267 | Strings[186] = "key_sbeg" 268 | Strings[187] = "key_scancel" 269 | Strings[188] = "key_scommand" 270 | Strings[189] = "key_scopy" 271 | Strings[190] = "key_screate" 272 | Strings[191] = "key_sdc" 273 | Strings[192] = "key_sdl" 274 | Strings[193] = "key_select" 275 | Strings[194] = "key_send" 276 | Strings[195] = "key_seol" 277 | Strings[196] = "key_sexit" 278 | Strings[197] = "key_sfind" 279 | Strings[198] = "key_shelp" 280 | Strings[199] = "key_shome" 281 | Strings[200] = "key_sic" 282 | Strings[201] = "key_sleft" 283 | Strings[202] = "key_smessage" 284 | Strings[203] = "key_smove" 285 | Strings[204] = "key_snext" 286 | Strings[205] = "key_soptions" 287 | Strings[206] = "key_sprevious" 288 | Strings[207] = "key_sprint" 289 | Strings[208] = "key_sredo" 290 | Strings[209] = "key_sreplace" 291 | Strings[210] = "key_sright" 292 | Strings[211] = "key_srsume" 293 | Strings[212] = "key_ssave" 294 | Strings[213] = "key_ssuspend" 295 | Strings[214] = "key_sundo" 296 | Strings[215] = "req_for_input" 297 | Strings[216] = "key_f11" 298 | Strings[217] = "key_f12" 299 | Strings[218] = "key_f13" 300 | Strings[219] = "key_f14" 301 | Strings[220] = "key_f15" 302 | Strings[221] = "key_f16" 303 | Strings[222] = "key_f17" 304 | Strings[223] = "key_f18" 305 | Strings[224] = "key_f19" 306 | Strings[225] = "key_f20" 307 | Strings[226] = "key_f21" 308 | Strings[227] = "key_f22" 309 | Strings[228] = "key_f23" 310 | Strings[229] = "key_f24" 311 | Strings[230] = "key_f25" 312 | Strings[231] = "key_f26" 313 | Strings[232] = "key_f27" 314 | Strings[233] = "key_f28" 315 | Strings[234] = "key_f29" 316 | Strings[235] = "key_f30" 317 | Strings[236] = "key_f31" 318 | Strings[237] = "key_f32" 319 | Strings[238] = "key_f33" 320 | Strings[239] = "key_f34" 321 | Strings[240] = "key_f35" 322 | Strings[241] = "key_f36" 323 | Strings[242] = "key_f37" 324 | Strings[243] = "key_f38" 325 | Strings[244] = "key_f39" 326 | Strings[245] = "key_f40" 327 | Strings[246] = "key_f41" 328 | Strings[247] = "key_f42" 329 | Strings[248] = "key_f43" 330 | Strings[249] = "key_f44" 331 | Strings[250] = "key_f45" 332 | Strings[251] = "key_f46" 333 | Strings[252] = "key_f47" 334 | Strings[253] = "key_f48" 335 | Strings[254] = "key_f49" 336 | Strings[255] = "key_f50" 337 | Strings[256] = "key_f51" 338 | Strings[257] = "key_f52" 339 | Strings[258] = "key_f53" 340 | Strings[259] = "key_f54" 341 | Strings[260] = "key_f55" 342 | Strings[261] = "key_f56" 343 | Strings[262] = "key_f57" 344 | Strings[263] = "key_f58" 345 | Strings[264] = "key_f59" 346 | Strings[265] = "key_f60" 347 | Strings[266] = "key_f61" 348 | Strings[267] = "key_f62" 349 | Strings[268] = "key_f63" 350 | Strings[269] = "clr_bol" 351 | Strings[270] = "clear_margins" 352 | Strings[271] = "set_left_margin" 353 | Strings[272] = "set_right_margin" 354 | Strings[273] = "label_format" 355 | Strings[274] = "set_clock" 356 | Strings[275] = "display_clock" 357 | Strings[276] = "remove_clock" 358 | Strings[277] = "create_window" 359 | Strings[278] = "goto_window" 360 | Strings[279] = "hangup" 361 | Strings[280] = "dial_phone" 362 | Strings[281] = "quick_dial" 363 | Strings[282] = "tone" 364 | Strings[283] = "pulse" 365 | Strings[284] = "flash_hook" 366 | Strings[285] = "fixed_pause" 367 | Strings[286] = "wait_tone" 368 | Strings[287] = "user0" 369 | Strings[288] = "user1" 370 | Strings[289] = "user2" 371 | Strings[290] = "user3" 372 | Strings[291] = "user4" 373 | Strings[292] = "user5" 374 | Strings[293] = "user6" 375 | Strings[294] = "user7" 376 | Strings[295] = "user8" 377 | Strings[296] = "user9" 378 | Strings[297] = "orig_pair" 379 | Strings[298] = "orig_colors" 380 | Strings[299] = "initialize_color" 381 | Strings[300] = "initialize_pair" 382 | Strings[301] = "set_color_pair" 383 | Strings[302] = "set_foreground" 384 | Strings[303] = "set_background" 385 | Strings[304] = "change_char_pitch" 386 | Strings[305] = "change_line_pitch" 387 | Strings[306] = "change_res_horz" 388 | Strings[307] = "change_res_vert" 389 | Strings[308] = "define_char" 390 | Strings[309] = "enter_doublewide_mode" 391 | Strings[310] = "enter_draft_quality" 392 | Strings[311] = "enter_italics_mode" 393 | Strings[312] = "enter_leftward_mode" 394 | Strings[313] = "enter_micro_mode" 395 | Strings[314] = "enter_near_letter_quality" 396 | Strings[315] = "enter_normal_quality" 397 | Strings[316] = "enter_shadow_mode" 398 | Strings[317] = "enter_subscript_mode" 399 | Strings[318] = "enter_superscript_mode" 400 | Strings[319] = "enter_upward_mode" 401 | Strings[320] = "exit_doublewide_mode" 402 | Strings[321] = "exit_italics_mode" 403 | Strings[322] = "exit_leftward_mode" 404 | Strings[323] = "exit_micro_mode" 405 | Strings[324] = "exit_shadow_mode" 406 | Strings[325] = "exit_subscript_mode" 407 | Strings[326] = "exit_superscript_mode" 408 | Strings[327] = "exit_upward_mode" 409 | Strings[328] = "micro_column_address" 410 | Strings[329] = "micro_down" 411 | Strings[330] = "micro_left" 412 | Strings[331] = "micro_right" 413 | Strings[332] = "micro_row_address" 414 | Strings[333] = "micro_up" 415 | Strings[334] = "order_of_pins" 416 | Strings[335] = "parm_down_micro" 417 | Strings[336] = "parm_left_micro" 418 | Strings[337] = "parm_right_micro" 419 | Strings[338] = "parm_up_micro" 420 | Strings[339] = "select_char_set" 421 | Strings[340] = "set_bottom_margin" 422 | Strings[341] = "set_bottom_margin_parm" 423 | Strings[342] = "set_left_margin_parm" 424 | Strings[343] = "set_right_margin_parm" 425 | Strings[344] = "set_top_margin" 426 | Strings[345] = "set_top_margin_parm" 427 | Strings[346] = "start_bit_image" 428 | Strings[347] = "start_char_set_def" 429 | Strings[348] = "stop_bit_image" 430 | Strings[349] = "stop_char_set_def" 431 | Strings[350] = "subscript_characters" 432 | Strings[351] = "superscript_characters" 433 | Strings[352] = "these_cause_cr" 434 | Strings[353] = "zero_motion" 435 | Strings[354] = "char_set_names" 436 | Strings[355] = "key_mouse" 437 | Strings[356] = "mouse_info" 438 | Strings[357] = "req_mouse_pos" 439 | Strings[358] = "get_mouse" 440 | Strings[359] = "set_a_foreground" 441 | Strings[360] = "set_a_background" 442 | Strings[361] = "pkey_plab" 443 | Strings[362] = "device_type" 444 | Strings[363] = "code_set_init" 445 | Strings[364] = "set0_des_seq" 446 | Strings[365] = "set1_des_seq" 447 | Strings[366] = "set2_des_seq" 448 | Strings[367] = "set3_des_seq" 449 | Strings[368] = "set_lr_margin" 450 | Strings[369] = "set_tb_margin" 451 | Strings[370] = "bit_image_repeat" 452 | Strings[371] = "bit_image_newline" 453 | Strings[372] = "bit_image_carriage_return" 454 | Strings[373] = "color_names" 455 | Strings[374] = "define_bit_image_region" 456 | Strings[375] = "end_bit_image_region" 457 | Strings[376] = "set_color_band" 458 | Strings[377] = "set_page_length" 459 | Strings[378] = "display_pc_char" 460 | Strings[379] = "enter_pc_charset_mode" 461 | Strings[380] = "exit_pc_charset_mode" 462 | Strings[381] = "enter_scancode_mode" 463 | Strings[382] = "exit_scancode_mode" 464 | Strings[383] = "pc_term_options" 465 | Strings[384] = "scancode_escape" 466 | Strings[385] = "alt_scancode_esc" 467 | Strings[386] = "enter_horizontal_hl_mode" 468 | Strings[387] = "enter_left_hl_mode" 469 | Strings[388] = "enter_low_hl_mode" 470 | Strings[389] = "enter_right_hl_mode" 471 | Strings[390] = "enter_top_hl_mode" 472 | Strings[391] = "enter_vertical_hl_mode" 473 | Strings[392] = "set_a_attributes" 474 | Strings[393] = "set_pglen_inch" 475 | 476 | -- internal caps 477 | Strings[394] = "termcap_init2" 478 | Strings[395] = "termcap_reset" 479 | Numbers[33] = "magic_cookie_glitch_ul" 480 | Booleans[37] = "backspaces_with_bs" 481 | Booleans[38] = "crt_no_scrolling" 482 | Booleans[39] = "no_correctly_working_cr" 483 | Numbers[34] = "carriage_return_delay" 484 | Numbers[35] = "new_line_delay" 485 | Strings[396] = "linefeed_if_not_lf" 486 | Strings[397] = "backspace_if_not_bs" 487 | Booleans[40] = "gnu_has_meta_key" 488 | Booleans[41] = "linefeed_is_newline" 489 | Numbers[36] = "backspace_delay" 490 | Numbers[37] = "horizontal_tab_delay" 491 | Numbers[38] = "number_of_function_keys" 492 | Strings[398] = "other_non_function_keys" 493 | Strings[399] = "arrow_key_map" 494 | Booleans[42] = "has_hardware_tabs" 495 | Booleans[43] = "return_does_clr_eol" 496 | Strings[400] = "acs_ulcorner" 497 | Strings[401] = "acs_llcorner" 498 | Strings[402] = "acs_urcorner" 499 | Strings[403] = "acs_lrcorner" 500 | Strings[404] = "acs_ltee" 501 | Strings[405] = "acs_rtee" 502 | Strings[406] = "acs_btee" 503 | Strings[407] = "acs_ttee" 504 | Strings[408] = "acs_hline" 505 | Strings[409] = "acs_vline" 506 | Strings[410] = "acs_plus" 507 | Strings[411] = "memory_lock" 508 | Strings[412] = "memory_unlock" 509 | Strings[413] = "box_chars_1" 510 | 511 | local short_to_long = { 512 | -- Boolean 513 | bw = "auto_left_margin"; 514 | am = "auto_right_margin"; 515 | bce = "back_color_erase"; 516 | ccc = "can_change"; 517 | xhp = "ceol_standout_glitch"; 518 | xhpa = "col_addr_glitch"; 519 | cpix = "cpi_changes_res"; 520 | crxm = "cr_cancels_micro_mode"; 521 | xt = "dest_tabs_magic_smso"; 522 | xenl = "eat_newline_glitch"; 523 | eo = "erase_overstrike"; 524 | gn = "generic_type"; 525 | hc = "hard_copy"; 526 | chts = "hard_cursor"; 527 | km = "has_meta_key"; 528 | daisy = "has_print_wheel"; 529 | hs = "has_status_line"; 530 | hls = "hue_lightness_saturation"; 531 | ["in"] = "insert_null_glitch"; 532 | lpix = "lpi_changes_res"; 533 | da = "memory_above"; 534 | db = "memory_below"; 535 | mir = "move_insert_mode"; 536 | msgr = "move_standout_mode"; 537 | nxon = "needs_xon_xoff"; 538 | xsb = "no_esc_ctlc"; 539 | npc = "no_pad_char"; 540 | ndscr = "non_dest_scroll_region"; 541 | nrrmc = "non_rev_rmcup"; 542 | os = "over_strike"; 543 | mc5i = "prtr_silent"; 544 | xvpa = "row_addr_glitch"; 545 | sam = "semi_auto_right_margin"; 546 | eslok = "status_line_esc_ok"; 547 | hz = "tilde_glitch"; 548 | ul = "transparent_underline"; 549 | xon = "xon_xoff"; 550 | 551 | -- Numeric 552 | cols = "columns"; 553 | it = "init_tabs"; 554 | lh = "label_height"; 555 | lw = "label_width"; 556 | lines = "lines"; 557 | lm = "lines_of_memory"; 558 | xmc = "magic_cookie_glitch"; 559 | ma = "max_attributes"; 560 | colors = "max_colors"; 561 | pairs = "max_pairs"; 562 | wnum = "maximum_windows"; 563 | ncv = "no_color_video"; 564 | nlab = "num_labels"; 565 | pb = "padding_baud_rate"; 566 | vt = "virtual_terminal"; 567 | wsl = "width_status_line"; 568 | 569 | -- Non-SVr4.0 Numeric 570 | bitwin = "bit_image_entwining"; 571 | bitype = "bit_image_type"; 572 | bufsz = "buffer_capacity"; 573 | btns = "buttons"; 574 | spinh = "dot_horz_spacing"; 575 | spinv = "dot_vert_spacing"; 576 | maddr = "max_micro_address"; 577 | mjump = "max_micro_jump"; 578 | mcs = "micro_col_size"; 579 | mls = "micro_line_size"; 580 | npins = "number_of_pins"; 581 | orc = "output_res_char"; 582 | orhi = "output_res_horz_inch"; 583 | orl = "output_res_line"; 584 | orvi = "output_res_vert_inch"; 585 | cps = "print_rate"; 586 | widcs = "wide_char_size"; 587 | 588 | -- String 589 | acsc = "acs_chars"; 590 | cbt = "back_tab"; 591 | bel = "bell"; 592 | cr = "carriage_return"; 593 | cpi = "change_char_pitch"; 594 | lpi = "change_line_pitch"; 595 | chr = "change_res_horz"; 596 | cvr = "change_res_vert"; 597 | csr = "change_scroll_region"; 598 | rmp = "char_padding"; 599 | tbc = "clear_all_tabs"; 600 | mgc = "clear_margins"; 601 | clear = "clear_screen"; 602 | el1 = "clr_bol"; 603 | el = "clr_eol"; 604 | ed = "clr_eos"; 605 | hpa = "column_address"; 606 | cmdch = "command_character"; 607 | cwin = "create_window"; 608 | cup = "cursor_address"; 609 | cud1 = "cursor_down"; 610 | home = "cursor_home"; 611 | civis = "cursor_invisible"; 612 | cub1 = "cursor_left"; 613 | mrcup = "cursor_mem_address"; 614 | cnorm = "cursor_normal"; 615 | cuf1 = "cursor_right"; 616 | ll = "cursor_to_ll"; 617 | cuu1 = "cursor_up"; 618 | cvvis = "cursor_visible"; 619 | defc = "define_char"; 620 | dch1 = "delete_character"; 621 | dl1 = "delete_line"; 622 | dial = "dial_phone"; 623 | dsl = "dis_status_line"; 624 | dclk = "display_clock"; 625 | hd = "down_half_line"; 626 | enacs = "ena_acs"; 627 | smacs = "enter_alt_charset_mode"; 628 | smam = "enter_am_mode"; 629 | blink = "enter_blink_mode"; 630 | bold = "enter_bold_mode"; 631 | smcup = "enter_ca_mode"; 632 | smdc = "enter_delete_mode"; 633 | dim = "enter_dim_mode"; 634 | swidm = "enter_doublewide_mode"; 635 | sdrfq = "enter_draft_quality"; 636 | smir = "enter_insert_mode"; 637 | sitm = "enter_italics_mode"; 638 | slm = "enter_leftward_mode"; 639 | smicm = "enter_micro_mode"; 640 | snlq = "enter_near_letter_quality"; 641 | snrmq = "enter_normal_quality"; 642 | prot = "enter_protected_mode"; 643 | rev = "enter_reverse_mode"; 644 | invis = "enter_secure_mode"; 645 | sshm = "enter_shadow_mode"; 646 | smso = "enter_standout_mode"; 647 | ssubm = "enter_subscript_mode"; 648 | ssupm = "enter_superscript_mode"; 649 | smul = "enter_underline_mode"; 650 | sum = "enter_upward_mode"; 651 | smxon = "enter_xon_mode"; 652 | ech = "erase_chars"; 653 | rmacs = "exit_alt_charset_mode"; 654 | rmam = "exit_am_mode"; 655 | sgr0 = "exit_attribute_mode"; 656 | rmcup = "exit_ca_mode"; 657 | rmdc = "exit_delete_mode"; 658 | rwidm = "exit_doublewide_mode"; 659 | rmir = "exit_insert_mode"; 660 | ritm = "exit_italics_mode"; 661 | rlm = "exit_leftward_mode"; 662 | rmicm = "exit_micro_mode"; 663 | rshm = "exit_shadow_mode"; 664 | rmso = "exit_standout_mode"; 665 | rsubm = "exit_subscript_mode"; 666 | rsupm = "exit_superscript_mode"; 667 | rmul = "exit_underline_mode"; 668 | rum = "exit_upward_mode"; 669 | rmxon = "exit_xon_mode"; 670 | pause = "fixed_pause"; 671 | hook = "flash_hook"; 672 | flash = "flash_screen"; 673 | ff = "form_feed"; 674 | fsl = "from_status_line"; 675 | wingo = "goto_window"; 676 | hup = "hangup"; 677 | is1 = "init_1string"; 678 | is2 = "init_2string"; 679 | is3 = "init_3string"; 680 | ["if"] = "init_file"; 681 | iprog = "init_prog"; 682 | initc = "initialize_color"; 683 | initp = "initialize_pair"; 684 | ich1 = "insert_character"; 685 | il1 = "insert_line"; 686 | ip = "insert_padding"; 687 | ka1 = "key_a1"; 688 | ka3 = "key_a3"; 689 | kb2 = "key_b2"; 690 | kbs = "key_backspace"; 691 | kbeg = "key_beg"; 692 | kcbt = "key_btab"; 693 | kc1 = "key_c1"; 694 | kc3 = "key_c3"; 695 | kcan = "key_cancel"; 696 | ktbc = "key_catab"; 697 | kclr = "key_clear"; 698 | kclo = "key_close"; 699 | kcmd = "key_command"; 700 | kcpy = "key_copy"; 701 | kcrt = "key_create"; 702 | kctab = "key_ctab"; 703 | kdch1 = "key_dc"; 704 | kdl1 = "key_dl"; 705 | kcud1 = "key_down"; 706 | krmir = "key_eic"; 707 | kend = "key_end"; 708 | kent = "key_enter"; 709 | kel = "key_eol"; 710 | ked = "key_eos"; 711 | kext = "key_exit"; 712 | kf0 = "key_f0"; 713 | kf1 = "key_f1"; 714 | kf10 = "key_f10"; 715 | kf11 = "key_f11"; 716 | kf12 = "key_f12"; 717 | kf13 = "key_f13"; 718 | kf14 = "key_f14"; 719 | kf15 = "key_f15"; 720 | kf16 = "key_f16"; 721 | kf17 = "key_f17"; 722 | kf18 = "key_f18"; 723 | kf19 = "key_f19"; 724 | kf2 = "key_f2"; 725 | kf20 = "key_f20"; 726 | kf21 = "key_f21"; 727 | kf22 = "key_f22"; 728 | kf23 = "key_f23"; 729 | kf24 = "key_f24"; 730 | kf25 = "key_f25"; 731 | kf26 = "key_f26"; 732 | kf27 = "key_f27"; 733 | kf28 = "key_f28"; 734 | kf29 = "key_f29"; 735 | kf3 = "key_f3"; 736 | kf30 = "key_f30"; 737 | kf31 = "key_f31"; 738 | kf32 = "key_f32"; 739 | kf33 = "key_f33"; 740 | kf34 = "key_f34"; 741 | kf35 = "key_f35"; 742 | kf36 = "key_f36"; 743 | kf37 = "key_f37"; 744 | kf38 = "key_f38"; 745 | kf39 = "key_f39"; 746 | kf4 = "key_f4"; 747 | kf40 = "key_f40"; 748 | kf41 = "key_f41"; 749 | kf42 = "key_f42"; 750 | kf43 = "key_f43"; 751 | kf44 = "key_f44"; 752 | kf45 = "key_f45"; 753 | kf46 = "key_f46"; 754 | kf47 = "key_f47"; 755 | kf48 = "key_f48"; 756 | kf49 = "key_f49"; 757 | kf5 = "key_f5"; 758 | kf50 = "key_f50"; 759 | kf51 = "key_f51"; 760 | kf52 = "key_f52"; 761 | kf53 = "key_f53"; 762 | kf54 = "key_f54"; 763 | kf55 = "key_f55"; 764 | kf56 = "key_f56"; 765 | kf57 = "key_f57"; 766 | kf58 = "key_f58"; 767 | kf59 = "key_f59"; 768 | kf6 = "key_f6"; 769 | kf60 = "key_f60"; 770 | kf61 = "key_f61"; 771 | kf62 = "key_f62"; 772 | kf63 = "key_f63"; 773 | kf7 = "key_f7"; 774 | kf8 = "key_f8"; 775 | kf9 = "key_f9"; 776 | kfnd = "key_find"; 777 | khlp = "key_help"; 778 | khome = "key_home"; 779 | kich1 = "key_ic"; 780 | kil1 = "key_il"; 781 | kcub1 = "key_left"; 782 | kll = "key_ll"; 783 | kmrk = "key_mark"; 784 | kmsg = "key_message"; 785 | kmov = "key_move"; 786 | knxt = "key_next"; 787 | knp = "key_npage"; 788 | kopn = "key_open"; 789 | kopt = "key_options"; 790 | kpp = "key_ppage"; 791 | kprv = "key_previous"; 792 | kprt = "key_print"; 793 | krdo = "key_redo"; 794 | kref = "key_reference"; 795 | krfr = "key_refresh"; 796 | krpl = "key_replace"; 797 | krst = "key_restart"; 798 | kres = "key_resume"; 799 | kcuf1 = "key_right"; 800 | ksav = "key_save"; 801 | kBEG = "key_sbeg"; 802 | kCAN = "key_scancel"; 803 | kCMD = "key_scommand"; 804 | kCPY = "key_scopy"; 805 | kCRT = "key_screate"; 806 | kDC = "key_sdc"; 807 | kDL = "key_sdl"; 808 | kslt = "key_select"; 809 | kEND = "key_send"; 810 | kEOL = "key_seol"; 811 | kEXT = "key_sexit"; 812 | kind = "key_sf"; 813 | kFND = "key_sfind"; 814 | kHLP = "key_shelp"; 815 | kHOM = "key_shome"; 816 | kIC = "key_sic"; 817 | kLFT = "key_sleft"; 818 | kMSG = "key_smessage"; 819 | kMOV = "key_smove"; 820 | kNXT = "key_snext"; 821 | kOPT = "key_soptions"; 822 | kPRV = "key_sprevious"; 823 | kPRT = "key_sprint"; 824 | kri = "key_sr"; 825 | kRDO = "key_sredo"; 826 | kRPL = "key_sreplace"; 827 | kRIT = "key_sright"; 828 | kRES = "key_srsume"; 829 | kSAV = "key_ssave"; 830 | kSPD = "key_ssuspend"; 831 | khts = "key_stab"; 832 | kUND = "key_sundo"; 833 | kspd = "key_suspend"; 834 | kund = "key_undo"; 835 | kcuu1 = "key_up"; 836 | rmkx = "keypad_local"; 837 | smkx = "keypad_xmit"; 838 | lf0 = "lab_f0"; 839 | lf1 = "lab_f1"; 840 | lf10 = "lab_f10"; 841 | lf2 = "lab_f2"; 842 | lf3 = "lab_f3"; 843 | lf4 = "lab_f4"; 844 | lf5 = "lab_f5"; 845 | lf6 = "lab_f6"; 846 | lf7 = "lab_f7"; 847 | lf8 = "lab_f8"; 848 | lf9 = "lab_f9"; 849 | fln = "label_format"; 850 | rmln = "label_off"; 851 | smln = "label_on"; 852 | rmm = "meta_off"; 853 | smm = "meta_on"; 854 | mhpa = "micro_column_address"; 855 | mcud1 = "micro_down"; 856 | mcub1 = "micro_left"; 857 | mcuf1 = "micro_right"; 858 | mvpa = "micro_row_address"; 859 | mcuu1 = "micro_up"; 860 | nel = "newline"; 861 | porder = "order_of_pins"; 862 | oc = "orig_colors"; 863 | op = "orig_pair"; 864 | pad = "pad_char"; 865 | dch = "parm_dch"; 866 | dl = "parm_delete_line"; 867 | cud = "parm_down_cursor"; 868 | mcud = "parm_down_micro"; 869 | ich = "parm_ich"; 870 | indn = "parm_index"; 871 | il = "parm_insert_line"; 872 | cub = "parm_left_cursor"; 873 | mcub = "parm_left_micro"; 874 | cuf = "parm_right_cursor"; 875 | mcuf = "parm_right_micro"; 876 | rin = "parm_rindex"; 877 | cuu = "parm_up_cursor"; 878 | mcuu = "parm_up_micro"; 879 | pfkey = "pkey_key"; 880 | pfloc = "pkey_local"; 881 | pfx = "pkey_xmit"; 882 | pln = "plab_norm"; 883 | mc0 = "print_screen"; 884 | mc5p = "prtr_non"; 885 | mc4 = "prtr_off"; 886 | mc5 = "prtr_on"; 887 | pulse = "pulse"; 888 | qdial = "quick_dial"; 889 | rmclk = "remove_clock"; 890 | rep = "repeat_char"; 891 | rfi = "req_for_input"; 892 | rs1 = "reset_1string"; 893 | rs2 = "reset_2string"; 894 | rs3 = "reset_3string"; 895 | rf = "reset_file"; 896 | rc = "restore_cursor"; 897 | vpa = "row_address"; 898 | sc = "save_cursor"; 899 | ind = "scroll_forward"; 900 | ri = "scroll_reverse"; 901 | scs = "select_char_set"; 902 | sgr = "set_attributes"; 903 | setb = "set_background"; 904 | smgb = "set_bottom_margin"; 905 | smgbp = "set_bottom_margin_parm"; 906 | sclk = "set_clock"; 907 | scp = "set_color_pair"; 908 | setf = "set_foreground"; 909 | smgl = "set_left_margin"; 910 | smglp = "set_left_margin_parm"; 911 | smgr = "set_right_margin"; 912 | smgrp = "set_right_margin_parm"; 913 | hts = "set_tab"; 914 | smgt = "set_top_margin"; 915 | smgtp = "set_top_margin_parm"; 916 | wind = "set_window"; 917 | sbim = "start_bit_image"; 918 | scsd = "start_char_set_def"; 919 | rbim = "stop_bit_image"; 920 | rcsd = "stop_char_set_def"; 921 | subcs = "subscript_characters"; 922 | supcs = "superscript_characters"; 923 | ht = "tab"; 924 | docr = "these_cause_cr"; 925 | tsl = "to_status_line"; 926 | tone = "tone"; 927 | uc = "underline_char"; 928 | hu = "up_half_line"; 929 | u0 = "user0"; 930 | u1 = "user1"; 931 | u2 = "user2"; 932 | u3 = "user3"; 933 | u4 = "user4"; 934 | u5 = "user5"; 935 | u6 = "user6"; 936 | u7 = "user7"; 937 | u8 = "user8"; 938 | u9 = "user9"; 939 | wait = "wait_tone"; 940 | xoffc = "xoff_character"; 941 | xonc = "xon_character"; 942 | zerom = "zero_motion"; 943 | 944 | -- Non-SVr4.0 String 945 | scesa = "alt_scancode_esc"; 946 | bicr = "bit_image_carriage_return"; 947 | binel = "bit_image_newline"; 948 | birep = "bit_image_repeat"; 949 | csnm = "char_set_names"; 950 | csin = "code_set_init"; 951 | colornm = "color_names"; 952 | defbi = "define_bit_image_region"; 953 | devt = "device_type"; 954 | dispc = "display_pc_char"; 955 | endbi = "end_bit_image_region"; 956 | smpch = "enter_pc_charset_mode"; 957 | smsc = "enter_scancode_mode"; 958 | rmpch = "exit_pc_charset_mode"; 959 | rmsc = "exit_scancode_mode"; 960 | getm = "get_mouse"; 961 | kmous = "key_mouse"; 962 | minfo = "mouse_info"; 963 | pctrm = "pc_term_options"; 964 | pfxl = "pkey_plab"; 965 | reqmp = "req_mouse_pos"; 966 | scesc = "scancode_escape"; 967 | s0ds = "set0_des_seq"; 968 | s1ds = "set1_des_seq"; 969 | s2ds = "set2_des_seq"; 970 | s3ds = "set3_des_seq"; 971 | setab = "set_a_background"; 972 | setaf = "set_a_foreground"; 973 | setcolor = "set_color_band"; 974 | smglr = "set_lr_margin"; 975 | slines = "set_page_length"; 976 | smgtb = "set_tb_margin"; 977 | 978 | -- XSI 979 | ehhlm = "enter_horizontal_hl_mode"; 980 | elhlm = "enter_left_hl_mode"; 981 | elohlm = "enter_low_hl_mode"; 982 | erhlm = "enter_right_hl_mode"; 983 | ethlm = "enter_top_hl_mode"; 984 | evhlm = "enter_vertical_hl_mode"; 985 | sgr1 = "set_a_attributes"; 986 | slength = "set_pglen_inch"; 987 | } 988 | 989 | local caps_mt = { 990 | __name = "tui.terminfo capabilities"; 991 | } 992 | 993 | function caps_mt:__index(k) 994 | k = short_to_long[k] 995 | if k ~= nil then 996 | return rawget(self, k) 997 | end 998 | end 999 | 1000 | local function read_compiled_terminfo(contents) 1001 | local magic, name_size, n_booleans, n_numbers, n_offsets, s_string, pos = sunpack(" 1 then 1005 | for name in contents:sub(pos, pos-2+name_size):gmatch("[^|]+") do 1006 | table.insert(names, name) 1007 | end 1008 | pos = pos + name_size 1009 | end 1010 | local caps = setmetatable({}, caps_mt) 1011 | if n_booleans ~= 65535 then 1012 | for i=0, n_booleans-1 do 1013 | if contents:byte(pos+i) ~= 0 then 1014 | caps[Booleans[i]] = true 1015 | end 1016 | end 1017 | pos = pos + n_booleans 1018 | end 1019 | -- pad to even offset 1020 | if pos % 2 == 0 then 1021 | assert(contents:byte(pos) == 0) 1022 | pos = pos + 1 1023 | end 1024 | if n_numbers ~= 65535 then 1025 | for i=0, n_numbers-1 do 1026 | local n = sunpack("" then 177 | local y = npop() 178 | local x = npop() 179 | push((x > y) and 1 or 0) 180 | pos = s + 1 181 | elseif c == "A" then 182 | local y = npop() ~= 0 183 | local x = npop() ~= 0 184 | push((x and y) and 1 or 0) 185 | pos = s + 1 186 | elseif c == "O" then 187 | local y = npop() ~= 0 188 | local x = npop() ~= 0 189 | push((x or y) and 1 or 0) 190 | pos = s + 1 191 | elseif c == "!" then 192 | push((npop() == 0) and 1 or 0) 193 | pos = s + 1 194 | elseif c == "~" then 195 | push(bnot(npop())) 196 | pos = s + 1 197 | elseif c == "i" then 198 | if params[1] == 0 then 199 | params[1] = 1 200 | end 201 | if params[2] == 0 then 202 | params[2] = 1 203 | end 204 | pos = s + 1 205 | elseif c == "?" then 206 | pos = s + 1 207 | elseif c == "t" then 208 | pos = s + 1 209 | local x = npop() 210 | if x == 0 then 211 | -- skip through to after %e or %; 212 | local level = 0 213 | while true do 214 | local t, e = str:match("%%([e%;%?])()", pos) 215 | if t == nil then 216 | break 217 | end 218 | pos = e 219 | if t == "?" then 220 | level = level + 1 221 | elseif t == ";" then 222 | if level > 0 then 223 | level = level - 1 224 | else 225 | break 226 | end 227 | elseif t == "e" and level == 0 then 228 | break 229 | end 230 | end 231 | end 232 | elseif c == "e" then 233 | pos = s + 1 234 | -- skip through to after %; 235 | local level = 0 236 | while true do 237 | local t, e = str:match("%%([%;%?])()", pos) 238 | if t == nil then 239 | break 240 | end 241 | pos = e 242 | if t == "?" then 243 | level = level + 1 244 | elseif t == ";" then 245 | if level > 0 then 246 | level = level - 1 247 | else 248 | break 249 | end 250 | end 251 | end 252 | elseif c == ";" then 253 | pos = s + 1 254 | else 255 | -- ncurses allows 'c' and 's' here in addition to documented ones 256 | local what, want_type, e = str:match("^%:?([%-%+%# ]?%d*%.?%d*([cdoxXs]))()", s) 257 | if what then 258 | local v 259 | if want_type == "s" then 260 | v = spop() 261 | else 262 | v = npop() 263 | end 264 | res_n = res_n + 1 265 | res[res_n] = string.format("%"..what, v) 266 | pos = e 267 | else 268 | pos = s + 1 269 | end 270 | end 271 | end 272 | end 273 | return table.concat(res, "", 1, res_n) 274 | end 275 | 276 | return { 277 | tparm = tparm; 278 | } 279 | -------------------------------------------------------------------------------- /tui/tput.lua: -------------------------------------------------------------------------------- 1 | local tui_terminfo = require "tui.terminfo" 2 | local tui_util = require "tui.util" 3 | 4 | local default_terminfo = tui_terminfo.find() 5 | 6 | local function init(fd, terminfo) 7 | if fd == nil then 8 | fd = io.stdout 9 | end 10 | if terminfo == nil then 11 | terminfo = default_terminfo 12 | end 13 | local str = { 14 | terminfo.init_prog or ""; 15 | terminfo.init_1string or ""; 16 | terminfo.init_2string or ""; 17 | terminfo.clear_margins or ""; 18 | terminfo.set_left_margin or ""; 19 | terminfo.set_right_margin or ""; 20 | terminfo.clear_all_tabs or ""; 21 | terminfo.set_tab or ""; 22 | ""; 23 | terminfo.init_3string or ""; 24 | } 25 | local file = terminfo.init_file 26 | if file then 27 | str[9] = tui_util.read_file(file) or "" 28 | end 29 | return fd:write(table.concat(str)) 30 | end 31 | 32 | local function reset(fd, terminfo) 33 | if fd == nil then 34 | fd = io.stdout 35 | end 36 | if terminfo == nil then 37 | terminfo = default_terminfo 38 | end 39 | local str = { 40 | terminfo.init_prog or ""; 41 | terminfo.reset_1string or terminfo.init_1string or ""; 42 | terminfo.reset_2string or terminfo.init_2string or ""; 43 | terminfo.clear_margins or ""; 44 | terminfo.set_left_margin or ""; 45 | terminfo.set_right_margin or ""; 46 | terminfo.clear_all_tabs or ""; 47 | terminfo.set_tab or ""; 48 | ""; 49 | terminfo.reset_3string or terminfo.init_3string or ""; 50 | } 51 | local file = terminfo.reset_file or terminfo.init_file 52 | if file then 53 | str[9] = tui_util.read_file(file) or "" 54 | end 55 | return fd:write(table.concat(str)) 56 | end 57 | 58 | return { 59 | init = init; 60 | reset = reset; 61 | } 62 | -------------------------------------------------------------------------------- /tui/util.lua: -------------------------------------------------------------------------------- 1 | local atexit 2 | if _VERSION == "Lua 5.1" then 3 | -- luacheck: std lua51 4 | function atexit(func) 5 | local proxy = newproxy(true) 6 | debug.setmetatable(proxy, {__gc = function() return func() end}) 7 | table.insert(debug.getregistry(), proxy) 8 | end 9 | else 10 | function atexit(func) 11 | table.insert(debug.getregistry(), setmetatable({}, {__gc = function() return func() end})) 12 | end 13 | end 14 | 15 | local function read_file(path) 16 | local fd, err, errno = io.open(path, "rb") 17 | if not fd then 18 | return nil, err, errno 19 | end 20 | local contents, err2, errno2 = fd:read("*a") 21 | fd:close() 22 | if not contents then 23 | return nil, err2, errno2 24 | end 25 | return contents 26 | end 27 | 28 | return { 29 | atexit = atexit; 30 | read_file = read_file; 31 | } 32 | --------------------------------------------------------------------------------