/* Moves cursor to the beginning of the current or previous word on Meta+B. */ static void find_prev_word(void) { while(input_stat.index > 0 && iswspace(input_stat.line[input_stat.index - 1])) { input_stat.curs_pos -= vifm_wcwidth(input_stat.line[input_stat.index - 1]); input_stat.index--; } while(input_stat.index > 0 && !iswspace(input_stat.line[input_stat.index - 1])) { input_stat.curs_pos -= vifm_wcwidth(input_stat.line[input_stat.index - 1]); input_stat.index--; } }
/* Returns width of the character in the terminal. */ static size_t get_char_screen_width(const char str[], size_t char_width) { const wchar_t wide = utf8_char_to_wchar(str, char_width); const size_t result = vifm_wcwidth(wide); return (result == (size_t)-1) ? 1 : result; }
/* Handles backspace. */ static void cmd_ctrl_h(key_info_t key_info, keys_info_t *keys_info) { input_stat.history_search = HIST_NONE; stop_completion(); if(should_quit_on_backspace()) { cmd_ctrl_c(key_info, keys_info); return; } if(input_stat.index == 0) { return; } input_stat.index--; input_stat.len--; input_stat.curs_pos -= vifm_wcwidth(input_stat.line[input_stat.index]); if(input_stat.index == input_stat.len) { input_stat.line[input_stat.index] = L'\0'; } else { wcsdel(input_stat.line, input_stat.index + 1, 1); } update_cmdline_text(); }
/* Moves cursor to the end of the current or next word on Meta+F. */ static void find_next_word(void) { while(input_stat.index < input_stat.len && iswspace(input_stat.line[input_stat.index])) { input_stat.curs_pos += vifm_wcwidth(input_stat.line[input_stat.index]); input_stat.index++; } while(input_stat.index < input_stat.len && !iswspace(input_stat.line[input_stat.index])) { input_stat.curs_pos += vifm_wcwidth(input_stat.line[input_stat.index]); input_stat.index++; } }
/* Handler of Ctrl-W shortcut, which remove all to the left until beginning of * the word is found (i.e. until first delimiter character). */ static void cmd_ctrl_w(key_info_t key_info, keys_info_t *keys_info) { int old; input_stat.history_search = HIST_NONE; stop_completion(); old = input_stat.index; while(input_stat.index > 0 && iswspace(input_stat.line[input_stat.index - 1])) { input_stat.curs_pos -= vifm_wcwidth(input_stat.line[input_stat.index - 1]); input_stat.index--; } if(iswalnum(input_stat.line[input_stat.index - 1])) { while(input_stat.index > 0 && iswalnum(input_stat.line[input_stat.index - 1])) { const wchar_t curr_wchar = input_stat.line[input_stat.index - 1]; input_stat.curs_pos -= vifm_wcwidth(curr_wchar); input_stat.index--; } } else { while(input_stat.index > 0 && !iswalnum(input_stat.line[input_stat.index - 1]) && !iswspace(input_stat.line[input_stat.index - 1])) { const wchar_t curr_wchar = input_stat.line[input_stat.index - 1]; input_stat.curs_pos -= vifm_wcwidth(curr_wchar); input_stat.index--; } } if(input_stat.index != old) { wcsdel(input_stat.line, input_stat.index + 1, old - input_stat.index); input_stat.len -= old - input_stat.index; } update_cmdline_text(); }
static void cmd_right(key_info_t key_info, keys_info_t *keys_info) { input_stat.history_search = HIST_NONE; stop_completion(); if(input_stat.index < input_stat.len) { input_stat.curs_pos += vifm_wcwidth(input_stat.line[input_stat.index]); input_stat.index++; update_cursor(); } }
static void cmd_left(key_info_t key_info, keys_info_t *keys_info) { input_stat.history_search = HIST_NONE; stop_completion(); if(input_stat.index > 0) { input_stat.index--; input_stat.curs_pos -= vifm_wcwidth(input_stat.line[input_stat.index]); update_cursor(); } }
static int def_handler(wchar_t key) { void *p; wchar_t buf[2] = {key, L'\0'}; input_stat.history_search = HIST_NONE; if(input_stat.complete_continue && input_stat.line[input_stat.index - 1] == L'/' && key == '/') { stop_completion(); return 0; } stop_completion(); if(key != L'\r' && !iswprint(key)) return 0; p = realloc(input_stat.line, (input_stat.len + 2) * sizeof(wchar_t)); if(p == NULL) { leave_cmdline_mode(); return 0; } input_stat.line = (wchar_t *) p; if(input_stat.len == 0) input_stat.line[0] = L'\0'; input_stat.index++; wcsins(input_stat.line, buf, input_stat.index); input_stat.len++; input_stat.curs_pos += vifm_wcwidth(key); update_cmdline_size(); update_cmdline_text(); return 0; }
/* Converts the leading character of the str string to a printable string. Puts * number of screen character positions taken by the resulting string * representation of a character into *screen_width. Returns pointer to a * statically allocated buffer. */ TSTATIC const char * strchar2str(const char str[], int pos, size_t *screen_width) { static char buf[32]; const size_t char_width = utf8_chrw(str); if(char_width != 1 || (unsigned char)str[0] >= (unsigned char)' ') { memcpy(buf, str, char_width); buf[char_width] = '\0'; *screen_width = vifm_wcwidth(get_first_wchar(str)); } else if(str[0] == '\n') { buf[0] = '\0'; *screen_width = 0; } else if(str[0] == '\b') { strcpy(buf, ""); *screen_width = 0; } else if(str[0] == '\r') { strcpy(buf, "<cr>"); *screen_width = 4; } else if(str[0] == '\t') { const size_t space_count = cfg.tab_stop - pos%cfg.tab_stop; memset(buf, ' ', space_count); buf[space_count] = '\0'; *screen_width = space_count; } else if(str[0] == '\033') { char *dst = buf; while(*str != 'm' && *str != '\0' && (size_t)(dst - buf) < sizeof(buf) - 2) { *dst++ = *str++; } if(*str != 'm') { buf[0] = '\0'; } else { *dst++ = 'm'; *dst = '\0'; } *screen_width = 0; } else if((unsigned char)str[0] < (unsigned char)' ') { buf[0] = '^'; buf[1] = ('A' - 1) + str[0]; buf[2] = '\0'; *screen_width = 2; } else { buf[0] = str[0]; buf[1] = '\0'; *screen_width = 1; } return buf; }
static int locale_works(void) { return (vifm_wcwidth(L'丝') == 2); }