/// Returns the number of characters in the escape code starting at 'code'. We only handle sequences /// that begin with \x1B. If it doesn't we return zero. We also return zero if we don't recognize the /// escape sequence based on querying terminfo and other heuristics. size_t escape_code_length(const wchar_t *code) { assert(code != NULL); if (*code != L'\x1B') return 0; size_t esc_seq_len = cached_layouts.find_escape_code(code); if (esc_seq_len) return esc_seq_len; bool found = is_color_escape_seq(code, &esc_seq_len); if (!found) found = is_visual_escape_seq(code, &esc_seq_len); if (!found) found = is_screen_name_escape_seq(code, &esc_seq_len); if (!found) found = is_iterm2_escape_seq(code, &esc_seq_len); if (!found) found = is_single_byte_escape_seq(code, &esc_seq_len); if (!found) found = is_csi_style_escape_seq(code, &esc_seq_len); if (!found) found = is_two_byte_escape_seq(code, &esc_seq_len); if (found) cached_layouts.add_escape_code(wcstring(code, esc_seq_len)); return esc_seq_len; }
/// Returns the number of characters in the escape code starting at 'code' (which should initially /// contain \x1b). size_t escape_code_length(const wchar_t *code) { assert(code != NULL); // The only escape codes we recognize start with \x1b. if (code[0] != L'\x1b') return 0; size_t resulting_length = 0; bool found = false; if (cur_term != NULL) { // Detect these terminfo color escapes with parameter value 0..7, all of which don't move // the cursor. char *const esc[] = { set_a_foreground, set_a_background, set_foreground, set_background, }; for (size_t p = 0; p < sizeof esc / sizeof *esc && !found; p++) { if (!esc[p]) continue; for (size_t k = 0; k < 8; k++) { size_t len = try_sequence(tparm(esc[p], k), code); if (len) { resulting_length = len; found = true; break; } } } } if (cur_term != NULL) { // Detect these semi-common terminfo escapes without any parameter values, all of which // don't move the cursor. char *const esc2[] = {enter_bold_mode, exit_attribute_mode, enter_underline_mode, exit_underline_mode, enter_standout_mode, exit_standout_mode, flash_screen, enter_subscript_mode, exit_subscript_mode, enter_superscript_mode, exit_superscript_mode, enter_blink_mode, enter_italics_mode, exit_italics_mode, enter_reverse_mode, enter_shadow_mode, exit_shadow_mode, enter_standout_mode, exit_standout_mode, enter_secure_mode}; for (size_t p = 0; p < sizeof esc2 / sizeof *esc2 && !found; p++) { if (!esc2[p]) continue; // Test both padded and unpadded version, just to be safe. Most versions of tparm don't // actually seem to do anything these days. size_t len = maxi(try_sequence(tparm(esc2[p]), code), try_sequence(esc2[p], code)); if (len) { resulting_length = len; found = true; } } } if (!found) found = is_screen_name_escape_seq(code, &resulting_length); if (!found) found = is_iterm2_escape_seq(code, &resulting_length); if (!found) found = is_single_byte_escape_seq(code, &resulting_length); if (!found) found = is_csi_style_escape_seq(code, &resulting_length); if (!found) found = is_two_byte_escape_seq(code, &resulting_length); return resulting_length; }