├── .github └── workflows │ └── rust.yml ├── .gitignore ├── .travis.yml ├── Cargo.toml ├── LICENSE ├── README.md ├── build.rs ├── examples ├── parse.rs ├── set_attributes.rs └── simple.rs ├── rustfmt.toml ├── src ├── capability.rs ├── database.rs ├── error.rs ├── expand.rs ├── lib.rs ├── names.rs └── parser │ ├── compiled.rs │ ├── expansion.rs │ ├── mod.rs │ ├── source.rs │ └── util.rs └── tests ├── cancer+secret ├── cancer-256color ├── st-256color ├── xterm-256color └── xterm.terminfo /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | name: Rust 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | env: 10 | CARGO_TERM_COLOR: always 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | - name: Build 20 | run: cargo build --verbose 21 | - name: Run tests 22 | run: cargo test --lib --verbose 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | rust: 3 | - stable 4 | - beta 5 | - nightly 6 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "terminfo" 3 | version = "0.9.0" 4 | edition = "2021" 5 | 6 | authors = ["meh. "] 7 | license = "WTFPL" 8 | 9 | description = "Terminal information." 10 | repository = "https://github.com/meh/rust-terminfo" 11 | keywords = ["terminal", "terminfo", "termcap", "term"] 12 | categories = ["command-line-interface"] 13 | 14 | build = "build.rs" 15 | 16 | [dependencies] 17 | nom = { version = "7", default-features = false, features = ["std"] } 18 | phf = "0.11" 19 | fnv = "1.0" 20 | 21 | [build-dependencies] 22 | phf_codegen = "0.11" 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyleft (ↄ) meh. | http://meh.schizofreni.co 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | terminfo 2 | ======== 3 | [![Crates.io](https://img.shields.io/crates/v/terminfo.svg)](https://crates.io/crates/terminfo) [![Crates.io](https://img.shields.io/crates/d/terminfo.svg)](https://crates.io/crates/terminfo) ![WTFPL](http://img.shields.io/badge/license-WTFPL-blue.svg) [![Build Status](https://github.com/meh/rust-terminfo/actions/workflows/rust.yml/badge.svg)](https://github.com/meh/rust-terminfo/actions/workflows/rust.yml) 4 | 5 | Terminal capabilities with type-safe getters. 6 | 7 | [Documentation](https://docs.rs/terminfo/latest/terminfo/) 8 | 9 | Example 10 | ------- 11 | 12 | ```rust 13 | use std::io; 14 | use terminfo::{capability as cap, Database}; 15 | 16 | fn main() { 17 | let info = Database::from_env().unwrap(); 18 | 19 | if let Some(cap::MaxColors(n)) = info.get::() { 20 | println!("The terminal supports {} colors.", n); 21 | } else { 22 | println!("The terminal does not support colors, what year is this?"); 23 | } 24 | 25 | if let Some(flash) = info.get::() { 26 | flash.expand().to(io::stdout()).unwrap(); 27 | } else { 28 | println!("FLASH GORDON!"); 29 | } 30 | 31 | info.get::().unwrap().expand().color(2).to(io::stdout()).unwrap(); 32 | info.get::().unwrap().expand().color(4).to(io::stdout()).unwrap(); 33 | println!("SUP"); 34 | info.get::().unwrap().expand().to(io::stdout()).unwrap(); 35 | } 36 | ``` 37 | 38 | Packaging and Distributing 39 | -------------------------- 40 | For all terminals but windows consoles, this library depends on a non-hashed 41 | (for now) terminfo database being present. For example, on Debian derivitives, 42 | you should depend on ncurses-term; on Arch Linux, you depend on ncurses; and on 43 | MinGW, you should depend on mingw32-terminfo. 44 | 45 | Unfortunately, if you're using a non-windows console on Windows (e.g. MinGW, 46 | Cygwin, Git Bash), you'll need to set the TERMINFO environment variable to 47 | point to the directory containing the terminfo database. 48 | -------------------------------------------------------------------------------- /build.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::fs::File; 3 | use std::io::{BufWriter, Write}; 4 | use std::path::Path; 5 | 6 | #[rustfmt::skip] 7 | const BOOLEAN: &[&str] = &[ 8 | "auto_left_margin", "auto_right_margin", "no_esc_ctlc", "ceol_standout_glitch", 9 | "eat_newline_glitch", "erase_overstrike", "generic_type", "hard_copy", "has_meta_key", 10 | "has_status_line", "insert_null_glitch", "memory_above", "memory_below", "move_insert_mode", 11 | "move_standout_mode", "over_strike", "status_line_esc_ok", "dest_tabs_magic_smso", 12 | "tilde_glitch", "transparent_underline", "xon_xoff", "needs_xon_xoff", "prtr_silent", 13 | "hard_cursor", "non_rev_rmcup", "no_pad_char", "non_dest_scroll_region", "can_change", 14 | "back_color_erase", "hue_lightness_saturation", "col_addr_glitch", "cr_cancels_micro_mode", 15 | "has_print_wheel", "row_addr_glitch", "semi_auto_right_margin", "cpi_changes_res", 16 | "lpi_changes_res", "backspaces_with_bs", "crt_no_scrolling", "no_correctly_working_cr", 17 | "gnu_has_meta_key", "linefeed_is_newline", "has_hardware_tabs", "return_does_clr_eol" 18 | ]; 19 | 20 | #[rustfmt::skip] 21 | const NUMBER: &[&str] = &[ 22 | "columns", "init_tabs", "lines", "lines_of_memory", "magic_cookie_glitch", "padding_baud_rate", 23 | "virtual_terminal", "width_status_line", "num_labels", "label_height", "label_width", 24 | "max_attributes", "maximum_windows", "max_colors", "max_pairs", "no_color_video", 25 | "buffer_capacity", "dot_vert_spacing", "dot_horz_spacing", "max_micro_address", 26 | "max_micro_jump", "micro_col_size", "micro_line_size", "number_of_pins", "output_res_char", 27 | "output_res_line", "output_res_horz_inch", "output_res_vert_inch", "print_rate", 28 | "wide_char_size", "buttons", "bit_image_entwining", "bit_image_type", "magic_cookie_glitch_ul", 29 | "carriage_return_delay", "new_line_delay", "backspace_delay", "horizontal_tab_delay", 30 | "number_of_function_keys" 31 | ]; 32 | 33 | #[rustfmt::skip] 34 | const STRING: &[&str] = &[ 35 | "back_tab", "bell", "carriage_return", "change_scroll_region", "clear_all_tabs", 36 | "clear_screen", "clr_eol", "clr_eos", "column_address", "command_character", "cursor_address", 37 | "cursor_down", "cursor_home", "cursor_invisible", "cursor_left", "cursor_mem_address", 38 | "cursor_normal", "cursor_right", "cursor_to_ll", "cursor_up", "cursor_visible", 39 | "delete_character", "delete_line", "dis_status_line", "down_half_line", 40 | "enter_alt_charset_mode", "enter_blink_mode", "enter_bold_mode", "enter_ca_mode", 41 | "enter_delete_mode", "enter_dim_mode", "enter_insert_mode", "enter_secure_mode", 42 | "enter_protected_mode", "enter_reverse_mode", "enter_standout_mode", "enter_underline_mode", 43 | "erase_chars", "exit_alt_charset_mode", "exit_attribute_mode", "exit_ca_mode", 44 | "exit_delete_mode", "exit_insert_mode", "exit_standout_mode", "exit_underline_mode", 45 | "flash_screen", "form_feed", "from_status_line", "init_1string", "init_2string", 46 | "init_3string", "init_file", "insert_character", "insert_line", "insert_padding", 47 | "key_backspace", "key_catab", "key_clear", "key_ctab", "key_dc", "key_dl", "key_down", 48 | "key_eic", "key_eol", "key_eos", "key_f0", "key_f1", "key_f10", "key_f2", "key_f3", "key_f4", 49 | "key_f5", "key_f6", "key_f7", "key_f8", "key_f9", "key_home", "key_ic", "key_il", "key_left", 50 | "key_ll", "key_npage", "key_ppage", "key_right", "key_sf", "key_sr", "key_stab", "key_up", 51 | "keypad_local", "keypad_xmit", "lab_f0", "lab_f1", "lab_f10", "lab_f2", "lab_f3", "lab_f4", 52 | "lab_f5", "lab_f6", "lab_f7", "lab_f8", "lab_f9", "meta_off", "meta_on", "newline", "pad_char", 53 | "parm_dch", "parm_delete_line", "parm_down_cursor", "parm_ich", "parm_index", 54 | "parm_insert_line", "parm_left_cursor", "parm_right_cursor", "parm_rindex", "parm_up_cursor", 55 | "pkey_key", "pkey_local", "pkey_xmit", "print_screen", "prtr_off", "prtr_on", "repeat_char", 56 | "reset_1string", "reset_2string", "reset_3string", "reset_file", "restore_cursor", 57 | "row_address", "save_cursor", "scroll_forward", "scroll_reverse", "set_attributes", "set_tab", 58 | "set_window", "tab", "to_status_line", "underline_char", "up_half_line", "init_prog", "key_a1", 59 | "key_a3", "key_b2", "key_c1", "key_c3", "prtr_non", "char_padding", "acs_chars", "plab_norm", 60 | "key_btab", "enter_xon_mode", "exit_xon_mode", "enter_am_mode", "exit_am_mode", 61 | "xon_character", "xoff_character", "ena_acs", "label_on", "label_off", "key_beg", "key_cancel", 62 | "key_close", "key_command", "key_copy", "key_create", "key_end", "key_enter", "key_exit", 63 | "key_find", "key_help", "key_mark", "key_message", "key_move", "key_next", "key_open", 64 | "key_options", "key_previous", "key_print", "key_redo", "key_reference", "key_refresh", 65 | "key_replace", "key_restart", "key_resume", "key_save", "key_suspend", "key_undo", "key_sbeg", 66 | "key_scancel", "key_scommand", "key_scopy", "key_screate", "key_sdc", "key_sdl", "key_select", 67 | "key_send", "key_seol", "key_sexit", "key_sfind", "key_shelp", "key_shome", "key_sic", 68 | "key_sleft", "key_smessage", "key_smove", "key_snext", "key_soptions", "key_sprevious", 69 | "key_sprint", "key_sredo", "key_sreplace", "key_sright", "key_srsume", "key_ssave", 70 | "key_ssuspend", "key_sundo", "req_for_input", "key_f11", "key_f12", "key_f13", "key_f14", 71 | "key_f15", "key_f16", "key_f17", "key_f18", "key_f19", "key_f20", "key_f21", "key_f22", 72 | "key_f23", "key_f24", "key_f25", "key_f26", "key_f27", "key_f28", "key_f29", "key_f30", 73 | "key_f31", "key_f32", "key_f33", "key_f34", "key_f35", "key_f36", "key_f37", "key_f38", 74 | "key_f39", "key_f40", "key_f41", "key_f42", "key_f43", "key_f44", "key_f45", "key_f46", 75 | "key_f47", "key_f48", "key_f49", "key_f50", "key_f51", "key_f52", "key_f53", "key_f54", 76 | "key_f55", "key_f56", "key_f57", "key_f58", "key_f59", "key_f60", "key_f61", "key_f62", 77 | "key_f63", "clr_bol", "clear_margins", "set_left_margin", "set_right_margin", "label_format", 78 | "set_clock", "display_clock", "remove_clock", "create_window", "goto_window", "hangup", 79 | "dial_phone", "quick_dial", "tone", "pulse", "flash_hook", "fixed_pause", "wait_tone", "user0", 80 | "user1", "user2", "user3", "user4", "user5", "user6", "user7", "user8", "user9", "orig_pair", 81 | "orig_colors", "initialize_color", "initialize_pair", "set_color_pair", "set_foreground", 82 | "set_background", "change_char_pitch", "change_line_pitch", "change_res_horz", 83 | "change_res_vert", "define_char", "enter_doublewide_mode", "enter_draft_quality", 84 | "enter_italics_mode", "enter_leftward_mode", "enter_micro_mode", "enter_near_letter_quality", 85 | "enter_normal_quality", "enter_shadow_mode", "enter_subscript_mode", "enter_superscript_mode", 86 | "enter_upward_mode", "exit_doublewide_mode", "exit_italics_mode", "exit_leftward_mode", 87 | "exit_micro_mode", "exit_shadow_mode", "exit_subscript_mode", "exit_superscript_mode", 88 | "exit_upward_mode", "micro_column_address", "micro_down", "micro_left", "micro_right", 89 | "micro_row_address", "micro_up", "order_of_pins", "parm_down_micro", "parm_left_micro", 90 | "parm_right_micro", "parm_up_micro", "select_char_set", "set_bottom_margin", 91 | "set_bottom_margin_parm", "set_left_margin_parm", "set_right_margin_parm", "set_top_margin", 92 | "set_top_margin_parm", "start_bit_image", "start_char_set_def", "stop_bit_image", 93 | "stop_char_set_def", "subscript_characters", "superscript_characters", "these_cause_cr", 94 | "zero_motion", "char_set_names", "key_mouse", "mouse_info", "req_mouse_pos", "get_mouse", 95 | "set_a_foreground", "set_a_background", "pkey_plab", "device_type", "code_set_init", 96 | "set0_des_seq", "set1_des_seq", "set2_des_seq", "set3_des_seq", "set_lr_margin", 97 | "set_tb_margin", "bit_image_repeat", "bit_image_newline", "bit_image_carriage_return", 98 | "color_names", "define_bit_image_region", "end_bit_image_region", "set_color_band", 99 | "set_page_length", "display_pc_char", "enter_pc_charset_mode", "exit_pc_charset_mode", 100 | "enter_scancode_mode", "exit_scancode_mode", "pc_term_options", "scancode_escape", 101 | "alt_scancode_esc", "enter_horizontal_hl_mode", "enter_left_hl_mode", "enter_low_hl_mode", 102 | "enter_right_hl_mode", "enter_top_hl_mode", "enter_vertical_hl_mode", "set_a_attributes", 103 | "set_pglen_inch", "termcap_init2", "termcap_reset", "linefeed_if_not_lf", 104 | "backspace_if_not_bs", "other_non_function_keys", "arrow_key_map", "acs_ulcorner", 105 | "acs_llcorner", "acs_urcorner", "acs_lrcorner", "acs_ltee", "acs_rtee", "acs_btee", "acs_ttee", 106 | "acs_hline", "acs_vline", "acs_plus", "memory_lock", "memory_unlock", "box_chars_1" 107 | ]; 108 | 109 | const TERMINFO: &[(&str, &str)] = &[ 110 | // Boolean names. 111 | ("auto_left_margin", "bw"), 112 | ("auto_right_margin", "am"), 113 | ("back_color_erase", "bce"), 114 | ("can_change", "ccc"), 115 | ("ceol_standout_glitch", "xhp"), 116 | ("col_addr_glitch", "xhpa"), 117 | ("cpi_changes_res", "cpix"), 118 | ("cr_cancels_micro_mode", "crxm"), 119 | ("dest_tabs_magic_smso", "xt"), 120 | ("eat_newline_glitch", "xenl"), 121 | ("erase_overstrike", "eo"), 122 | ("generic_type", "gn"), 123 | ("hard_copy", "hc"), 124 | ("hard_cursor", "chts"), 125 | ("has_meta_key", "km"), 126 | ("has_print_wheel", "daisy"), 127 | ("has_status_line", "hs"), 128 | ("hue_lightness_saturation", "hls"), 129 | ("insert_null_glitch", "in"), 130 | ("lpi_changes_res", "lpix"), 131 | ("memory_above", "da"), 132 | ("memory_below", "db"), 133 | ("move_insert_mode", "mir"), 134 | ("move_standout_mode", "msgr"), 135 | ("needs_xon_xoff", "nxon"), 136 | ("no_esc_ctlc", "xsb"), 137 | ("no_pad_char", "npc"), 138 | ("non_dest_scroll_region", "ndscr"), 139 | ("non_rev_rmcup", "nrrmc"), 140 | ("over_strike", "os"), 141 | ("prtr_silent", "mc5i"), 142 | ("row_addr_glitch", "xvpa"), 143 | ("semi_auto_right_margin", "sam"), 144 | ("status_line_esc_ok", "eslok"), 145 | ("tilde_glitch", "hz"), 146 | ("transparent_underline", "ul"), 147 | ("xon_xoff", "xon"), 148 | // Number names. 149 | ("bit_image_entwining", "bitwin"), 150 | ("bit_image_type", "bitype"), 151 | ("buffer_capacity", "bufsz"), 152 | ("buttons", "btns"), 153 | ("columns", "cols"), 154 | ("dot_horz_spacing", "spinh"), 155 | ("dot_vert_spacing", "spinv"), 156 | ("init_tabs", "it"), 157 | ("label_height", "lh"), 158 | ("label_width", "lw"), 159 | ("lines", "lines"), 160 | ("lines_of_memory", "lm"), 161 | ("max_attributes", "ma"), 162 | ("magic_cookie_glitch", "xmc"), 163 | ("max_colors", "colors"), 164 | ("max_micro_address", "maddr"), 165 | ("max_micro_jump", "mjump"), 166 | ("max_pairs", "pairs"), 167 | ("maximum_windows", "wnum"), 168 | ("micro_col_size", "mcs"), 169 | ("micro_line_size", "mls"), 170 | ("no_color_video", "ncv"), 171 | ("num_labels", "nlab"), 172 | ("number_of_pins", "npins"), 173 | ("output_res_char", "orc"), 174 | ("output_res_line", "orl"), 175 | ("output_res_horz_inch", "orhi"), 176 | ("output_res_vert_inch", "orvi"), 177 | ("padding_baud_rate", "pb"), 178 | ("print_rate", "cps"), 179 | ("virtual_terminal", "vt"), 180 | ("wide_char_size", "widcs"), 181 | ("width_status_line", "wsl"), 182 | // String names. 183 | ("acs_chars", "acsc"), 184 | ("alt_scancode_esc", "scesa"), 185 | ("back_tab", "cbt"), 186 | ("bell", "bel"), 187 | ("bit_image_carriage_return", "bicr"), 188 | ("bit_image_newline", "binel"), 189 | ("bit_image_repeat", "birep"), 190 | ("carriage_return", "cr"), 191 | ("change_char_pitch", "cpi"), 192 | ("change_line_pitch", "lpi"), 193 | ("change_res_horz", "chr"), 194 | ("change_res_vert", "cvr"), 195 | ("change_scroll_region", "csr"), 196 | ("char_padding", "rmp"), 197 | ("char_set_names", "csnm"), 198 | ("clear_all_tabs", "tbc"), 199 | ("clear_margins", "mgc"), 200 | ("clear_screen", "clear"), 201 | ("clr_bol", "el1"), 202 | ("clr_eol", "el"), 203 | ("clr_eos", "ed"), 204 | ("code_set_init", "csin"), 205 | ("color_names", "colornm"), 206 | ("column_address", "hpa"), 207 | ("command_character", "cmdch"), 208 | ("create_window", "cwin"), 209 | ("cursor_address", "cup"), 210 | ("cursor_down", "cud1"), 211 | ("cursor_home", "home"), 212 | ("cursor_invisible", "civis"), 213 | ("cursor_left", "cub1"), 214 | ("cursor_mem_address", "mrcup"), 215 | ("cursor_normal", "cnorm"), 216 | ("cursor_right", "cuf1"), 217 | ("cursor_to_ll", "ll"), 218 | ("cursor_up", "cuu1"), 219 | ("cursor_visible", "cvvis"), 220 | ("define_bit_image_region", "defbi"), 221 | ("define_char", "defc"), 222 | ("delete_character", "dch1"), 223 | ("delete_line", "dl1"), 224 | ("device_type", "devt"), 225 | ("dial_phone", "dial"), 226 | ("dis_status_line", "dsl"), 227 | ("display_clock", "dclk"), 228 | ("display_pc_char", "dispc"), 229 | ("down_half_line", "hd"), 230 | ("ena_acs", "enacs"), 231 | ("end_bit_image_region", "endbi"), 232 | ("enter_alt_charset_mode", "smacs"), 233 | ("enter_am_mode", "smam"), 234 | ("enter_blink_mode", "blink"), 235 | ("enter_bold_mode", "bold"), 236 | ("enter_ca_mode", "smcup"), 237 | ("enter_delete_mode", "smdc"), 238 | ("enter_dim_mode", "dim"), 239 | ("enter_doublewide_mode", "swidm"), 240 | ("enter_draft_quality", "sdrfq"), 241 | ("enter_horizontal_hl_mode", "ehhlm"), 242 | ("enter_insert_mode", "smir"), 243 | ("enter_italics_mode", "sitm"), 244 | ("enter_left_hl_mode", "elhlm"), 245 | ("enter_leftward_mode", "slm"), 246 | ("enter_low_hl_mode", "elohlm"), 247 | ("enter_micro_mode", "smicm"), 248 | ("enter_near_letter_quality", "snlq"), 249 | ("enter_normal_quality", "snrmq"), 250 | ("enter_pc_charset_mode", "smpch"), 251 | ("enter_protected_mode", "prot"), 252 | ("enter_reverse_mode", "rev"), 253 | ("enter_right_hl_mode", "erhlm"), 254 | ("enter_scancode_mode", "smsc"), 255 | ("enter_secure_mode", "invis"), 256 | ("enter_shadow_mode", "sshm"), 257 | ("enter_standout_mode", "smso"), 258 | ("enter_subscript_mode", "ssubm"), 259 | ("enter_superscript_mode", "ssupm"), 260 | ("enter_top_hl_mode", "ethlm"), 261 | ("enter_underline_mode", "smul"), 262 | ("enter_upward_mode", "sum"), 263 | ("enter_vertical_hl_mode", "evhlm"), 264 | ("enter_xon_mode", "smxon"), 265 | ("erase_chars", "ech"), 266 | ("exit_alt_charset_mode", "rmacs"), 267 | ("exit_am_mode", "rmam"), 268 | ("exit_attribute_mode", "sgr0"), 269 | ("exit_ca_mode", "rmcup"), 270 | ("exit_delete_mode", "rmdc"), 271 | ("exit_doublewide_mode", "rwidm"), 272 | ("exit_insert_mode", "rmir"), 273 | ("exit_italics_mode", "ritm"), 274 | ("exit_leftward_mode", "rlm"), 275 | ("exit_micro_mode", "rmicm"), 276 | ("exit_pc_charset_mode", "rmpch"), 277 | ("exit_scancode_mode", "rmsc"), 278 | ("exit_shadow_mode", "rshm"), 279 | ("exit_standout_mode", "rmso"), 280 | ("exit_subscript_mode", "rsubm"), 281 | ("exit_superscript_mode", "rsupm"), 282 | ("exit_underline_mode", "rmul"), 283 | ("exit_upward_mode", "rum"), 284 | ("exit_xon_mode", "rmxon"), 285 | ("fixed_pause", "pause"), 286 | ("flash_hook", "hook"), 287 | ("flash_screen", "flash"), 288 | ("form_feed", "ff"), 289 | ("from_status_line", "fsl"), 290 | ("get_mouse", "getm"), 291 | ("goto_window", "wingo"), 292 | ("hangup", "hup"), 293 | ("init_1string", "is1"), 294 | ("init_2string", "is2"), 295 | ("init_3string", "is3"), 296 | ("init_file", "if"), 297 | ("init_prog", "iprog"), 298 | ("initialize_color", "initc"), 299 | ("initialize_pair", "initp"), 300 | ("insert_character", "ich1"), 301 | ("insert_line", "il1"), 302 | ("insert_padding", "ip"), 303 | ("key_a1", "ka1"), 304 | ("key_a3", "ka3"), 305 | ("key_b2", "kb2"), 306 | ("key_backspace", "kbs"), 307 | ("key_beg", "kbeg"), 308 | ("key_btab", "kcbt"), 309 | ("key_c1", "kc1"), 310 | ("key_c3", "kc3"), 311 | ("key_cancel", "kcan"), 312 | ("key_catab", "ktbc"), 313 | ("key_clear", "kclr"), 314 | ("key_close", "kclo"), 315 | ("key_command", "kcmd"), 316 | ("key_copy", "kcpy"), 317 | ("key_create", "kcrt"), 318 | ("key_ctab", "kctab"), 319 | ("key_dc", "kdch1"), 320 | ("key_dl", "kdl1"), 321 | ("key_down", "kcud1"), 322 | ("key_eic", "krmir"), 323 | ("key_end", "kend"), 324 | ("key_enter", "kent"), 325 | ("key_eol", "kel"), 326 | ("key_eos", "ked"), 327 | ("key_exit", "kext"), 328 | ("key_f0", "kf0"), 329 | ("key_f1", "kf1"), 330 | ("key_f62", "kf62"), 331 | ("key_f63", "kf63"), 332 | ("key_find", "kfnd"), 333 | ("key_help", "khlp"), 334 | ("key_home", "khome"), 335 | ("key_ic", "kich1"), 336 | ("key_il", "kil1"), 337 | ("key_left", "kcub1"), 338 | ("key_ll", "kll"), 339 | ("key_mark", "kmrk"), 340 | ("key_message", "kmsg"), 341 | ("key_mouse", "kmous"), 342 | ("key_move", "kmov"), 343 | ("key_next", "knxt"), 344 | ("key_npage", "knp"), 345 | ("key_open", "kopn"), 346 | ("key_options", "kopt"), 347 | ("key_ppage", "kpp"), 348 | ("key_previous", "kprv"), 349 | ("key_print", "kprt"), 350 | ("key_redo", "krdo"), 351 | ("key_reference", "kref"), 352 | ("key_refresh", "krfr"), 353 | ("key_replace", "krpl"), 354 | ("key_restart", "krst"), 355 | ("key_resume", "kres"), 356 | ("key_right", "kcuf1"), 357 | ("key_save", "ksav"), 358 | ("key_sbeg", "kBEG"), 359 | ("key_scancel", "kCAN"), 360 | ("key_scommand", "kCMD"), 361 | ("key_scopy", "kCPY"), 362 | ("key_screate", "kCRT"), 363 | ("key_sdc", "kDC"), 364 | ("key_sdl", "kDL"), 365 | ("key_select", "kslt"), 366 | ("key_send", "kEND"), 367 | ("key_seol", "kEOL"), 368 | ("key_sexit", "kEXT"), 369 | ("key_sf", "kind"), 370 | ("key_sfind", "kFND"), 371 | ("key_shelp", "kHLP"), 372 | ("key_shome", "kHOM"), 373 | ("key_sic", "kIC"), 374 | ("key_sleft", "kLFT"), 375 | ("key_smessage", "kMSG"), 376 | ("key_smove", "kMOV"), 377 | ("key_snext", "kNXT"), 378 | ("key_soptions", "kOPT"), 379 | ("key_sprevious", "kPRV"), 380 | ("key_sprint", "kPRT"), 381 | ("key_sr", "kri"), 382 | ("key_sredo", "kRDO"), 383 | ("key_sreplace", "kRPL"), 384 | ("key_sright", "kRIT"), 385 | ("key_srsume", "kRES"), 386 | ("key_ssave", "kSAV"), 387 | ("key_ssuspend", "kSPD"), 388 | ("key_stab", "khts"), 389 | ("key_sundo", "kUND"), 390 | ("key_suspend", "kspd"), 391 | ("key_undo", "kund"), 392 | ("key_up", "kcuu1"), 393 | ("keypad_local", "rmkx"), 394 | ("keypad_xmit", "smkx"), 395 | ("lab_f0", "lf0"), 396 | ("lab_f1", "lf1"), 397 | ("lab_f2", "lf2"), 398 | ("lab_f3", "lf3"), 399 | ("lab_f4", "lf4"), 400 | ("lab_f5", "lf5"), 401 | ("lab_f6", "lf6"), 402 | ("lab_f7", "lf7"), 403 | ("lab_f8", "lf8"), 404 | ("lab_f9", "lf9"), 405 | ("lab_f10", "lf10"), 406 | ("label_format", "fln"), 407 | ("label_off", "rmln"), 408 | ("label_on", "smln"), 409 | ("meta_off", "rmm"), 410 | ("meta_on", "smm"), 411 | ("micro_column_address", "mhpa"), 412 | ("micro_down", "mcud1"), 413 | ("micro_left", "mcub1"), 414 | ("micro_right", "mcuf1"), 415 | ("micro_row_address", "mvpa"), 416 | ("micro_up", "mcuu1"), 417 | ("mouse_info", "minfo"), 418 | ("newline", "nel"), 419 | ("order_of_pins", "porder"), 420 | ("orig_colors", "oc"), 421 | ("orig_pair", "op"), 422 | ("pad_char", "pad"), 423 | ("parm_dch", "dch"), 424 | ("parm_delete_line", "dl"), 425 | ("parm_down_cursor", "cud"), 426 | ("parm_down_micro", "mcud"), 427 | ("parm_ich", "ich"), 428 | ("parm_index", "indn"), 429 | ("parm_insert_line", "il"), 430 | ("parm_left_cursor", "cub"), 431 | ("parm_left_micro", "mcub"), 432 | ("parm_right_cursor", "cuf"), 433 | ("parm_right_micro", "mcuf"), 434 | ("parm_rindex", "rin"), 435 | ("parm_up_cursor", "cuu"), 436 | ("parm_up_micro", "mcuu"), 437 | ("pc_term_options", "pctrm"), 438 | ("pkey_key", "pfkey"), 439 | ("pkey_local", "pfloc"), 440 | ("pkey_plab", "pfxl"), 441 | ("pkey_xmit", "pfx"), 442 | ("plab_norm", "pln"), 443 | ("print_screen", "mc0"), 444 | ("prtr_non", "mc5p"), 445 | ("prtr_off", "mc4"), 446 | ("prtr_on", "mc5"), 447 | ("pulse", "pulse"), 448 | ("quick_dial", "qdial"), 449 | ("remove_clock", "rmclk"), 450 | ("repeat_char", "rep"), 451 | ("req_for_input", "rfi"), 452 | ("req_mouse_pos", "reqmp"), 453 | ("reset_1string", "rs1"), 454 | ("reset_2string", "rs2"), 455 | ("reset_3string", "rs3"), 456 | ("reset_file", "rf"), 457 | ("restore_cursor", "rc"), 458 | ("row_address", "vpa"), 459 | ("save_cursor", "sc"), 460 | ("scancode_escape", "scesc"), 461 | ("scroll_forward", "ind"), 462 | ("scroll_reverse", "ri"), 463 | ("select_char_set", "scs"), 464 | ("set0_des_seq", "s0ds"), 465 | ("set1_des_seq", "s1ds"), 466 | ("set2_des_seq", "s2ds"), 467 | ("set3_des_seq", "s3ds"), 468 | ("set_a_attributes", "sgr1"), 469 | ("set_a_background", "setab"), 470 | ("set_a_foreground", "setaf"), 471 | ("set_attributes", "sgr"), 472 | ("set_background", "setb"), 473 | ("set_bottom_margin", "smgb"), 474 | ("set_bottom_margin_parm", "smgbp"), 475 | ("set_clock", "sclk"), 476 | ("set_color_band", "setcolor"), 477 | ("set_color_pair", "scp"), 478 | ("set_foreground", "setf"), 479 | ("set_left_margin", "smgl"), 480 | ("set_left_margin_parm", "smglp"), 481 | ("set_lr_margin", "smglr"), 482 | ("set_page_length", "slines"), 483 | ("set_pglen_inch", "slength"), 484 | ("set_right_margin", "smgr"), 485 | ("set_right_margin_parm", "smgrp"), 486 | ("set_tab", "hts"), 487 | ("set_tb_margin", "smgtb"), 488 | ("set_top_margin", "smgt"), 489 | ("set_top_margin_parm", "smgtp"), 490 | ("set_window", "wind"), 491 | ("start_bit_image", "sbim"), 492 | ("start_char_set_def", "scsd"), 493 | ("stop_bit_image", "rbim"), 494 | ("stop_char_set_def", "rcsd"), 495 | ("subscript_characters", "subcs"), 496 | ("superscript_characters", "supcs"), 497 | ("tab", "ht"), 498 | ("these_cause_cr", "docr"), 499 | ("to_status_line", "tsl"), 500 | ("tone", "tone"), 501 | ("user0", "u0"), 502 | ("user1", "u1"), 503 | ("user2", "u2"), 504 | ("user3", "u3"), 505 | ("user4", "u4"), 506 | ("user5", "u5"), 507 | ("user6", "u6"), 508 | ("user7", "u7"), 509 | ("user8", "u8"), 510 | ("user9", "u9"), 511 | ("underline_char", "uc"), 512 | ("up_half_line", "hu"), 513 | ("wait_tone", "wait"), 514 | ("xoff_character", "xoffc"), 515 | ("xon_character", "xonc"), 516 | ("zero_motion", "zerom"), 517 | ]; 518 | 519 | const TERMCAP: &[(&str, &str)] = &[ 520 | // Boolean names. 521 | ("auto_left_margin", "bw"), 522 | ("auto_right_margin", "am"), 523 | ("back_color_erase", "ut"), 524 | ("can_change", "cc"), 525 | ("ceol_standout_glitch", "xs"), 526 | ("col_addr_glitch", "YA"), 527 | ("cpi_changes_res", "YF"), 528 | ("cr_cancels_micro_mode", "YB"), 529 | ("dest_tabs_magic_smso", "xt"), 530 | ("eat_newline_glitch", "xn"), 531 | ("erase_overstrike", "eo"), 532 | ("generic_type", "gn"), 533 | ("hard_copy", "hc"), 534 | ("hard_cursor", "HC"), 535 | ("has_meta_key", "km"), 536 | ("has_print_wheel", "YC"), 537 | ("has_status_line", "hs"), 538 | ("hue_lightness_saturation", "hl"), 539 | ("insert_null_glitch", "in"), 540 | ("lpi_changes_res", "YG"), 541 | ("memory_above", "da"), 542 | ("memory_below", "db"), 543 | ("move_insert_mode", "mi"), 544 | ("move_standout_mode", "ms"), 545 | ("needs_xon_xoff", "nx"), 546 | ("no_esc_ctlc", "xb"), 547 | ("no_pad_char", "NP"), 548 | ("non_dest_scroll_region", "ND"), 549 | ("non_rev_rmcup", "NR"), 550 | ("over_strike", "os"), 551 | ("prtr_silent", "5i"), 552 | ("row_addr_glitch", "YD"), 553 | ("semi_auto_right_margin", "YE"), 554 | ("status_line_esc_ok", "es"), 555 | ("tilde_glitch", "hz"), 556 | ("transparent_underline", "ul"), 557 | ("xon_xoff", "xo"), 558 | // Number names. 559 | ("bit_image_entwining", "Yo"), 560 | ("bit_image_type", "Yp"), 561 | ("buffer_capacity", "Ya"), 562 | ("buttons", "BT"), 563 | ("columns", "co"), 564 | ("dot_horz_spacing", "Yc"), 565 | ("dot_vert_spacing", "Yb"), 566 | ("init_tabs", "it"), 567 | ("label_height", "lh"), 568 | ("label_width", "lw"), 569 | ("lines", "li"), 570 | ("lines_of_memory", "lm"), 571 | ("max_attributes", "ma"), 572 | ("magic_cookie_glitch", "sg"), 573 | ("max_colors", "Co"), 574 | ("max_micro_address", "Yd"), 575 | ("max_micro_jump", "Ye"), 576 | ("max_pairs", "pa"), 577 | ("maximum_windows", "MW"), 578 | ("micro_col_size", "Yf"), 579 | ("micro_line_size", "Yg"), 580 | ("no_color_video", "NC"), 581 | ("num_labels", "Nl"), 582 | ("number_of_pins", "Yh"), 583 | ("output_res_char", "Yi"), 584 | ("output_res_line", "Yj"), 585 | ("output_res_horz_inch", "Yk"), 586 | ("output_res_vert_inch", "Yl"), 587 | ("padding_baud_rate", "pb"), 588 | ("print_rate", "Ym"), 589 | ("virtual_terminal", "vt"), 590 | ("wide_char_size", "Yn"), 591 | ("width_status_line", "ws"), 592 | // String names. 593 | ("acs_chars", "ac"), 594 | ("alt_scancode_esc", "S8"), 595 | ("back_tab", "bt"), 596 | ("bell", "bl"), 597 | ("bit_image_carriage_return", "Yv"), 598 | ("bit_image_newline", "Zz"), 599 | ("bit_image_repeat", "Xy"), 600 | ("carriage_return", "cr"), 601 | ("change_char_pitch", "ZA"), 602 | ("change_line_pitch", "ZB"), 603 | ("change_res_horz", "ZC"), 604 | ("change_res_vert", "ZD"), 605 | ("change_scroll_region", "cs"), 606 | ("char_padding", "rP"), 607 | ("char_set_names", "Zy"), 608 | ("clear_all_tabs", "ct"), 609 | ("clear_margins", "MC"), 610 | ("clear_screen", "cl"), 611 | ("clr_bol", "cb"), 612 | ("clr_eol", "ce"), 613 | ("clr_eos", "cd"), 614 | ("code_set_init", "ci"), 615 | ("color_names", "Yw"), 616 | ("column_address", "ch"), 617 | ("command_character", "CC"), 618 | ("cursor_address", "cm"), 619 | ("cursor_down", "do"), 620 | ("cursor_home", "ho"), 621 | ("cursor_invisible", "vi"), 622 | ("cursor_left", "le"), 623 | ("cursor_mem_address", "CM"), 624 | ("cursor_normal", "ve"), 625 | ("cursor_right", "nd"), 626 | ("cursor_to_ll", "ll"), 627 | ("cursor_up", "up"), 628 | ("cursor_visible", "vs"), 629 | ("define_bit_image_region", "Yx"), 630 | ("define_char", "ZE"), 631 | ("delete_character", "dc"), 632 | ("delete_line", "dl"), 633 | ("device_type", "dv"), 634 | ("dial_phone", "DI"), 635 | ("dis_status_line", "ds"), 636 | ("display_clock", "DK"), 637 | ("display_pc_char", "S1"), 638 | ("down_half_line", "hd"), 639 | ("ena_acs", "eA"), 640 | ("end_bit_image_region", "Yy"), 641 | ("enter_alt_charset_mode", "as"), 642 | ("enter_am_mode", "SA"), 643 | ("enter_blink_mode", "mb"), 644 | ("enter_bold_mode", "md"), 645 | ("enter_ca_mode", "ti"), 646 | ("enter_delete_mode", "dm"), 647 | ("enter_dim_mode", "mh"), 648 | ("enter_doublewide_mode", "ZF"), 649 | ("enter_draft_quality", "ZG"), 650 | ("enter_insert_mode", "im"), 651 | ("enter_italics_mode", "ZH"), 652 | ("enter_leftward_mode", "ZI"), 653 | ("enter_micro_mode", "ZJ"), 654 | ("enter_near_letter_quality", "ZK"), 655 | ("enter_normal_quality", "ZL"), 656 | ("enter_pc_charset_mode", "S2"), 657 | ("enter_protected_mode", "mp"), 658 | ("enter_reverse_mode", "mr"), 659 | ("enter_scancode_mode", "S4"), 660 | ("enter_secure_mode", "mk"), 661 | ("enter_shadow_mode", "ZM"), 662 | ("enter_standout_mode", "so"), 663 | ("enter_subscript_mode", "ZN"), 664 | ("enter_superscript_mode", "ZO"), 665 | ("enter_underline_mode", "us"), 666 | ("enter_upward_mode", "ZP"), 667 | ("enter_xon_mode", "SX"), 668 | ("erase_chars", "ec"), 669 | ("exit_alt_charset_mode", "ae"), 670 | ("exit_am_mode", "RA"), 671 | ("exit_attribute_mode", "me"), 672 | ("exit_ca_mode", "te"), 673 | ("exit_delete_mode", "ed"), 674 | ("exit_doublewide_mode", "ZQ"), 675 | ("exit_insert_mode", "ei"), 676 | ("exit_italics_mode", "ZR"), 677 | ("exit_leftward_mode", "ZS"), 678 | ("exit_micro_mode", "ZT"), 679 | ("exit_pc_charset_mode", "S3"), 680 | ("exit_scancode_mode", "S5"), 681 | ("exit_shadow_mode", "ZU"), 682 | ("exit_standout_mode", "se"), 683 | ("exit_subscript_mode", "ZV"), 684 | ("exit_superscript_mode", "ZW"), 685 | ("exit_underline_mode", "ue"), 686 | ("exit_upward_mode", "ZX"), 687 | ("exit_xon_mode", "RX"), 688 | ("fixed_pause", "PA"), 689 | ("flash_hook", "fh"), 690 | ("flash_screen", "vb"), 691 | ("form_feed", "ff"), 692 | ("from_status_line", "fs"), 693 | ("get_mouse", "Gm"), 694 | ("goto_window", "WG"), 695 | ("hangup", "HU"), 696 | ("init_1string", "i1"), 697 | ("init_2string", "is"), 698 | ("init_3string", "i3"), 699 | ("init_file", "if"), 700 | ("init_prog", "iP"), 701 | ("initialize_color", "Ic"), 702 | ("initialize_pair", "Ip"), 703 | ("insert_character", "ic"), 704 | ("insert_line", "al"), 705 | ("insert_padding", "ip"), 706 | ("key_a1", "K1"), 707 | ("key_a3", "K3"), 708 | ("key_b2", "K2"), 709 | ("key_backspace", "kb"), 710 | ("key_btab", "kB"), 711 | ("key_c1", "K4"), 712 | ("key_c3", "K5"), 713 | ("key_catab", "ka"), 714 | ("key_clear", "kC"), 715 | ("key_ctab", "kt"), 716 | ("key_dc", "kD"), 717 | ("key_dl", "kL"), 718 | ("key_down", "kd"), 719 | ("key_eic", "kM"), 720 | ("key_eol", "kE"), 721 | ("key_eos", "kS"), 722 | ("key_f0", "k0"), 723 | ("key_f1", "k1"), 724 | ("key_f62", "Fq"), 725 | ("key_f63", "Fr"), 726 | ("key_help", "%1"), 727 | ("key_home", "kh"), 728 | ("key_ic", "kI"), 729 | ("key_il", "kA"), 730 | ("key_left", "kl"), 731 | ("key_ll", "kH"), 732 | ("key_mark", "%2"), 733 | ("key_message", "%3"), 734 | ("key_mouse", "Km"), 735 | ("key_move", "%4"), 736 | ("key_next", "%5"), 737 | ("key_npage", "kN"), 738 | ("key_open", "%6"), 739 | ("key_options", "%7"), 740 | ("key_ppage", "kP"), 741 | ("key_previous", "%8"), 742 | ("key_print", "%9"), 743 | ("key_redo", "%0"), 744 | ("key_reference", "&1"), 745 | ("key_refresh", "&2"), 746 | ("key_replace", "&3"), 747 | ("key_restart", "&4"), 748 | ("key_resume", "&5"), 749 | ("key_right", "kr"), 750 | ("key_save", "&6"), 751 | ("key_sbeg", "&9"), 752 | ("key_scancel", "&0"), 753 | ("key_scommand", "*1"), 754 | ("key_scopy", "*2"), 755 | ("key_screate", "*3"), 756 | ("key_sdc", "*4"), 757 | ("key_sdl", "*5"), 758 | ("key_select", "*6"), 759 | ("key_send", "*7"), 760 | ("key_seol", "*8"), 761 | ("key_sexit", "*9"), 762 | ("key_sf", "kF"), 763 | ("key_sfind", "*0"), 764 | ("key_shelp", "#1"), 765 | ("key_shome", "#2"), 766 | ("key_sic", "#3"), 767 | ("key_sleft", "#4"), 768 | ("key_smessage", "%a"), 769 | ("key_smove", "%b"), 770 | ("key_snext", "%c"), 771 | ("key_soptions", "%d"), 772 | ("key_sprevious", "%e"), 773 | ("key_sprint", "%f"), 774 | ("key_sr", "kR"), 775 | ("key_sredo", "%g"), 776 | ("key_sreplace", "%h"), 777 | ("key_sright", "%i"), 778 | ("key_srsume", "%j"), 779 | ("key_ssave", "!1"), 780 | ("key_ssuspend", "!2"), 781 | ("key_stab", "kT"), 782 | ("key_sundo", "!3"), 783 | ("key_suspend", "&7"), 784 | ("key_undo", "&8"), 785 | ("key_up", "ku"), 786 | ("keypad_local", "ke"), 787 | ("keypad_xmit", "ks"), 788 | ("lab_f0", "l0"), 789 | ("lab_f1", "l1"), 790 | ("lab_f2", "l2"), 791 | ("lab_f3", "l3"), 792 | ("lab_f4", "l4"), 793 | ("lab_f5", "l5"), 794 | ("lab_f6", "l6"), 795 | ("lab_f7", "l7"), 796 | ("lab_f8", "l8"), 797 | ("lab_f9", "l9"), 798 | ("lab_f10", "la"), 799 | ("label_format", "Lf"), 800 | ("label_off", "LF"), 801 | ("label_on", "LO"), 802 | ("meta_off", "mo"), 803 | ("meta_on", "mm"), 804 | ("micro_column_address", "ZY"), 805 | ("micro_down", "ZZ"), 806 | ("micro_left", "Za"), 807 | ("micro_right", "Zb"), 808 | ("micro_row_address", "Zc"), 809 | ("micro_up", "Zd"), 810 | ("mouse_info", "Mi"), 811 | ("newline", "nw"), 812 | ("order_of_pins", "Ze"), 813 | ("orig_colors", "oc"), 814 | ("orig_pair", "op"), 815 | ("pad_char", "pc"), 816 | ("parm_dch", "DC"), 817 | ("parm_delete_line", "DL"), 818 | ("parm_down_cursor", "DO"), 819 | ("parm_down_micro", "Zf"), 820 | ("parm_ich", "IC"), 821 | ("parm_index", "SF"), 822 | ("parm_insert_line", "AL"), 823 | ("parm_left_cursor", "LE"), 824 | ("parm_left_micro", "Zg"), 825 | ("parm_right_cursor", "RI"), 826 | ("parm_right_micro", "Zh"), 827 | ("parm_rindex", "SR"), 828 | ("parm_up_cursor", "UP"), 829 | ("parm_up_micro", "Zi"), 830 | ("pc_term_options", "S6"), 831 | ("pkey_key", "pk"), 832 | ("pkey_local", "pl"), 833 | ("pkey_plab", "xl"), 834 | ("pkey_xmit", "px"), 835 | ("plab_norm", "pn"), 836 | ("print_screen", "ps"), 837 | ("prtr_non", "pO"), 838 | ("prtr_off", "pf"), 839 | ("prtr_on", "po"), 840 | ("pulse", "PU"), 841 | ("quick_dial", "QD"), 842 | ("remove_clock", "RC"), 843 | ("repeat_char", "rp"), 844 | ("req_for_input", "RF"), 845 | ("req_mouse_pos", "RQ"), 846 | ("reset_1string", "r1"), 847 | ("reset_2string", "r2"), 848 | ("reset_3string", "r3"), 849 | ("reset_file", "rf"), 850 | ("restore_cursor", "rc"), 851 | ("row_address", "cv"), 852 | ("save_cursor", "sc"), 853 | ("scancode_escape", "S7"), 854 | ("scroll_forward", "sf"), 855 | ("scroll_reverse", "sr"), 856 | ("select_char_set", "Zj"), 857 | ("set0_des_seq", "s0"), 858 | ("set1_des_seq", "s1"), 859 | ("set2_des_seq", "s2"), 860 | ("set3_des_seq", "s3"), 861 | ("set_a_background", "AB"), 862 | ("set_a_foreground", "AF"), 863 | ("set_attributes", "sa"), 864 | ("set_background", "Sb"), 865 | ("set_bottom_margin", "Zk"), 866 | ("set_bottom_margin_parm", "Zl"), 867 | ("set_clock", "SC"), 868 | ("set_color_band", "Yz"), 869 | ("set_color_pair", "sp"), 870 | ("set_foreground", "Sf"), 871 | ("set_left_margin", "ML"), 872 | ("set_left_margin_parm", "Zm"), 873 | ("set_page_length", "YZ"), 874 | ("set_pglen_inch", "YI"), 875 | ("set_right_margin", "MR"), 876 | ("set_right_margin_parm", "Zn"), 877 | ("set_tab", "st"), 878 | ("set_tb_margin", "MT"), 879 | ("set_top_margin", "Zo"), 880 | ("set_top_margin_parm", "Zp"), 881 | ("set_window", "wi"), 882 | ("start_bit_image", "Zq"), 883 | ("start_char_set_def", "Zr"), 884 | ("stop_bit_image", "Zs"), 885 | ("stop_char_set_def", "Zt"), 886 | ("subscript_characters", "Zu"), 887 | ("superscript_characters", "Zv"), 888 | ("tab", "ta"), 889 | ("these_cause_cr", "Zw"), 890 | ("to_status_line", "ts"), 891 | ("tone", "TO"), 892 | ("user0", "u0"), 893 | ("user1", "u1"), 894 | ("user2", "u2"), 895 | ("user3", "u3"), 896 | ("user4", "u4"), 897 | ("user5", "u5"), 898 | ("user6", "u6"), 899 | ("user7", "u7"), 900 | ("user8", "u8"), 901 | ("user9", "u9"), 902 | ("underline_char", "uc"), 903 | ("up_half_line", "hu"), 904 | ("wait_tone", "WA"), 905 | ("xoff_character", "XF"), 906 | ("xon_character", "XN"), 907 | ("zero_motion", "Zx"), 908 | ]; 909 | 910 | fn main() { 911 | let path = Path::new(&env::var("OUT_DIR").unwrap()).join("names.rs"); 912 | let mut file = BufWriter::new(File::create(&path).unwrap()); 913 | 914 | write!(&mut file, "pub static BOOLEAN: ::phf::Map = ").unwrap(); 915 | let mut builder = phf_codegen::Map::new(); 916 | for (index, name) in BOOLEAN.iter().enumerate() { 917 | builder.entry(index as u16, &format!("\"{}\"", name)); 918 | } 919 | write!(&mut file, "{}", builder.build()).unwrap(); 920 | writeln!(&mut file, ";").unwrap(); 921 | 922 | let keys = BOOLEAN.iter().map(|n| format!("\"{}\"", n)).collect::>(); 923 | write!(&mut file, "pub static BOOLEAN_INDEX: ::phf::Map<&'static str, u16> = ").unwrap(); 924 | let mut builder = phf_codegen::Map::<&str>::new(); 925 | for (index, name) in keys.iter().enumerate() { 926 | builder.entry(name, &index.to_string()); 927 | } 928 | write!(&mut file, "{}", builder.build()).unwrap(); 929 | writeln!(&mut file, ";").unwrap(); 930 | 931 | write!(&mut file, "pub static NUMBER: ::phf::Map = ").unwrap(); 932 | let mut builder = phf_codegen::Map::new(); 933 | for (index, name) in NUMBER.iter().enumerate() { 934 | builder.entry(index as u16, &format!("\"{}\"", name)); 935 | } 936 | write!(&mut file, "{}", builder.build()).unwrap(); 937 | writeln!(&mut file, ";").unwrap(); 938 | 939 | let keys = NUMBER.iter().map(|n| format!("\"{}\"", n)).collect::>(); 940 | write!(&mut file, "pub static NUMBER_INDEX: ::phf::Map<&'static str, u16> = ").unwrap(); 941 | let mut builder = phf_codegen::Map::<&str>::new(); 942 | for (index, name) in keys.iter().enumerate() { 943 | builder.entry(name, &index.to_string()); 944 | } 945 | write!(&mut file, "{}", builder.build()).unwrap(); 946 | writeln!(&mut file, ";").unwrap(); 947 | 948 | write!(&mut file, "pub static STRING: ::phf::Map = ").unwrap(); 949 | let mut builder = phf_codegen::Map::new(); 950 | for (index, name) in STRING.iter().enumerate() { 951 | builder.entry(index as u16, &format!("\"{}\"", name)); 952 | } 953 | write!(&mut file, "{}", builder.build()).unwrap(); 954 | writeln!(&mut file, ";").unwrap(); 955 | 956 | let keys = STRING.iter().map(|n| format!("\"{}\"", n)).collect::>(); 957 | write!(&mut file, "pub static STRING_INDEX: ::phf::Map<&'static str, u16> = ").unwrap(); 958 | let mut builder = phf_codegen::Map::<&str>::new(); 959 | for (index, name) in keys.iter().enumerate() { 960 | builder.entry(name, &index.to_string()); 961 | } 962 | write!(&mut file, "{}", builder.build()).unwrap(); 963 | writeln!(&mut file, ";").unwrap(); 964 | 965 | write!(&mut file, "pub static TERMINFO: ::phf::Map<&'static str, &'static str> = ").unwrap(); 966 | let mut builder = phf_codegen::Map::new(); 967 | for &(name, value) in TERMINFO { 968 | builder.entry(name, &format!("\"{}\"", value)); 969 | } 970 | write!(&mut file, "{}", builder.build()).unwrap(); 971 | writeln!(&mut file, ";").unwrap(); 972 | 973 | write!(&mut file, "pub static TERMCAP: ::phf::Map<&'static str, &'static str> = ").unwrap(); 974 | let mut builder = phf_codegen::Map::new(); 975 | for &(name, value) in TERMCAP { 976 | builder.entry(name, &format!("\"{}\"", value)); 977 | } 978 | write!(&mut file, "{}", builder.build()).unwrap(); 979 | writeln!(&mut file, ";").unwrap(); 980 | 981 | write!(&mut file, "pub static ALIASES: ::phf::Map<&'static str, &'static str> = ").unwrap(); 982 | let mut builder = phf_codegen::Map::new(); 983 | for &(value, name) in TERMINFO { 984 | builder.entry(name, &format!("\"{}\"", value)); 985 | } 986 | for &(value, name) in TERMCAP { 987 | if !TERMINFO.iter().any(|entry| name == entry.1) { 988 | builder.entry(name, &format!("\"{}\"", value)); 989 | } 990 | } 991 | write!(&mut file, "{}", builder.build()).unwrap(); 992 | writeln!(&mut file, ";").unwrap(); 993 | } 994 | -------------------------------------------------------------------------------- /examples/parse.rs: -------------------------------------------------------------------------------- 1 | // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | // Version 2, December 2004 3 | // 4 | // Copyleft (ↄ) meh. | http://meh.schizofreni.co 5 | // 6 | // Everyone is permitted to copy and distribute verbatim or modified 7 | // copies of this license document, and changing it is allowed as long 8 | // as the name is changed. 9 | // 10 | // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | // TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | // 13 | // 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | 15 | use std::env; 16 | 17 | fn main() { 18 | println!("{:?}", terminfo::Database::from_path(env::args().nth(1).expect("no file given"))); 19 | } 20 | -------------------------------------------------------------------------------- /examples/set_attributes.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | use terminfo::{capability as cap, Database}; 3 | 4 | fn main() { 5 | let info = Database::from_env().unwrap(); 6 | 7 | if let Some(set_attributes) = info.get::() { 8 | let clear = info.get::().unwrap(); 9 | 10 | set_attributes.expand().bold(true).underline(true).to(io::stdout()).unwrap(); 11 | 12 | println!("bold and underline"); 13 | 14 | clear.expand().to(io::stdout()).unwrap(); 15 | } else { 16 | println!("The terminal does not support mass-setting attributes"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/simple.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | use terminfo::{capability as cap, Database}; 3 | 4 | fn main() { 5 | let info = Database::from_env().unwrap(); 6 | 7 | if let Some(cap::MaxColors(n)) = info.get::() { 8 | println!("The terminal supports {} colors.", n); 9 | } else { 10 | println!("The terminal does not support colors, what year is this?"); 11 | } 12 | 13 | if let Some(flash) = info.get::() { 14 | flash.expand().to(io::stdout()).unwrap(); 15 | } else { 16 | println!("FLASH GORDON!"); 17 | } 18 | 19 | info.get::().unwrap().expand().color(2).to(io::stdout()).unwrap(); 20 | info.get::().unwrap().expand().color(4).to(io::stdout()).unwrap(); 21 | println!("SUP"); 22 | info.get::().unwrap().expand().to(io::stdout()).unwrap(); 23 | } 24 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | hard_tabs = true 2 | use_small_heuristics = "Max" 3 | -------------------------------------------------------------------------------- /src/capability.rs: -------------------------------------------------------------------------------- 1 | // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | // Version 2, December 2004 3 | // 4 | // Copyleft (ↄ) meh. | http://meh.schizofreni.co 5 | // 6 | // Everyone is permitted to copy and distribute verbatim or modified 7 | // copies of this license document, and changing it is allowed as long 8 | // as the name is changed. 9 | // 10 | // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | // TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | // 13 | // 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | 15 | //! Standard capabilities. 16 | 17 | use std::borrow::Cow; 18 | use std::io::Write; 19 | 20 | use crate::error; 21 | use crate::expand::{Context, Expand, Parameter}; 22 | 23 | /// A trait for any object that will represent a terminal capability. 24 | pub trait Capability<'a>: Sized { 25 | /// Returns the name of the capability in its long form. 26 | fn name() -> &'static str; 27 | 28 | /// Parse the capability from its raw value. 29 | fn from(value: Option<&'a Value>) -> Option; 30 | 31 | /// Convert the capability into its raw value. 32 | fn into(self) -> Option; 33 | } 34 | 35 | /// Possible value types for capabilities. 36 | #[derive(Eq, PartialEq, Clone, Debug)] 37 | pub enum Value { 38 | /// A boolean. 39 | True, 40 | 41 | /// A number. 42 | Number(i32), 43 | 44 | /// An ASCII string requiring expansion. 45 | String(Vec), 46 | } 47 | 48 | /// Expansion helper struct. 49 | #[derive(Debug)] 50 | pub struct Expansion<'a, T: 'a + AsRef<[u8]>> { 51 | string: &'a T, 52 | params: [Parameter; 9], 53 | context: Option<&'a mut Context>, 54 | } 55 | 56 | impl<'a, T: AsRef<[u8]>> Expansion<'a, T> { 57 | /// Expand using the given context. 58 | pub fn with<'c: 'a>(mut self, context: &'c mut Context) -> Self { 59 | self.context = Some(context); 60 | self 61 | } 62 | 63 | /// Expand to the given output. 64 | pub fn to(self, output: W) -> error::Result<()> { 65 | self.string.as_ref().expand( 66 | output, 67 | &self.params, 68 | self.context.unwrap_or(&mut Default::default()), 69 | ) 70 | } 71 | 72 | /// Expand into a vector. 73 | pub fn to_vec(self) -> error::Result> { 74 | let mut result = Vec::with_capacity(self.string.as_ref().len()); 75 | self.to(&mut result)?; 76 | Ok(result) 77 | } 78 | } 79 | 80 | macro_rules! from { 81 | (number $ty:ty) => { 82 | impl From<$ty> for Value { 83 | fn from(value: $ty) -> Self { 84 | Value::Number(value as i32) 85 | } 86 | } 87 | }; 88 | 89 | (string ref $ty:ty) => { 90 | impl<'a> From<&'a $ty> for Value { 91 | fn from(value: &'a $ty) -> Self { 92 | Value::String(value.into()) 93 | } 94 | } 95 | }; 96 | 97 | (string $ty:ty) => { 98 | impl From<$ty> for Value { 99 | fn from(value: $ty) -> Self { 100 | Value::String(value.into()) 101 | } 102 | } 103 | }; 104 | } 105 | 106 | impl From<()> for Value { 107 | fn from(_: ()) -> Self { 108 | Value::True 109 | } 110 | } 111 | 112 | from!(number u8); 113 | from!(number i8); 114 | from!(number u16); 115 | from!(number i16); 116 | from!(number u32); 117 | from!(number i32); 118 | 119 | from!(string String); 120 | from!(string ref str); 121 | from!(string Vec); 122 | from!(string ref [u8]); 123 | 124 | macro_rules! define { 125 | (boolean $ident:ident => $capability:expr) => ( 126 | #[derive(Eq, PartialEq, Copy, Clone, Debug)] 127 | pub struct $ident(pub bool); 128 | 129 | impl<'a> Capability<'a> for $ident { 130 | #[inline] 131 | fn name() -> &'static str { 132 | $capability 133 | } 134 | 135 | #[inline] 136 | fn from(value: Option<&Value>) -> Option { 137 | if let Some(&Value::True) = value { 138 | Some($ident(true)) 139 | } 140 | else { 141 | Some($ident(false)) 142 | } 143 | } 144 | 145 | #[inline] 146 | fn into(self) -> Option { 147 | if self.0 { 148 | Some(Value::True) 149 | } 150 | else { 151 | None 152 | } 153 | } 154 | } 155 | 156 | impl From<$ident> for bool { 157 | fn from(cap: $ident) -> Self { 158 | cap.0 159 | } 160 | } 161 | ); 162 | 163 | (number $ident:ident => $capability:expr) => ( 164 | #[derive(Eq, PartialEq, Copy, Clone, Debug)] 165 | pub struct $ident(pub i32); 166 | 167 | impl<'a> Capability<'a> for $ident { 168 | #[inline] 169 | fn name() -> &'static str { 170 | $capability 171 | } 172 | 173 | #[inline] 174 | fn from(value: Option<&Value>) -> Option { 175 | if let Some(&Value::Number(value)) = value { 176 | Some($ident(value)) 177 | } 178 | else { 179 | None 180 | } 181 | } 182 | 183 | #[inline] 184 | fn into(self) -> Option { 185 | Some(Value::Number(self.0)) 186 | } 187 | } 188 | 189 | impl From<$ident> for i32 { 190 | fn from(cap: $ident) -> Self { 191 | cap.0 192 | } 193 | } 194 | ); 195 | 196 | (string define $ident:ident => $capability:expr) => ( 197 | #[derive(Eq, PartialEq, Clone, Debug)] 198 | pub struct $ident<'a>(Cow<'a, [u8]>); 199 | 200 | impl<'a> Capability<'a> for $ident<'a> { 201 | #[inline] 202 | fn name() -> &'static str { 203 | $capability 204 | } 205 | 206 | #[inline] 207 | fn from(value: Option<&'a Value>) -> Option<$ident<'a>> { 208 | if let Some(&Value::String(ref value)) = value { 209 | Some($ident(Cow::Borrowed(value))) 210 | } 211 | else { 212 | None 213 | } 214 | } 215 | 216 | #[inline] 217 | fn into(self) -> Option { 218 | Some(Value::String(match self.0 { 219 | Cow::Borrowed(value) => 220 | value.into(), 221 | 222 | Cow::Owned(value) => 223 | value 224 | })) 225 | } 226 | } 227 | 228 | impl<'a, T: AsRef<&'a [u8]>> From for $ident<'a> { 229 | #[inline] 230 | fn from(value: T) -> Self { 231 | $ident(Cow::Borrowed(value.as_ref())) 232 | } 233 | } 234 | 235 | impl<'a> AsRef<[u8]> for $ident<'a> { 236 | #[inline] 237 | fn as_ref(&self) -> &[u8] { 238 | &self.0 239 | } 240 | } 241 | 242 | impl<'a> $ident<'a> { 243 | /// Begin expanding the capability. 244 | #[inline] 245 | pub fn expand(&self) -> Expansion<$ident> { 246 | Expansion { 247 | string: self, 248 | params: Default::default(), 249 | context: None, 250 | } 251 | } 252 | } 253 | ); 254 | 255 | (string $ident:ident => $capability:expr) => ( 256 | define!(string define $ident => $capability); 257 | ); 258 | 259 | (string $ident:ident => $capability:expr; $($rest:tt)+) => ( 260 | define!(string define $ident => $capability); 261 | define!(string parameters $ident; $($rest)+); 262 | define!(string builder $ident; 0, $($rest)+, ); 263 | ); 264 | 265 | (string parameters $ident:ident; $($name:ident : $ty:ty),+) => ( 266 | impl<'a> Expansion<'a, $ident<'a>> { 267 | /// Pass all expansion parameters at once. 268 | #[allow(unused_assignments)] 269 | #[inline] 270 | // https://github.com/meh/rust-terminfo/issues/28 271 | #[allow(clippy::too_many_arguments)] 272 | pub fn parameters(mut self, $($name: $ty),*) -> Self { 273 | let mut index = 0; 274 | 275 | $({ 276 | self.params[index] = $name.into(); 277 | index += 1; 278 | })*; 279 | 280 | self 281 | } 282 | } 283 | ); 284 | 285 | (string builder $ident:ident; $index:expr, ) => (); 286 | 287 | (string builder $ident:ident; $index:expr, $name:ident : u8, $($rest:tt)*) => ( 288 | define!(string builder direct $ident; $index, $name : u8); 289 | define!(string builder $ident; $index + 1, $($rest)*); 290 | ); 291 | 292 | (string builder $ident:ident; $index:expr, $name:ident : i8, $($rest:tt)*) => ( 293 | define!(string builder direct $ident; $index, $name : i8); 294 | define!(string builder $ident; $index + 1, $($rest)*); 295 | ); 296 | 297 | (string builder $ident:ident; $index:expr, $name:ident : u16, $($rest:tt)*) => ( 298 | define!(string builder direct $ident; $index, $name : u16); 299 | define!(string builder $ident; $index + 1, $($rest)*); 300 | ); 301 | 302 | (string builder $ident:ident; $index:expr, $name:ident : i16 $($rest:tt)*) => ( 303 | define!(string builder direct $ident; $index, $name : i16); 304 | define!(string builder $ident; $index + 1, $($rest)*); 305 | ); 306 | 307 | (string builder $ident:ident; $index:expr, $name:ident : u32, $($rest:tt)*) => ( 308 | define!(string builder direct $ident; $index, $name : u32); 309 | define!(string builder $ident; $index + 1, $($rest)*); 310 | ); 311 | 312 | (string builder $ident:ident; $index:expr, $name:ident : i32, $($rest:tt)*) => ( 313 | define!(string builder direct $ident; $index, $name : i32); 314 | define!(string builder $ident; $index + 1, $($rest)*); 315 | ); 316 | 317 | (string builder $ident:ident; $index:expr, $name:ident : $ty:ty, $($rest:tt)*) => ( 318 | define!(string builder into $ident; $index, $name : $ty); 319 | define!(string builder $ident; $index + 1, $($rest)*); 320 | ); 321 | 322 | (string builder direct $ident:ident; $index:expr, $name:ident : $ty:ty) => ( 323 | impl<'a> Expansion<'a, $ident<'a>> { 324 | /// Set the given parameter. 325 | #[inline] 326 | pub fn $name(mut self, value: $ty) -> Self { 327 | self.params[$index] = value.into(); 328 | self 329 | } 330 | } 331 | ); 332 | 333 | (string builder into $ident:ident; $index:expr, $name:ident : $ty:ty) => ( 334 | impl<'a> Expansion<'a, $ident<'a>> { 335 | /// Set the given parameter. 336 | #[inline] 337 | pub fn $name>(mut self, value: T) -> Self { 338 | self.params[$index] = value.into().into(); 339 | self 340 | } 341 | } 342 | ); 343 | } 344 | 345 | define!(boolean AutoLeftMargin => "auto_left_margin"); 346 | define!(boolean AutoRightMargin => "auto_right_margin"); 347 | define!(boolean NoEscCtlc => "no_esc_ctlc"); 348 | define!(boolean CeolStandoutGlitch => "ceol_standout_glitch"); 349 | define!(boolean EatNewlineGlitch => "eat_newline_glitch"); 350 | define!(boolean EraseOverstrike => "erase_overstrike"); 351 | define!(boolean GenericType => "generic_type"); 352 | define!(boolean HardCopy => "hard_copy"); 353 | define!(boolean HasMetaKey => "has_meta_key"); 354 | define!(boolean HasStatusLine => "has_status_line"); 355 | define!(boolean InsertNullGlitch => "insert_null_glitch"); 356 | define!(boolean MemoryAbove => "memory_above"); 357 | define!(boolean MemoryBelow => "memory_below"); 358 | define!(boolean MoveInsertMode => "move_insert_mode"); 359 | define!(boolean MoveStandoutMode => "move_standout_mode"); 360 | define!(boolean OverStrike => "over_strike"); 361 | define!(boolean StatusLineEscOk => "status_line_esc_ok"); 362 | define!(boolean DestTabsMagicSmso => "dest_tabs_magic_smso"); 363 | define!(boolean TildeGlitch => "tilde_glitch"); 364 | define!(boolean TransparentUnderline => "transparent_underline"); 365 | define!(boolean XonXoff => "xon_xoff"); 366 | define!(boolean NeedsXonXoff => "needs_xon_xoff"); 367 | define!(boolean PrtrSilent => "prtr_silent"); 368 | define!(boolean HardCursor => "hard_cursor"); 369 | define!(boolean NonRevRmcup => "non_rev_rmcup"); 370 | define!(boolean NoPadChar => "no_pad_char"); 371 | define!(boolean NonDestScrollRegion => "non_dest_scroll_region"); 372 | define!(boolean CanChange => "can_change"); 373 | define!(boolean BackColorErase => "back_color_erase"); 374 | define!(boolean HueLightnessSaturation => "hue_lightness_saturation"); 375 | define!(boolean ColAddrGlitch => "col_addr_glitch"); 376 | define!(boolean CrCancelsMicroMode => "cr_cancels_micro_mode"); 377 | define!(boolean HasPrintWheel => "has_print_wheel"); 378 | define!(boolean RowAddrGlitch => "row_addr_glitch"); 379 | define!(boolean SemiAutoRightMargin => "semi_auto_right_margin"); 380 | define!(boolean CpiChangesRes => "cpi_changes_res"); 381 | define!(boolean LpiChangesRes => "lpi_changes_res"); 382 | define!(boolean BackspacesWithBs => "backspaces_with_bs"); 383 | define!(boolean CrtNoScrolling => "crt_no_scrolling"); 384 | define!(boolean NoCorrectlyWorkingCr => "no_correctly_working_cr"); 385 | define!(boolean GnuHasMetaKey => "gnu_has_meta_key"); 386 | define!(boolean LinefeedIsNewline => "linefeed_is_newline"); 387 | define!(boolean HasHardwareTabs => "has_hardware_tabs"); 388 | define!(boolean ReturnDoesClrEol => "return_does_clr_eol"); 389 | 390 | define!(number Columns => "columns"); 391 | define!(number InitTabs => "init_tabs"); 392 | define!(number Lines => "lines"); 393 | define!(number LinesOfMemory => "lines_of_memory"); 394 | define!(number MagicCookieGlitch => "magic_cookie_glitch"); 395 | define!(number PaddingBaudRate => "padding_baud_rate"); 396 | define!(number VirtualTerminal => "virtual_terminal"); 397 | define!(number WidthStatusLine => "width_status_line"); 398 | define!(number NumLabels => "num_labels"); 399 | define!(number LabelHeight => "label_height"); 400 | define!(number LabelWidth => "label_width"); 401 | define!(number MaxAttributes => "max_attributes"); 402 | define!(number MaximumWindows => "maximum_windows"); 403 | define!(number MaxColors => "max_colors"); 404 | define!(number MaxPairs => "max_pairs"); 405 | define!(number NoColorVideo => "no_color_video"); 406 | define!(number BufferCapacity => "buffer_capacity"); 407 | define!(number DotVertSpacing => "dot_vert_spacing"); 408 | define!(number DotHorzSpacing => "dot_horz_spacing"); 409 | define!(number MaxMicroAddress => "max_micro_address"); 410 | define!(number MaxMicroJump => "max_micro_jump"); 411 | define!(number MicroColSize => "micro_col_size"); 412 | define!(number MicroLineSize => "micro_line_size"); 413 | define!(number NumberOfPins => "number_of_pins"); 414 | define!(number OutputResChar => "output_res_char"); 415 | define!(number OutputResLine => "output_res_line"); 416 | define!(number OutputResHorzInch => "output_res_horz_inch"); 417 | define!(number OutputResVertInch => "output_res_vert_inch"); 418 | define!(number PrintRate => "print_rate"); 419 | define!(number WideCharSize => "wide_char_size"); 420 | define!(number Buttons => "buttons"); 421 | define!(number BitImageEntwining => "bit_image_entwining"); 422 | define!(number BitImageType => "bit_image_type"); 423 | define!(number MagicCookieGlitchUl => "magic_cookie_glitch_ul"); 424 | define!(number CarriageReturnDelay => "carriage_return_delay"); 425 | define!(number NewLineDelay => "new_line_delay"); 426 | define!(number BackspaceDelay => "backspace_delay"); 427 | define!(number HorizontalTabDelay => "horizontal_tab_delay"); 428 | define!(number NumberOfFunctionKeys => "number_of_function_keys"); 429 | 430 | define!(string BackTab => "back_tab"); 431 | define!(string Bell => "bell"); 432 | define!(string CarriageReturn => "carriage_return"); 433 | define!(string ClearAllTabs => "clear_all_tabs"); 434 | define!(string ClearScreen => "clear_screen"); 435 | define!(string ClrEol => "clr_eol"); 436 | define!(string ClrEos => "clr_eos"); 437 | define!(string CommandCharacter => "command_character"); 438 | define!(string CursorDown => "cursor_down"); 439 | define!(string CursorHome => "cursor_home"); 440 | define!(string CursorInvisible => "cursor_invisible"); 441 | define!(string CursorLeft => "cursor_left"); 442 | define!(string CursorMemAddress => "cursor_mem_address"); 443 | define!(string CursorNormal => "cursor_normal"); 444 | define!(string CursorRight => "cursor_right"); 445 | define!(string CursorToLl => "cursor_to_ll"); 446 | define!(string CursorUp => "cursor_up"); 447 | define!(string CursorVisible => "cursor_visible"); 448 | define!(string DeleteCharacter => "delete_character"); 449 | define!(string DeleteLine => "delete_line"); 450 | define!(string DisStatusLine => "dis_status_line"); 451 | define!(string DownHalfLine => "down_half_line"); 452 | define!(string EnterAltCharsetMode => "enter_alt_charset_mode"); 453 | define!(string EnterBlinkMode => "enter_blink_mode"); 454 | define!(string EnterBoldMode => "enter_bold_mode"); 455 | define!(string EnterCaMode => "enter_ca_mode"); 456 | define!(string EnterDeleteMode => "enter_delete_mode"); 457 | define!(string EnterDimMode => "enter_dim_mode"); 458 | define!(string EnterInsertMode => "enter_insert_mode"); 459 | define!(string EnterSecureMode => "enter_secure_mode"); 460 | define!(string EnterProtectedMode => "enter_protected_mode"); 461 | define!(string EnterReverseMode => "enter_reverse_mode"); 462 | define!(string EnterStandoutMode => "enter_standout_mode"); 463 | define!(string EnterUnderlineMode => "enter_underline_mode"); 464 | define!(string ExitAltCharsetMode => "exit_alt_charset_mode"); 465 | define!(string ExitAttributeMode => "exit_attribute_mode"); 466 | define!(string ExitCaMode => "exit_ca_mode"); 467 | define!(string ExitDeleteMode => "exit_delete_mode"); 468 | define!(string ExitInsertMode => "exit_insert_mode"); 469 | define!(string ExitStandoutMode => "exit_standout_mode"); 470 | define!(string ExitUnderlineMode => "exit_underline_mode"); 471 | define!(string FlashScreen => "flash_screen"); 472 | define!(string FormFeed => "form_feed"); 473 | define!(string FromStatusLine => "from_status_line"); 474 | define!(string Init1String => "init_1string"); 475 | define!(string Init2String => "init_2string"); 476 | define!(string Init3String => "init_3string"); 477 | define!(string InitFile => "init_file"); 478 | define!(string InsertCharacter => "insert_character"); 479 | define!(string InsertLine => "insert_line"); 480 | define!(string InsertPadding => "insert_padding"); 481 | define!(string KeyBackspace => "key_backspace"); 482 | define!(string KeyCATab => "key_catab"); 483 | define!(string KeyClear => "key_clear"); 484 | define!(string KeyCTab => "key_ctab"); 485 | define!(string KeyDc => "key_dc"); 486 | define!(string KeyDl => "key_dl"); 487 | define!(string KeyDown => "key_down"); 488 | define!(string KeyEic => "key_eic"); 489 | define!(string KeyEol => "key_eol"); 490 | define!(string KeyEos => "key_eos"); 491 | define!(string KeyF0 => "key_f0"); 492 | define!(string KeyF1 => "key_f1"); 493 | define!(string KeyF10 => "key_f10"); 494 | define!(string KeyF2 => "key_f2"); 495 | define!(string KeyF3 => "key_f3"); 496 | define!(string KeyF4 => "key_f4"); 497 | define!(string KeyF5 => "key_f5"); 498 | define!(string KeyF6 => "key_f6"); 499 | define!(string KeyF7 => "key_f7"); 500 | define!(string KeyF8 => "key_f8"); 501 | define!(string KeyF9 => "key_f9"); 502 | define!(string KeyHome => "key_home"); 503 | define!(string KeyIc => "key_ic"); 504 | define!(string KeyIl => "key_il"); 505 | define!(string KeyLeft => "key_left"); 506 | define!(string KeyLl => "key_ll"); 507 | define!(string KeyNPage => "key_npage"); 508 | define!(string KeyPPage => "key_ppage"); 509 | define!(string KeyRight => "key_right"); 510 | define!(string KeySf => "key_sf"); 511 | define!(string KeySr => "key_sr"); 512 | define!(string KeySTab => "key_stab"); 513 | define!(string KeyUp => "key_up"); 514 | define!(string KeypadLocal => "keypad_local"); 515 | define!(string KeypadXmit => "keypad_xmit"); 516 | define!(string LabF0 => "lab_f0"); 517 | define!(string LabF1 => "lab_f1"); 518 | define!(string LabF10 => "lab_f10"); 519 | define!(string LabF2 => "lab_f2"); 520 | define!(string LabF3 => "lab_f3"); 521 | define!(string LabF4 => "lab_f4"); 522 | define!(string LabF5 => "lab_f5"); 523 | define!(string LabF6 => "lab_f6"); 524 | define!(string LabF7 => "lab_f7"); 525 | define!(string LabF8 => "lab_f8"); 526 | define!(string LabF9 => "lab_f9"); 527 | define!(string MetaOff => "meta_off"); 528 | define!(string MetaOn => "meta_on"); 529 | define!(string Newline => "newline"); 530 | define!(string PadChar => "pad_char"); 531 | define!(string PKeyKey => "pkey_key"); 532 | define!(string PKeyLocal => "pkey_local"); 533 | define!(string PKeyXmit => "pkey_xmit"); 534 | define!(string PrintScreen => "print_screen"); 535 | define!(string PrtrOff => "prtr_off"); 536 | define!(string PrtrOn => "prtr_on"); 537 | define!(string RepeatChar => "repeat_char"); 538 | define!(string Reset1String => "reset_1string"); 539 | define!(string Reset2String => "reset_2string"); 540 | define!(string Reset3String => "reset_3string"); 541 | define!(string ResetFile => "reset_file"); 542 | define!(string RestoreCursor => "restore_cursor"); 543 | define!(string SaveCursor => "save_cursor"); 544 | define!(string ScrollForward => "scroll_forward"); 545 | define!(string ScrollReverse => "scroll_reverse"); 546 | define!(string SetTab => "set_tab"); 547 | define!(string SetWindow => "set_window"); 548 | define!(string Tab => "tab"); 549 | define!(string ToStatusLine => "to_status_line"); 550 | define!(string UnderlineChar => "underline_char"); 551 | define!(string UpHalfLine => "up_half_line"); 552 | define!(string InitProg => "init_prog"); 553 | define!(string KeyA1 => "key_a1"); 554 | define!(string KeyA3 => "key_a3"); 555 | define!(string KeyB2 => "key_b2"); 556 | define!(string KeyC1 => "key_c1"); 557 | define!(string KeyC3 => "key_c3"); 558 | define!(string PrtrNon => "prtr_non"); 559 | define!(string CharPadding => "char_padding"); 560 | define!(string AcsChars => "acs_chars"); 561 | define!(string PlabNorm => "plab_norm"); 562 | define!(string KeyBTab => "key_btab"); 563 | define!(string EnterXonMode => "enter_xon_mode"); 564 | define!(string ExitXonMode => "exit_xon_mode"); 565 | define!(string EnterAmMode => "enter_am_mode"); 566 | define!(string ExitAmMode => "exit_am_mode"); 567 | define!(string XonCharacter => "xon_character"); 568 | define!(string XoffCharacter => "xoff_character"); 569 | define!(string EnaAcs => "ena_acs"); 570 | define!(string LabelOn => "label_on"); 571 | define!(string LabelOff => "label_off"); 572 | define!(string KeyBeg => "key_beg"); 573 | define!(string KeyCancel => "key_cancel"); 574 | define!(string KeyClose => "key_close"); 575 | define!(string KeyCommand => "key_command"); 576 | define!(string KeyCopy => "key_copy"); 577 | define!(string KeyCreate => "key_create"); 578 | define!(string KeyEnd => "key_end"); 579 | define!(string KeyEnter => "key_enter"); 580 | define!(string KeyExit => "key_exit"); 581 | define!(string KeyFind => "key_find"); 582 | define!(string KeyHelp => "key_help"); 583 | define!(string KeyMark => "key_mark"); 584 | define!(string KeyMessage => "key_message"); 585 | define!(string KeyMove => "key_move"); 586 | define!(string KeyNext => "key_next"); 587 | define!(string KeyOpen => "key_open"); 588 | define!(string KeyOptions => "key_options"); 589 | define!(string KeyPrevious => "key_previous"); 590 | define!(string KeyPrint => "key_print"); 591 | define!(string KeyRedo => "key_redo"); 592 | define!(string KeyReference => "key_reference"); 593 | define!(string KeyRefresh => "key_refresh"); 594 | define!(string KeyReplace => "key_replace"); 595 | define!(string KeyRestart => "key_restart"); 596 | define!(string KeyResume => "key_resume"); 597 | define!(string KeySave => "key_save"); 598 | define!(string KeySuspend => "key_suspend"); 599 | define!(string KeyUndo => "key_undo"); 600 | define!(string KeySBeg => "key_sbeg"); 601 | define!(string KeySCancel => "key_scancel"); 602 | define!(string KeySCommand => "key_scommand"); 603 | define!(string KeySCopy => "key_scopy"); 604 | define!(string KeySCreate => "key_screate"); 605 | define!(string KeySDc => "key_sdc"); 606 | define!(string KeySDl => "key_sdl"); 607 | define!(string KeySelect => "key_select"); 608 | define!(string KeySEnd => "key_send"); 609 | define!(string KeySEol => "key_seol"); 610 | define!(string KeySExit => "key_sexit"); 611 | define!(string KeySFind => "key_sfind"); 612 | define!(string KeySHelp => "key_shelp"); 613 | define!(string KeySHome => "key_shome"); 614 | define!(string KeySIc => "key_sic"); 615 | define!(string KeySLeft => "key_sleft"); 616 | define!(string KeySMessage => "key_smessage"); 617 | define!(string KeySMove => "key_smove"); 618 | define!(string KeySNext => "key_snext"); 619 | define!(string KeySOptions => "key_soptions"); 620 | define!(string KeySPrevious => "key_sprevious"); 621 | define!(string KeySPrint => "key_sprint"); 622 | define!(string KeySRedo => "key_sredo"); 623 | define!(string KeySReplace => "key_sreplace"); 624 | define!(string KeySRight => "key_sright"); 625 | define!(string KeySRsume => "key_srsume"); 626 | define!(string KeySSave => "key_ssave"); 627 | define!(string KeySSuspend => "key_ssuspend"); 628 | define!(string KeySUndo => "key_sundo"); 629 | define!(string ReqForInput => "req_for_input"); 630 | define!(string KeyF11 => "key_f11"); 631 | define!(string KeyF12 => "key_f12"); 632 | define!(string KeyF13 => "key_f13"); 633 | define!(string KeyF14 => "key_f14"); 634 | define!(string KeyF15 => "key_f15"); 635 | define!(string KeyF16 => "key_f16"); 636 | define!(string KeyF17 => "key_f17"); 637 | define!(string KeyF18 => "key_f18"); 638 | define!(string KeyF19 => "key_f19"); 639 | define!(string KeyF20 => "key_f20"); 640 | define!(string KeyF21 => "key_f21"); 641 | define!(string KeyF22 => "key_f22"); 642 | define!(string KeyF23 => "key_f23"); 643 | define!(string KeyF24 => "key_f24"); 644 | define!(string KeyF25 => "key_f25"); 645 | define!(string KeyF26 => "key_f26"); 646 | define!(string KeyF27 => "key_f27"); 647 | define!(string KeyF28 => "key_f28"); 648 | define!(string KeyF29 => "key_f29"); 649 | define!(string KeyF30 => "key_f30"); 650 | define!(string KeyF31 => "key_f31"); 651 | define!(string KeyF32 => "key_f32"); 652 | define!(string KeyF33 => "key_f33"); 653 | define!(string KeyF34 => "key_f34"); 654 | define!(string KeyF35 => "key_f35"); 655 | define!(string KeyF36 => "key_f36"); 656 | define!(string KeyF37 => "key_f37"); 657 | define!(string KeyF38 => "key_f38"); 658 | define!(string KeyF39 => "key_f39"); 659 | define!(string KeyF40 => "key_f40"); 660 | define!(string KeyF41 => "key_f41"); 661 | define!(string KeyF42 => "key_f42"); 662 | define!(string KeyF43 => "key_f43"); 663 | define!(string KeyF44 => "key_f44"); 664 | define!(string KeyF45 => "key_f45"); 665 | define!(string KeyF46 => "key_f46"); 666 | define!(string KeyF47 => "key_f47"); 667 | define!(string KeyF48 => "key_f48"); 668 | define!(string KeyF49 => "key_f49"); 669 | define!(string KeyF50 => "key_f50"); 670 | define!(string KeyF51 => "key_f51"); 671 | define!(string KeyF52 => "key_f52"); 672 | define!(string KeyF53 => "key_f53"); 673 | define!(string KeyF54 => "key_f54"); 674 | define!(string KeyF55 => "key_f55"); 675 | define!(string KeyF56 => "key_f56"); 676 | define!(string KeyF57 => "key_f57"); 677 | define!(string KeyF58 => "key_f58"); 678 | define!(string KeyF59 => "key_f59"); 679 | define!(string KeyF60 => "key_f60"); 680 | define!(string KeyF61 => "key_f61"); 681 | define!(string KeyF62 => "key_f62"); 682 | define!(string KeyF63 => "key_f63"); 683 | define!(string ClrBol => "clr_bol"); 684 | define!(string ClearMargins => "clear_margins"); 685 | define!(string SetLeftMargin => "set_left_margin"); 686 | define!(string SetRightMargin => "set_right_margin"); 687 | define!(string LabelFormat => "label_format"); 688 | define!(string SetClock => "set_clock"); 689 | define!(string DisplayClock => "display_clock"); 690 | define!(string RemoveClock => "remove_clock"); 691 | define!(string CreateWindow => "create_window"); 692 | define!(string GotoWindow => "goto_window"); 693 | define!(string Hangup => "hangup"); 694 | define!(string DialPhone => "dial_phone"); 695 | define!(string QuickDial => "quick_dial"); 696 | define!(string Tone => "tone"); 697 | define!(string Pulse => "pulse"); 698 | define!(string FlashHook => "flash_hook"); 699 | define!(string FixedPause => "fixed_pause"); 700 | define!(string WaitTone => "wait_tone"); 701 | define!(string User0 => "user0"); 702 | define!(string User1 => "user1"); 703 | define!(string User2 => "user2"); 704 | define!(string User3 => "user3"); 705 | define!(string User4 => "user4"); 706 | define!(string User5 => "user5"); 707 | define!(string User6 => "user6"); 708 | define!(string User7 => "user7"); 709 | define!(string User8 => "user8"); 710 | define!(string User9 => "user9"); 711 | define!(string OrigPair => "orig_pair"); 712 | define!(string OrigColors => "orig_colors"); 713 | define!(string InitializeColor => "initialize_color"); 714 | define!(string InitializePair => "initialize_pair"); 715 | define!(string SetColorPair => "set_color_pair"); 716 | define!(string ChangeCharPitch => "change_char_pitch"); 717 | define!(string ChangeLinePitch => "change_line_pitch"); 718 | define!(string ChangeResHorz => "change_res_horz"); 719 | define!(string ChangeResVert => "change_res_vert"); 720 | define!(string DefineChar => "define_char"); 721 | define!(string EnterDoublewideMode => "enter_doublewide_mode"); 722 | define!(string EnterDraftQuality => "enter_draft_quality"); 723 | define!(string EnterItalicsMode => "enter_italics_mode"); 724 | define!(string EnterLeftwardMode => "enter_leftward_mode"); 725 | define!(string EnterMicroMode => "enter_micro_mode"); 726 | define!(string EnterNearLetterQuality => "enter_near_letter_quality"); 727 | define!(string EnterNormalQuality => "enter_normal_quality"); 728 | define!(string EnterShadowMode => "enter_shadow_mode"); 729 | define!(string EnterSubscriptMode => "enter_subscript_mode"); 730 | define!(string EnterSuperscriptMode => "enter_superscript_mode"); 731 | define!(string EnterUpwardMode => "enter_upward_mode"); 732 | define!(string ExitDoublewideMode => "exit_doublewide_mode"); 733 | define!(string ExitItalicsMode => "exit_italics_mode"); 734 | define!(string ExitLeftwardMode => "exit_leftward_mode"); 735 | define!(string ExitMicroMode => "exit_micro_mode"); 736 | define!(string ExitShadowMode => "exit_shadow_mode"); 737 | define!(string ExitSubscriptMode => "exit_subscript_mode"); 738 | define!(string ExitSuperscriptMode => "exit_superscript_mode"); 739 | define!(string ExitUpwardMode => "exit_upward_mode"); 740 | define!(string MicroColumnAddress => "micro_column_address"); 741 | define!(string MicroDown => "micro_down"); 742 | define!(string MicroLeft => "micro_left"); 743 | define!(string MicroRight => "micro_right"); 744 | define!(string MicroRowAddress => "micro_row_address"); 745 | define!(string MicroUp => "micro_up"); 746 | define!(string OrderOfPins => "order_of_pins"); 747 | define!(string SelectCharSet => "select_char_set"); 748 | define!(string SetBottomMargin => "set_bottom_margin"); 749 | define!(string SetBottomMarginParm => "set_bottom_margin_parm"); 750 | define!(string SetLeftMarginParm => "set_left_margin_parm"); 751 | define!(string SetRightMarginParm => "set_right_margin_parm"); 752 | define!(string SetTopMargin => "set_top_margin"); 753 | define!(string SetTopMarginParm => "set_top_margin_parm"); 754 | define!(string StartBitImage => "start_bit_image"); 755 | define!(string StartCharSetDef => "start_char_set_def"); 756 | define!(string StopBitImage => "stop_bit_image"); 757 | define!(string StopCharSetDef => "stop_char_set_def"); 758 | define!(string SubscriptCharacters => "subscript_characters"); 759 | define!(string SuperscriptCharacters => "superscript_characters"); 760 | define!(string TheseCauseCr => "these_cause_cr"); 761 | define!(string ZeroMotion => "zero_motion"); 762 | define!(string CharSetNames => "char_set_names"); 763 | define!(string KeyMouse => "key_mouse"); 764 | define!(string MouseInfo => "mouse_info"); 765 | define!(string ReqMousePos => "req_mouse_pos"); 766 | define!(string GetMouse => "get_mouse"); 767 | define!(string PkeyPlab => "pkey_plab"); 768 | define!(string DeviceType => "device_type"); 769 | define!(string CodeSetInit => "code_set_init"); 770 | define!(string Set0DesSeq => "set0_des_seq"); 771 | define!(string Set1DesSeq => "set1_des_seq"); 772 | define!(string Set2DesSeq => "set2_des_seq"); 773 | define!(string Set3DesSeq => "set3_des_seq"); 774 | define!(string SetLrMargin => "set_lr_margin"); 775 | define!(string SetTbMargin => "set_tb_margin"); 776 | define!(string BitImageRepeat => "bit_image_repeat"); 777 | define!(string BitImageNewline => "bit_image_newline"); 778 | define!(string BitImageCarriageReturn => "bit_image_carriage_return"); 779 | define!(string ColorNames => "color_names"); 780 | define!(string DefineBitImageRegion => "define_bit_image_region"); 781 | define!(string EndBitImageRegion => "end_bit_image_region"); 782 | define!(string SetColorBand => "set_color_band"); 783 | define!(string SetPageLength => "set_page_length"); 784 | define!(string DisplayPcChar => "display_pc_char"); 785 | define!(string EnterPcCharsetMode => "enter_pc_charset_mode"); 786 | define!(string ExitPcCharsetMode => "exit_pc_charset_mode"); 787 | define!(string EnterScancodeMode => "enter_scancode_mode"); 788 | define!(string ExitScancodeMode => "exit_scancode_mode"); 789 | define!(string PcTermOptions => "pc_term_options"); 790 | define!(string ScancodeEscape => "scancode_escape"); 791 | define!(string AltScancodeEsc => "alt_scancode_esc"); 792 | define!(string EnterHorizontalHlMode => "enter_horizontal_hl_mode"); 793 | define!(string EnterLeftHlMode => "enter_left_hl_mode"); 794 | define!(string EnterLowHlMode => "enter_low_hl_mode"); 795 | define!(string EnterRightHlMode => "enter_right_hl_mode"); 796 | define!(string EnterTopHlMode => "enter_top_hl_mode"); 797 | define!(string EnterVerticalHlMode => "enter_vertical_hl_mode"); 798 | define!(string SetAAttributes => "set_a_attributes"); 799 | define!(string SetPglenInch => "set_pglen_inch"); 800 | define!(string TermcapInit2 => "termcap_init2"); 801 | define!(string TermcapReset => "termcap_reset"); 802 | define!(string LinefeedIfNotLf => "linefeed_if_not_lf"); 803 | define!(string BackspaceIfNotBs => "backspace_if_not_bs"); 804 | define!(string OtherNonFunctionKeys => "other_non_function_keys"); 805 | define!(string ArrowKeyMap => "arrow_key_map"); 806 | define!(string AcsULcorner => "acs_ulcorner"); 807 | define!(string AcsLLcorner => "acs_llcorner"); 808 | define!(string AcsURcorner => "acs_urcorner"); 809 | define!(string AcsLRcorner => "acs_lrcorner"); 810 | define!(string AcsLTee => "acs_ltee"); 811 | define!(string AcsRTee => "acs_rtee"); 812 | define!(string AcsBTee => "acs_btee"); 813 | define!(string AcsTTee => "acs_ttee"); 814 | define!(string AcsHLine => "acs_hline"); 815 | define!(string AcsVLine => "acs_vline"); 816 | define!(string AcsPlus => "acs_plus"); 817 | define!(string MemoryLock => "memory_lock"); 818 | define!(string MemoryUnlock => "memory_unlock"); 819 | define!(string BoxChars1 => "box_chars_1"); 820 | 821 | define!(string ChangeScrollRegion => "change_scroll_region"; 822 | top: u32, 823 | bottom: u32); 824 | 825 | define!(string ColumnAddress => "column_address"; 826 | x: u32); 827 | 828 | define!(string CursorAddress => "cursor_address"; 829 | y: u32, 830 | x: u32); 831 | 832 | define!(string EraseChars => "erase_chars"; 833 | count: u32); 834 | 835 | define!(string ParmDch => "parm_dch"; 836 | count: u32); 837 | 838 | define!(string ParmDeleteLine => "parm_delete_line"; 839 | count: u32); 840 | 841 | define!(string ParmDownCursor => "parm_down_cursor"; 842 | count: u32); 843 | 844 | define!(string ParmIch => "parm_ich"; 845 | count: u32); 846 | 847 | define!(string ParmIndex => "parm_index"; 848 | count: u32); 849 | 850 | define!(string ParmInsertLine => "parm_insert_line"; 851 | count: u32); 852 | 853 | define!(string ParmLeftCursor => "parm_left_cursor"; 854 | count: u32); 855 | 856 | define!(string ParmRightCursor => "parm_right_cursor"; 857 | count: u32); 858 | 859 | define!(string ParmRindex => "parm_rindex"; 860 | count: u32); 861 | 862 | define!(string ParmUpCursor => "parm_up_cursor"; 863 | count: u32); 864 | 865 | define!(string ParmDownMicro => "parm_down_micro"; 866 | count: u32); 867 | 868 | define!(string ParmLeftMicro => "parm_left_micro"; 869 | count: u32); 870 | 871 | define!(string ParmRightMicro => "parm_right_micro"; 872 | count: u32); 873 | 874 | define!(string ParmUpMicro => "parm_up_micro"; 875 | count: u32); 876 | 877 | define!(string RowAddress => "row_address"; 878 | y: u32); 879 | 880 | define!(string SetAttributes => "set_attributes"; 881 | standout: bool, 882 | underline: bool, 883 | reverse: bool, 884 | blink: bool, 885 | dim: bool, 886 | bold: bool, 887 | invisible: bool, 888 | protected: bool, 889 | alt_charset: bool); 890 | 891 | define!(string SetAForeground => "set_a_foreground"; 892 | color: u8); 893 | 894 | define!(string SetABackground => "set_a_background"; 895 | color: u8); 896 | 897 | define!(string SetForeground => "set_foreground"; 898 | color: u8); 899 | 900 | define!(string SetBackground => "set_background"; 901 | color: u8); 902 | 903 | // Extended capabilities from screen. 904 | define!(boolean XTermTitle => "XT"); 905 | define!(boolean BrightAttribute => "AX"); 906 | define!(boolean XTermMouse => "XM"); 907 | 908 | // Extended capabilities from tmux. 909 | define!(boolean TrueColor => "Tc"); 910 | 911 | define!(string SetClipboard => "Ms"; 912 | selection: String, 913 | content: Vec); 914 | 915 | define!(string SetCursorStyle => "Ss"; 916 | kind: u8); 917 | 918 | define!(string ResetCursorStyle => "Se"); 919 | 920 | // True color extended capabilities from vim. 921 | define!(string SetTrueColorForeground => "8f"; 922 | r: u8, 923 | g: u8, 924 | b: u8); 925 | 926 | define!(string SetTrueColorBackground => "8b"; 927 | r: u8, 928 | g: u8, 929 | b: u8); 930 | 931 | define!(string ResetCursorColor => "Cr"); 932 | 933 | define!(string SetCursorColor => "Cs"; 934 | color: String); 935 | 936 | #[cfg(test)] 937 | mod test { 938 | use super::*; 939 | use crate::Database; 940 | 941 | #[test] 942 | fn cursor_address() { 943 | assert_eq!( 944 | b"\x1B[3;5H".to_vec(), 945 | Database::from_path("tests/cancer-256color") 946 | .unwrap() 947 | .get::() 948 | .unwrap() 949 | .expand() 950 | .parameters(2, 4) 951 | .to_vec() 952 | .unwrap() 953 | ); 954 | 955 | assert_eq!( 956 | b"\x1B[3;5H".to_vec(), 957 | Database::from_path("tests/cancer-256color") 958 | .unwrap() 959 | .get::() 960 | .unwrap() 961 | .expand() 962 | .x(4) 963 | .y(2) 964 | .to_vec() 965 | .unwrap() 966 | ); 967 | 968 | assert_eq!( 969 | b"\x1B[38;2;50;100;150m".to_vec(), 970 | Database::from_path("tests/cancer-256color") 971 | .unwrap() 972 | .get::() 973 | .unwrap() 974 | .expand() 975 | .r(50) 976 | .g(100) 977 | .b(150) 978 | .to_vec() 979 | .unwrap() 980 | ); 981 | 982 | assert_eq!( 983 | b"\x1B]clipboard:set:PRIMARY:hue\x07".to_vec(), 984 | Database::from_path("tests/cancer-256color") 985 | .unwrap() 986 | .get::() 987 | .unwrap() 988 | .expand() 989 | .selection("PRIMARY") 990 | .content("hue") 991 | .to_vec() 992 | .unwrap() 993 | ); 994 | } 995 | } 996 | -------------------------------------------------------------------------------- /src/database.rs: -------------------------------------------------------------------------------- 1 | // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | // Version 2, December 2004 3 | // 4 | // Copyleft (ↄ) meh. | http://meh.schizofreni.co 5 | // 6 | // Everyone is permitted to copy and distribute verbatim or modified 7 | // copies of this license document, and changing it is allowed as long 8 | // as the name is changed. 9 | // 10 | // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | // TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | // 13 | // 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | 15 | use fnv::FnvHasher; 16 | use std::collections::HashMap; 17 | use std::env; 18 | use std::fs::{self, File}; 19 | use std::hash::BuildHasherDefault; 20 | use std::io::Read; 21 | use std::path::{Path, PathBuf}; 22 | 23 | use crate::capability::{Capability, Value}; 24 | use crate::error::{self, Error}; 25 | use crate::names; 26 | use crate::parser::compiled; 27 | 28 | /// A capability database. 29 | #[derive(Eq, PartialEq, Clone, Debug)] 30 | pub struct Database { 31 | name: String, 32 | aliases: Vec, 33 | description: String, 34 | inner: HashMap>, 35 | } 36 | 37 | /// Builder for a new `Database`. 38 | #[derive(Default, Debug)] 39 | pub struct Builder { 40 | name: Option, 41 | aliases: Vec, 42 | description: Option, 43 | inner: HashMap>, 44 | } 45 | 46 | impl Builder { 47 | /// Build the database. 48 | pub fn build(self) -> Result { 49 | Ok(Database { 50 | name: self.name.ok_or(())?, 51 | aliases: self.aliases, 52 | description: self.description.unwrap_or_default(), 53 | inner: self.inner, 54 | }) 55 | } 56 | 57 | /// Set the terminal name. 58 | pub fn name>(&mut self, name: T) -> &mut Self { 59 | self.name = Some(name.into()); 60 | self 61 | } 62 | 63 | /// Set the terminal aliases. 64 | pub fn aliases(&mut self, iter: I) -> &mut Self 65 | where 66 | T: Into, 67 | I: IntoIterator, 68 | { 69 | self.aliases = iter.into_iter().map(|a| a.into()).collect(); 70 | self 71 | } 72 | 73 | /// Set the terminal description. 74 | pub fn description>(&mut self, description: T) -> &mut Self { 75 | self.description = Some(description.into()); 76 | self 77 | } 78 | 79 | /// Set a capability. 80 | /// 81 | /// ## Example 82 | /// 83 | /// ``` 84 | /// use terminfo::{Database, capability as cap}; 85 | /// 86 | /// let mut info = Database::new(); 87 | /// info.name("foo"); 88 | /// info.description("foo terminal"); 89 | /// 90 | /// // Set the amount of available colors. 91 | /// info.set(cap::MaxColors(16)); 92 | /// 93 | /// info.build().unwrap(); 94 | /// ``` 95 | pub fn set<'a, C: Capability<'a>>(&'a mut self, value: C) -> &mut Self { 96 | if !self.inner.contains_key(C::name()) { 97 | if let Some(value) = C::into(value) { 98 | self.inner.insert(C::name().into(), value); 99 | } 100 | } 101 | 102 | self 103 | } 104 | 105 | /// Set a raw capability. 106 | /// 107 | /// ## Example 108 | /// 109 | /// ``` 110 | /// use terminfo::{Database, capability as cap}; 111 | /// 112 | /// let mut info = Database::new(); 113 | /// info.name("foo"); 114 | /// info.description("foo terminal"); 115 | /// 116 | /// // Set the amount of available colors. 117 | /// info.raw("colors", 16); 118 | /// 119 | /// info.build().unwrap(); 120 | /// ``` 121 | pub fn raw, V: Into>(&mut self, name: S, value: V) -> &mut Self { 122 | let name = name.as_ref(); 123 | let name = names::ALIASES.get(name).copied().unwrap_or(name); 124 | 125 | if !self.inner.contains_key(name) { 126 | self.inner.insert(name.into(), value.into()); 127 | } 128 | 129 | self 130 | } 131 | } 132 | 133 | impl Database { 134 | /// Create a database builder for constucting a database. 135 | // Clippy is right, the naming is is unconventional, but it’s probably not worth changing 136 | #[allow(clippy::new_ret_no_self)] 137 | pub fn new() -> Builder { 138 | Builder::default() 139 | } 140 | 141 | /// Load a database from the current environment. 142 | pub fn from_env() -> error::Result { 143 | if let Ok(name) = env::var("TERM") { 144 | Self::from_name(name) 145 | } else { 146 | Err(Error::NotFound) 147 | } 148 | } 149 | 150 | /// Load a database for the given name. 151 | pub fn from_name>(name: N) -> error::Result { 152 | let name = name.as_ref(); 153 | let first = name.chars().next().ok_or(Error::NotFound)?; 154 | 155 | // See https://manpages.debian.org/buster/ncurses-bin/terminfo.5.en.html#Fetching_Compiled_Descriptions 156 | let mut search = Vec::::new(); 157 | 158 | #[allow(deprecated)] 159 | if let Some(dir) = env::var_os("TERMINFO") { 160 | search.push(dir.into()); 161 | } else if let Some(mut home) = std::env::home_dir() { 162 | home.push(".terminfo"); 163 | search.push(home); 164 | } 165 | 166 | if let Ok(dirs) = env::var("TERMINFO_DIRS") { 167 | for dir in dirs.split(':') { 168 | search.push(dir.into()); 169 | } 170 | } 171 | 172 | // handle non-FHS systems like Termux 173 | if let Ok(prefix) = env::var("PREFIX") { 174 | let path = Path::new(&prefix); 175 | search.push(path.join("etc/terminfo")); 176 | search.push(path.join("lib/terminfo")); 177 | search.push(path.join("share/terminfo")); 178 | } 179 | 180 | search.push("/etc/terminfo".into()); 181 | search.push("/lib/terminfo".into()); 182 | search.push("/usr/share/terminfo".into()); 183 | search.push("/usr/local/share/terminfo".into()); 184 | search.push("/usr/local/share/site-terminfo".into()); 185 | search.push("/boot/system/data/terminfo".into()); 186 | 187 | for path in search { 188 | if fs::metadata(&path).is_err() { 189 | continue; 190 | } 191 | 192 | // Check standard location. 193 | { 194 | let mut path = path.clone(); 195 | path.push(first.to_string()); 196 | path.push(name); 197 | 198 | if fs::metadata(&path).is_ok() { 199 | return Self::from_path(path); 200 | } 201 | } 202 | 203 | // Check non-standard location. 204 | { 205 | let mut path = path.clone(); 206 | path.push(format!("{:x}", first as usize)); 207 | path.push(name); 208 | 209 | if fs::metadata(&path).is_ok() { 210 | return Self::from_path(path); 211 | } 212 | } 213 | } 214 | 215 | Err(Error::NotFound) 216 | } 217 | 218 | /// Load a database from the given path. 219 | pub fn from_path>(path: P) -> error::Result { 220 | let mut file = File::open(path)?; 221 | let mut buffer = Vec::new(); 222 | file.read_to_end(&mut buffer)?; 223 | 224 | Self::from_buffer(buffer) 225 | } 226 | 227 | /// Load a database from a buffer. 228 | pub fn from_buffer>(buffer: T) -> error::Result { 229 | if let Ok((_, database)) = compiled::parse(buffer.as_ref()) { 230 | Ok(database.into()) 231 | } else { 232 | Err(Error::Parse) 233 | } 234 | } 235 | 236 | /// The terminal name. 237 | pub fn name(&self) -> &str { 238 | &self.name 239 | } 240 | 241 | /// The terminal aliases. 242 | pub fn aliases(&self) -> &[String] { 243 | &self.aliases 244 | } 245 | 246 | /// The terminal description. 247 | pub fn description(&self) -> &str { 248 | &self.description 249 | } 250 | 251 | /// Get a capability. 252 | /// 253 | /// ## Example 254 | /// 255 | /// ``` 256 | /// use terminfo::{Database, capability as cap}; 257 | /// 258 | /// let info = Database::from_env().unwrap(); 259 | /// let colors: i32 = info.get::().unwrap().into(); 260 | /// ``` 261 | pub fn get<'a, C: Capability<'a>>(&'a self) -> Option { 262 | C::from(self.inner.get(C::name())) 263 | } 264 | 265 | /// Get a capability by name. 266 | /// 267 | /// ## Note 268 | /// 269 | /// This interface only makes sense for extended capabilities since they 270 | /// don't have standardized types. 271 | /// 272 | /// ## Example 273 | /// 274 | /// ``` 275 | /// use terminfo::Database; 276 | /// 277 | /// let info = Database::from_env().unwrap(); 278 | /// let truecolor = info.raw("Tc").is_some(); 279 | /// ``` 280 | pub fn raw>(&self, name: S) -> Option<&Value> { 281 | let name = name.as_ref(); 282 | let name = names::ALIASES.get(name).copied().unwrap_or(name); 283 | 284 | self.inner.get(name) 285 | } 286 | } 287 | -------------------------------------------------------------------------------- /src/error.rs: -------------------------------------------------------------------------------- 1 | // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | // Version 2, December 2004 3 | // 4 | // Copyleft (ↄ) meh. | http://meh.schizofreni.co 5 | // 6 | // Everyone is permitted to copy and distribute verbatim or modified 7 | // copies of this license document, and changing it is allowed as long 8 | // as the name is changed. 9 | // 10 | // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | // TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | // 13 | // 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | 15 | use std::error; 16 | use std::fmt; 17 | use std::io; 18 | 19 | #[derive(Debug)] 20 | pub enum Error { 21 | /// IO error. 22 | Io(io::Error), 23 | 24 | /// Database not found. 25 | NotFound, 26 | 27 | /// Parsing error. 28 | Parse, 29 | 30 | /// Expansion error. 31 | Expand(Expand), 32 | } 33 | 34 | #[derive(Eq, PartialEq, Copy, Clone, Debug)] 35 | pub enum Expand { 36 | /// The expansion string is invalid. 37 | Invalid, 38 | 39 | /// There was a type mismatch while expanding. 40 | TypeMismatch, 41 | 42 | /// The stack underflowed while expanding. 43 | StackUnderflow, 44 | } 45 | 46 | pub type Result = ::std::result::Result; 47 | 48 | impl From for Error { 49 | fn from(value: io::Error) -> Self { 50 | Error::Io(value) 51 | } 52 | } 53 | 54 | impl From for Error { 55 | fn from(value: Expand) -> Self { 56 | Error::Expand(value) 57 | } 58 | } 59 | 60 | impl fmt::Display for Error { 61 | fn fmt(&self, f: &mut fmt::Formatter) -> ::std::result::Result<(), fmt::Error> { 62 | match *self { 63 | Error::Io(ref err) => err.fmt(f), 64 | 65 | Error::NotFound => f.write_str("Capability database not found."), 66 | 67 | Error::Parse => f.write_str("Failed to parse capability database."), 68 | 69 | Error::Expand(ref err) => match *err { 70 | Expand::Invalid => f.write_str("The expansion string is invalid."), 71 | 72 | Expand::StackUnderflow => f.write_str("Not enough elements on the stack."), 73 | 74 | Expand::TypeMismatch => f.write_str("Type mismatch."), 75 | }, 76 | } 77 | } 78 | } 79 | 80 | impl error::Error for Error {} 81 | -------------------------------------------------------------------------------- /src/expand.rs: -------------------------------------------------------------------------------- 1 | // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | // Version 2, December 2004 3 | // 4 | // Copyleft (ↄ) meh. | http://meh.schizofreni.co 5 | // 6 | // Everyone is permitted to copy and distribute verbatim or modified 7 | // copies of this license document, and changing it is allowed as long 8 | // as the name is changed. 9 | // 10 | // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | // TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | // 13 | // 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | 15 | use std::char; 16 | use std::io::{BufWriter, Write}; 17 | 18 | use crate::error; 19 | use crate::parser::expansion::*; 20 | 21 | /// Trait for items that can be expanded. 22 | pub trait Expand { 23 | fn expand( 24 | &self, 25 | output: W, 26 | parameters: &[Parameter], 27 | context: &mut Context, 28 | ) -> error::Result<()>; 29 | } 30 | 31 | /// An expansion parameter. 32 | #[derive(Eq, PartialEq, Clone, Debug)] 33 | pub enum Parameter { 34 | /// A number. 35 | Number(i32), 36 | 37 | /// An ASCII string. 38 | String(Vec), 39 | } 40 | 41 | impl Default for Parameter { 42 | fn default() -> Self { 43 | Parameter::Number(0) 44 | } 45 | } 46 | 47 | macro_rules! from { 48 | (number $ty:ty) => { 49 | impl From<$ty> for Parameter { 50 | fn from(value: $ty) -> Self { 51 | Parameter::Number(value as i32) 52 | } 53 | } 54 | }; 55 | 56 | (string ref $ty:ty) => { 57 | impl<'a> From<&'a $ty> for Parameter { 58 | fn from(value: &'a $ty) -> Self { 59 | Parameter::String(value.into()) 60 | } 61 | } 62 | }; 63 | 64 | (string $ty:ty) => { 65 | impl From<$ty> for Parameter { 66 | fn from(value: $ty) -> Self { 67 | Parameter::String(value.into()) 68 | } 69 | } 70 | }; 71 | } 72 | 73 | from!(number bool); 74 | from!(number u8); 75 | from!(number i8); 76 | from!(number u16); 77 | from!(number i16); 78 | from!(number u32); 79 | from!(number i32); 80 | 81 | from!(string String); 82 | from!(string ref str); 83 | from!(string Vec); 84 | from!(string ref [u8]); 85 | 86 | /// The expansion context. 87 | /// 88 | /// The same context should be passed around through every expansion for the 89 | /// same `Database`. 90 | #[derive(Eq, PartialEq, Default, Debug)] 91 | pub struct Context { 92 | pub fixed: [Parameter; 26], 93 | pub dynamic: [Parameter; 26], 94 | } 95 | 96 | /// Expand a parametrized string. 97 | /// 98 | /// ## Examples 99 | /// 100 | /// Write the expansion to `stdout`. 101 | /// 102 | /// ``` 103 | /// use terminfo::{Database, capability as cap, expand}; 104 | /// use std::io; 105 | /// 106 | /// # fn main() { 107 | /// 108 | /// let info = Database::from_env().unwrap(); 109 | /// 110 | /// // Move the cursor to X: 20, Y: 30 111 | /// expand!(io::stdout(), info.get::().unwrap().as_ref(); 20, 30).unwrap(); 112 | /// 113 | /// # } 114 | /// ``` 115 | /// 116 | /// Load the expansion for later usage. 117 | /// 118 | /// ``` 119 | /// use terminfo::{Database, capability as cap, expand}; 120 | /// use std::io; 121 | /// 122 | /// # fn main() { 123 | /// 124 | /// let info = Database::from_env().unwrap(); 125 | /// 126 | /// // Set foreground color to red. 127 | /// let red = expand!(info.get::().unwrap().as_ref(); 1).unwrap(); 128 | /// let on_blue = expand!(info.get::().unwrap().as_ref(); 4).unwrap(); 129 | /// 130 | /// # } 131 | /// ``` 132 | #[macro_export] 133 | macro_rules! expand { 134 | ($value:expr) => ( 135 | $crate::expand!($value;) 136 | ); 137 | 138 | ($value:expr => $context:expr) => ( 139 | $crate::expand!($value => $context;) 140 | ); 141 | 142 | ($value:expr; $($item:expr),*) => ( 143 | $crate::expand!($value => &mut ::std::default::Default::default(); $($item),*) 144 | ); 145 | 146 | ($value:expr => $context:expr; $($item:expr),*) => ({ 147 | let mut output = ::std::vec::Vec::new(); 148 | 149 | $crate::expand!(&mut output, $value => $context; $($item),*).map(|()| output) 150 | }); 151 | 152 | ($output:expr, $value:expr) => ( 153 | $crate::expand!($output, $value;) 154 | ); 155 | 156 | ($output:expr, $value:expr => $context:expr) => ( 157 | $crate::expand!($output, $value => $context;) 158 | ); 159 | 160 | ($output:expr, $value:expr; $($item:expr),*) => ( 161 | $crate::expand!($output, $value => &mut ::std::default::Default::default(); $($item),*) 162 | ); 163 | 164 | ($output:expr, $value:expr => $context:expr; $($item:expr),*) => ({ 165 | use $crate::Expand; 166 | $value.expand($output, &[$($item.into()),*], $context) 167 | }) 168 | } 169 | 170 | impl Expand for [u8] { 171 | fn expand( 172 | &self, 173 | output: W, 174 | parameters: &[Parameter], 175 | context: &mut Context, 176 | ) -> error::Result<()> { 177 | let mut output = BufWriter::new(output); 178 | let mut input = self; 179 | let mut params: [Parameter; 9] = Default::default(); 180 | let mut stack = Vec::new(); 181 | let mut conditional = false; 182 | let mut incremented = false; 183 | 184 | for (dest, source) in params.iter_mut().zip(parameters.iter()) { 185 | *dest = source.clone(); 186 | } 187 | 188 | macro_rules! next { 189 | () => { 190 | match parse(input) { 191 | Ok((rest, item)) => { 192 | input = rest; 193 | item 194 | } 195 | 196 | Err(_) => return Err(error::Expand::Invalid.into()), 197 | } 198 | }; 199 | } 200 | 201 | 'main: while !input.is_empty() { 202 | match next!() { 203 | Item::Conditional(Conditional::If) => { 204 | conditional = true; 205 | } 206 | 207 | Item::Conditional(Conditional::End) if conditional => { 208 | conditional = false; 209 | } 210 | 211 | Item::Conditional(Conditional::Then) if conditional => match stack.pop() { 212 | Some(Parameter::Number(0)) => { 213 | let mut level = 0; 214 | 215 | while !input.is_empty() { 216 | match next!() { 217 | Item::Conditional(Conditional::End) 218 | | Item::Conditional(Conditional::Else) 219 | if level == 0 => 220 | { 221 | continue 'main 222 | } 223 | 224 | Item::Conditional(Conditional::If) => level += 1, 225 | 226 | Item::Conditional(Conditional::End) => level -= 1, 227 | 228 | _ => (), 229 | } 230 | } 231 | 232 | return Err(error::Expand::Invalid.into()); 233 | } 234 | 235 | Some(_) => (), 236 | 237 | None => return Err(error::Expand::StackUnderflow.into()), 238 | }, 239 | 240 | Item::Conditional(Conditional::Else) if conditional => { 241 | let mut level = 0; 242 | 243 | while !input.is_empty() { 244 | match next!() { 245 | Item::Conditional(Conditional::End) if level == 0 => continue 'main, 246 | 247 | Item::Conditional(Conditional::If) => level += 1, 248 | 249 | Item::Conditional(Conditional::End) => level -= 1, 250 | 251 | _ => (), 252 | } 253 | } 254 | 255 | return Err(error::Expand::Invalid.into()); 256 | } 257 | 258 | Item::Conditional(..) => return Err(error::Expand::Invalid.into()), 259 | 260 | Item::String(value) => output.write_all(value)?, 261 | 262 | Item::Constant(Constant::Character(ch)) => { 263 | stack.push(Parameter::Number(ch as i32)); 264 | } 265 | 266 | Item::Constant(Constant::Integer(value)) => { 267 | stack.push(Parameter::Number(value)); 268 | } 269 | 270 | Item::Variable(Variable::Length) => match stack.pop() { 271 | Some(Parameter::String(ref value)) => { 272 | stack.push(Parameter::Number(value.len() as i32)); 273 | } 274 | 275 | Some(_) => { 276 | return Err(error::Expand::TypeMismatch.into()); 277 | } 278 | 279 | None => { 280 | return Err(error::Expand::StackUnderflow.into()); 281 | } 282 | }, 283 | 284 | Item::Variable(Variable::Push(index)) => { 285 | stack.push(params[index as usize].clone()); 286 | } 287 | 288 | Item::Variable(Variable::Set(dynamic, index)) => { 289 | if let Some(value) = stack.pop() { 290 | if dynamic { 291 | context.dynamic[index as usize] = value.clone(); 292 | } else { 293 | context.fixed[index as usize] = value.clone(); 294 | } 295 | } else { 296 | return Err(error::Expand::StackUnderflow.into()); 297 | } 298 | } 299 | 300 | Item::Variable(Variable::Get(dynamic, index)) => { 301 | if dynamic { 302 | stack.push(context.dynamic[index as usize].clone()); 303 | } else { 304 | stack.push(context.fixed[index as usize].clone()); 305 | } 306 | } 307 | 308 | Item::Operation(Operation::Increment) if !incremented => { 309 | incremented = true; 310 | 311 | if let (&Parameter::Number(x), &Parameter::Number(y)) = (¶ms[0], ¶ms[1]) 312 | { 313 | params[0] = Parameter::Number(x + 1); 314 | params[1] = Parameter::Number(y + 1); 315 | } else { 316 | return Err(error::Expand::TypeMismatch.into()); 317 | } 318 | } 319 | 320 | Item::Operation(Operation::Increment) => (), 321 | 322 | Item::Operation(Operation::Binary(operation)) => match (stack.pop(), stack.pop()) { 323 | (Some(Parameter::Number(y)), Some(Parameter::Number(x))) => { 324 | stack.push(Parameter::Number(match operation { 325 | Binary::Add => x + y, 326 | Binary::Subtract => x - y, 327 | Binary::Multiply => x * y, 328 | Binary::Divide => { 329 | if y != 0 { 330 | x / y 331 | } else { 332 | 0 333 | } 334 | } 335 | Binary::Remainder => { 336 | if y != 0 { 337 | x % y 338 | } else { 339 | 0 340 | } 341 | } 342 | 343 | Binary::AND => x & y, 344 | Binary::OR => x | y, 345 | Binary::XOR => x ^ y, 346 | 347 | Binary::And => (x != 0 && y != 0) as i32, 348 | Binary::Or => (x != 0 || y != 0) as i32, 349 | 350 | Binary::Equal => (x == y) as i32, 351 | Binary::Greater => (x > y) as i32, 352 | Binary::Lesser => (x < y) as i32, 353 | })) 354 | } 355 | 356 | (Some(_), Some(_)) => return Err(error::Expand::TypeMismatch.into()), 357 | 358 | _ => return Err(error::Expand::StackUnderflow.into()), 359 | }, 360 | 361 | Item::Operation(Operation::Unary(operation)) => match stack.pop() { 362 | Some(Parameter::Number(x)) => stack.push(Parameter::Number(match operation { 363 | Unary::Not => (x != 0) as i32, 364 | Unary::NOT => !x, 365 | })), 366 | 367 | Some(_) => return Err(error::Expand::TypeMismatch.into()), 368 | 369 | _ => return Err(error::Expand::StackUnderflow.into()), 370 | }, 371 | 372 | Item::Print(p) => { 373 | /// Calculate the length of a formatted number. 374 | fn length(value: i32, p: &Print) -> usize { 375 | let digits = match p.format { 376 | Format::Dec => (value as f32).abs().log(10.0).floor() as usize + 1, 377 | 378 | Format::Oct => (value as f32).abs().log(8.0).floor() as usize + 1, 379 | 380 | Format::Hex | Format::HEX => { 381 | (value as f32).abs().log(16.0).floor() as usize + 1 382 | } 383 | 384 | _ => unreachable!(), 385 | }; 386 | 387 | let mut length = digits; 388 | 389 | // Add the minimum number of digits. 390 | if p.flags.precision > digits { 391 | length += p.flags.precision - digits; 392 | } 393 | 394 | // Add the sign if present. 395 | if p.format == Format::Dec && (value < 0 || p.flags.sign) { 396 | length += 1; 397 | } 398 | 399 | // Add the alternate representation. 400 | if p.flags.alternate { 401 | match p.format { 402 | Format::Hex | Format::HEX => length += 2, 403 | 404 | Format::Oct => length += 1, 405 | 406 | _ => (), 407 | } 408 | } 409 | 410 | length 411 | } 412 | 413 | macro_rules! w { 414 | ($value:expr) => ( 415 | output.write_all($value)? 416 | ); 417 | 418 | ($($item:tt)*) => ( 419 | write!(output, $($item)*)? 420 | ); 421 | } 422 | 423 | macro_rules! f { 424 | (by $length:expr) => ( 425 | for _ in 0 .. p.flags.width - $length { 426 | output.write_all(if p.flags.space { b" " } else { b"0" })?; 427 | } 428 | ); 429 | 430 | (before by $length:expr) => ( 431 | if !p.flags.left && p.flags.width > $length { 432 | f!(by $length); 433 | } 434 | ); 435 | 436 | (after by $length:expr) => ( 437 | if p.flags.left && p.flags.width > $length { 438 | f!(by $length); 439 | } 440 | ); 441 | 442 | (before $value:expr) => ( 443 | f!(before by length($value, &p)); 444 | ); 445 | 446 | (after $value:expr) => ( 447 | f!(after by length($value, &p)); 448 | ); 449 | } 450 | 451 | match (p.format, stack.pop()) { 452 | (Format::Str, Some(Parameter::String(ref value))) => { 453 | let mut value = &value[..]; 454 | 455 | if p.flags.precision > 0 && p.flags.precision < value.len() { 456 | value = &value[..p.flags.precision]; 457 | } 458 | 459 | f!(before by value.len()); 460 | w!(value); 461 | f!(after by value.len()); 462 | } 463 | 464 | (Format::Chr, Some(Parameter::Number(value))) => { 465 | w!("{}", value as u8 as char) 466 | } 467 | 468 | (Format::Uni, Some(Parameter::Number(value))) => w!( 469 | "{}", 470 | char::from_u32(value as u32).ok_or(error::Expand::TypeMismatch)? 471 | ), 472 | 473 | (Format::Dec, Some(Parameter::Number(value))) => { 474 | f!(before value); 475 | 476 | if p.flags.sign && value >= 0 { 477 | w!(b"+"); 478 | } 479 | 480 | w!("{:.1$}", value, p.flags.precision); 481 | 482 | f!(after value); 483 | } 484 | 485 | (Format::Oct, Some(Parameter::Number(value))) => { 486 | f!(before value); 487 | 488 | if p.flags.alternate { 489 | w!(b"0"); 490 | } 491 | 492 | w!("{:.1$o}", value, p.flags.precision); 493 | 494 | f!(after value); 495 | } 496 | 497 | (Format::Hex, Some(Parameter::Number(value))) => { 498 | f!(before value); 499 | 500 | if p.flags.alternate { 501 | w!(b"0x"); 502 | } 503 | 504 | w!("{:.1$x}", value, p.flags.precision); 505 | 506 | f!(after value); 507 | } 508 | 509 | (Format::HEX, Some(Parameter::Number(value))) => { 510 | f!(before value); 511 | 512 | if p.flags.alternate { 513 | w!(b"0X"); 514 | } 515 | 516 | w!("{:.1$X}", value, p.flags.precision); 517 | 518 | f!(after value); 519 | } 520 | 521 | (_, Some(_)) => return Err(error::Expand::TypeMismatch.into()), 522 | 523 | (_, None) => return Err(error::Expand::StackUnderflow.into()), 524 | } 525 | } 526 | } 527 | } 528 | 529 | Ok(()) 530 | } 531 | } 532 | 533 | #[cfg(test)] 534 | mod test { 535 | #[test] 536 | fn test_basic_setabf() { 537 | assert_eq!(b"\\E[48;5;1m".to_vec(), expand!(b"\\E[48;5;%p1%dm"; 1).unwrap()); 538 | } 539 | 540 | #[test] 541 | fn print() { 542 | assert_eq!(b"0001".to_vec(), expand!(b"%p1%4d"; 1).unwrap()); 543 | 544 | assert_eq!(b"10".to_vec(), expand!(b"%p1%o"; 8).unwrap()); 545 | } 546 | 547 | #[test] 548 | fn conditional() { 549 | assert_eq!(b"1".to_vec(), expand!(b"%?%p1%t1%e2%;"; 1).unwrap()); 550 | 551 | assert_eq!(b"2".to_vec(), expand!(b"%?%p1%t1%e2%;"; 0).unwrap()); 552 | 553 | assert_eq!(b"3".to_vec(), expand!(b"%?%p1%t%e%p2%t2%e%p3%t3%;"; 0, 0, 1).unwrap()); 554 | } 555 | } 556 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | // Version 2, December 2004 3 | // 4 | // Copyleft (ↄ) meh. | http://meh.schizofreni.co 5 | // 6 | // Everyone is permitted to copy and distribute verbatim or modified 7 | // copies of this license document, and changing it is allowed as long 8 | // as the name is changed. 9 | // 10 | // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | // TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | // 13 | // 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | 15 | #[cfg(doctest)] 16 | #[doc = include_str!("../README.md")] 17 | extern "C" {} 18 | 19 | mod error; 20 | pub use crate::error::{Error, Result}; 21 | 22 | /// Parsers for various formats. 23 | mod parser; 24 | 25 | /// String capability expansion. 26 | #[macro_use] 27 | pub mod expand; 28 | pub use crate::expand::Expand; 29 | 30 | /// Standard terminal capabilities. 31 | pub mod capability; 32 | pub use crate::capability::{Capability, Value}; 33 | 34 | mod database; 35 | pub use crate::database::Database; 36 | 37 | /// Constants to deal with name differences across terminfo and termcap. 38 | pub mod names; 39 | -------------------------------------------------------------------------------- /src/names.rs: -------------------------------------------------------------------------------- 1 | // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | // Version 2, December 2004 3 | // 4 | // Copyleft (ↄ) meh. | http://meh.schizofreni.co 5 | // 6 | // Everyone is permitted to copy and distribute verbatim or modified 7 | // copies of this license document, and changing it is allowed as long 8 | // as the name is changed. 9 | // 10 | // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | // TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | // 13 | // 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | 15 | include!(concat!(env!("OUT_DIR"), "/names.rs")); 16 | -------------------------------------------------------------------------------- /src/parser/compiled.rs: -------------------------------------------------------------------------------- 1 | // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | // Version 2, December 2004 3 | // 4 | // Copyleft (ↄ) meh. | http://meh.schizofreni.co 5 | // 6 | // Everyone is permitted to copy and distribute verbatim or modified 7 | // copies of this license document, and changing it is allowed as long 8 | // as the name is changed. 9 | // 10 | // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | // TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | // 13 | // 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | 15 | use nom::branch::alt; 16 | use nom::bytes::streaming::{tag, take, take_until}; 17 | use nom::combinator::{complete, cond, map, map_opt, map_parser, opt}; 18 | use nom::multi::count; 19 | use nom::number::streaming::{le_i16, le_i32}; 20 | use nom::IResult; 21 | use std::str; 22 | 23 | use crate::capability::Value; 24 | use crate::names; 25 | 26 | #[derive(Eq, PartialEq, Clone, Debug)] 27 | pub struct Database<'a> { 28 | names: &'a [u8], 29 | standard: Standard<'a>, 30 | extended: Option>, 31 | } 32 | 33 | impl<'a> From> for crate::Database { 34 | fn from(source: Database<'a>) -> Self { 35 | let mut names = source 36 | .names 37 | .split(|&c| c == b'|') 38 | .map(|s| unsafe { str::from_utf8_unchecked(s) }) 39 | .map(|s| s.trim()) 40 | .collect::>(); 41 | 42 | let mut database = crate::Database::new(); 43 | 44 | database.name(names.remove(0)); 45 | names.pop().map(|name| database.description(name)); 46 | database.aliases(names); 47 | 48 | for (index, _) in source.standard.booleans.iter().enumerate().filter(|&(_, &value)| value) { 49 | if let Some(&name) = names::BOOLEAN.get(&(index as u16)) { 50 | database.raw(name, Value::True); 51 | } 52 | } 53 | 54 | for (index, &value) in source.standard.numbers.iter().enumerate().filter(|&(_, &n)| n >= 0) 55 | { 56 | if let Some(&name) = names::NUMBER.get(&(index as u16)) { 57 | database.raw(name, Value::Number(value)); 58 | } 59 | } 60 | 61 | for (index, &offset) in source.standard.strings.iter().enumerate().filter(|&(_, &n)| n >= 0) 62 | { 63 | if let Some(&name) = names::STRING.get(&(index as u16)) { 64 | let string = &source.standard.table[offset as usize..]; 65 | let edge = string.iter().position(|&c| c == 0).unwrap(); 66 | 67 | database.raw(name, Value::String(Vec::from(&string[..edge]))); 68 | } 69 | } 70 | 71 | if let Some(extended) = source.extended { 72 | let names = extended 73 | .table 74 | .split(|&c| c == 0) 75 | .skip(extended.strings.iter().cloned().filter(|&n| n >= 0).count()) 76 | .map(|s| unsafe { str::from_utf8_unchecked(s) }) 77 | .collect::>(); 78 | 79 | for (index, _) in extended.booleans.iter().enumerate().filter(|&(_, &value)| value) { 80 | database.raw(names[index], Value::True); 81 | } 82 | 83 | for (index, &value) in extended.numbers.iter().enumerate().filter(|&(_, &n)| n >= 0) { 84 | database.raw(names[extended.booleans.len() + index], Value::Number(value)); 85 | } 86 | 87 | for (index, &offset) in extended.strings.iter().enumerate().filter(|&(_, &n)| n >= 0) { 88 | let string = &extended.table[offset as usize..]; 89 | let edge = string.iter().position(|&c| c == 0).unwrap(); 90 | 91 | database.raw( 92 | names[extended.booleans.len() + extended.numbers.len() + index], 93 | Value::String(Vec::from(&string[..edge])), 94 | ); 95 | } 96 | } 97 | 98 | database.build().unwrap() 99 | } 100 | } 101 | 102 | #[derive(Eq, PartialEq, Clone, Debug)] 103 | pub struct Standard<'a> { 104 | booleans: Vec, 105 | numbers: Vec, 106 | strings: Vec, 107 | table: &'a [u8], 108 | } 109 | 110 | #[derive(Eq, PartialEq, Clone, Debug)] 111 | pub struct Extended<'a> { 112 | booleans: Vec, 113 | numbers: Vec, 114 | strings: Vec, 115 | names: Vec, 116 | table: &'a [u8], 117 | } 118 | 119 | fn bit_size(magic: &[u8]) -> usize { 120 | match magic[1] { 121 | 0x01 => 16, 122 | 0x02 => 32, 123 | 124 | _ => unreachable!("unknown magic number"), 125 | } 126 | } 127 | 128 | pub fn parse(input: &[u8]) -> IResult<&[u8], Database> { 129 | let (input, magic) = alt((tag([0x1A, 0x01]), tag([0x1E, 0x02])))(input)?; 130 | 131 | let (input, name_size) = size(input)?; 132 | let (input, bool_count) = size(input)?; 133 | let (input, num_count) = size(input)?; 134 | let (input, string_count) = size(input)?; 135 | let (input, table_size) = size(input)?; 136 | 137 | let (input, names) = map_parser(take(name_size), take_until("\x00"))(input)?; 138 | 139 | let (input, booleans) = count(boolean, bool_count)(input)?; 140 | 141 | let (input, _) = cond((name_size + bool_count) % 2 != 0, take(1_usize))(input)?; 142 | 143 | let (input, numbers) = count(|input| capability(input, bit_size(magic)), num_count)(input)?; 144 | 145 | let (input, strings) = count(|input| capability(input, 16), string_count)(input)?; 146 | 147 | let (input, table) = take(table_size)(input)?; 148 | 149 | let (input, extended) = opt(complete(|input| { 150 | let (input, _) = cond(table_size % 2 != 0, take(1_usize))(input)?; 151 | 152 | let (input, ext_bool_count) = size(input)?; 153 | let (input, ext_num_count) = size(input)?; 154 | let (input, ext_string_count) = size(input)?; 155 | let (input, _ext_offset_count) = size(input)?; 156 | let (input, ext_table_size) = size(input)?; 157 | 158 | let (input, booleans) = count(boolean, ext_bool_count)(input)?; 159 | 160 | let (input, _) = cond(ext_bool_count % 2 != 0, take(1_usize))(input)?; 161 | 162 | let (input, numbers) = 163 | count(|input| capability(input, bit_size(magic)), ext_num_count)(input)?; 164 | 165 | let (input, strings) = count(|input| capability(input, 16), ext_string_count)(input)?; 166 | 167 | let (input, names) = count( 168 | |input| capability(input, 16), 169 | ext_bool_count + ext_num_count + ext_string_count, 170 | )(input)?; 171 | 172 | let (input, table) = take(ext_table_size)(input)?; 173 | 174 | Ok((input, Extended { booleans, numbers, strings, names, table })) 175 | }))(input)?; 176 | 177 | Ok(( 178 | input, 179 | Database { names, standard: Standard { booleans, numbers, strings, table }, extended }, 180 | )) 181 | } 182 | 183 | fn boolean(input: &[u8]) -> IResult<&[u8], bool> { 184 | alt((map(tag([0]), |_| false), map(tag([1]), |_| true)))(input) 185 | } 186 | 187 | fn size(input: &[u8]) -> IResult<&[u8], usize> { 188 | map_opt(le_i16, |n| match n { 189 | -1 => Some(0), 190 | n if n >= 0 => Some(n as usize), 191 | _ => None, 192 | })(input) 193 | } 194 | 195 | fn capability(input: &[u8], bits: usize) -> IResult<&[u8], i32> { 196 | alt(( 197 | map_opt( 198 | cond(bits == 16, map_opt(le_i16, |n| if n >= -2 { Some(n as i32) } else { None })), 199 | |o| o, 200 | ), 201 | map_opt(cond(bits == 32, map_opt(le_i32, |n| if n >= -2 { Some(n) } else { None })), |o| o), 202 | ))(input) 203 | } 204 | 205 | #[cfg(test)] 206 | mod test { 207 | use super::*; 208 | use crate::capability as cap; 209 | use std::fs::File; 210 | use std::io::Read; 211 | use std::path::Path; 212 | 213 | fn load, F: FnOnce(crate::Database)>(path: P, f: F) { 214 | let mut file = File::open(path).unwrap(); 215 | let mut buffer = Vec::new(); 216 | file.read_to_end(&mut buffer).unwrap(); 217 | 218 | f(parse(&buffer).unwrap().1.into()) 219 | } 220 | 221 | #[test] 222 | fn name() { 223 | load("tests/cancer-256color", |db| assert_eq!("cancer-256color", db.name())); 224 | } 225 | 226 | #[test] 227 | fn aliases() { 228 | load("tests/st-256color", |db| assert_eq!(vec!["stterm-256color"], db.aliases())); 229 | } 230 | 231 | #[test] 232 | fn description() { 233 | load("tests/cancer-256color", |db| { 234 | assert_eq!("terminal cancer with 256 colors", db.description()) 235 | }); 236 | } 237 | 238 | #[test] 239 | fn standard() { 240 | load("tests/st-256color", |db| { 241 | assert_eq!(Some(cap::Columns(80)), db.get::()); 242 | assert_eq!(Some(cap::AutoRightMargin(true)), db.get::()); 243 | assert_eq!(Some(cap::AutoLeftMargin(false)), db.get::()); 244 | }); 245 | } 246 | 247 | #[test] 248 | fn extended() { 249 | load("tests/cancer-256color", |db| { 250 | assert_eq!(Some(&cap::Value::True), db.raw("Ts")); 251 | assert_eq!(Some(&cap::Value::True), db.raw("AX")); 252 | assert_eq!(Some(&cap::Value::String(b"\x1B[2 q".to_vec())), db.raw("Se")); 253 | }); 254 | } 255 | 256 | #[test] 257 | fn bigger_numbers() { 258 | load("tests/xterm-256color", |db| assert_eq!("xterm-256color", db.name())); 259 | } 260 | } 261 | -------------------------------------------------------------------------------- /src/parser/expansion.rs: -------------------------------------------------------------------------------- 1 | // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | // Version 2, December 2004 3 | // 4 | // Copyleft (ↄ) meh. | http://meh.schizofreni.co 5 | // 6 | // Everyone is permitted to copy and distribute verbatim or modified 7 | // copies of this license document, and changing it is allowed as long 8 | // as the name is changed. 9 | // 10 | // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | // TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | // 13 | // 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | 15 | use crate::parser::util::number; 16 | use nom::branch::alt; 17 | use nom::bytes::complete; 18 | use nom::bytes::streaming::{tag, take, take_while}; 19 | use nom::character::is_digit; 20 | use nom::character::streaming::one_of; 21 | use nom::combinator::{map, opt, value}; 22 | use nom::error::{make_error, ErrorKind}; 23 | use nom::IResult; 24 | 25 | #[derive(Eq, PartialEq, Copy, Clone, Debug)] 26 | pub enum Item<'a> { 27 | String(&'a [u8]), 28 | Constant(Constant), 29 | Variable(Variable), 30 | Operation(Operation), 31 | Conditional(Conditional), 32 | Print(Print), 33 | } 34 | 35 | #[derive(Eq, PartialEq, Copy, Clone, Debug)] 36 | pub enum Constant { 37 | Character(u8), 38 | Integer(i32), 39 | } 40 | 41 | #[derive(Eq, PartialEq, Copy, Clone, Debug)] 42 | pub enum Variable { 43 | Length, 44 | Push(u8), 45 | Set(bool, u8), 46 | Get(bool, u8), 47 | } 48 | 49 | #[derive(Eq, PartialEq, Copy, Clone, Debug)] 50 | pub enum Operation { 51 | Increment, 52 | Unary(Unary), 53 | Binary(Binary), 54 | } 55 | 56 | #[derive(Eq, PartialEq, Copy, Clone, Debug)] 57 | pub enum Unary { 58 | Not, 59 | NOT, 60 | } 61 | 62 | #[derive(Eq, PartialEq, Copy, Clone, Debug)] 63 | pub enum Binary { 64 | Add, 65 | Subtract, 66 | Multiply, 67 | Divide, 68 | Remainder, 69 | 70 | AND, 71 | OR, 72 | XOR, 73 | 74 | And, 75 | Or, 76 | 77 | Equal, 78 | Greater, 79 | Lesser, 80 | } 81 | 82 | #[derive(Eq, PartialEq, Copy, Clone, Debug)] 83 | pub enum Conditional { 84 | If, 85 | Then, 86 | Else, 87 | End, 88 | } 89 | 90 | #[derive(Eq, PartialEq, Copy, Clone, Debug)] 91 | pub struct Print { 92 | pub flags: Flags, 93 | pub format: Format, 94 | } 95 | 96 | #[derive(Eq, PartialEq, Copy, Clone, Debug)] 97 | pub enum Format { 98 | Chr, 99 | Uni, 100 | Str, 101 | Dec, 102 | Oct, 103 | Hex, 104 | HEX, 105 | } 106 | 107 | #[derive(Eq, PartialEq, Copy, Clone, Default, Debug)] 108 | pub struct Flags { 109 | pub width: usize, 110 | pub precision: usize, 111 | 112 | pub alternate: bool, 113 | pub left: bool, 114 | pub sign: bool, 115 | pub space: bool, 116 | } 117 | 118 | pub fn parse(input: &[u8]) -> IResult<&[u8], Item> { 119 | alt((expansion, string))(input) 120 | } 121 | 122 | fn string(input: &[u8]) -> IResult<&[u8], Item> { 123 | map(complete::take_till(|b| b == b'%'), Item::String)(input) 124 | } 125 | 126 | fn expansion(input: &[u8]) -> IResult<&[u8], Item> { 127 | let (input, _) = tag("%")(input)?; 128 | let (input, item) = alt((percent, constant, variable, operation, conditional, print))(input)?; 129 | 130 | Ok((input, item)) 131 | } 132 | 133 | fn percent(input: &[u8]) -> IResult<&[u8], Item> { 134 | value(Item::String(b"%"), tag("%"))(input) 135 | } 136 | 137 | fn constant(input: &[u8]) -> IResult<&[u8], Item> { 138 | alt((constant_char, constant_integer))(input) 139 | } 140 | 141 | fn constant_char(input: &[u8]) -> IResult<&[u8], Item> { 142 | let (input, _) = tag("'")(input)?; 143 | let (input, ch) = take(1_usize)(input)?; 144 | let (input, _) = tag("'")(input)?; 145 | 146 | Ok((input, Item::Constant(Constant::Character(ch[0])))) 147 | } 148 | 149 | fn constant_integer(input: &[u8]) -> IResult<&[u8], Item> { 150 | let (input, _) = tag("{")(input)?; 151 | let (input, digit) = take_while(is_digit)(input)?; 152 | let (input, _) = tag("}")(input)?; 153 | 154 | Ok((input, Item::Constant(Constant::Integer(number(digit))))) 155 | } 156 | 157 | fn variable(input: &[u8]) -> IResult<&[u8], Item> { 158 | let (input, c) = take(1_usize)(input)?; 159 | match c { 160 | b"l" => Ok((input, Item::Variable(Variable::Length))), 161 | 162 | b"p" => map(one_of("123456789"), |n| Item::Variable(Variable::Push(n as u8 - b'1')))(input), 163 | 164 | b"P" => alt(( 165 | map(one_of("abcdefghijklmnopqrstuvwxyz"), |n| { 166 | Item::Variable(Variable::Set(true, n as u8 - b'a')) 167 | }), 168 | map(one_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), |n| { 169 | Item::Variable(Variable::Set(false, n as u8 - b'A')) 170 | }), 171 | ))(input), 172 | 173 | b"g" => alt(( 174 | map(one_of("abcdefghijklmnopqrstuvwxyz"), |n| { 175 | Item::Variable(Variable::Get(true, n as u8 - b'a')) 176 | }), 177 | map(one_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), |n| { 178 | Item::Variable(Variable::Get(false, n as u8 - b'A')) 179 | }), 180 | ))(input), 181 | 182 | _ => Err(nom::Err::Error(make_error(input, ErrorKind::Switch))), 183 | } 184 | } 185 | 186 | fn operation(input: &[u8]) -> IResult<&[u8], Item> { 187 | let (input, c) = take(1_usize)(input)?; 188 | match c { 189 | b"+" => Ok((input, Item::Operation(Operation::Binary(Binary::Add)))), 190 | b"-" => Ok((input, Item::Operation(Operation::Binary(Binary::Subtract)))), 191 | b"*" => Ok((input, Item::Operation(Operation::Binary(Binary::Multiply)))), 192 | b"/" => Ok((input, Item::Operation(Operation::Binary(Binary::Divide)))), 193 | b"m" => Ok((input, Item::Operation(Operation::Binary(Binary::Remainder)))), 194 | b"i" => Ok((input, Item::Operation(Operation::Increment))), 195 | 196 | b"&" => Ok((input, Item::Operation(Operation::Binary(Binary::AND)))), 197 | b"|" => Ok((input, Item::Operation(Operation::Binary(Binary::OR)))), 198 | b"^" => Ok((input, Item::Operation(Operation::Binary(Binary::XOR)))), 199 | b"~" => Ok((input, Item::Operation(Operation::Unary(Unary::NOT)))), 200 | 201 | b"A" => Ok((input, Item::Operation(Operation::Binary(Binary::And)))), 202 | b"O" => Ok((input, Item::Operation(Operation::Binary(Binary::Or)))), 203 | b"!" => Ok((input, Item::Operation(Operation::Unary(Unary::Not)))), 204 | 205 | b"=" => Ok((input, Item::Operation(Operation::Binary(Binary::Equal)))), 206 | b">" => Ok((input, Item::Operation(Operation::Binary(Binary::Greater)))), 207 | b"<" => Ok((input, Item::Operation(Operation::Binary(Binary::Lesser)))), 208 | 209 | _ => Err(nom::Err::Error(make_error(input, ErrorKind::Switch))), 210 | } 211 | } 212 | 213 | fn conditional(input: &[u8]) -> IResult<&[u8], Item> { 214 | let (input, c) = take(1_usize)(input)?; 215 | match c { 216 | b"?" => Ok((input, Item::Conditional(Conditional::If))), 217 | b"t" => Ok((input, Item::Conditional(Conditional::Then))), 218 | b"e" => Ok((input, Item::Conditional(Conditional::Else))), 219 | b";" => Ok((input, Item::Conditional(Conditional::End))), 220 | 221 | _ => Err(nom::Err::Error(make_error(input, ErrorKind::Switch))), 222 | } 223 | } 224 | 225 | fn print(input: &[u8]) -> IResult<&[u8], Item> { 226 | let (input, _) = opt(tag(":"))(input)?; 227 | 228 | let (input, flags) = take_while(is_flag)(input)?; 229 | let (input, width) = opt(take_while(is_digit))(input)?; 230 | let (input, precision) = opt(|input| { 231 | let (input, _) = tag(".")(input)?; 232 | let (input, amount) = take_while(is_digit)(input)?; 233 | 234 | Ok((input, amount)) 235 | })(input)?; 236 | 237 | let (input, format) = one_of("doxXsc")(input)?; 238 | 239 | Ok(( 240 | input, 241 | Item::Print(Print { 242 | flags: Flags { 243 | width: number(width.unwrap_or(b"0")) as usize, 244 | precision: number(precision.unwrap_or(b"0")) as usize, 245 | 246 | alternate: flags.contains(&b'#'), 247 | left: flags.contains(&b'-'), 248 | sign: flags.contains(&b'+'), 249 | space: flags.contains(&b' '), 250 | }, 251 | 252 | format: match format { 253 | 'd' => Format::Dec, 254 | 'o' => Format::Oct, 255 | 'x' => Format::Hex, 256 | 'X' => Format::HEX, 257 | 's' => Format::Str, 258 | 'c' => Format::Chr, 259 | 'u' => Format::Uni, 260 | _ => unreachable!(), 261 | }, 262 | }), 263 | )) 264 | } 265 | 266 | fn is_flag(i: u8) -> bool { 267 | i == b' ' || i == b'-' || i == b'+' || i == b'#' 268 | } 269 | 270 | #[cfg(test)] 271 | mod test { 272 | use super::*; 273 | 274 | macro_rules! test { 275 | ($string:expr => $($item:tt)*) => ( 276 | assert_eq!(Item::$($item)*, parse($string).unwrap().1); 277 | ) 278 | } 279 | 280 | #[test] 281 | fn string() { 282 | test!(b"foobar" => 283 | String(b"foobar")); 284 | } 285 | 286 | #[test] 287 | fn percent() { 288 | test!(b"%%" => 289 | String(b"%")); 290 | } 291 | 292 | #[test] 293 | fn constant() { 294 | test!(b"%{24}" => 295 | Constant(Constant::Integer(24))); 296 | 297 | test!(b"%'a'" => 298 | Constant(Constant::Character(b'a'))); 299 | } 300 | 301 | #[test] 302 | fn variable() { 303 | test!(b"%l" => 304 | Variable(Variable::Length)); 305 | 306 | test!(b"%p1" => 307 | Variable(Variable::Push(0))); 308 | 309 | test!(b"%Pa" => 310 | Variable(Variable::Set(true, 0))); 311 | 312 | test!(b"%PA" => 313 | Variable(Variable::Set(false, 0))); 314 | 315 | test!(b"%ga" => 316 | Variable(Variable::Get(true, 0))); 317 | 318 | test!(b"%gA" => 319 | Variable(Variable::Get(false, 0))); 320 | } 321 | 322 | #[test] 323 | fn operation() { 324 | test!(b"%i" => 325 | Operation(Operation::Increment)); 326 | 327 | test!(b"%+" => 328 | Operation(Operation::Binary(Binary::Add))); 329 | 330 | test!(b"%-" => 331 | Operation(Operation::Binary(Binary::Subtract))); 332 | 333 | test!(b"%*" => 334 | Operation(Operation::Binary(Binary::Multiply))); 335 | 336 | test!(b"%/" => 337 | Operation(Operation::Binary(Binary::Divide))); 338 | 339 | test!(b"%m" => 340 | Operation(Operation::Binary(Binary::Remainder))); 341 | 342 | test!(b"%&" => 343 | Operation(Operation::Binary(Binary::AND))); 344 | 345 | test!(b"%|" => 346 | Operation(Operation::Binary(Binary::OR))); 347 | 348 | test!(b"%^" => 349 | Operation(Operation::Binary(Binary::XOR))); 350 | 351 | test!(b"%~" => 352 | Operation(Operation::Unary(Unary::NOT))); 353 | 354 | test!(b"%A" => 355 | Operation(Operation::Binary(Binary::And))); 356 | 357 | test!(b"%O" => 358 | Operation(Operation::Binary(Binary::Or))); 359 | 360 | test!(b"%!" => 361 | Operation(Operation::Unary(Unary::Not))); 362 | 363 | test!(b"%=" => 364 | Operation(Operation::Binary(Binary::Equal))); 365 | 366 | test!(b"%>" => 367 | Operation(Operation::Binary(Binary::Greater))); 368 | 369 | test!(b"%<" => 370 | Operation(Operation::Binary(Binary::Lesser))); 371 | } 372 | 373 | #[test] 374 | fn conditional() { 375 | test!(b"%?" => 376 | Conditional(Conditional::If)); 377 | 378 | test!(b"%t" => 379 | Conditional(Conditional::Then)); 380 | 381 | test!(b"%e" => 382 | Conditional(Conditional::Else)); 383 | 384 | test!(b"%;" => 385 | Conditional(Conditional::End)); 386 | } 387 | 388 | #[test] 389 | fn print() { 390 | test!(b"%s" => 391 | Print(Print { flags: Default::default(), format: Format::Str })); 392 | 393 | test!(b"% 30s" => 394 | Print(Print { flags: Flags { width: 30, space: true, .. Default::default() }, format: Format::Str })); 395 | 396 | test!(b"%:-3.4d" => 397 | Print(Print { flags: Flags { width: 3, precision: 4, left: true, .. Default::default() }, format: Format::Dec })); 398 | } 399 | } 400 | -------------------------------------------------------------------------------- /src/parser/mod.rs: -------------------------------------------------------------------------------- 1 | // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | // Version 2, December 2004 3 | // 4 | // Copyleft (ↄ) meh. | http://meh.schizofreni.co 5 | // 6 | // Everyone is permitted to copy and distribute verbatim or modified 7 | // copies of this license document, and changing it is allowed as long 8 | // as the name is changed. 9 | // 10 | // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | // TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | // 13 | // 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | 15 | #[macro_use] 16 | mod util; 17 | 18 | pub mod compiled; 19 | pub mod expansion; 20 | pub mod source; 21 | -------------------------------------------------------------------------------- /src/parser/source.rs: -------------------------------------------------------------------------------- 1 | // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | // Version 2, December 2004 3 | // 4 | // Copyleft (ↄ) meh. | http://meh.schizofreni.co 5 | // 6 | // Everyone is permitted to copy and distribute verbatim or modified 7 | // copies of this license document, and changing it is allowed as long 8 | // as the name is changed. 9 | // 10 | // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | // TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | // 13 | // 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | 15 | use crate::parser::util::unescape; 16 | use crate::parser::util::{end, is_eol, is_ws, ws}; 17 | use crate::parser::util::{is_printable_no_comma, is_printable_no_control, is_printable_no_pipe}; 18 | use nom::branch::alt; 19 | use nom::bytes::streaming::{tag, take, take_until, take_while}; 20 | use nom::character::{is_digit, streaming::line_ending as eol}; 21 | use nom::combinator::{complete, map, map_res, opt}; 22 | use nom::error::{make_error, ErrorKind}; 23 | use nom::sequence::terminated; 24 | use nom::IResult; 25 | use std::borrow::Cow; 26 | use std::str; 27 | 28 | #[derive(Eq, PartialEq, Clone, Debug)] 29 | pub enum Item<'a> { 30 | Comment(&'a str), 31 | 32 | Definition { name: &'a str, aliases: Vec<&'a str>, description: &'a str }, 33 | 34 | True(&'a str), 35 | Number(&'a str, i16), 36 | String(&'a str, Cow<'a, [u8]>), 37 | Disable(&'a str), 38 | } 39 | 40 | pub fn parse(input: &[u8]) -> IResult<&[u8], Item> { 41 | alt((comment, definition, disable, entry))(input) 42 | } 43 | 44 | fn comment(input: &[u8]) -> IResult<&[u8], Item> { 45 | let (input, _) = tag("#")(input)?; 46 | let (input, content) = map_res(terminated(take_until("\n"), tag("\n")), str::from_utf8)(input)?; 47 | let (input, _) = opt(complete(take_while(is_eol)))(input)?; 48 | 49 | Ok((input, Item::Comment(content.trim()))) 50 | } 51 | 52 | fn definition(input: &[u8]) -> IResult<&[u8], Item> { 53 | let (input, name) = 54 | map(take_while(is_printable_no_pipe), |n| unsafe { str::from_utf8_unchecked(n) })(input)?; 55 | 56 | let (input, _) = tag("|")(input)?; 57 | 58 | let (input, content) = 59 | map(take_while(is_printable_no_comma), |n| unsafe { str::from_utf8_unchecked(n) })(input)?; 60 | 61 | let (input, _) = tag(",")(input)?; 62 | 63 | let (input, _) = take_while(is_ws)(input)?; 64 | 65 | let (input, _) = eol(input)?; 66 | let (input, _) = opt(complete(take_while(is_eol)))(input)?; 67 | 68 | Ok((input, { 69 | let mut aliases = content.split(|c| c == '|').map(|n| n.trim()).collect::>(); 70 | 71 | Item::Definition { name, description: aliases.pop().unwrap(), aliases } 72 | })) 73 | } 74 | 75 | fn disable(input: &[u8]) -> IResult<&[u8], Item> { 76 | let (input, _) = ws(input)?; 77 | let (input, _) = take_while(is_ws)(input)?; 78 | let (input, _) = tag("@")(input)?; 79 | 80 | let (input, name) = 81 | map(take_while(is_printable_no_control), |n| unsafe { str::from_utf8_unchecked(n) })( 82 | input, 83 | )?; 84 | 85 | let (input, _) = tag(",")(input)?; 86 | let (input, _) = take_while(is_ws)(input)?; 87 | let (input, _) = end(input)?; 88 | let (input, _) = opt(complete(take_while(is_eol)))(input)?; 89 | 90 | Ok((input, Item::Disable(name))) 91 | } 92 | 93 | fn entry(input: &[u8]) -> IResult<&[u8], Item> { 94 | let (input, _) = ws(input)?; 95 | let (input, _) = take_while(is_ws)(input)?; 96 | 97 | let (input, name) = 98 | map(take_while(is_printable_no_control), |n| unsafe { str::from_utf8_unchecked(n) })( 99 | input, 100 | )?; 101 | 102 | let (input, c) = take(1_usize)(input)?; 103 | let (input, value) = match c { 104 | b"," => (input, Item::True(name)), 105 | 106 | b"#" => { 107 | let (input, value) = 108 | map(take_while(is_digit), |n| unsafe { str::from_utf8_unchecked(n) })(input)?; 109 | 110 | let (input, _) = tag(",")(input)?; 111 | 112 | (input, Item::Number(name, value.parse().unwrap())) 113 | } 114 | 115 | b"=" => { 116 | let (input, value) = take_while(is_printable_no_comma)(input)?; 117 | 118 | let (input, _) = tag(",")(input)?; 119 | 120 | (input, Item::String(name, unescape(value))) 121 | } 122 | 123 | _ => Err(nom::Err::Error(make_error(input, ErrorKind::Switch)))?, 124 | }; 125 | 126 | let (input, _) = take_while(is_ws)(input)?; 127 | let (input, _) = end(input)?; 128 | let (input, _) = opt(complete(take_while(is_eol)))(input)?; 129 | 130 | Ok((input, value)) 131 | } 132 | 133 | #[cfg(test)] 134 | mod test { 135 | use super::*; 136 | 137 | use std::fs::File; 138 | use std::io::Read; 139 | 140 | #[test] 141 | fn parsing() { 142 | let mut file = File::open("tests/xterm.terminfo").unwrap(); 143 | let mut buffer = Vec::new(); 144 | file.read_to_end(&mut buffer).unwrap(); 145 | 146 | let mut input = &buffer[..]; 147 | 148 | while !input.is_empty() { 149 | match parse(input) { 150 | Ok((rest, _)) => input = rest, 151 | 152 | Err(::nom::Err::Incomplete(_)) => panic!("incomplete"), 153 | 154 | Err(err) => panic!("parsing: {:?}", err), 155 | } 156 | } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /src/parser/util.rs: -------------------------------------------------------------------------------- 1 | // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | // Version 2, December 2004 3 | // 4 | // Copyleft (ↄ) meh. | http://meh.schizofreni.co 5 | // 6 | // Everyone is permitted to copy and distribute verbatim or modified 7 | // copies of this license document, and changing it is allowed as long 8 | // as the name is changed. 9 | // 10 | // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | // TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | // 13 | // 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | 15 | use nom::branch::alt; 16 | use nom::character::streaming::char; 17 | use nom::character::{is_digit, streaming::line_ending as eol}; 18 | use nom::combinator::eof; 19 | use nom::IResult; 20 | use std::borrow::Cow; 21 | use std::str; 22 | use std::u8; 23 | 24 | const NONE: u8 = 0b000000; 25 | const PRINT: u8 = 0b000001; 26 | const SPACE: u8 = 0b000010; 27 | const CONTROL: u8 = 0b000100; 28 | const PIPE: u8 = 0b001000; 29 | const COMMA: u8 = 0b010000; 30 | const EOL: u8 = 0b100000; 31 | 32 | // Ugly table of DOOM, gotta run and gun. 33 | #[rustfmt::skip] 34 | static ASCII: [u8; 256] = [ 35 | NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, 36 | NONE, SPACE, EOL, NONE, NONE, EOL, NONE, NONE, 37 | NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, 38 | NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, 39 | PRINT | SPACE, PRINT, PRINT, PRINT | CONTROL, PRINT, PRINT, PRINT, PRINT, 40 | PRINT, PRINT, PRINT, PRINT, PRINT | COMMA | CONTROL, PRINT, PRINT, PRINT, 41 | PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, 42 | PRINT, PRINT, PRINT, PRINT, PRINT, PRINT | CONTROL, PRINT, PRINT, 43 | PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, 44 | PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, 45 | PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, 46 | PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, 47 | PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, 48 | PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, 49 | PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, 50 | PRINT, PRINT, PRINT, PRINT, PRINT | PIPE, PRINT, PRINT, NONE, 51 | NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, 52 | NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, 53 | NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, 54 | NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, 55 | NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, 56 | NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, 57 | NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, 58 | NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, 59 | NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, 60 | NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, 61 | NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, 62 | NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, 63 | NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, 64 | NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, 65 | NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, 66 | NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, 67 | ]; 68 | 69 | #[inline(always)] 70 | pub fn is_ws(ch: u8) -> bool { 71 | unsafe { ASCII.get_unchecked(ch as usize) & SPACE == SPACE } 72 | } 73 | 74 | #[inline(always)] 75 | pub fn is_eol(ch: u8) -> bool { 76 | unsafe { ASCII.get_unchecked(ch as usize) & EOL == EOL } 77 | } 78 | 79 | #[inline(always)] 80 | pub fn is_printable_no_pipe(ch: u8) -> bool { 81 | unsafe { ASCII.get_unchecked(ch as usize) & (PRINT | PIPE) == PRINT } 82 | } 83 | 84 | #[inline(always)] 85 | pub fn is_printable_no_comma(ch: u8) -> bool { 86 | unsafe { ASCII.get_unchecked(ch as usize) & (PRINT | COMMA) == PRINT } 87 | } 88 | 89 | #[inline(always)] 90 | pub fn is_printable_no_control(ch: u8) -> bool { 91 | unsafe { ASCII.get_unchecked(ch as usize) & (PRINT | CONTROL) == PRINT } 92 | } 93 | 94 | pub fn ws(input: &[u8]) -> IResult<&[u8], char> { 95 | alt((char(' '), char('\t')))(input) 96 | } 97 | 98 | pub fn end(input: &[u8]) -> IResult<&[u8], &[u8]> { 99 | alt((eof, eol))(input) 100 | } 101 | 102 | #[inline] 103 | pub fn number(i: &[u8]) -> i32 { 104 | let mut n: i32 = 0; 105 | 106 | for &ch in i { 107 | let d = (ch as i32).wrapping_sub(b'0' as i32); 108 | 109 | if d <= 9 { 110 | n = n.saturating_mul(10).saturating_add(d); 111 | } 112 | } 113 | 114 | n 115 | } 116 | 117 | pub fn unescape(i: &[u8]) -> Cow<[u8]> { 118 | fn escape>(output: &mut Vec, iter: &mut I) { 119 | match iter.next() { 120 | None => (), 121 | 122 | Some(b'a') => output.push(0x07), 123 | 124 | Some(b'b') => output.push(0x08), 125 | 126 | Some(b'E') | Some(b'e') => output.push(0x1B), 127 | 128 | Some(b'f') => output.push(0x0C), 129 | 130 | Some(b'l') | Some(b'n') => output.push(b'\n'), 131 | 132 | Some(b'r') => output.push(b'\r'), 133 | 134 | Some(b's') => output.push(b' '), 135 | 136 | Some(b't') => output.push(b'\t'), 137 | 138 | Some(b'^') => output.push(b'^'), 139 | 140 | Some(b'\\') => output.push(b'\\'), 141 | 142 | Some(b',') => output.push(b','), 143 | 144 | Some(b':') => output.push(b':'), 145 | 146 | Some(b'0') => output.push(0x00), 147 | 148 | Some(a) if is_digit(a) => match (iter.next(), iter.next()) { 149 | (Some(b), Some(c)) if is_digit(b) && is_digit(c) => { 150 | if let Ok(number) = 151 | u8::from_str_radix(unsafe { str::from_utf8_unchecked(&[a, b, c]) }, 8) 152 | { 153 | output.push(number); 154 | } else { 155 | output.extend(&[a, b, c]); 156 | } 157 | } 158 | 159 | (Some(b), None) => output.extend(&[b'\\', a, b]), 160 | 161 | (None, None) => output.extend(&[b'\\', a]), 162 | 163 | _ => unreachable!(), 164 | }, 165 | 166 | Some(ch) => output.extend(&[b'\\', ch]), 167 | } 168 | } 169 | 170 | fn control>(output: &mut Vec, iter: &mut I) { 171 | match iter.next() { 172 | None => (), 173 | 174 | Some(ch) if ch.is_ascii_uppercase() => output.push(ch - b'A' + 1), 175 | 176 | Some(ch) if ch.is_ascii_lowercase() => output.push(ch - b'a' + 1), 177 | 178 | Some(ch) => output.extend(&[b'^', ch]), 179 | } 180 | } 181 | 182 | let mut chars = i.iter().cloned(); 183 | let mut offset = 0; 184 | 185 | while let Some(ch) = chars.next() { 186 | if ch == b'\\' || ch == b'^' { 187 | let mut output = i[..offset].to_vec(); 188 | 189 | match ch { 190 | b'\\' => escape(&mut output, &mut chars), 191 | 192 | b'^' => control(&mut output, &mut chars), 193 | 194 | _ => unreachable!(), 195 | } 196 | 197 | while let Some(ch) = chars.next() { 198 | match ch { 199 | b'\\' => escape(&mut output, &mut chars), 200 | 201 | b'^' => control(&mut output, &mut chars), 202 | 203 | ch => output.push(ch), 204 | } 205 | } 206 | 207 | return Cow::Owned(output); 208 | } 209 | 210 | offset += 1; 211 | } 212 | 213 | Cow::Borrowed(i) 214 | } 215 | -------------------------------------------------------------------------------- /tests/cancer+secret: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meh/rust-terminfo/7bbf236c1bdcdb39f4e40ecf2f840da1c576a461/tests/cancer+secret -------------------------------------------------------------------------------- /tests/cancer-256color: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meh/rust-terminfo/7bbf236c1bdcdb39f4e40ecf2f840da1c576a461/tests/cancer-256color -------------------------------------------------------------------------------- /tests/st-256color: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meh/rust-terminfo/7bbf236c1bdcdb39f4e40ecf2f840da1c576a461/tests/st-256color -------------------------------------------------------------------------------- /tests/xterm-256color: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meh/rust-terminfo/7bbf236c1bdcdb39f4e40ecf2f840da1c576a461/tests/xterm-256color -------------------------------------------------------------------------------- /tests/xterm.terminfo: -------------------------------------------------------------------------------- 1 | # $XTermId: terminfo,v 1.161 2012/09/05 00:24:08 tom Exp $ 2 | # 3 | # Updates/notes/new entries (e.g., xterm-8bit, xterm-16color, xterm-256color) 4 | # - Thomas E. Dickey 5 | # 6 | #------------------------------------------------------------------------------ 7 | # Copyright 1996-2011,2012 by Thomas E. Dickey 8 | # 9 | # All Rights Reserved 10 | # 11 | # Permission is hereby granted, free of charge, to any person obtaining a 12 | # copy of this software and associated documentation files (the 13 | # "Software"), to deal in the Software without restriction, including 14 | # without limitation the rights to use, copy, modify, merge, publish, 15 | # distribute, sublicense, and/or sell copies of the Software, and to 16 | # permit persons to whom the Software is furnished to do so, subject to 17 | # the following conditions: 18 | # 19 | # The above copyright notice and this permission notice shall be included 20 | # in all copies or substantial portions of the Software. 21 | # 22 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 23 | # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 25 | # IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY 26 | # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 27 | # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 28 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | # 30 | # Except as contained in this notice, the name(s) of the above copyright 31 | # holders shall not be used in advertising or otherwise to promote the 32 | # sale, use or other dealings in this Software without prior written 33 | # authorization. 34 | #------------------------------------------------------------------------------ 35 | # 36 | # Special Capabilities: 37 | # -------------------- 38 | # ich has a corresponding capability that inserts a single blank. We could 39 | # have used ich1=\E[@, which works with ncurses, but that is not standard 40 | # behavior. If it is set, then SVr4 vi (e.g., Solaris 2.6) emits both 41 | # smir/rmir and ich1. 42 | # meml locks memory above the cursor; memu unlocks (ala HP terminals). This 43 | # is not recognized by some older (e.g., SVr3) tic programs, but none 44 | # do more than warn about it. Ignore the warning. 45 | # smcup clears memory before switching to the alternate screen. The older 46 | # (deprecated) \E[?47h did not do this, requiring applications to 47 | # embed a \E[2J in the rmcup string. However, that behavior cannot 48 | # be disabled via titeInhibit, making that resource not function as 49 | # intended on systems with terminfo. 50 | # rs2/is2 are shorter with XFree86 xterm because it supports DECSTR. We 51 | # use the shorter sequence for compatibility with the termcap, which 52 | # is trimmed to keep it shorter than 1023 characters. It (escape \E[!p) 53 | # replaces these in the conventional vt100 reset-string: 54 | # \E7 - save cursor (fixes origin-mode side-effect) 55 | # \E[r - reset scrolling margins 56 | # \E[m - reset SGR (including color) 57 | # \E[?7h - reset wraparound mode (DECAWM) 58 | # \E[?1l - reset application cursor keys (DECCKM) 59 | # \E[?6l - reset origin mode (DECOM) 60 | # \E8 - restore cursor 61 | # DECSTR is recognized by XFree86 xterm even in vt52 mode. 62 | # 63 | # Editing Keypad: 64 | # -------------- 65 | # XFree86 xterm emulates vt220 if the decTerminalID resource is set to 200 or 66 | # higher. Otherwise it emulates a vt100 or vt52 depending on the value of the 67 | # resource. When emulating a vt220, we support the editing keypad. Sun and PC 68 | # keyboards have an editing keypad which is similar to the vt220: 69 | # 70 | # VT220 editing keypad 71 | # ---------------------------- 72 | # Find Insert Remove 73 | # Select Prev Next 74 | # ---------------------------- 75 | # 76 | # Sun/PC editing keypad 77 | # ---------------------------- 78 | # Insert Home PageUp 79 | # Delete End PageDn 80 | # ---------------------------- 81 | # 82 | # If the sunKeyboard resource is true, we map it this way (adjusting the values 83 | # of Home, End and Delete): 84 | # VT220 Sun/PC 85 | # ---------------------------- 86 | # Find Home 87 | # Select End 88 | # Insert Insert 89 | # Remove Delete 90 | # Prev PageUp 91 | # Next PageDn 92 | # ---------------------------- 93 | # 94 | # Note that all of the keys on the editing keypad transmit escape sequences. A 95 | # vt220 does this only when in vt220 mode; when emulating a vt100 the editing 96 | # keypad is inactive. 97 | # 98 | # Alternative keycodes: 99 | # -------------------- 100 | # Several of the function keys have alternative names, depending on the type of 101 | # host which your xterm is connected to. DEC (i.e., the VMS system) uses F15 102 | # as the HELP key, F16 as the DO key. Unix applications generally do not do 103 | # this. Curses applications in particular, assign a unique keycode to each 104 | # capability string. These terminal descriptions do not have conflicting 105 | # definitions, to ensure that Unix curses applications use a consistent set of 106 | # keycodes. To get a VMS-bias, make these substitutions: 107 | # 1. change khome to kfnd 108 | # 2. change kend to kslt 109 | # The original xterm-r6 entry does in fact have a VMS bias. 110 | # 111 | # Some legacy applications using the termcap emulation may expect kll where 112 | # we have specified kend. 113 | # 114 | # Function keys with modifiers (Sun/PC): 115 | # ------------------------------------- 116 | # Shift-Fx - kf{12+x} 117 | # Control-Fx - kf{24+x} 118 | # Shift-Control-Fx - kf{36+x} 119 | # 120 | # The terminfo defines some special keys which are documented as "shifted", 121 | # e.g., kDC is shifted-delete-character. 122 | # 123 | # Note however, that even though the terminfo says a key might be sent, there 124 | # may be conflicts which prevent this. For example, it is common to use 125 | # shifted pageup and pagedown for window manager functions. The default 126 | # translation for xterm since X11R4 has overridden shifted Insert, Select, 127 | # PageUp and PageDown, which correspond to terminfo kIC, kEND, kPRV and kNXT 128 | # respectively. 129 | # 130 | xterm-new|modern xterm terminal emulator, 131 | npc, 132 | indn=\E[%p1%dS, 133 | kb2=\EOE, 134 | kcbt=\E[Z, 135 | kent=\EOM, 136 | rin=\E[%p1%dT, 137 | use=xterm+pcfkeys, 138 | use=xterm+tmux, 139 | use=xterm-basic, 140 | # 141 | # Encode modifiers using parameters (see "Xterm Control Sequences" ctlseqs.ms). 142 | # Note that this is unrelated to PCTERM. 143 | # 144 | # Some names are extensions allowed by ncurses, e.g., 145 | # kDN, kDN5, kDN6, kLFT5, kLFT6, kRIT5, kRIT6, kUP, kUP5, kUP6 146 | # 147 | # The uppercase names are made up, since there are no standards that apply. 148 | # If they were limited to two characters, they could in principle be translated 149 | # to termcap. However, termcap sizes are limited to 1023 bytes, so there is 150 | # little point in ensuring that extended key names can be translated to 151 | # termcap. A terminfo file can be up to 4096 bytes; using all extended keys 152 | # that xterm can generate would in fact exceed that limit. 153 | # 154 | # The numbers correspond to the modifier parameters documented in Xterm 155 | # Control Sequences: 156 | # 157 | # 2 Shift 158 | # 3 Alt 159 | # 4 Shift + Alt 160 | # 5 Control 161 | # 6 Shift + Control 162 | # 7 Alt + Control 163 | # 8 Shift + Alt + Control 164 | # 165 | # X/Open Curses defines some shift combinations, which are also used here 166 | # where applicable. Since it does define some shift combinations, no number 167 | # (2) is used for suffixing the made-up names. Some combinations are not 168 | # useful, e.g., they may reboot your computer, or they may require too many 169 | # fingers. I stopped at modifier 7, just to keep things simple -TD 170 | # 171 | # XTerm resources: 172 | # --------------- 173 | # The xterm+pcfn, xterm+pcf0, xterm+pcf1, xterm+pcf2 and xterm+pcf3 fragments 174 | # correspond to default resource settings for xterm on a 104-key PC keyboard 175 | # with 12 function-keys: 176 | # 177 | # *sunKeyboard:false 178 | # *oldXtermFKeys:false 179 | # *modifyCursorKeys:2 180 | # *modifyFunctionKeys:2 181 | # *ctrlFKeys:10 182 | # 183 | # The key numbers are computed based on the modifiers: 184 | # 185 | # kf1-kf12 are F1-F12 186 | # kf13-kf24 are shift F1-F12 187 | # kf25-kf36 are control F1-F12 188 | # kf37-kf48 are control+shift F1-F12 189 | # kf49-kf60 are alt F1-F12 190 | # kf61-kf63 are shift-alt F1-F3 191 | # 192 | # Note that ncurses would allow definition of kf64 and beyond, if there were 193 | # an application that required it. 194 | # 195 | xterm+pcfkeys|fragment for PC-style keys, 196 | use=xterm+app, 197 | use=xterm+pcf2, 198 | use=xterm+pce2, 199 | use=xterm+pcc2, 200 | 201 | # This chunk is based on suggestions by Ailin Nemui and Nicholas Marriott, who 202 | # asked for some of xterm's advanced features to be added to its terminfo 203 | # entry. It defines extended capabilities not found in standard terminfo or 204 | # termcap. These are useful in tmux, for instance, hence the name. 205 | # 206 | # One caveat in adding extended capabilities in ncurses is that if the names 207 | # are longer than two characters, then they will not be visible through the 208 | # termcap interface. 209 | # 210 | # Ms modifies the selection/clipboard. Its parameters are 211 | # p1 = the storage unit (clipboard, selection or cut buffer) 212 | # p2 = the base64-encoded clipboard content. 213 | # 214 | # Ss is used to set the cursor style as described by the DECSCUSR 215 | # function to a block or underline. 216 | # Se resets the cursor style to the terminal power-on default. 217 | # 218 | # Cs and Ce set and reset the cursor colour. 219 | xterm+tmux|advanced xterm features used in tmux, 220 | Cr=\E]112\007, 221 | Cs=\E]12;%p1%s\007, 222 | Ms=\E]52;%p1%s;%p2%s\007, 223 | Se=\E[2 q, 224 | Ss=\E[%p1%d q, 225 | # 226 | # The ctrlFKeys resource is only relevant to the xterm+pcfn and xterm+pcfN 227 | # entries, since the modifyFunctionKeys resource overrides ctrlFKeys when it is 228 | # positive. A different choice of ctrlFKeys would give a different set of 229 | # function-key strings. 230 | xterm+pcfn|fragment with modifyFunctionKeys:-1 and ctrlFKeys:10, 231 | kf1=\EOP, 232 | kf10=\E[21~, 233 | kf11=\E[23~, 234 | kf12=\E[24~, 235 | kf13=\E[25~, 236 | kf14=\E[26~, 237 | kf15=\E[28~, 238 | kf16=\E[29~, 239 | kf17=\E[31~, 240 | kf18=\E[32~, 241 | kf19=\E[33~, 242 | kf2=\EOQ, 243 | kf20=\E[34~, 244 | kf21=\E[42~, 245 | kf22=\E[43~, 246 | kf23=\E[44~, 247 | kf24=\E[45~, 248 | kf25=\E[46~, 249 | kf26=\E[47~, 250 | kf27=\E[48~, 251 | kf28=\E[49~, 252 | kf29=\E[50~, 253 | kf3=\EOR, 254 | kf30=\E[51~, 255 | kf31=\E[52~, 256 | kf32=\E[53~, 257 | kf33=\E[54~, 258 | kf34=\E[55~, 259 | kf35=\E[56~, 260 | kf36=\E[57~, 261 | kf37=\E[58~, 262 | kf38=\E[59~, 263 | kf39=\E[60~, 264 | kf4=\EOS, 265 | kf40=\E[61~, 266 | kf41=\E[62~, 267 | kf42=\E[63~, 268 | kf43=\E[64~, 269 | kf44=\E[65~, 270 | kf45=\E[66~, 271 | kf46=\E[67~, 272 | kf47=\E[68~, 273 | kf48=\E[69~, 274 | kf5=\E[15~, 275 | kf6=\E[17~, 276 | kf7=\E[18~, 277 | kf8=\E[19~, 278 | kf9=\E[20~, 279 | 280 | # Changing ctrlFKeys to 12 would let us number the keys using just shift- and 281 | # control- modifiers: 282 | # kf1-kf12 are F1-F12 283 | # kf13-kf24 are shift F1-F12 284 | # kf25-kf36 are control F1-F12 285 | # kf37-kf48 are control+shift F1-F12 286 | xterm+pcfN|fragment with modifyFunctionKeys:-1 and ctrlFKeys:12, 287 | kf1=\EOP, 288 | kf10=\E[21~, 289 | kf11=\E[23~, 290 | kf12=\E[24~, 291 | kf13=\E[25~, 292 | kf14=\E[26~, 293 | kf15=\E[28~, 294 | kf16=\E[29~, 295 | kf17=\E[31~, 296 | kf18=\E[32~, 297 | kf19=\E[33~, 298 | kf2=\EOQ, 299 | kf20=\E[34~, 300 | kf21=\E[42~, 301 | kf22=\E[43~, 302 | kf23=\E[44~, 303 | kf24=\E[45~, 304 | kf25=\E[46~, 305 | kf26=\E[47~, 306 | kf27=\E[48~, 307 | kf28=\E[49~, 308 | kf29=\E[50~, 309 | kf3=\EOR, 310 | kf30=\E[51~, 311 | kf31=\E[52~, 312 | kf32=\E[53~, 313 | kf33=\E[54~, 314 | kf34=\E[55~, 315 | kf35=\E[56~, 316 | kf36=\E[57~, 317 | kf37=\E[58~, 318 | kf38=\E[59~, 319 | kf39=\E[60~, 320 | kf4=\EOS, 321 | kf40=\E[61~, 322 | kf41=\E[62~, 323 | kf42=\E[63~, 324 | kf43=\E[64~, 325 | kf44=\E[65~, 326 | kf45=\E[66~, 327 | kf46=\E[67~, 328 | kf47=\E[68~, 329 | kf48=\E[69~, 330 | kf5=\E[15~, 331 | kf6=\E[17~, 332 | kf7=\E[18~, 333 | kf8=\E[19~, 334 | kf9=\E[20~, 335 | 336 | xterm+pcf0|fragment with modifyFunctionKeys:0, 337 | kf1=\EOP, 338 | kf10=\E[21~, 339 | kf11=\E[23~, 340 | kf12=\E[24~, 341 | kf13=\EO2P, 342 | kf14=\EO2Q, 343 | kf15=\EO2R, 344 | kf16=\EO2S, 345 | kf17=\E[15;2~, 346 | kf18=\E[17;2~, 347 | kf19=\E[18;2~, 348 | kf2=\EOQ, 349 | kf20=\E[19;2~, 350 | kf21=\E[20;2~, 351 | kf22=\E[21;2~, 352 | kf23=\E[23;2~, 353 | kf24=\E[24;2~, 354 | kf25=\EO5P, 355 | kf26=\EO5Q, 356 | kf27=\EO5R, 357 | kf28=\EO5S, 358 | kf29=\E[15;5~, 359 | kf3=\EOR, 360 | kf30=\E[17;5~, 361 | kf31=\E[18;5~, 362 | kf32=\E[19;5~, 363 | kf33=\E[20;5~, 364 | kf34=\E[21;5~, 365 | kf35=\E[23;5~, 366 | kf36=\E[24;5~, 367 | kf37=\EO6P, 368 | kf38=\EO6Q, 369 | kf39=\EO6R, 370 | kf4=\EOS, 371 | kf40=\EO6S, 372 | kf41=\E[15;6~, 373 | kf42=\E[17;6~, 374 | kf43=\E[18;6~, 375 | kf44=\E[19;6~, 376 | kf45=\E[20;6~, 377 | kf46=\E[21;6~, 378 | kf47=\E[23;6~, 379 | kf48=\E[24;6~, 380 | kf49=\EO3P, 381 | kf5=\E[15~, 382 | kf50=\EO3Q, 383 | kf51=\EO3R, 384 | kf52=\EO3S, 385 | kf53=\E[15;3~, 386 | kf54=\E[17;3~, 387 | kf55=\E[18;3~, 388 | kf56=\E[19;3~, 389 | kf57=\E[20;3~, 390 | kf58=\E[21;3~, 391 | kf59=\E[23;3~, 392 | kf6=\E[17~, 393 | kf60=\E[24;3~, 394 | kf61=\EO4P, 395 | kf62=\EO4Q, 396 | kf63=\EO4R, 397 | kf7=\E[18~, 398 | kf8=\E[19~, 399 | kf9=\E[20~, 400 | 401 | # This is almost the same as xterm+pcf2 because the unmodified keys all happen 402 | # to have a pattern that forces the modifier to the same position. 403 | xterm+pcf1|fragment with modifyFunctionKeys:1, 404 | kf1=\EOP, 405 | kf10=\E[21~, 406 | kf11=\E[23~, 407 | kf12=\E[24~, 408 | kf13=\E[2P, 409 | kf14=\E[2Q, 410 | kf15=\E[2R, 411 | kf16=\E[2S, 412 | kf17=\E[15;2~, 413 | kf18=\E[17;2~, 414 | kf19=\E[18;2~, 415 | kf2=\EOQ, 416 | kf20=\E[19;2~, 417 | kf21=\E[20;2~, 418 | kf22=\E[21;2~, 419 | kf23=\E[23;2~, 420 | kf24=\E[24;2~, 421 | kf25=\E[5P, 422 | kf26=\E[5Q, 423 | kf27=\E[5R, 424 | kf28=\E[5S, 425 | kf29=\E[15;5~, 426 | kf3=\EOR, 427 | kf30=\E[17;5~, 428 | kf31=\E[18;5~, 429 | kf32=\E[19;5~, 430 | kf33=\E[20;5~, 431 | kf34=\E[21;5~, 432 | kf35=\E[23;5~, 433 | kf36=\E[24;5~, 434 | kf37=\E[6P, 435 | kf38=\E[6Q, 436 | kf39=\E[6R, 437 | kf4=\EOS, 438 | kf40=\E[6S, 439 | kf41=\E[15;6~, 440 | kf42=\E[17;6~, 441 | kf43=\E[18;6~, 442 | kf44=\E[19;6~, 443 | kf45=\E[20;6~, 444 | kf46=\E[21;6~, 445 | kf47=\E[23;6~, 446 | kf48=\E[24;6~, 447 | kf49=\E[3P, 448 | kf5=\E[15~, 449 | kf50=\E[3Q, 450 | kf51=\E[3R, 451 | kf52=\E[3S, 452 | kf53=\E[15;3~, 453 | kf54=\E[17;3~, 454 | kf55=\E[18;3~, 455 | kf56=\E[19;3~, 456 | kf57=\E[20;3~, 457 | kf58=\E[21;3~, 458 | kf59=\E[23;3~, 459 | kf6=\E[17~, 460 | kf60=\E[24;3~, 461 | kf61=\E[4P, 462 | kf62=\E[4Q, 463 | kf63=\E[4R, 464 | kf7=\E[18~, 465 | kf8=\E[19~, 466 | kf9=\E[20~, 467 | 468 | xterm+pcf2|fragment with modifyFunctionKeys:2, 469 | kf1=\EOP, 470 | kf10=\E[21~, 471 | kf11=\E[23~, 472 | kf12=\E[24~, 473 | kf13=\E[1;2P, 474 | kf14=\E[1;2Q, 475 | kf15=\E[1;2R, 476 | kf16=\E[1;2S, 477 | kf17=\E[15;2~, 478 | kf18=\E[17;2~, 479 | kf19=\E[18;2~, 480 | kf2=\EOQ, 481 | kf20=\E[19;2~, 482 | kf21=\E[20;2~, 483 | kf22=\E[21;2~, 484 | kf23=\E[23;2~, 485 | kf24=\E[24;2~, 486 | kf25=\E[1;5P, 487 | kf26=\E[1;5Q, 488 | kf27=\E[1;5R, 489 | kf28=\E[1;5S, 490 | kf29=\E[15;5~, 491 | kf3=\EOR, 492 | kf30=\E[17;5~, 493 | kf31=\E[18;5~, 494 | kf32=\E[19;5~, 495 | kf33=\E[20;5~, 496 | kf34=\E[21;5~, 497 | kf35=\E[23;5~, 498 | kf36=\E[24;5~, 499 | kf37=\E[1;6P, 500 | kf38=\E[1;6Q, 501 | kf39=\E[1;6R, 502 | kf4=\EOS, 503 | kf40=\E[1;6S, 504 | kf41=\E[15;6~, 505 | kf42=\E[17;6~, 506 | kf43=\E[18;6~, 507 | kf44=\E[19;6~, 508 | kf45=\E[20;6~, 509 | kf46=\E[21;6~, 510 | kf47=\E[23;6~, 511 | kf48=\E[24;6~, 512 | kf49=\E[1;3P, 513 | kf5=\E[15~, 514 | kf50=\E[1;3Q, 515 | kf51=\E[1;3R, 516 | kf52=\E[1;3S, 517 | kf53=\E[15;3~, 518 | kf54=\E[17;3~, 519 | kf55=\E[18;3~, 520 | kf56=\E[19;3~, 521 | kf57=\E[20;3~, 522 | kf58=\E[21;3~, 523 | kf59=\E[23;3~, 524 | kf6=\E[17~, 525 | kf60=\E[24;3~, 526 | kf61=\E[1;4P, 527 | kf62=\E[1;4Q, 528 | kf63=\E[1;4R, 529 | kf7=\E[18~, 530 | kf8=\E[19~, 531 | kf9=\E[20~, 532 | 533 | xterm+pcf3|fragment with modifyFunctionKeys:3, 534 | kf1=\EOP, 535 | kf10=\E[21~, 536 | kf11=\E[23~, 537 | kf12=\E[24~, 538 | kf13=\E[>1;2P, 539 | kf14=\E[>1;2Q, 540 | kf15=\E[>1;2R, 541 | kf16=\E[>1;2S, 542 | kf17=\E[>15;2~, 543 | kf18=\E[>17;2~, 544 | kf19=\E[>18;2~, 545 | kf2=\EOQ, 546 | kf20=\E[>19;2~, 547 | kf21=\E[>20;2~, 548 | kf22=\E[>21;2~, 549 | kf23=\E[>23;2~, 550 | kf24=\E[>24;2~, 551 | kf25=\E[>1;5P, 552 | kf26=\E[>1;5Q, 553 | kf27=\E[>1;5R, 554 | kf28=\E[>1;5S, 555 | kf29=\E[>15;5~, 556 | kf3=\EOR, 557 | kf30=\E[>17;5~, 558 | kf31=\E[>18;5~, 559 | kf32=\E[>19;5~, 560 | kf33=\E[>20;5~, 561 | kf34=\E[>21;5~, 562 | kf35=\E[>23;5~, 563 | kf36=\E[>24;5~, 564 | kf37=\E[>1;6P, 565 | kf38=\E[>1;6Q, 566 | kf39=\E[>1;6R, 567 | kf4=\EOS, 568 | kf40=\E[>1;6S, 569 | kf41=\E[>15;6~, 570 | kf42=\E[>17;6~, 571 | kf43=\E[>18;6~, 572 | kf44=\E[>19;6~, 573 | kf45=\E[>20;6~, 574 | kf46=\E[>21;6~, 575 | kf47=\E[>23;6~, 576 | kf48=\E[>24;6~, 577 | kf49=\E[>1;3P, 578 | kf5=\E[15~, 579 | kf50=\E[>1;3Q, 580 | kf51=\E[>1;3R, 581 | kf52=\E[>1;3S, 582 | kf53=\E[>15;3~, 583 | kf54=\E[>17;3~, 584 | kf55=\E[>18;3~, 585 | kf56=\E[>19;3~, 586 | kf57=\E[>20;3~, 587 | kf58=\E[>21;3~, 588 | kf59=\E[>23;3~, 589 | kf6=\E[17~, 590 | kf60=\E[>24;3~, 591 | kf61=\E[>1;4P, 592 | kf62=\E[>1;4Q, 593 | kf63=\E[>1;4R, 594 | kf7=\E[18~, 595 | kf8=\E[19~, 596 | kf9=\E[20~, 597 | # 598 | # The "PC-style" modifier scheme was introduced in xterm patch #94 (1999/3/27) 599 | # and revised in patch #167 (2002/8/24). 600 | # 601 | # The original assignments from patch #94 for cursor-keys had some technical 602 | # issues: 603 | # 604 | # A parameter for a function-key to represent a modifier is just more 605 | # bits. But for a cursor-key it may change the behavior of the 606 | # application. For instance, emacs decodes the first parameter of a 607 | # cursor-key as a repeat count. 608 | # 609 | # A parameterized string should (really) not begin with SS3 (\EO). 610 | # Rather, CSI (\E[) should be used. 611 | # 612 | # For these reasons, the original assignments were deprecated. For 613 | # compatibility reasons, they are still available as a setting of xterm's 614 | # modifyCursorKeys resource. These fragments list the modified cursor-keys 615 | # that might apply to xterm+pcfkeys with different values of that resource. 616 | xterm+pcc3|fragment with modifyCursorKeys:3, 617 | kLFT=\E[>1;2D, 618 | kRIT=\E[>1;2C, 619 | kind=\E[>1;2B, 620 | kri=\E[>1;2A, 621 | kDN=\E[>1;2B, 622 | kDN3=\E[>1;3B, 623 | kDN4=\E[>1;4B, 624 | kDN5=\E[>1;5B, 625 | kDN6=\E[>1;6B, 626 | kDN7=\E[>1;7B, 627 | kLFT3=\E[>1;3D, 628 | kLFT4=\E[>1;4D, 629 | kLFT5=\E[>1;5D, 630 | kLFT6=\E[>1;6D, 631 | kLFT7=\E[>1;7D, 632 | kRIT3=\E[>1;3C, 633 | kRIT4=\E[>1;4C, 634 | kRIT5=\E[>1;5C, 635 | kRIT6=\E[>1;6C, 636 | kRIT7=\E[>1;7C, 637 | kUP=\E[>1;2A, 638 | kUP3=\E[>1;3A, 639 | kUP4=\E[>1;4A, 640 | kUP5=\E[>1;5A, 641 | kUP6=\E[>1;6A, 642 | kUP7=\E[>1;7A, 643 | 644 | xterm+pcc2|fragment with modifyCursorKeys:2, 645 | kLFT=\E[1;2D, 646 | kRIT=\E[1;2C, 647 | kind=\E[1;2B, 648 | kri=\E[1;2A, 649 | kDN=\E[1;2B, 650 | kDN3=\E[1;3B, 651 | kDN4=\E[1;4B, 652 | kDN5=\E[1;5B, 653 | kDN6=\E[1;6B, 654 | kDN7=\E[1;7B, 655 | kLFT3=\E[1;3D, 656 | kLFT4=\E[1;4D, 657 | kLFT5=\E[1;5D, 658 | kLFT6=\E[1;6D, 659 | kLFT7=\E[1;7D, 660 | kRIT3=\E[1;3C, 661 | kRIT4=\E[1;4C, 662 | kRIT5=\E[1;5C, 663 | kRIT6=\E[1;6C, 664 | kRIT7=\E[1;7C, 665 | kUP=\E[1;2A, 666 | kUP3=\E[1;3A, 667 | kUP4=\E[1;4A, 668 | kUP5=\E[1;5A, 669 | kUP6=\E[1;6A, 670 | kUP7=\E[1;7A, 671 | 672 | xterm+pcc1|fragment with modifyCursorKeys:1, 673 | kLFT=\E[2D, 674 | kRIT=\E[2C, 675 | kind=\E[2B, 676 | kri=\E[2A, 677 | kDN=\E[2B, 678 | kDN3=\E[3B, 679 | kDN4=\E[4B, 680 | kDN5=\E[5B, 681 | kDN6=\E[6B, 682 | kDN7=\E[7B, 683 | kLFT3=\E[3D, 684 | kLFT4=\E[4D, 685 | kLFT5=\E[5D, 686 | kLFT6=\E[6D, 687 | kLFT7=\E[7D, 688 | kRIT3=\E[3C, 689 | kRIT4=\E[4C, 690 | kRIT5=\E[5C, 691 | kRIT6=\E[6C, 692 | kRIT7=\E[7C, 693 | kUP=\E[2A, 694 | kUP3=\E[3A, 695 | kUP4=\E[4A, 696 | kUP5=\E[5A, 697 | kUP6=\E[6A, 698 | kUP7=\E[7A, 699 | 700 | xterm+pcc0|fragment with modifyCursorKeys:0, 701 | kLFT=\EO2D, 702 | kRIT=\EO2C, 703 | kind=\EO2B, 704 | kri=\EO2A, 705 | kDN=\EO2B, 706 | kDN3=\EO3B, 707 | kDN4=\EO4B, 708 | kDN5=\EO5B, 709 | kDN6=\EO6B, 710 | kDN7=\EO7B, 711 | kLFT3=\EO3D, 712 | kLFT4=\EO4D, 713 | kLFT5=\EO5D, 714 | kLFT6=\EO6D, 715 | kLFT7=\EO7D, 716 | kRIT3=\EO3C, 717 | kRIT4=\EO4C, 718 | kRIT5=\EO5C, 719 | kRIT6=\EO6C, 720 | kRIT7=\EO7C, 721 | kUP=\EO2A, 722 | kUP3=\EO3A, 723 | kUP4=\EO4A, 724 | kUP5=\EO5A, 725 | kUP6=\EO6A, 726 | kUP7=\EO7A, 727 | 728 | # The home/end keys on the editing keypad are also treated as cursor keys. 729 | xterm+pce3|fragment with modifyCursorKeys:3, 730 | kDC=\E[>3;2~, 731 | kEND=\E[>1;2F, 732 | kHOM=\E[>1;2H, 733 | kIC=\E[>2;2~, 734 | kNXT=\E[>6;2~, 735 | kPRV=\E[>5;2~, 736 | kDC3=\E[>3;3~, 737 | kDC4=\E[>3;4~, 738 | kDC5=\E[>3;5~, 739 | kDC6=\E[>3;6~, 740 | kDC7=\E[>3;7~, 741 | kEND3=\E[>1;3F, 742 | kEND4=\E[>1;4F, 743 | kEND5=\E[>1;5F, 744 | kEND6=\E[>1;6F, 745 | kEND7=\E[>1;7F, 746 | kHOM3=\E[>1;3H, 747 | kHOM4=\E[>1;4H, 748 | kHOM5=\E[>1;5H, 749 | kHOM6=\E[>1;6H, 750 | kHOM7=\E[>1;7H, 751 | kIC3=\E[>2;3~, 752 | kIC4=\E[>2;4~, 753 | kIC5=\E[>2;5~, 754 | kIC6=\E[>2;6~, 755 | kIC7=\E[>2;7~, 756 | kNXT3=\E[>6;3~, 757 | kNXT4=\E[>6;4~, 758 | kNXT5=\E[>6;5~, 759 | kNXT6=\E[>6;6~, 760 | kNXT7=\E[>6;7~, 761 | kPRV3=\E[>5;3~, 762 | kPRV4=\E[>5;4~, 763 | kPRV5=\E[>5;5~, 764 | kPRV6=\E[>5;6~, 765 | kPRV7=\E[>5;7~, 766 | use=xterm+pce0, 767 | 768 | xterm+pce2|fragment with modifyCursorKeys:2, 769 | kDC=\E[3;2~, 770 | kEND=\E[1;2F, 771 | kHOM=\E[1;2H, 772 | kIC=\E[2;2~, 773 | kNXT=\E[6;2~, 774 | kPRV=\E[5;2~, 775 | kDC3=\E[3;3~, 776 | kDC4=\E[3;4~, 777 | kDC5=\E[3;5~, 778 | kDC6=\E[3;6~, 779 | kDC7=\E[3;7~, 780 | kEND3=\E[1;3F, 781 | kEND4=\E[1;4F, 782 | kEND5=\E[1;5F, 783 | kEND6=\E[1;6F, 784 | kEND7=\E[1;7F, 785 | kHOM3=\E[1;3H, 786 | kHOM4=\E[1;4H, 787 | kHOM5=\E[1;5H, 788 | kHOM6=\E[1;6H, 789 | kHOM7=\E[1;7H, 790 | kIC3=\E[2;3~, 791 | kIC4=\E[2;4~, 792 | kIC5=\E[2;5~, 793 | kIC6=\E[2;6~, 794 | kIC7=\E[2;7~, 795 | kNXT3=\E[6;3~, 796 | kNXT4=\E[6;4~, 797 | kNXT5=\E[6;5~, 798 | kNXT6=\E[6;6~, 799 | kNXT7=\E[6;7~, 800 | kPRV3=\E[5;3~, 801 | kPRV4=\E[5;4~, 802 | kPRV5=\E[5;5~, 803 | kPRV6=\E[5;6~, 804 | kPRV7=\E[5;7~, 805 | use=xterm+pce0, 806 | 807 | xterm+pce1|fragment with modifyCursorKeys:1, 808 | kDC=\E[3;2~, 809 | kEND=\E[2F, 810 | kHOM=\E[2H, 811 | kIC=\E[2;2~, 812 | kNXT=\E[6;2~, 813 | kPRV=\E[5;2~, 814 | kDC3=\E[3;3~, 815 | kDC4=\E[3;4~, 816 | kDC5=\E[3;5~, 817 | kDC6=\E[3;6~, 818 | kDC7=\E[3;7~, 819 | kEND3=\E[3F, 820 | kEND4=\E[4F, 821 | kEND5=\E[5F, 822 | kEND6=\E[6F, 823 | kEND7=\E[7F, 824 | kHOM3=\E[3H, 825 | kHOM4=\E[4H, 826 | kHOM5=\E[5H, 827 | kHOM6=\E[6H, 828 | kHOM7=\E[7H, 829 | kIC3=\E[2;3~, 830 | kIC4=\E[2;4~, 831 | kIC5=\E[2;5~, 832 | kIC6=\E[2;6~, 833 | kIC7=\E[2;7~, 834 | kNXT3=\E[6;3~, 835 | kNXT4=\E[6;4~, 836 | kNXT5=\E[6;5~, 837 | kNXT6=\E[6;6~, 838 | kNXT7=\E[6;7~, 839 | kPRV3=\E[5;3~, 840 | kPRV4=\E[5;4~, 841 | kPRV5=\E[5;5~, 842 | kPRV6=\E[5;6~, 843 | kPRV7=\E[5;7~, 844 | use=xterm+pce0, 845 | 846 | xterm+pce0|fragment with modifyCursorKeys:0, 847 | kDC=\E[3;2~, 848 | kEND=\EO2F, 849 | kHOM=\EO2H, 850 | kIC=\E[2;2~, 851 | kNXT=\E[6;2~, 852 | kPRV=\E[5;2~, 853 | kDC3=\E[3;3~, 854 | kDC4=\E[3;4~, 855 | kDC5=\E[3;5~, 856 | kDC6=\E[3;6~, 857 | kDC7=\E[3;7~, 858 | kEND3=\EO3F, 859 | kEND4=\EO4F, 860 | kEND5=\EO5F, 861 | kEND6=\EO6F, 862 | kEND7=\EO7F, 863 | kHOM3=\EO3H, 864 | kHOM4=\EO4H, 865 | kHOM5=\EO5H, 866 | kHOM6=\EO6H, 867 | kHOM7=\EO7H, 868 | kIC3=\E[2;3~, 869 | kIC4=\E[2;4~, 870 | kIC5=\E[2;5~, 871 | kIC6=\E[2;6~, 872 | kIC7=\E[2;7~, 873 | kNXT3=\E[6;3~, 874 | kNXT4=\E[6;4~, 875 | kNXT5=\E[6;5~, 876 | kNXT6=\E[6;6~, 877 | kNXT7=\E[6;7~, 878 | kPRV3=\E[5;3~, 879 | kPRV4=\E[5;4~, 880 | kPRV5=\E[5;5~, 881 | kPRV6=\E[5;6~, 882 | kPRV7=\E[5;7~, 883 | use=xterm+edit, 884 | # 885 | # This chunk is used for building the VT220/Sun/PC keyboard variants. 886 | xterm-basic|modern xterm terminal emulator - common, 887 | OTbs, 888 | am, 889 | bce, 890 | km, 891 | mc5i, 892 | mir, 893 | msgr, 894 | xenl, 895 | AX, 896 | XT, 897 | colors#8, 898 | cols#80, 899 | it#8, 900 | lines#24, 901 | pairs#64, 902 | acsc=``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, 903 | bel=^G, 904 | blink=\E[5m, 905 | bold=\E[1m, 906 | cbt=\E[Z, 907 | civis=\E[?25l, 908 | clear=\E[H\E[2J, 909 | cnorm=\E[?12l\E[?25h, 910 | cr=^M, 911 | csr=\E[%i%p1%d;%p2%dr, 912 | cub=\E[%p1%dD, 913 | cub1=^H, 914 | cud=\E[%p1%dB, 915 | cud1=^J, 916 | cuf=\E[%p1%dC, 917 | cuf1=\E[C, 918 | cup=\E[%i%p1%d;%p2%dH, 919 | cuu=\E[%p1%dA, 920 | cuu1=\E[A, 921 | cvvis=\E[?12;25h, 922 | dch=\E[%p1%dP, 923 | dch1=\E[P, 924 | dl=\E[%p1%dM, 925 | dl1=\E[M, 926 | ech=\E[%p1%dX, 927 | ed=\E[J, 928 | el=\E[K, 929 | el1=\E[1K, 930 | flash=\E[?5h$<100/>\E[?5l, 931 | home=\E[H, 932 | hpa=\E[%i%p1%dG, 933 | ht=^I, 934 | hts=\EH, 935 | ich=\E[%p1%d@, 936 | il=\E[%p1%dL, 937 | il1=\E[L, 938 | ind=^J, 939 | invis=\E[8m, 940 | is2=\E[!p\E[?3;4l\E[4l\E>, 941 | kmous=\E[M, 942 | mc0=\E[i, 943 | mc4=\E[4i, 944 | mc5=\E[5i, 945 | meml=\El, 946 | memu=\Em, 947 | op=\E[39;49m, 948 | rc=\E8, 949 | rev=\E[7m, 950 | ri=\EM, 951 | rmacs=\E(B, 952 | rmam=\E[?7l, 953 | rmcup=\E[?1049l, 954 | rmir=\E[4l, 955 | rmkx=\E[?1l\E>, 956 | rmm=\E[?1034l, 957 | rmso=\E[27m, 958 | rmul=\E[24m, 959 | rs1=\Ec, 960 | rs2=\E[!p\E[?3;4l\E[4l\E>, 961 | sc=\E7, 962 | setab=\E[4%p1%dm, 963 | setaf=\E[3%p1%dm, 964 | setb=\E[4%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m, 965 | setf=\E[3%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m, 966 | sgr=%?%p9%t\E(0%e\E(B%;\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m, 967 | sgr0=\E(B\E[m, 968 | smacs=\E(0, 969 | smam=\E[?7h, 970 | smcup=\E[?1049h, 971 | smir=\E[4h, 972 | smkx=\E[?1h\E=, 973 | smm=\E[?1034h, 974 | smso=\E[7m, 975 | smul=\E[4m, 976 | tbc=\E[3g, 977 | u6=\E[%i%d;%dR, 978 | u7=\E[6n, 979 | u8=\E[?1;2c, 980 | u9=\E[c, 981 | vpa=\E[%i%p1%dd, 982 | E3=\E[3;J, 983 | use=xterm+kbs, 984 | # 985 | # The xterm-new description has all of the features, but is not completely 986 | # compatible with vt220. If you are using a Sun or PC keyboard, set the 987 | # sunKeyboard resource to true: 988 | # + maps the editing keypad 989 | # + interprets control-function-key as a second array of keys, so a 990 | # 12-fkey keyboard can support vt220's 20-fkeys. 991 | # + maps numeric keypad "+" to ",". 992 | # + uses DEC-style control sequences for the application keypad. 993 | # 994 | # Some packagers modify xterm's resource definitions to provide extra function 995 | # keys by using the shift-modifier in the translations resource. However, that 996 | # interferes with the DECUDK functionality. 997 | # 998 | xterm-vt220|xterm emulating vt220, 999 | ka1=\EOw, 1000 | ka3=\EOy, 1001 | kb2=\EOu, 1002 | kc1=\EOq, 1003 | kc3=\EOs, 1004 | kcbt=\E[Z, 1005 | kend=\E[4~, 1006 | kent=\EOM, 1007 | kf1=\EOP, 1008 | kf10=\E[21~, 1009 | kf11=\E[23~, 1010 | kf12=\E[24~, 1011 | kf13=\E[25~, 1012 | kf14=\E[26~, 1013 | kf15=\E[28~, 1014 | kf16=\E[29~, 1015 | kf17=\E[31~, 1016 | kf18=\E[32~, 1017 | kf19=\E[33~, 1018 | kf2=\EOQ, 1019 | kf20=\E[34~, 1020 | kf3=\EOR, 1021 | kf4=\EOS, 1022 | kf5=\E[15~, 1023 | kf6=\E[17~, 1024 | kf7=\E[18~, 1025 | kf8=\E[19~, 1026 | kf9=\E[20~, 1027 | khome=\E[1~, 1028 | kich1=\E[2~, 1029 | knp=\E[6~, 1030 | kpp=\E[5~, 1031 | ka2=\EOx, 1032 | kb1=\EOt, 1033 | kb3=\EOv, 1034 | kc2=\EOr, 1035 | use=xterm+app, 1036 | use=xterm+edit, 1037 | use=xterm-basic, 1038 | # 1039 | xterm-vt52|xterm emulating dec vt52, 1040 | cols#80, 1041 | it#8, 1042 | lines#24, 1043 | acsc=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, 1044 | bel=^G, 1045 | clear=\EH\EJ, 1046 | cr=^M, 1047 | cub1=\ED, 1048 | cud1=\EB, 1049 | cuf1=\EC, 1050 | cup=\EY%p1%' '%+%c%p2%' '%+%c, 1051 | cuu1=\EA, 1052 | ed=\EJ, 1053 | el=\EK, 1054 | home=\EH, 1055 | ht=^I, 1056 | ind=^J, 1057 | kcub1=\ED, 1058 | kcud1=\EB, 1059 | kcuf1=\EC, 1060 | kcuu1=\EA, 1061 | nel=^M^J, 1062 | ri=\EI, 1063 | rmacs=\EG, 1064 | smacs=\EF, 1065 | use=xterm+kbs, 1066 | # 1067 | # Sun does not number the function keys this way in their sparse termcap; their 1068 | # terminal descriptions ignore the keypads. kb(7M) states that there are codes 1069 | # reserved for 64 function keys, 16 each in left, right, top and bottom. Each 1070 | # keyboard type has a different number of function keys in different 1071 | # arrangements. Using xkeycaps for reference: 1072 | # 1073 | # Type 3: left 10, top 9, right 15 1074 | # ------ 1075 | # kf1-kf9 are XK_F1-XK_F9 1076 | # There is no kf10 on this keyboard type. 1077 | # kf11-kf20 are keysyms XK_L1 through XK_L10. 1078 | # kf31-kf45 are keysyms XK_R1 through XK_R15. 1079 | # 1080 | # However, X's keysymdef.h is hard-coded to make 1081 | # XK_L1==XK_F11 and 1082 | # XK_R1==XK_F21, 1083 | # by someone who was unfamiliar with terminal types other than Sun's. So 1084 | # xterm uses the internal X keysymbols, but the terminfo entry uses the Sun 1085 | # numbering scheme. 1086 | # 1087 | # Type 4: left 11, top 12, right 15 1088 | # ------ 1089 | # The left-keypad contains an unnumbered Help-key. 1090 | # The right-keypad also contains NumLock, Ins, Del, Enter, + and - keys which 1091 | # do not appear to be part of the R-sequence. 1092 | # 1093 | # Type 5: left 9, top 12, right (more than one keypad) 1094 | # ------ 1095 | # These keyboards do not use the same naming convention, look like a hybrid of 1096 | # the type 4 and IBM keyboards. 1097 | # 1098 | # XTerm resources: 1099 | # --------------- 1100 | # Set the modifyFunctionKeys resource to negative (-1) to make it simple to 1101 | # enter the higher function-key values using shift- and control-modifiers. 1102 | # 1103 | xterm-sun|xterm with sun function keys, 1104 | kb2=\E[218z, 1105 | kcpy=\E[197z, 1106 | kcub1=\EOD, 1107 | kcud1=\EOB, 1108 | kcuf1=\EOC, 1109 | kcuu1=\EOA, 1110 | kdch1=\E[3z, 1111 | kend=\E[220z, 1112 | kent=\EOM, 1113 | kf1=\E[224z, 1114 | kf10=\E[233z, 1115 | kf11=\E[192z, 1116 | kf12=\E[193z, 1117 | kf13=\E[194z, 1118 | kf14=\E[195z, 1119 | kf15=\E[196z, 1120 | kf17=\E[198z, 1121 | kf18=\E[199z, 1122 | kf19=\E[200z, 1123 | kf2=\E[225z, 1124 | kf20=\E[201z, 1125 | kf3=\E[226z, 1126 | kf31=\E[208z, 1127 | kf32=\E[209z, 1128 | kf33=\E[210z, 1129 | kf34=\E[211z, 1130 | kf35=\E[212z, 1131 | kf36=\E[213z, 1132 | kf38=\E[215z, 1133 | kf4=\E[227z, 1134 | kf40=\E[217z, 1135 | kf42=\E[219z, 1136 | kf44=\E[221z, 1137 | kf45=\E[222z, 1138 | kf46=\E[234z, 1139 | kf47=\E[235z, 1140 | kf5=\E[228z, 1141 | kf6=\E[229z, 1142 | kf7=\E[230z, 1143 | kf8=\E[231z, 1144 | kf9=\E[232z, 1145 | kfnd=\E[200z, 1146 | khlp=\E[196z, 1147 | khome=\E[214z, 1148 | kich1=\E[2z, 1149 | knp=\E[222z, 1150 | kpp=\E[216z, 1151 | kund=\E[195z, 1152 | use=xterm-basic, 1153 | # 1154 | xterm-hp|xterm with hpterm function keys, 1155 | kclr=\EJ, 1156 | kcub1=\ED, 1157 | kcud1=\EB, 1158 | kcuf1=\EC, 1159 | kcuu1=\EA, 1160 | kdch1=\EP, 1161 | kend=\EF, 1162 | kf1=\Ep, 1163 | kf2=\Eq, 1164 | kf3=\Er, 1165 | kf4=\Es, 1166 | kf5=\Et, 1167 | kf6=\Eu, 1168 | kf7=\Ev, 1169 | kf8=\Ew, 1170 | khome=\Eh, 1171 | kich1=\EQ, 1172 | knp=\ES, 1173 | kpp=\ET, 1174 | use=xterm-basic, 1175 | # 1176 | # scoterm implements 48 function-keys using shift- and control-modifiers to 1177 | # multiple 12 function-keys. X has a hard-coded limit of 35 function-keys, 1178 | # but xterm can represent larger values. 1179 | # 1180 | # XTerm resources: 1181 | # --------------- 1182 | # Set the modifyFunctionKeys resource to negative (-1) to make it simple to 1183 | # enter the higher function-key values using shift- and control-modifiers. 1184 | # 1185 | # Also, set ctrlFKeys resource to 12 (the default is 10) to make xterm see 48 1186 | # function-keys on a keyboard with 12 function-keys and 4 control/shift 1187 | # modifier combinations. 1188 | # 1189 | xterm-sco|xterm with SCO function keys, 1190 | kbeg=\E[E, 1191 | kdch1=\177, 1192 | kf1=\E[M, 1193 | kf10=\E[V, 1194 | kf11=\E[W, 1195 | kf12=\E[X, 1196 | kf13=\E[Y, 1197 | kf14=\E[Z, 1198 | kf15=\E[a, 1199 | kf16=\E[b, 1200 | kf17=\E[c, 1201 | kf18=\E[d, 1202 | kf19=\E[e, 1203 | kf2=\E[N, 1204 | kf20=\E[f, 1205 | kf21=\E[g, 1206 | kf22=\E[h, 1207 | kf23=\E[i, 1208 | kf24=\E[j, 1209 | kf25=\E[k, 1210 | kf26=\E[l, 1211 | kf27=\E[m, 1212 | kf28=\E[n, 1213 | kf29=\E[o, 1214 | kf3=\E[O, 1215 | kf30=\E[p, 1216 | kf31=\E[q, 1217 | kf32=\E[r, 1218 | kf33=\E[s, 1219 | kf34=\E[t, 1220 | kf35=\E[u, 1221 | kf36=\E[v, 1222 | kf37=\E[w, 1223 | kf38=\E[x, 1224 | kf39=\E[y, 1225 | kf4=\E[P, 1226 | kf40=\E[z, 1227 | kf41=\E[@, 1228 | kf42=\E[[, 1229 | kf43=\E[\\, 1230 | kf44=\E[], 1231 | kf45=\E[\^, 1232 | kf46=\E[_, 1233 | kf47=\E[`, 1234 | kf48=\E[{, 1235 | kf5=\E[Q, 1236 | kf6=\E[R, 1237 | kf7=\E[S, 1238 | kf8=\E[T, 1239 | kf9=\E[U, 1240 | kich1=\E[L, 1241 | kmous=\E[>M, 1242 | knp=\E[G, 1243 | kpp=\E[I, 1244 | use=xterm+noapp, 1245 | use=xterm-basic, 1246 | # 1247 | # Other variants (these are all very old entries, from X11R5): 1248 | xterm-24|xterms|vs100|xterm terminal emulator (X Window System), 1249 | lines#24, 1250 | use=xterm-old, 1251 | xterm-65|xterm with tall window 65x80 (X Window System), 1252 | lines#65, 1253 | use=xterm-old, 1254 | xterm-bold|xterm with bold instead of underline (X Window System), 1255 | sgr=%?%p9%t\016%e\017%;B\E[0%?%p6%t;1%;%?%p2%t;1%;%?%p1%p3%|%t;7%;m, 1256 | smso=\E[7m, 1257 | smul=\E[1m, 1258 | use=xterm-old, 1259 | xterm-boldso|xterm with bold for standout (X Window System), 1260 | rmso=\E[m, 1261 | smso=\E[1m, 1262 | use=xterm-old, 1263 | xterm-mono|monochrome xterm, 1264 | bce@, 1265 | colors@, 1266 | ncv@, 1267 | pairs@, 1268 | op@, 1269 | setab@, 1270 | setaf@, 1271 | setb@, 1272 | setf@, 1273 | sgr@, 1274 | use=xterm-old, 1275 | # 1276 | # VTxxx terminals are usually set up so that full-screen applications will use 1277 | # the cursor application mode strings. This is good for full-screen 1278 | # applications, including legacy applications which may have hard-coded 1279 | # behavior, but bad for interactive shells (e.g., tcsh, bash) which use arrow 1280 | # keys to scroll through a history of command strings. 1281 | # 1282 | # To see the difference between normal/application modes, consider this example: 1283 | # + In normal (non-application) mode, the terminal transmits a down-arrow 1284 | # as \E[C, which happens to echo as a down-arrow. 1285 | # + In application mode the terminal transmits \EOC, which echoes as C. 1286 | # That is because the \EO is the SS3 control, which says to use the 1287 | # character from the G3 character set for the next cell. 1288 | # 1289 | # One example of hard-coded behavior would be for applications written to work 1290 | # with VT52 and VT100 terminals. If the application's parser ignores 'O' and 1291 | # '?' characters after the escape, then the cursor and keypad strings for the 1292 | # two terminals are the same. (Indeed, one of the first curses applications 1293 | # which I used did something like this to cover "ANSI" terminals -TD). 1294 | # 1295 | # To make this work (leaving the cursor keys in normal mode), we have to adjust 1296 | # the terminal initialization sequences: 1297 | # 1298 | # smkx/rmkx set/reset the cursor and keypad application modes. We retain 1299 | # the latter (otherwise many applications fail). 1300 | # 1301 | # smcup/rmcup set/restore cursor-addressing mode for full-screen 1302 | # applications. For xterm, this normally means the alternate 1303 | # screen, which is not compatible with interactive shells. Some 1304 | # programs are "smart" and disable these. 1305 | # 1306 | xterm-noapp|xterm with cursor keys in normal mode, 1307 | rmcup@, 1308 | rmkx=\E>, 1309 | smcup@, 1310 | smkx=\E=, 1311 | use=xterm+noapp, 1312 | use=xterm, 1313 | 1314 | xterm+noapp|fragment with cursor keys in normal mode, 1315 | kcub1=\E[D, 1316 | kcud1=\E[B, 1317 | kcuf1=\E[C, 1318 | kcuu1=\E[A, 1319 | use=xterm+noapp+pc, 1320 | 1321 | xterm+app|fragment with cursor keys in application mode, 1322 | kcub1=\EOD, 1323 | kcud1=\EOB, 1324 | kcuf1=\EOC, 1325 | kcuu1=\EOA, 1326 | use=xterm+app+pc, 1327 | 1328 | xterm+noapp+pc|fragment for noapp pc-style home/end, 1329 | kend=\E[F, 1330 | khome=\E[H, 1331 | 1332 | xterm+app+pc|fragment for app pc-style home/end, 1333 | kend=\EOF, 1334 | khome=\EOH, 1335 | 1336 | xterm+edit|fragment for 6-key editing-keypad, 1337 | kdch1=\E[3~, 1338 | kich1=\E[2~, 1339 | knp=\E[6~, 1340 | kpp=\E[5~, 1341 | use=xterm+pc+edit, 1342 | 1343 | xterm+decedit|fragment for vt220 6-key editing-keypad, 1344 | kdch1=\E[3~, 1345 | kich1=\E[2~, 1346 | knp=\E[6~, 1347 | kpp=\E[5~, 1348 | use=xterm+vt+edit, 1349 | 1350 | xterm+pc+edit|fragment for pc-style editing keypad, 1351 | kend=\E[4~, 1352 | khome=\E[1~, 1353 | 1354 | xterm+vt+edit|fragment for vt220-style editing keypad, 1355 | kfnd=\E[1~, 1356 | kslt=\E[4~, 1357 | 1358 | # 1359 | # This should work for the commonly used "color xterm" variations (XFree86 1360 | # xterm, color_xterm, nxterm, rxvt). Note that it does not set 'bce', so for 1361 | # XFree86 and and rxvt, some applications that use colors will be less 1362 | # efficient, and in a few special cases (with "smart" optimization) the wrong 1363 | # color will be painted in spots. 1364 | xterm-color|generic "ANSI" color xterm (X Window System), 1365 | colors#8, 1366 | ncv@, 1367 | pairs#64, 1368 | op=\E[m, 1369 | setab=\E[4%p1%dm, 1370 | setaf=\E[3%p1%dm, 1371 | use=xterm-r6, 1372 | # 1373 | # vi may work better with this entry, because vi 1374 | # doesn't use insert mode much 1375 | xterm-ic|xterm-vi|xterm with insert character instead of insert mode, 1376 | mir@, 1377 | ich=\E[%p1%d@, 1378 | ich1=\E[@, 1379 | rmir@, 1380 | smir@, 1381 | use=xterm, 1382 | # 1383 | # This is used only for testing (it's not relevant to DEC VTxxx terminals, but 1384 | # to ncurses). 1385 | xterm-xmc|xterm with magic-cookie glitch, 1386 | xmc#1, 1387 | use=xterm-new, 1388 | # 1389 | # This one also is primarily for testing ncurses; while the ISO 6429 defines 1390 | # the REP control, none of the DEC VTxxx terminals (VT52 through VT420) support 1391 | # it. 1392 | xterm-rep|xterm with repeat-character control, 1393 | rep=%p1%c\E[%p2%{1}%-%db, 1394 | use=xterm-new, 1395 | # 1396 | # This is mainly for testing xterm; the real VT220 will not let you switch 1397 | # character sets without first altering the keyboard language in the setup 1398 | # screen. Some emulators allow this anyway. (Note that these strings are 1399 | # normally used only for printers). The parameter to csnm and scs is the same 1400 | # in both cases: the keyboard language parameter returned by CSI ? 2 6 n. 1401 | xterm-nrc|xterm with VT220 national replacement character sets, 1402 | csnm=%?%p1%{1}%=%tNorth American%e%p1%{2}%=%tBritish%e%p1%{3}%=%tFlemish%e%p1%{4}%=%tFrench Canadian%e%p1%{5}%=%tDanish%e%p1%{6}%=%tFinnish%e%p1%{7}%=%tGerman%e%p1%{8}%=%tDutch%e%p1%{9}%=%tItalian%e%p1%{10}%=%tSwiss (French)%e%p1%{11}%=%tSwiss (German)%e%p1%{12}%=%tSwedish%e%p1%{13}%=%tNorwegian%e%p1%{14}%=%tFrench/Belgian%e%p1%{15}%=%tSpanish%;, 1403 | scs=%?%p1%{1}%=%t\E(B%e%p1%{2}%=%t\E(A%e%p1%{3}%=%t\E(R%e%p1%{4}%=%t\E(9%e%p1%{5}%=%t\E(E%e%p1%{6}%=%t\E(5%e%p1%{7}%=%t\E(K%e%p1%{8}%=%t\E(4%e%p1%{9}%=%t\E(Y%e%p1%{10}%=%t\E(=%e%p1%{11}%=%t\E(=%e%p1%{12}%=%t\E(7%e%p1%{13}%=%t\E(E%e%p1%{14}%=%t\E(R%e%p1%{15}%=%t\E(Z%;, 1404 | use=xterm-new, 1405 | # 1406 | # Foreground 0-15 maps (with toggles) into 30-37 & 90-97 1407 | # Background 0-15 maps (with toggles) into 40-47 & 100-107 1408 | # 1409 | # Originally I suppressed setaf/setab, since ANSI specifies only 8 colors, but 1410 | # Stephen Marley persuaded me to allow the "ANSI" color controls to extend to 1411 | # 16 colors. (Note that ncurses 4.2 uses setf/setb from this description; 1412 | # however 5.0 selects either according to their availability). - T.Dickey 1413 | # 1414 | # SVr4 curses does not use more than 8 colors anyway, so using 16 colors is 1415 | # either for terminfo-level applications or via ncurses. 1416 | xterm-16color|xterm with 16 colors, 1417 | colors#16, 1418 | pairs#256, 1419 | setab=\E[%?%p1%{8}%<%t%p1%{40}%+%e%p1%{92}%+%;%dm, 1420 | setaf=\E[%?%p1%{8}%<%t%p1%{30}%+%e%p1%{82}%+%;%dm, 1421 | setb=%p1%{8}%/%{6}%*%{4}%+\E[%d%p1%{8}%m%Pa%?%ga%{1}%=%t4%e%ga%{3}%=%t6%e%ga%{4}%=%t1%e%ga%{6}%=%t3%e%ga%d%;m, 1422 | setf=%p1%{8}%/%{6}%*%{3}%+\E[%d%p1%{8}%m%Pa%?%ga%{1}%=%t4%e%ga%{3}%=%t6%e%ga%{4}%=%t1%e%ga%{6}%=%t3%e%ga%d%;m, 1423 | use=xterm+256color, 1424 | use=xterm-new, 1425 | # 1426 | # This uses RGB values 0..1000 1427 | # 1428 | # 256 colors should give 65536 pairs, but terminfo stores numbers in a signed 1429 | # short. Most people will not notice problems with only 32767 pairs. 1430 | xterm+256color|xterm 256-color feature, 1431 | ccc, 1432 | colors#256, 1433 | pairs#32767, 1434 | initc=\E]4;%p1%d;rgb\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\\, 1435 | setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m, 1436 | setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m, 1437 | setb@, 1438 | setf@, 1439 | xterm-256color|xterm with 256 colors, 1440 | use=xterm+256color, 1441 | use=xterm-new, 1442 | xterm-88color|xterm with 88 colors, 1443 | colors#88, 1444 | pairs#7744, 1445 | use=xterm-256color, 1446 | # 1447 | # This is an 8-bit version of xterm, which emulates DEC vt220 with ANSI color. 1448 | # To use it, your decTerminalID resource must be set to 200 or above, and the 1449 | # sunKeyboard resource set to true. 1450 | # 1451 | # HTS \E H \210 1452 | # RI \E M \215 1453 | # SS3 \E O \217 1454 | # CSI \E [ \233 1455 | # 1456 | xterm-8bit|xterm terminal emulator with 8-bit controls (X Window System), 1457 | OTbs, 1458 | am, 1459 | bce, 1460 | km, 1461 | mc5i, 1462 | mir, 1463 | msgr, 1464 | npc, 1465 | xenl, 1466 | AX, 1467 | colors#8, 1468 | cols#80, 1469 | it#8, 1470 | lines#24, 1471 | pairs#64, 1472 | acsc=``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, 1473 | bel=^G, 1474 | blink=\2335m, 1475 | bold=\2331m, 1476 | cbt=\233Z, 1477 | civis=\233?25l, 1478 | clear=\233H\2332J, 1479 | cnorm=\233?25l\233?25h, 1480 | cr=^M, 1481 | csr=\233%i%p1%d;%p2%dr, 1482 | cub=\233%p1%dD, 1483 | cub1=^H, 1484 | cud=\233%p1%dB, 1485 | cud1=^J, 1486 | cuf=\233%p1%dC, 1487 | cuf1=\233C, 1488 | cup=\233%i%p1%d;%p2%dH, 1489 | cuu=\233%p1%dA, 1490 | cuu1=\233A, 1491 | cvvis=\233?12;25h, 1492 | dch=\233%p1%dP, 1493 | dch1=\233P, 1494 | dl=\233%p1%dM, 1495 | dl1=\233M, 1496 | ech=\233%p1%dX, 1497 | ed=\233J, 1498 | el=\233K, 1499 | el1=\2331K, 1500 | flash=\233?5h$<100/>\233?5l, 1501 | home=\233H, 1502 | hpa=\233%i%p1%dG, 1503 | ht=^I, 1504 | hts=\210, 1505 | ich=\233%p1%d@, 1506 | il=\233%p1%dL, 1507 | il1=\233L, 1508 | ind=^J, 1509 | invis=\2338m, 1510 | is2=\E[62"p\E G\233m\233?7h\E>\E7\233?1;3;4;6l\2334l\233r\E8, 1511 | ka1=\217w, 1512 | ka3=\217u, 1513 | kb2=\217y, 1514 | kbeg=\217E, 1515 | kc1=\217q, 1516 | kc3=\217s, 1517 | kcbt=\233Z, 1518 | kcub1=\217D, 1519 | kcud1=\217B, 1520 | kcuf1=\217C, 1521 | kcuu1=\217A, 1522 | kdch1=\2333~, 1523 | kend=\2334~, 1524 | kent=\217M, 1525 | kf1=\23311~, 1526 | kf10=\23321~, 1527 | kf11=\23323~, 1528 | kf12=\23324~, 1529 | kf13=\23325~, 1530 | kf14=\23326~, 1531 | kf15=\23328~, 1532 | kf16=\23329~, 1533 | kf17=\23331~, 1534 | kf18=\23332~, 1535 | kf19=\23333~, 1536 | kf2=\23312~, 1537 | kf20=\23334~, 1538 | kf3=\23313~, 1539 | kf4=\23314~, 1540 | kf5=\23315~, 1541 | kf6=\23317~, 1542 | kf7=\23318~, 1543 | kf8=\23319~, 1544 | kf9=\23320~, 1545 | khome=\2331~, 1546 | kich1=\2332~, 1547 | kmous=\233M, 1548 | knp=\2336~, 1549 | kpp=\2335~, 1550 | mc0=\233i, 1551 | mc4=\2334i, 1552 | mc5=\2335i, 1553 | meml=\El, 1554 | memu=\Em, 1555 | op=\23339;49m, 1556 | rc=\E8, 1557 | rev=\2337m, 1558 | ri=\215, 1559 | rmacs=\E(B, 1560 | rmam=\233?7l, 1561 | rmcup=\233?1049l, 1562 | rmir=\2334l, 1563 | rmkx=\233?1l\E>, 1564 | rmso=\23327m, 1565 | rmul=\23324m, 1566 | rs1=\Ec, 1567 | rs2=\E[62"p\E G\233m\233?7h\E>\E7\233?1;3;4;6l\2334l\233r\E8, 1568 | sc=\E7, 1569 | setab=\2334%p1%dm, 1570 | setaf=\2333%p1%dm, 1571 | setb=\2334%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m, 1572 | setf=\2333%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m, 1573 | sgr=\2330%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m%?%p9%t\E(0%e\E(B%;, 1574 | sgr0=\2330m\E(B, 1575 | smacs=\E(0, 1576 | smam=\233?7h, 1577 | smcup=\233?1049h, 1578 | smir=\2334h, 1579 | smkx=\233?1h\E=, 1580 | smso=\2337m, 1581 | smul=\2334m, 1582 | tbc=\2333g, 1583 | u6=\233[%i%d;%dR, 1584 | u7=\E[6n, 1585 | u8=\233[?1;2c, 1586 | u9=\E[c, 1587 | vpa=\233%i%p1%dd, 1588 | use=xterm+kbs, 1589 | # 1590 | xterm-xf86-v44|xterm terminal emulator (XFree86 4.4 Window System), 1591 | OTbs, 1592 | am, 1593 | bce, 1594 | km, 1595 | mc5i, 1596 | mir, 1597 | msgr, 1598 | npc, 1599 | xenl, 1600 | AX, 1601 | XT, 1602 | colors#8, 1603 | cols#80, 1604 | it#8, 1605 | lines#24, 1606 | pairs#64, 1607 | acsc=``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, 1608 | bel=^G, 1609 | blink=\E[5m, 1610 | bold=\E[1m, 1611 | cbt=\E[Z, 1612 | civis=\E[?25l, 1613 | clear=\E[H\E[2J, 1614 | cnorm=\E[?12l\E[?25h, 1615 | cr=^M, 1616 | csr=\E[%i%p1%d;%p2%dr, 1617 | cub=\E[%p1%dD, 1618 | cub1=^H, 1619 | cud=\E[%p1%dB, 1620 | cud1=^J, 1621 | cuf=\E[%p1%dC, 1622 | cuf1=\E[C, 1623 | cup=\E[%i%p1%d;%p2%dH, 1624 | cuu=\E[%p1%dA, 1625 | cuu1=\E[A, 1626 | cvvis=\E[?12;25h, 1627 | dch=\E[%p1%dP, 1628 | dch1=\E[P, 1629 | dl=\E[%p1%dM, 1630 | dl1=\E[M, 1631 | ech=\E[%p1%dX, 1632 | ed=\E[J, 1633 | el=\E[K, 1634 | el1=\E[1K, 1635 | enacs=\E(B\E)0, 1636 | flash=\E[?5h$<100/>\E[?5l, 1637 | home=\E[H, 1638 | hpa=\E[%i%p1%dG, 1639 | ht=^I, 1640 | hts=\EH, 1641 | ich=\E[%p1%d@, 1642 | il=\E[%p1%dL, 1643 | il1=\E[L, 1644 | ind=^J, 1645 | indn=\E[%p1%dS, 1646 | invis=\E[8m, 1647 | is2=\E[!p\E[?3;4l\E[4l\E>, 1648 | kDC=\E[3;2~, 1649 | kEND=\E[1;2F, 1650 | kHOM=\E[1;2H, 1651 | kIC=\E[2;2~, 1652 | kLFT=\E[1;2D, 1653 | kNXT=\E[6;2~, 1654 | kPRV=\E[5;2~, 1655 | kRIT=\E[1;2C, 1656 | kb2=\EOE, 1657 | kcbt=\E[Z, 1658 | kcub1=\EOD, 1659 | kcud1=\EOB, 1660 | kcuf1=\EOC, 1661 | kcuu1=\EOA, 1662 | kdch1=\E[3~, 1663 | kend=\EOF, 1664 | kent=\EOM, 1665 | kf1=\EOP, 1666 | kf10=\E[21~, 1667 | kf11=\E[23~, 1668 | kf12=\E[24~, 1669 | kf13=\EO2P, 1670 | kf14=\EO2Q, 1671 | kf15=\EO2R, 1672 | kf16=\EO2S, 1673 | kf17=\E[15;2~, 1674 | kf18=\E[17;2~, 1675 | kf19=\E[18;2~, 1676 | kf2=\EOQ, 1677 | kf20=\E[19;2~, 1678 | kf21=\E[20;2~, 1679 | kf22=\E[21;2~, 1680 | kf23=\E[23;2~, 1681 | kf24=\E[24;2~, 1682 | kf25=\EO5P, 1683 | kf26=\EO5Q, 1684 | kf27=\EO5R, 1685 | kf28=\EO5S, 1686 | kf29=\E[15;5~, 1687 | kf3=\EOR, 1688 | kf30=\E[17;5~, 1689 | kf31=\E[18;5~, 1690 | kf32=\E[19;5~, 1691 | kf33=\E[20;5~, 1692 | kf34=\E[21;5~, 1693 | kf35=\E[23;5~, 1694 | kf36=\E[24;5~, 1695 | kf37=\EO6P, 1696 | kf38=\EO6Q, 1697 | kf39=\EO6R, 1698 | kf4=\EOS, 1699 | kf40=\EO6S, 1700 | kf41=\E[15;6~, 1701 | kf42=\E[17;6~, 1702 | kf43=\E[18;6~, 1703 | kf44=\E[19;6~, 1704 | kf45=\E[20;6~, 1705 | kf46=\E[21;6~, 1706 | kf47=\E[23;6~, 1707 | kf48=\E[24;6~, 1708 | kf5=\E[15~, 1709 | kf6=\E[17~, 1710 | kf7=\E[18~, 1711 | kf8=\E[19~, 1712 | kf9=\E[20~, 1713 | khome=\EOH, 1714 | kich1=\E[2~, 1715 | kmous=\E[M, 1716 | knp=\E[6~, 1717 | kpp=\E[5~, 1718 | mc0=\E[i, 1719 | mc4=\E[4i, 1720 | mc5=\E[5i, 1721 | meml=\El, 1722 | memu=\Em, 1723 | op=\E[39;49m, 1724 | rc=\E8, 1725 | rev=\E[7m, 1726 | ri=\EM, 1727 | rin=\E[%p1%dT, 1728 | rmacs=^O, 1729 | rmam=\E[?7l, 1730 | rmcup=\E[?1049l, 1731 | rmir=\E[4l, 1732 | rmkx=\E[?1l\E>, 1733 | rmso=\E[27m, 1734 | rmul=\E[24m, 1735 | rs1=\Ec, 1736 | rs2=\E[!p\E[?3;4l\E[4l\E>, 1737 | sc=\E7, 1738 | setab=\E[4%p1%dm, 1739 | setaf=\E[3%p1%dm, 1740 | setb=\E[4%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m, 1741 | setf=\E[3%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m, 1742 | sgr=\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m%?%p9%t\016%e\017%;, 1743 | sgr0=\E[m\017, 1744 | smacs=^N, 1745 | smam=\E[?7h, 1746 | smcup=\E[?1049h, 1747 | smir=\E[4h, 1748 | smkx=\E[?1h\E=, 1749 | smso=\E[7m, 1750 | smul=\E[4m, 1751 | tbc=\E[3g, 1752 | u6=\E[%i%d;%dR, 1753 | u7=\E[6n, 1754 | u8=\E[?1;2c, 1755 | u9=\E[c, 1756 | vpa=\E[%i%p1%dd, 1757 | ka2=\EOx, 1758 | kb1=\EOt, 1759 | kb3=\EOv, 1760 | kc2=\EOr, 1761 | use=xterm+kbs, 1762 | xterm-xfree86|xterm terminal emulator (XFree86 4.4 Window System), 1763 | use=xterm-xf86-v44, 1764 | # 1765 | # Compatible with the R6 xterm, with the following changes: 1766 | # + added acsc (perhaps some versions of tic assume the standard vt100 1767 | # alternate character set) 1768 | # + added u6, u7, u8, u9 strings for Daniel Weaver's tack program. 1769 | # + added kmous string for ncurses. 1770 | # + added khome/kend strings (which conflict with kfnd/kslt, see note). 1771 | xterm-r6|xterm X11R6 version, 1772 | OTbs, 1773 | am, 1774 | km, 1775 | mir, 1776 | msgr, 1777 | xenl, 1778 | cols#80, 1779 | it#8, 1780 | lines#24, 1781 | acsc=``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, 1782 | bel=^G, 1783 | bold=\E[1m, 1784 | clear=\E[H\E[2J, 1785 | cr=^M, 1786 | csr=\E[%i%p1%d;%p2%dr, 1787 | cub=\E[%p1%dD, 1788 | cub1=^H, 1789 | cud=\E[%p1%dB, 1790 | cud1=^J, 1791 | cuf=\E[%p1%dC, 1792 | cuf1=\E[C, 1793 | cup=\E[%i%p1%d;%p2%dH, 1794 | cuu=\E[%p1%dA, 1795 | cuu1=\E[A, 1796 | dch=\E[%p1%dP, 1797 | dch1=\E[P, 1798 | dl=\E[%p1%dM, 1799 | dl1=\E[M, 1800 | ed=\E[J, 1801 | el=\E[K, 1802 | enacs=\E)0, 1803 | home=\E[H, 1804 | ht=^I, 1805 | hts=\EH, 1806 | il=\E[%p1%dL, 1807 | il1=\E[L, 1808 | ind=^J, 1809 | is2=\E[m\E[?7h\E[4l\E>\E7\E[r\E[?1;3;4;6l\E8, 1810 | kcub1=\EOD, 1811 | kcud1=\EOB, 1812 | kcuf1=\EOC, 1813 | kcuu1=\EOA, 1814 | kdch1=\E[3~, 1815 | kf1=\E[11~, 1816 | kf10=\E[21~, 1817 | kf11=\E[23~, 1818 | kf12=\E[24~, 1819 | kf13=\E[25~, 1820 | kf14=\E[26~, 1821 | kf15=\E[28~, 1822 | kf16=\E[29~, 1823 | kf17=\E[31~, 1824 | kf18=\E[32~, 1825 | kf19=\E[33~, 1826 | kf2=\E[12~, 1827 | kf20=\E[34~, 1828 | kf3=\E[13~, 1829 | kf4=\E[14~, 1830 | kf5=\E[15~, 1831 | kf6=\E[17~, 1832 | kf7=\E[18~, 1833 | kf8=\E[19~, 1834 | kf9=\E[20~, 1835 | kmous=\E[M, 1836 | meml=\El, 1837 | memu=\Em, 1838 | rc=\E8, 1839 | rev=\E[7m, 1840 | ri=\EM, 1841 | rmacs=^O, 1842 | rmcup=\E[2J\E[?47l\E8, 1843 | rmir=\E[4l, 1844 | rmkx=\E[?1l\E>, 1845 | rmso=\E[m, 1846 | rmul=\E[m, 1847 | rs2=\E[m\E[?7h\E[4l\E>\E7\E[r\E[?1;3;4;6l\E8, 1848 | sc=\E7, 1849 | sgr0=\E[m, 1850 | smacs=^N, 1851 | smcup=\E7\E[?47h, 1852 | smir=\E[4h, 1853 | smkx=\E[?1h\E=, 1854 | smso=\E[7m, 1855 | smul=\E[4m, 1856 | tbc=\E[3g, 1857 | u6=\E[%i%d;%dR, 1858 | u7=\E[6n, 1859 | u8=\E[?1;2c, 1860 | u9=\E[c, 1861 | use=xterm+kbs, 1862 | use=xterm+decedit, 1863 | xterm-old|antique xterm version, 1864 | use=xterm-r6, 1865 | # 1866 | # Compatible with the R5 xterm, with the following changes: 1867 | # + changed 'blink=@', to 'blink@' (the former meant that "@" would start 1868 | # a blink, the latter that it is not supported). 1869 | # + changed kf1 through kf4 to correspond with actual usage. Though X 1870 | # supports keypad symbols for PF1 to PF4, and xterm interprets these 1871 | # correctly, the F1 to F4 codes are commonly (but incorrectly) used. 1872 | # + moved reset string from rs1 to rs2, to correlate better with termcap. 1873 | # + make khome consistent with other entries. 1874 | # + use rmul/smul, rmir/smir from termcap, but not rmcup/smcup because 1875 | # not everyone wants the alternate screen. 1876 | # + added u6, u7, u8, u9 strings for Daniel Weaver's tack program. 1877 | # + added kmous string for ncurses. 1878 | xterm-r5|xterm R5 version, 1879 | OTbs, 1880 | am, 1881 | km, 1882 | msgr, 1883 | xenl, 1884 | cols#80, 1885 | it#8, 1886 | lines#24, 1887 | bel=^G, 1888 | bold=\E[1m, 1889 | clear=\E[H\E[2J, 1890 | cr=^M, 1891 | csr=\E[%i%p1%d;%p2%dr, 1892 | cub=\E[%p1%dD, 1893 | cub1=^H, 1894 | cud=\E[%p1%dB, 1895 | cud1=^J, 1896 | cuf=\E[%p1%dC, 1897 | cuf1=\E[C, 1898 | cup=\E[%i%p1%d;%p2%dH, 1899 | cuu=\E[%p1%dA, 1900 | cuu1=\E[A, 1901 | dch=\E[%p1%dP, 1902 | dch1=\E[P, 1903 | dl=\E[%p1%dM, 1904 | dl1=\E[M, 1905 | ed=\E[J, 1906 | el=\E[K, 1907 | home=\E[H, 1908 | ht=^I, 1909 | hts=\EH, 1910 | ich=\E[%p1%d@, 1911 | ich1=\E[@, 1912 | il=\E[%p1%dL, 1913 | il1=\E[L, 1914 | ind=^J, 1915 | kcub1=\EOD, 1916 | kcud1=\EOB, 1917 | kcuf1=\EOC, 1918 | kcuu1=\EOA, 1919 | kdch1=\E[3~, 1920 | kdl1=\E[31~, 1921 | kel=\E[8~, 1922 | kend=\E[4~, 1923 | kf0=\EOq, 1924 | kf1=\E[11~, 1925 | kf10=\E[21~, 1926 | kf11=\E[23~, 1927 | kf12=\E[24~, 1928 | kf2=\E[12~, 1929 | kf3=\E[13~, 1930 | kf4=\E[14~, 1931 | kf5=\E[15~, 1932 | kf6=\E[17~, 1933 | kf7=\E[18~, 1934 | kf8=\E[19~, 1935 | kf9=\E[20~, 1936 | khome=\E[1~, 1937 | kich1=\E[2~, 1938 | kil1=\E[30~, 1939 | kmous=\E[M, 1940 | knp=\E[6~, 1941 | kpp=\E[5~, 1942 | rc=\E8, 1943 | rev=\E[7m, 1944 | ri=\EM, 1945 | rmir=\E[4l, 1946 | rmkx=\E[?1l\E>, 1947 | rmso=\E[m, 1948 | rmul=\E[m, 1949 | rs2=\E>\E[?1;3;4;5;6l\E[4l\E[?7h\E[m\E[r\E[2J\E[H, 1950 | sc=\E7, 1951 | sgr=\E[%?%p1%t;7%;%?%p2%t;4%;%?%p3%t;7%;%?%p4%t;5%;%?%p6%t;1%;m, 1952 | sgr0=\E[m, 1953 | smir=\E[4h, 1954 | smkx=\E[?1h\E=, 1955 | smso=\E[7m, 1956 | smul=\E[4m, 1957 | tbc=\E[3g, 1958 | u6=\E[%i%d;%dR, 1959 | u7=\E[6n, 1960 | u8=\E[?1;2c, 1961 | u9=\E[c, 1962 | use=xterm+kbs, 1963 | # 1964 | # 1965 | # Customization begins here. 1966 | # 1967 | # This is the only entry which you should have to customize, since "xterm" 1968 | # is widely used for a variety of incompatible terminal emulations including 1969 | # color_xterm and rxvt. 1970 | xterm|X11 terminal emulator, 1971 | use=xterm-new, 1972 | # use=xterm-r6, 1973 | 1974 | # This fragment is for people who cannot agree on what the backspace key 1975 | # should send. 1976 | xterm+kbs|fragment for backspace key, 1977 | kbs=^H, 1978 | --------------------------------------------------------------------------------