static BINDING_FUNCTION(binding_backward_delete_char) { if (lines && line_index == 0 && lines_index > 0 && xwcslen(lines[lines_index]) + xwcslen(lines[lines_index - 1]) < LINE_MAXLEN) { int i; line_index = xwcslen(lines[lines_index - 1]); xwcscat(lines[lines_index - 1], lines[lines_index]); xfree(lines[lines_index]); for (i = lines_index; i < array_count((char **) lines); i++) lines[i] = lines[i + 1]; lines = xrealloc(lines, (array_count((char **) lines) + 1) * sizeof(CHAR_T *)); lines_index--; lines_adjust(); ncurses_typing_mod = 1; } else if (xwcslen(line) > 0 && line_index > 0) { memmove(line + line_index - 1, line + line_index, (LINE_MAXLEN - line_index) * sizeof(CHAR_T)); line[LINE_MAXLEN - 1] = 0; line_index--; ncurses_typing_mod = 1; } }
static BINDING_FUNCTION(binding_yank) { if (yanked && xwcslen(yanked) + xwcslen(line) + 1 < LINE_MAXLEN) { memmove(line + line_index + xwcslen(yanked), line + line_index, (LINE_MAXLEN - line_index - xwcslen(yanked)) * sizeof(CHAR_T)); memcpy(line + line_index, yanked, sizeof(CHAR_T) * xwcslen(yanked)); line_index += xwcslen(yanked); } }
static int ncurses_lineslen() { if (ncurses_lines) { int n = -1; CHAR_T **l; if (ncurses_lines[0][0] == '/') return 0; for (l = ncurses_lines; *l; l++) n += xwcslen(*l) + 1; return n; } else return (ncurses_line[0] == '/' ? 0 : xwcslen(ncurses_line)); }
static BINDING_FUNCTION(binding_forward_word) { size_t linelen = xwcslen(line); while (line_index < linelen && line[line_index] == ' ') line_index++; while (line_index < linelen && line[line_index] != ' ') line_index++; }
/* cut prompt to given width and recalculate its' width */ void ncurses_update_real_prompt(ncurses_window_t *n) { g_assert(n); #if 0 /* XXX: shortening */ const int _maxlen = n->window && n->window->_maxx ? n->window->_maxx : 80; const int maxlen = ncurses_noecho ? _maxlen - 3 : _maxlen / 3; xfree(n->prompt_real); if (maxlen <= 6) /* we assume the terminal is too narrow to display any input with prompt */ n->prompt_real = NULL; else { #ifdef USE_UNICODE n->prompt_real = normal_to_wcs(n->prompt); #else n->prompt_real = (CHAR_T *) xstrdup(n->prompt); #endif } n->prompt_real_len = xwcslen(n->prompt_real); if (n->prompt_real_len > maxlen) { /* need to cut it */ const CHAR_T *dots = (CHAR_T *) TEXT("..."); #ifdef USE_UNICODE const wchar_t udots[2] = { 0x2026, 0 }; if (console_charset_is_utf8) /* use unicode hellip, if using utf8 */ dots = udots; #endif { const int dotslen = xwcslen(dots); const int taillen = (maxlen - dotslen) / 2; /* rounded down */ const int headlen = (maxlen - dotslen) - taillen; /* rounded up */ CHAR_T *tmp = xmalloc(sizeof(CHAR_T) * (maxlen + 1)); xwcslcpy(tmp, n->prompt_real, headlen + 1); xwcslcpy(tmp + headlen, dots, dotslen + 1); xwcslcpy(tmp + headlen + dotslen, n->prompt_real + n->prompt_real_len - taillen, taillen + 1); xfree(n->prompt_real); n->prompt_real = tmp; n->prompt_real_len = maxlen; } } #endif }
static BINDING_FUNCTION(binding_delete_char) { if (line_index == xwcslen(line) && lines_index < array_count((char **) lines) - 1 && xwcslen(line) + xwcslen(lines[lines_index + 1]) < LINE_MAXLEN) { int i; xwcscat(line, lines[lines_index + 1]); xfree(lines[lines_index + 1]); for (i = lines_index + 1; i < array_count((char **) lines); i++) lines[i] = lines[i + 1]; lines = xrealloc(lines, (array_count((char **) lines) + 1) * sizeof(CHAR_T *)); lines_adjust(); ncurses_typing_mod = 1; } else if (line_index < xwcslen(line)) { memmove(line + line_index, line + line_index + 1, (LINE_MAXLEN - line_index - 1) * sizeof(CHAR_T)); line[LINE_MAXLEN - 1] = 0; ncurses_typing_mod = 1; } }
/* * lines_adjust() * * poprawia kursor po przesuwaniu go w pionie. */ void ncurses_lines_adjust(void) { size_t linelen; if (lines_index < lines_start) lines_start = lines_index; if (lines_index - 4 > lines_start) lines_start = lines_index - 4; ncurses_line = ncurses_lines[lines_index]; linelen = xwcslen(ncurses_line); if (line_index > linelen) line_index = linelen; }
/* * returns currsor x position */ static int ncurses_redraw_input_line(CHAR_T *text) { #ifdef HAVE_LIBASPELL char *aspell_line = NULL; #endif int i, stop, cur_posx = 0; int attr = A_NORMAL; const int linelen = xwcslen(text); int promptlen = getcurx(input); int width = input->_maxx + 1 - promptlen; int y = getcury(input); #ifdef HAVE_LIBASPELL if (spell_checker) { aspell_line = xmalloc(linelen + 1); spellcheck(text, aspell_line); } #endif stop = linelen < width+line_start ? linelen : width + line_start; for (i = line_start; i < stop; i++) { if (line_index == i) { cur_posx = getcurx(input); } #ifdef HAVE_LIBASPELL if (aspell_line && aspell_line[i] == ASPELLCHAR && text[i] != ' ') /* jesli b³êdny to wy¶wietlamy podkre¶lony */ attr = A_UNDERLINE; else attr = A_NORMAL; #endif print_char(input, text[i], attr); } if (line_index >= i) { cur_posx = getcurx(input); } #ifdef HAVE_LIBASPELL xfree(aspell_line); #endif if (width>2) { wattrset(input, color_pair(COLOR_BLACK, COLOR_BLACK) | A_BOLD); if (line_start > 0) mvwaddch(input, y, promptlen, '<'); if (linelen && linelen - line_start > width) mvwaddch(input, y, input->_maxx, '>'); } wattrset(input, A_NORMAL); return cur_posx; }
static BINDING_FUNCTION(binding_kill_word) { CHAR_T *p = line + line_index; int eaten = 0; while (*p && *p == ' ') { p++; eaten++; } while (*p && *p != ' ') { p++; eaten++; } memmove(line + line_index, line + line_index + eaten, sizeof(CHAR_T) * (xwcslen(line) - line_index - eaten + 1)); }
static BINDING_FUNCTION(binding_forward_char) { size_t linelen = xwcslen(line); if (lines) { if (line_index < linelen) line_index++; else { if (lines_index < array_count((char **) lines) - 1) { lines_index++; line_index = 0; line_start = 0; } lines_adjust(); } return; } if (line_index < linelen) line_index++; }
static BINDING_FUNCTION(binding_word_rubout) { CHAR_T *p; int eaten = 0; if (!line_index) return; xfree(yanked); p = line + line_index; if (xisspace(*(p - 1))) { while (p > line && xisspace(*(p - 1))) { p--; eaten++; } } else { while (p > line && ! xisalpha(*(p - 1)) && ! xisspace(*(p - 1))) { p--; eaten++; } } if (p > line) { while (p > line && ! xisspace(*(p - 1)) && xisalpha(*(p - 1))) { p--; eaten++; } } yanked = xcalloc(eaten + 1, sizeof(CHAR_T)); xwcslcpy(yanked, p, eaten + 1); memmove(p, line + line_index, (xwcslen(line) - line_index + 1) * sizeof(CHAR_T)); line_index -= eaten; }
inline CHAR_T *xwcsdup(CHAR_T *str) { if (!str) return NULL; return g_memdup(str, (xwcslen(str)+1) * sizeof(CHAR_T)); }
static BINDING_FUNCTION(binding_complete) { if (!lines) { #if USE_UNICODE int line_start_tmp, line_index_tmp; char nline[LINE_MAXLEN + 1]; /* (* MB_CUR_MAX)? No, it would be anyway truncated by completion */ int i, j; int nlen; line_start_tmp = line_index_tmp = 0; for (i = 0, j = 0; line[i] && i < LINE_MAXLEN; i++) { char buf[MB_LEN_MAX+1]; int tmp; int k; tmp = wctomb(buf, line[i]); if (tmp <= 0 || tmp > MB_CUR_MAX) { debug_error("binding_complete() wctomb() failed (%d) [%d]\n", tmp, MB_CUR_MAX); return; } if (j+tmp >= LINE_MAXLEN) { debug_error("binding_complete() buffer might be truncated, aborting\n"); return; } if (line_start == i) line_start_tmp = j; if (line_index == i) line_index_tmp = j; for (k = 0; k < tmp && buf[k]; k++) nline[j++] = buf[k]; } /* XXX, put into loop, wcslen()+1? */ if (line_start == i) line_start_tmp = j; if (line_index == i) line_index_tmp = j; nline[j] = '\0'; debug("wcs-completion WC->MB (%d,%d) => (%d,%d) [%d;%d]\n", line_start, line_index, line_start_tmp, line_index_tmp, j, i); ncurses_complete(&line_start_tmp, &line_index_tmp, nline); nlen = strlen(nline); line_start = line_index = 0; for (i = 0, j = 0; j < nlen; i++) { int tmp; tmp = mbtowc(&line[i], &nline[j], nlen-j); if (tmp <= 0) { debug_error("binding_complete() mbtowc() failed (%d)\n", tmp); break; /* return; */ } if (line_start_tmp == j) line_start = i; if (line_index_tmp == j) line_index = i; j += tmp; } /* XXX, put into loop, <= nlen? */ if (line_start_tmp == j) line_start = i; if (line_index_tmp == j) line_index = i; debug("wcs-completion MB->WC (%d,%d) => (%d,%d) [%d;%d]\n", line_start_tmp, line_index_tmp, line_start, line_index, j, i); line[i] = '\0'; #else ncurses_complete(&line_start, &line_index, (char *) line); #endif } else { int i, count = 8 - (line_index % 8); if (xwcslen(line) + count >= LINE_MAXLEN - 1) return; memmove(line + line_index + count, line + line_index, sizeof(CHAR_T) * (LINE_MAXLEN - line_index - count)); for (i = line_index; i < line_index + count; i++) line[i] = CHAR(' '); line_index += count; } }