/****************************************************************************** * TinTin++ * * Copyright (C) 2005 (See CREDITS file) * * * * This program is protected under the GNU GPL (See COPYING) * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * *******************************************************************************/ /****************************************************************************** * (T)he K(I)cki(N) (T)ickin D(I)kumud Clie(N)t * * * * coded by Igor van den Hoven 2006 * ******************************************************************************/ #include "tintin.h" DO_COMMAND(do_cursor) { char left[BUFFER_SIZE], right[BUFFER_SIZE], temp[BUFFER_SIZE]; int cnt; arg = get_arg_in_braces(arg, left, TRUE); arg = get_arg_in_braces(arg, right, TRUE); substitute(ses, right, right, SUB_VAR|SUB_FUN); if (*left == 0) { tintin_header(ses, " CURSOR OPTIONS "); for (cnt = 0 ; *cursor_table[cnt].fun ; cnt++) { if (*cursor_table[cnt].name) { convert_meta(cursor_table[cnt].code, temp); tintin_printf2(ses, " [%-18s] [%-6s] %s", cursor_table[cnt].name, temp, cursor_table[cnt].desc); } } tintin_header(ses, ""); } else { for (cnt = 0 ; *cursor_table[cnt].fun ; cnt++) { if (is_abbrev(left, cursor_table[cnt].name)) { cursor_table[cnt].fun(right); return ses; } } tintin_printf(ses, "#ERROR: #CURSOR {%s} IS NOT A VALID OPTION.", capitalize(left)); } return ses; } DO_CURSOR(cursor_backspace) { if (gtd->input_cur == 0) { return; } cursor_left(""); cursor_delete(""); modified_input(); } DO_CURSOR(cursor_buffer_down) { do_buffer(gtd->ses, "DOWN"); } DO_CURSOR(cursor_buffer_end) { do_buffer(gtd->ses, "END"); } DO_CURSOR(cursor_buffer_home) { do_buffer(gtd->ses, "HOME"); } DO_CURSOR(cursor_buffer_lock) { do_buffer(gtd->ses, "LOCK"); } DO_CURSOR(cursor_buffer_up) { do_buffer(gtd->ses, "UP"); } DO_CURSOR(cursor_check_line) { if (gtd->input_pos != gtd->input_cur) { if (gtd->input_cur < gtd->ses->cols - 2) { cursor_redraw_line(""); return; } } if (gtd->input_pos > 2 && gtd->input_pos < gtd->ses->cols - 2) { return; } if (gtd->input_pos >= gtd->ses->cols - 2) { cursor_redraw_line(""); return; } if (gtd->input_pos != gtd->input_cur && gtd->input_pos <= 2) { cursor_redraw_line(""); return; } } DO_CURSOR(cursor_clear_left) { if (gtd->input_cur == 0) { return; } sprintf(gtd->paste_buf, "%.*s", gtd->input_cur, gtd->input_buf); memmove(>d->input_buf[0], >d->input_buf[gtd->input_cur+1], gtd->input_len - gtd->input_cur); input_printf("\033[%dD\033[%dP", gtd->input_cur, gtd->input_cur); gtd->input_len -= gtd->input_cur; gtd->input_buf[gtd->input_len] = 0; if (gtd->input_cur != gtd->input_pos) { gtd->input_cur = 0; gtd->input_pos = 0; cursor_redraw_line(""); } else { gtd->input_cur = 0; gtd->input_pos = 0; } modified_input(); } DO_CURSOR(cursor_clear_line) { if (gtd->input_len == 0) { return; } if (gtd->input_pos) { input_printf("\033[%dG\033[%dP", gtd->input_off, gtd->input_len); } else { input_printf("\033[%dP", gtd->input_len); } gtd->input_len = 0; gtd->input_cur = 0; gtd->input_pos = 0; gtd->input_buf[0] = 0; modified_input(); } DO_CURSOR(cursor_clear_right) { if (gtd->input_cur == gtd->input_len) { return; } strcpy(gtd->paste_buf, >d->input_buf[gtd->input_cur]); input_printf("\033[%dP", gtd->input_len - gtd->input_pos); gtd->input_buf[gtd->input_cur] = 0; gtd->input_len = gtd->input_cur; modified_input(); } DO_CURSOR(cursor_convert_meta) { SET_BIT(gtd->flags, TINTIN_FLAG_CONVERTMETACHAR); } DO_CURSOR(cursor_delete_exit) { if (gtd->input_len == 0) { cursor_exit(""); } else { cursor_delete(""); } } DO_CURSOR(cursor_delete) { if (gtd->input_len == 0) { return; } if (gtd->input_len == gtd->input_cur) { return; } memmove(>d->input_buf[gtd->input_cur], >d->input_buf[gtd->input_cur+1], gtd->input_len - gtd->input_cur); gtd->input_len--; input_printf("\033[1P"); cursor_fix_line(""); modified_input(); } DO_CURSOR(cursor_delete_word_left) { int index_cur; if (gtd->input_cur == 0) { return; } index_cur = gtd->input_cur; while (gtd->input_cur && gtd->input_buf[gtd->input_cur - 1] == ' ') { gtd->input_cur--; gtd->input_pos--; } while (gtd->input_cur && gtd->input_buf[gtd->input_cur - 1] != ' ') { gtd->input_cur--; gtd->input_pos--; } sprintf(gtd->paste_buf, "%.*s", index_cur - gtd->input_cur, >d->input_buf[gtd->input_cur]); memmove(>d->input_buf[gtd->input_cur], >d->input_buf[index_cur], gtd->input_len - index_cur + 1); input_printf("\033[%dD\033[%dP", index_cur - gtd->input_cur, index_cur - gtd->input_cur); gtd->input_len -= index_cur - gtd->input_cur; cursor_check_line(""); modified_input(); } DO_CURSOR(cursor_delete_word_right) { int index_cur, index_pos; if (gtd->input_cur == gtd->input_len) { return; } index_cur = gtd->input_cur; index_pos = gtd->input_pos; while (gtd->input_cur != gtd->input_len && gtd->input_buf[gtd->input_cur] == ' ') { gtd->input_cur++; gtd->input_pos++; } while (gtd->input_cur != gtd->input_len && gtd->input_buf[gtd->input_cur] != ' ') { gtd->input_cur++; gtd->input_pos++; } sprintf(gtd->paste_buf, "%.*s", gtd->input_cur - index_cur, >d->input_buf[gtd->input_cur]); memmove(>d->input_buf[index_cur], >d->input_buf[gtd->input_cur], gtd->input_len - gtd->input_cur + 1); input_printf("\033[%dP", gtd->input_cur - index_cur); gtd->input_len -= gtd->input_cur - index_cur; gtd->input_pos = index_pos; gtd->input_cur = index_cur; cursor_fix_line(""); modified_input(); } DO_CURSOR(cursor_echo_on) { SET_BIT(gtd->ses->telopts, TELOPT_FLAG_ECHO); } DO_CURSOR(cursor_echo_off) { DEL_BIT(gtd->ses->telopts, TELOPT_FLAG_ECHO); } DO_CURSOR(cursor_end) { if (gtd->input_cur == gtd->input_len) { return; } gtd->input_cur = gtd->input_len; cursor_redraw_line(""); } DO_CURSOR(cursor_enter) { input_printf("\n"); gtd->input_buf[gtd->input_len] = 0; gtd->input_len = 0; gtd->input_cur = 0; gtd->input_pos = 0; gtd->macro_buf[0] = 0; gtd->input_tmp[0] = 0; if (HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYSEARCH)) { struct listroot *root = gtd->ses->list[LIST_HISTORY]; if (root->update >= 0 && root->update < root->used) { strcpy(gtd->input_buf, root->list[root->update]->left); } DEL_BIT(gtd->flags, TINTIN_FLAG_HISTORYSEARCH); gtd->input_off = 1; } SET_BIT(gtd->flags, TINTIN_FLAG_PROCESSINPUT); modified_input(); } DO_CURSOR(cursor_exit) { if (gtd->ses == gts) { do_end(NULL, ""); } else { cleanup_session(gtd->ses); } } DO_CURSOR(cursor_history_next) { struct listroot *root = gtd->ses->list[LIST_HISTORY]; if (HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYSEARCH)) { if (root->update == root->used) { return; } for (root->update++ ; root->update < root->used ; root->update++) { if (*gtd->input_buf && find(gtd->ses, root->list[root->update]->left, gtd->input_buf, SUB_NONE)) { break; } } if (root->update < root->used) { input_printf("\033[%dC \033[0K%.*s\033[%dG", gtd->input_len - gtd->input_cur + 1, gtd->ses->cols - 16 - gtd->input_len, root->list[root->update]->left, gtd->input_pos + 11); } return; } if (root->list[0] == NULL) { return; } if (!HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYBROWSE)) { return; } else if (root->update < root->used) { for (root->update++ ; root->update < root->used ; root->update++) { if (!strncmp(gtd->input_tmp, root->list[root->update]->left, strlen(gtd->input_tmp))) { break; } } } cursor_clear_line(""); if (root->update == root->used) { strcpy(gtd->input_buf, gtd->input_tmp); } else { strcpy(gtd->input_buf, root->list[root->update]->left); } gtd->input_len = strlen(gtd->input_buf); gtd->input_cur = gtd->input_len; gtd->input_pos = 0; cursor_redraw_line(""); SET_BIT(gtd->flags, TINTIN_FLAG_HISTORYBROWSE); } DO_CURSOR(cursor_history_prev) { struct listroot *root = gtd->ses->list[LIST_HISTORY]; if (HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYSEARCH)) { if (root->update <= 0) { return; } for (root->update-- ; root->update >= 0 ; root->update--) { if (*gtd->input_buf && find(gtd->ses, root->list[root->update]->left, gtd->input_buf, SUB_NONE)) { break; } } if (root->update >= 0) { input_printf("\033[%dC \033[0K%.*s\033[%dG", gtd->input_len - gtd->input_cur + 1, gtd->ses->cols - 16 - gtd->input_len, root->list[root->update]->left, gtd->input_pos + 11); } return; } if (root->list[0] == NULL) { return; } if (!HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYBROWSE)) { strcpy(gtd->input_tmp, gtd->input_buf); for (root->update = root->used - 1 ; root->update >= 0 ; root->update--) { if (!strncmp(gtd->input_tmp, root->list[root->update]->left, strlen(gtd->input_tmp))) { break; } } } else if (root->update >= 0) { for (root->update-- ; root->update >= 0 ; root->update--) { if (!strncmp(gtd->input_tmp, root->list[root->update]->left, strlen(gtd->input_tmp))) { break; } } } cursor_clear_line(""); if (root->update == -1) { strcpy(gtd->input_buf, gtd->input_tmp); } else { strcpy(gtd->input_buf, root->list[root->update]->left); } gtd->input_len = strlen(gtd->input_buf); gtd->input_cur = gtd->input_len; gtd->input_pos = 0; cursor_redraw_line(""); SET_BIT(gtd->flags, TINTIN_FLAG_HISTORYBROWSE); } DO_CURSOR(cursor_history_search) { struct listroot *root = gtd->ses->list[LIST_HISTORY]; if (root->list[0] == NULL) { return; } if (!HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYSEARCH)) { strcpy(gtd->input_tmp, gtd->input_buf); cursor_clear_line(""); SET_BIT(gtd->flags, TINTIN_FLAG_HISTORYSEARCH); gtd->input_off = 11; root->update = root->used - 1; input_printf("(search) [ ] \033[3D"); } else { if (root->update >= 0 && root->update < root->used) { strcpy(gtd->input_buf, root->list[root->update]->left); } input_printf("\033[1G\033[0K"); gtd->input_len = strlen(gtd->input_buf); gtd->input_cur = gtd->input_len; gtd->input_pos = gtd->input_len; root->update = -1; DEL_BIT(gtd->flags, TINTIN_FLAG_HISTORYSEARCH); gtd->input_off = 1; cursor_redraw_line(""); } } DO_CURSOR(cursor_history_find) { struct listroot *root = gtd->ses->list[LIST_HISTORY]; push_call("cursor_history_find(%s)", gtd->input_buf); for (root->update = root->used - 1 ; root->update >= 0 ; root->update--) { if (*gtd->input_buf && find(gtd->ses, root->list[root->update]->left, gtd->input_buf, SUB_NONE)) { break; } } if (root->update >= 0) { if (gtd->input_len == gtd->input_cur) { input_printf("\033[0K] %.*s\033[%dG", gtd->ses->cols - 16 - gtd->input_len, root->list[root->update]->left, gtd->input_pos + 11); } else { input_printf("\033[%dC\033[0K]\033[3C%.*s\033[%dG", gtd->input_len - gtd->input_cur, gtd->ses->cols - 16 - gtd->input_len, root->list[root->update]->left, gtd->input_pos + 1); } } else { if (gtd->input_len == gtd->input_cur) { input_printf("\033[0K]\033[%dG", gtd->input_pos + 11); } else { input_printf("\033[%dC\033[0K]\033[%dG", gtd->input_len - gtd->input_cur, gtd->input_pos + 11); } } pop_call(); return; } DO_CURSOR(cursor_home) { if (gtd->input_cur == 0) { return; } input_printf("\033[%dD", gtd->input_pos); if (gtd->input_cur != gtd->input_pos) { gtd->input_cur = 0; gtd->input_pos = 0; cursor_redraw_line(""); } else { gtd->input_cur = 0; gtd->input_pos = 0; } } DO_CURSOR(cursor_insert) { if (*arg == 0) { TOG_BIT(gtd->flags, TINTIN_FLAG_INSERTINPUT); } else if (!strcasecmp(arg, "ON")) { SET_BIT(gtd->flags, TINTIN_FLAG_INSERTINPUT); } else if (!strcasecmp(arg, "OFF")) { DEL_BIT(gtd->flags, TINTIN_FLAG_INSERTINPUT); } else { tintin_printf(NULL, "#SYNTAX: #CURSOR {INSERT} {ON|OFF}."); } } DO_CURSOR(cursor_left) { if (gtd->input_cur > 0) { gtd->input_cur--; gtd->input_pos--; input_printf("\033[1D"); cursor_check_line(""); } } DO_CURSOR(cursor_left_word) { int index_cur; if (gtd->input_cur == 0) { return; } index_cur = gtd->input_cur; while (gtd->input_cur && gtd->input_buf[gtd->input_cur - 1] == ' ') { gtd->input_cur--; gtd->input_pos--; } while (gtd->input_cur && gtd->input_buf[gtd->input_cur - 1] != ' ') { gtd->input_cur--; gtd->input_pos--; } input_printf("\033[%dD", index_cur - gtd->input_cur); cursor_check_line(""); } DO_CURSOR(cursor_paste_buffer) { if (*gtd->paste_buf == 0) { return; } ins_sprintf(>d->input_buf[gtd->input_cur], "%s", gtd->paste_buf); gtd->input_len += strlen(gtd->paste_buf); gtd->input_cur += strlen(gtd->paste_buf); cursor_redraw_line(""); modified_input(); } DO_CURSOR(cursor_redraw_input) { if (IS_SPLIT(gtd->ses)) { cursor_redraw_line(""); } else { input_printf("\033[1G\033[0K%s%s\033[0K", gtd->ses->more_output, gtd->input_buf); gtd->input_cur = gtd->input_len; gtd->input_pos = gtd->input_len % gtd->ses->cols; } } DO_CURSOR(cursor_redraw_line) { input_printf("\033[%dG\033[%dX", gtd->input_off, gtd->input_len); if (gtd->input_pos != gtd->input_cur) { if (gtd->input_cur < gtd->ses->cols - 2) { gtd->input_pos = gtd->input_cur; } } if (gtd->input_pos >= gtd->ses->cols - 2) { while (gtd->input_pos >= gtd->ses->cols - 2) { gtd->input_pos -= gtd->ses->cols / 3; } } if (gtd->input_pos != gtd->input_cur) { if (gtd->input_pos <= 2) { while (gtd->input_pos <= 2) { gtd->input_pos += gtd->ses->cols * 2 / 3; } } } if (gtd->input_pos != gtd->input_cur) { input_printf("<%.*s\033[%dG", gtd->ses->cols - 1, >d->input_buf[gtd->input_cur - gtd->input_pos + 1], gtd->input_pos+gtd->input_off); } else { input_printf("%.*s\033[%dG", gtd->ses->cols, >d->input_buf[gtd->input_cur - gtd->input_pos], gtd->input_pos+gtd->input_off); } cursor_fix_line(""); } DO_CURSOR(cursor_fix_line) { if (gtd->input_len - gtd->input_cur + gtd->input_pos > gtd->ses->cols) { input_printf("\033[%dG%.1s>\033[%dG", gtd->ses->cols - 1, >d->input_buf[gtd->input_cur + gtd->ses->cols - gtd->input_pos-2], gtd->input_pos+gtd->input_off); } else if (gtd->input_len - gtd->input_cur + gtd->input_pos == gtd->ses->cols) { input_printf("\033[%dG%.2s\033[%dG", gtd->ses->cols - 1, >d->input_buf[gtd->input_cur + gtd->ses->cols - gtd->input_pos-2], gtd->input_pos+gtd->input_off); } } DO_CURSOR(cursor_right) { if (gtd->input_cur < gtd->input_len) { gtd->input_cur++; gtd->input_pos++; input_printf("\033[1C"); } cursor_check_line(""); } DO_CURSOR(cursor_right_word) { int index_cur; if (gtd->input_cur == gtd->input_len) { return; } index_cur = gtd->input_cur; while (gtd->input_cur < gtd->input_len && gtd->input_buf[gtd->input_cur] == ' ') { gtd->input_cur++; gtd->input_pos++; } while (gtd->input_cur < gtd->input_len && gtd->input_buf[gtd->input_cur] != ' ') { gtd->input_cur++; gtd->input_pos++; } input_printf("\033[%dC", gtd->input_cur - index_cur); cursor_check_line(""); } DO_CURSOR(cursor_suspend) { do_suspend(gtd->ses, ""); } /* Improved tab handling by Ben Love */ int cursor_tab_add(int input_now, int stop_after_first) { struct listroot *root = gtd->ses->list[LIST_TAB]; char tab[BUFFER_SIZE]; for (root->update = 0 ; root->update < root->used ; root->update++) { substitute(gtd->ses, root->list[root->update]->left, tab, SUB_VAR|SUB_FUN); if (!strncmp(tab, >d->input_buf[input_now], strlen(>d->input_buf[input_now]))) { if (search_node_list(gtd->ses->list[LIST_TABCYCLE], tab)) { continue; } insert_node_list(gtd->ses->list[LIST_TABCYCLE], tab, "", ""); if (stop_after_first) { return TRUE; } } } return FALSE; } int cursor_auto_tab_add(int input_now, int stop_after_first) { char tab[BUFFER_SIZE], buf[BUFFER_SIZE]; int scroll_cnt, line_cnt; char *arg; line_cnt = 0; scroll_cnt = gtd->ses->scroll_row; do { if (scroll_cnt == gtd->ses->scroll_max -1) { scroll_cnt = 0; } else { scroll_cnt++; } if (gtd->ses->buffer[scroll_cnt] == NULL) { break; } if (str_hash_grep(gtd->ses->buffer[scroll_cnt], FALSE)) { continue; } if (line_cnt++ >= gtd->ses->auto_tab) { break; } strip_vt102_codes(gtd->ses->buffer[scroll_cnt], buf); arg = buf; while (*arg) { arg = get_arg_stop_spaces(arg, tab, 0); if (!strncmp(tab, >d->input_buf[input_now], strlen(>d->input_buf[input_now]))) { if (search_node_list(gtd->ses->list[LIST_TABCYCLE], tab)) { continue; } insert_node_list(gtd->ses->list[LIST_TABCYCLE], tab, "", ""); if (stop_after_first) { return TRUE; } } if (*arg == COMMAND_SEPARATOR) { arg++; } } } while (scroll_cnt != gtd->ses->scroll_row); return FALSE; } void cursor_hide_completion(int input_now) { struct listroot *root = gtd->ses->list[LIST_TABCYCLE]; struct listnode *f_node; struct listnode *l_node; int len_change; f_node = root->list[0]; l_node = root->list[root->used - 1]; if (root->used && !strcmp(l_node->left, gtd->input_buf + input_now)) { len_change = strlen(l_node->left) - strlen(f_node->left); if (len_change > 0) { if (gtd->input_cur < gtd->input_len) { input_printf("\033[%dC", gtd->input_len - gtd->input_cur); } input_printf("\033[%dD\033[%dP", len_change, len_change); gtd->input_len = gtd->input_len - len_change; gtd->input_buf[gtd->input_len] = 0; gtd->input_cur = gtd->input_len; gtd->input_pos = gtd->input_pos; } } return; } void cursor_show_completion(int input_now, int show_last_node) { struct listroot *root = gtd->ses->list[LIST_TABCYCLE]; struct listnode *node; if (!root->used) { return; } node = show_last_node ? root->list[root->used - 1] : root->list[0]; if (gtd->input_cur < gtd->input_len) { input_printf("\033[%dC", gtd->input_len - gtd->input_cur); } if (gtd->input_len > input_now) { input_printf("\033[%dD\033[%dP", gtd->input_len - input_now, gtd->input_len - input_now); } if (input_now + (int) strlen(node->left) < gtd->ses->cols - 2) { input_printf("%s", node->left); } strcpy(>d->input_buf[input_now], node->left); gtd->input_len = input_now + strlen(node->left); gtd->input_cur = gtd->input_len; gtd->input_pos = gtd->input_len; cursor_check_line(""); if (node == root->list[0]) { kill_list(gtd->ses->list[LIST_TABCYCLE]); } return; } int cursor_calc_input_now(void) { int input_now; if (gtd->input_len == 0 || gtd->input_buf[gtd->input_len - 1] == ' ') { return -1; } for (input_now = gtd->input_len - 1 ; input_now ; input_now--) { if (gtd->input_buf[input_now] == ' ') { return input_now + 1; } } return input_now; } DO_CURSOR(cursor_tab_forward) { int input_now, tab_found; input_now = cursor_calc_input_now(); if (input_now == -1) { return; } cursor_hide_completion(input_now); if (!gtd->ses->list[LIST_TABCYCLE]->list[0]) { insert_node_list(gtd->ses->list[LIST_TABCYCLE], >d->input_buf[input_now], "", ""); } tab_found = cursor_tab_add(input_now, TRUE); cursor_show_completion(input_now, tab_found); } DO_CURSOR(cursor_tab_backward) { struct listroot *root = gtd->ses->list[LIST_TABCYCLE]; int input_now; input_now = cursor_calc_input_now(); if (input_now == -1) { return; } cursor_hide_completion(input_now); if (root->used) { delete_index_list(gtd->ses->list[LIST_TABCYCLE], root->used - 1); } if (!root->list[0]) { insert_node_list(gtd->ses->list[LIST_TABCYCLE], >d->input_buf[input_now], "", ""); cursor_tab_add(input_now, FALSE); } cursor_show_completion(input_now, TRUE); } DO_CURSOR(cursor_auto_tab_forward) { int input_now, tab_found; input_now = cursor_calc_input_now(); if (input_now == -1) { return; } cursor_hide_completion(input_now); if (!gtd->ses->list[LIST_TABCYCLE]->list[0]) { insert_node_list(gtd->ses->list[LIST_TABCYCLE], >d->input_buf[input_now], "", ""); } tab_found = cursor_auto_tab_add(input_now, TRUE); cursor_show_completion(input_now, FALSE); } DO_CURSOR(cursor_auto_tab_backward) { struct listroot *root = gtd->ses->list[LIST_TABCYCLE]; int input_now; input_now = cursor_calc_input_now(); if (input_now == -1) { return; } cursor_hide_completion(input_now); if (root->used) { delete_index_list(gtd->ses->list[LIST_TABCYCLE], root->used - 1); } if (!root->list[0]) { insert_node_list(gtd->ses->list[LIST_TABCYCLE], >d->input_buf[input_now], "", ""); cursor_auto_tab_add(input_now, FALSE); } cursor_show_completion(input_now, TRUE); } DO_CURSOR(cursor_mixed_tab_forward) { int input_now, tab_found; input_now = cursor_calc_input_now(); if (input_now == -1) { return; } cursor_hide_completion(input_now); if (!gtd->ses->list[LIST_TABCYCLE]->list[0]) { insert_node_list(gtd->ses->list[LIST_TABCYCLE], >d->input_buf[input_now], "", ""); } tab_found = cursor_tab_add(input_now, TRUE) || cursor_auto_tab_add(input_now, TRUE); cursor_show_completion(input_now, tab_found); } DO_CURSOR(cursor_mixed_tab_backward) { struct listroot *root = gtd->ses->list[LIST_TABCYCLE]; int input_now; input_now = cursor_calc_input_now(); if (input_now == -1) { return; } cursor_hide_completion(input_now); if (root->used) { delete_index_list(gtd->ses->list[LIST_TABCYCLE], root->used - 1); } if (!root->list[0]) { insert_node_list(gtd->ses->list[LIST_TABCYCLE], >d->input_buf[input_now], "", ""); cursor_tab_add(input_now, FALSE); cursor_auto_tab_add(input_now, FALSE); } cursor_show_completion(input_now, TRUE); }