2005-11-01 17:37:44 +00:00
|
|
|
/* $Id$ */
|
|
|
|
/**************************************************************************
|
|
|
|
* prompt.c *
|
|
|
|
* *
|
2005-11-28 19:35:29 +00:00
|
|
|
* Copyright (C) 1999-2004 Chris Allegretta *
|
2006-01-06 07:10:30 +00:00
|
|
|
* Copyright (C) 2005-2006 David Lawrence Ramsey *
|
2005-11-01 17:37:44 +00:00
|
|
|
* 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, 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., 51 Franklin St, Fifth Floor, Boston, MA *
|
|
|
|
* 02110-1301, USA. *
|
|
|
|
* *
|
|
|
|
**************************************************************************/
|
|
|
|
|
2005-12-08 02:47:10 +00:00
|
|
|
#include "proto.h"
|
2005-11-01 17:37:44 +00:00
|
|
|
|
2005-11-01 18:35:47 +00:00
|
|
|
#include <stdio.h>
|
2005-11-01 17:37:44 +00:00
|
|
|
#include <stdarg.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
static char *prompt = NULL;
|
|
|
|
/* The prompt string for statusbar
|
|
|
|
* questions. */
|
|
|
|
static size_t statusbar_x = (size_t)-1;
|
|
|
|
/* The cursor position in answer. */
|
2005-11-07 06:32:07 +00:00
|
|
|
static size_t statusbar_pww = (size_t)-1;
|
|
|
|
/* The place we want in answer. */
|
2005-11-01 18:35:47 +00:00
|
|
|
static bool reset_statusbar_x = FALSE;
|
2005-11-01 17:37:44 +00:00
|
|
|
/* Should we reset the cursor position
|
|
|
|
* at the statusbar prompt? */
|
|
|
|
|
2005-12-08 07:09:08 +00:00
|
|
|
/* Read in a character, interpret it as a shortcut or toggle if
|
|
|
|
* necessary, and return it. Set meta_key to TRUE if the character is a
|
|
|
|
* meta sequence, set func_key to TRUE if the character is a function
|
|
|
|
* key, set s_or_t to TRUE if the character is a shortcut or toggle
|
|
|
|
* key, set ran_func to TRUE if we ran a function associated with a
|
|
|
|
* shortcut key, and set finished to TRUE if we're done after running
|
|
|
|
* or trying to run a function associated with a shortcut key. If
|
|
|
|
* allow_funcs is FALSE, don't actually run any functions associated
|
2006-02-18 21:32:29 +00:00
|
|
|
* with shortcut keys. refresh_func is the function we will call to
|
|
|
|
* refresh the edit window. */
|
2005-11-01 17:37:44 +00:00
|
|
|
int do_statusbar_input(bool *meta_key, bool *func_key, bool *s_or_t,
|
2006-02-18 21:32:29 +00:00
|
|
|
bool *ran_func, bool *finished, bool allow_funcs, void
|
|
|
|
(*refresh_func)(void))
|
2005-11-01 17:37:44 +00:00
|
|
|
{
|
|
|
|
int input;
|
|
|
|
/* The character we read in. */
|
|
|
|
static int *kbinput = NULL;
|
|
|
|
/* The input buffer. */
|
|
|
|
static size_t kbinput_len = 0;
|
|
|
|
/* The length of the input buffer. */
|
|
|
|
const shortcut *s;
|
|
|
|
bool have_shortcut;
|
|
|
|
|
|
|
|
*s_or_t = FALSE;
|
|
|
|
*ran_func = FALSE;
|
|
|
|
*finished = FALSE;
|
|
|
|
|
|
|
|
/* Read in a character. */
|
|
|
|
input = get_kbinput(bottomwin, meta_key, func_key);
|
|
|
|
|
|
|
|
#ifndef DISABLE_MOUSE
|
|
|
|
/* If we got a mouse click and it was on a shortcut, read in the
|
|
|
|
* shortcut character. */
|
|
|
|
if (allow_funcs && *func_key == TRUE && input == KEY_MOUSE) {
|
|
|
|
if (do_statusbar_mouse())
|
|
|
|
input = get_kbinput(bottomwin, meta_key, func_key);
|
|
|
|
else
|
|
|
|
input = ERR;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Check for a shortcut in the current list. */
|
|
|
|
s = get_shortcut(currshortcut, &input, meta_key, func_key);
|
|
|
|
|
|
|
|
/* If we got a shortcut from the current list, or a "universal"
|
|
|
|
* statusbar prompt shortcut, set have_shortcut to TRUE. */
|
|
|
|
have_shortcut = (s != NULL || input == NANO_REFRESH_KEY ||
|
|
|
|
input == NANO_HOME_KEY || input == NANO_END_KEY ||
|
2005-12-08 07:09:08 +00:00
|
|
|
input == NANO_BACK_KEY || input == NANO_FORWARD_KEY ||
|
2005-11-01 17:37:44 +00:00
|
|
|
input == NANO_BACKSPACE_KEY || input == NANO_DELETE_KEY ||
|
|
|
|
input == NANO_CUT_KEY ||
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2005-11-01 17:37:44 +00:00
|
|
|
input == NANO_NEXTWORD_KEY ||
|
|
|
|
#endif
|
|
|
|
(*meta_key == TRUE && (
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2005-11-01 17:37:44 +00:00
|
|
|
input == NANO_PREVWORD_KEY ||
|
|
|
|
#endif
|
2005-11-16 04:14:03 +00:00
|
|
|
input == NANO_VERBATIM_KEY
|
|
|
|
#ifndef NANO_TINY
|
|
|
|
|| input == NANO_BRACKET_KEY
|
|
|
|
#endif
|
|
|
|
)));
|
2005-11-01 17:37:44 +00:00
|
|
|
|
|
|
|
/* Set s_or_t to TRUE if we got a shortcut. */
|
|
|
|
*s_or_t = have_shortcut;
|
|
|
|
|
|
|
|
if (allow_funcs) {
|
|
|
|
/* If we got a character, and it isn't a shortcut or toggle,
|
|
|
|
* it's a normal text character. Display the warning if we're
|
|
|
|
* in view mode, or add the character to the input buffer if
|
|
|
|
* we're not. */
|
|
|
|
if (input != ERR && *s_or_t == FALSE) {
|
|
|
|
/* If we're using restricted mode, the filename isn't blank,
|
|
|
|
* and we're at the "Write File" prompt, disable text
|
|
|
|
* input. */
|
|
|
|
if (!ISSET(RESTRICTED) || openfile->filename[0] == '\0' ||
|
|
|
|
currshortcut != writefile_list) {
|
|
|
|
kbinput_len++;
|
|
|
|
kbinput = (int *)nrealloc(kbinput, kbinput_len *
|
|
|
|
sizeof(int));
|
|
|
|
kbinput[kbinput_len - 1] = input;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If we got a shortcut, or if there aren't any other characters
|
|
|
|
* waiting after the one we read in, we need to display all the
|
|
|
|
* characters in the input buffer if it isn't empty. */
|
|
|
|
if (*s_or_t == TRUE || get_key_buffer_len() == 0) {
|
|
|
|
if (kbinput != NULL) {
|
|
|
|
/* Display all the characters in the input buffer at
|
|
|
|
* once, filtering out control characters. */
|
|
|
|
char *output = charalloc(kbinput_len + 1);
|
|
|
|
size_t i;
|
|
|
|
bool got_enter;
|
|
|
|
/* Whether we got the Enter key. */
|
|
|
|
|
|
|
|
for (i = 0; i < kbinput_len; i++)
|
|
|
|
output[i] = (char)kbinput[i];
|
|
|
|
output[i] = '\0';
|
|
|
|
|
|
|
|
do_statusbar_output(output, kbinput_len, &got_enter,
|
|
|
|
FALSE);
|
|
|
|
|
|
|
|
free(output);
|
|
|
|
|
|
|
|
/* Empty the input buffer. */
|
|
|
|
kbinput_len = 0;
|
|
|
|
free(kbinput);
|
|
|
|
kbinput = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (have_shortcut) {
|
|
|
|
switch (input) {
|
|
|
|
/* Handle the "universal" statusbar prompt shortcuts. */
|
|
|
|
case NANO_REFRESH_KEY:
|
2006-02-18 21:32:29 +00:00
|
|
|
refresh_func();
|
2005-11-01 17:37:44 +00:00
|
|
|
break;
|
|
|
|
case NANO_HOME_KEY:
|
|
|
|
do_statusbar_home();
|
|
|
|
break;
|
|
|
|
case NANO_END_KEY:
|
|
|
|
do_statusbar_end();
|
|
|
|
break;
|
|
|
|
case NANO_BACK_KEY:
|
|
|
|
do_statusbar_left();
|
|
|
|
break;
|
2005-12-08 07:09:08 +00:00
|
|
|
case NANO_FORWARD_KEY:
|
|
|
|
do_statusbar_right();
|
|
|
|
break;
|
2005-11-01 17:37:44 +00:00
|
|
|
case NANO_BACKSPACE_KEY:
|
|
|
|
/* If we're using restricted mode, the filename
|
|
|
|
* isn't blank, and we're at the "Write File"
|
|
|
|
* prompt, disable Backspace. */
|
|
|
|
if (!ISSET(RESTRICTED) || openfile->filename[0] ==
|
|
|
|
'\0' || currshortcut != writefile_list)
|
|
|
|
do_statusbar_backspace();
|
|
|
|
break;
|
|
|
|
case NANO_DELETE_KEY:
|
|
|
|
/* If we're using restricted mode, the filename
|
|
|
|
* isn't blank, and we're at the "Write File"
|
|
|
|
* prompt, disable Delete. */
|
|
|
|
if (!ISSET(RESTRICTED) || openfile->filename[0] ==
|
|
|
|
'\0' || currshortcut != writefile_list)
|
|
|
|
do_statusbar_delete();
|
|
|
|
break;
|
|
|
|
case NANO_CUT_KEY:
|
|
|
|
/* If we're using restricted mode, the filename
|
|
|
|
* isn't blank, and we're at the "Write File"
|
|
|
|
* prompt, disable Cut. */
|
|
|
|
if (!ISSET(RESTRICTED) || openfile->filename[0] ==
|
|
|
|
'\0' || currshortcut != writefile_list)
|
|
|
|
do_statusbar_cut_text();
|
|
|
|
break;
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2005-11-01 17:37:44 +00:00
|
|
|
case NANO_NEXTWORD_KEY:
|
|
|
|
do_statusbar_next_word(FALSE);
|
|
|
|
break;
|
|
|
|
case NANO_PREVWORD_KEY:
|
|
|
|
if (*meta_key == TRUE)
|
|
|
|
do_statusbar_prev_word(FALSE);
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
case NANO_VERBATIM_KEY:
|
|
|
|
if (*meta_key == TRUE) {
|
|
|
|
/* If we're using restricted mode, the filename
|
|
|
|
* isn't blank, and we're at the "Write File"
|
|
|
|
* prompt, disable verbatim input. */
|
|
|
|
if (!ISSET(RESTRICTED) ||
|
|
|
|
openfile->filename[0] == '\0' ||
|
|
|
|
currshortcut != writefile_list) {
|
|
|
|
bool got_enter;
|
|
|
|
/* Whether we got the Enter key. */
|
|
|
|
|
|
|
|
do_statusbar_verbatim_input(&got_enter);
|
|
|
|
|
|
|
|
/* If we got the Enter key, set input to the
|
|
|
|
* key value for Enter, and set finished to
|
|
|
|
* TRUE to indicate that we're done. */
|
|
|
|
if (got_enter) {
|
|
|
|
input = NANO_ENTER_KEY;
|
|
|
|
*finished = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-11-16 02:45:10 +00:00
|
|
|
break;
|
2005-11-16 04:14:03 +00:00
|
|
|
#ifndef NANO_TINY
|
|
|
|
case NANO_BRACKET_KEY:
|
|
|
|
if (*meta_key == TRUE)
|
|
|
|
do_statusbar_find_bracket();
|
|
|
|
break;
|
|
|
|
#endif
|
2005-11-01 17:37:44 +00:00
|
|
|
/* Handle the normal statusbar prompt shortcuts, setting
|
|
|
|
* ran_func to TRUE if we try to run their associated
|
|
|
|
* functions and setting finished to TRUE to indicate
|
2005-12-08 07:09:08 +00:00
|
|
|
* that we're done after running or trying to run their
|
|
|
|
* associated functions. */
|
2005-11-01 17:37:44 +00:00
|
|
|
default:
|
|
|
|
if (s->func != NULL) {
|
|
|
|
*ran_func = TRUE;
|
|
|
|
if (!ISSET(VIEW_MODE) || s->viewok)
|
|
|
|
s->func();
|
|
|
|
}
|
|
|
|
*finished = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return input;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef DISABLE_MOUSE
|
2005-12-08 07:09:08 +00:00
|
|
|
/* Handle a mouse click on the statusbar prompt or the shortcut list. */
|
2005-11-01 17:37:44 +00:00
|
|
|
bool do_statusbar_mouse(void)
|
|
|
|
{
|
|
|
|
int mouse_x, mouse_y;
|
|
|
|
bool retval = get_mouseinput(&mouse_x, &mouse_y, TRUE);
|
|
|
|
|
|
|
|
if (!retval) {
|
|
|
|
/* We can click in the statusbar window text to move the
|
|
|
|
* cursor. */
|
|
|
|
if (wenclose(bottomwin, mouse_y, mouse_x)) {
|
2005-11-01 18:35:47 +00:00
|
|
|
size_t start_col;
|
|
|
|
|
|
|
|
assert(prompt != NULL);
|
|
|
|
|
|
|
|
start_col = strlenpt(prompt) + 1;
|
2005-11-01 17:37:44 +00:00
|
|
|
|
|
|
|
/* Subtract out the sizes of topwin and edit. */
|
|
|
|
mouse_y -= (2 - no_more_space()) + editwinrows;
|
|
|
|
|
|
|
|
/* Move to where the click occurred. */
|
|
|
|
if (mouse_x > start_col && mouse_y == 0) {
|
2005-11-07 21:45:44 +00:00
|
|
|
size_t pww_save = statusbar_pww;
|
|
|
|
|
2005-11-01 17:37:44 +00:00
|
|
|
statusbar_x = actual_x(answer,
|
|
|
|
get_statusbar_page_start(start_col, start_col +
|
|
|
|
statusbar_xplustabs()) + mouse_x - start_col -
|
|
|
|
1);
|
2005-11-07 06:32:07 +00:00
|
|
|
statusbar_pww = statusbar_xplustabs();
|
2005-11-07 21:45:44 +00:00
|
|
|
|
|
|
|
if (need_statusbar_horizontal_update(pww_save))
|
|
|
|
update_statusbar_line(answer, statusbar_x);
|
2005-11-01 17:37:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* The user typed output_len multibyte characters. Add them to the
|
|
|
|
* statusbar prompt, setting got_enter to TRUE if we get a newline, and
|
|
|
|
* filtering out all control characters if allow_cntrls is TRUE. */
|
|
|
|
void do_statusbar_output(char *output, size_t output_len, bool
|
|
|
|
*got_enter, bool allow_cntrls)
|
|
|
|
{
|
|
|
|
size_t answer_len, i = 0;
|
|
|
|
char *char_buf = charalloc(mb_cur_max());
|
|
|
|
int char_buf_len;
|
|
|
|
|
|
|
|
assert(answer != NULL);
|
|
|
|
|
|
|
|
answer_len = strlen(answer);
|
|
|
|
*got_enter = FALSE;
|
|
|
|
|
|
|
|
while (i < output_len) {
|
|
|
|
/* If allow_cntrls is FALSE, filter out nulls and newlines,
|
|
|
|
* since they're control characters. */
|
|
|
|
if (allow_cntrls) {
|
|
|
|
/* Null to newline, if needed. */
|
|
|
|
if (output[i] == '\0')
|
|
|
|
output[i] = '\n';
|
|
|
|
/* Newline to Enter, if needed. */
|
|
|
|
else if (output[i] == '\n') {
|
|
|
|
/* Set got_enter to TRUE to indicate that we got the
|
|
|
|
* Enter key, put back the rest of the characters in
|
|
|
|
* output so that they can be parsed and output again,
|
|
|
|
* and get out. */
|
|
|
|
*got_enter = TRUE;
|
|
|
|
unparse_kbinput(output + i, output_len - i);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Interpret the next multibyte character. */
|
|
|
|
char_buf_len = parse_mbchar(output + i, char_buf, NULL);
|
|
|
|
|
|
|
|
i += char_buf_len;
|
|
|
|
|
|
|
|
/* If allow_cntrls is FALSE, filter out a control character. */
|
|
|
|
if (!allow_cntrls && is_cntrl_mbchar(output + i - char_buf_len))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* More dangerousness fun =) */
|
|
|
|
answer = charealloc(answer, answer_len + (char_buf_len * 2));
|
|
|
|
|
|
|
|
assert(statusbar_x <= answer_len);
|
|
|
|
|
2005-11-05 04:59:00 +00:00
|
|
|
charmove(answer + statusbar_x + char_buf_len,
|
|
|
|
answer + statusbar_x, answer_len - statusbar_x +
|
2005-11-01 17:37:44 +00:00
|
|
|
char_buf_len);
|
2005-11-05 04:59:00 +00:00
|
|
|
strncpy(answer + statusbar_x, char_buf, char_buf_len);
|
2005-11-01 17:37:44 +00:00
|
|
|
answer_len += char_buf_len;
|
|
|
|
|
|
|
|
statusbar_x += char_buf_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(char_buf);
|
2005-11-07 06:32:07 +00:00
|
|
|
|
|
|
|
statusbar_pww = statusbar_xplustabs();
|
|
|
|
|
2005-11-07 21:45:44 +00:00
|
|
|
update_statusbar_line(answer, statusbar_x);
|
2005-11-01 17:37:44 +00:00
|
|
|
}
|
|
|
|
|
2005-12-08 07:09:08 +00:00
|
|
|
/* Move to the beginning of the prompt text. If the SMART_HOME flag is
|
|
|
|
* set, move to the first non-whitespace character of the prompt text if
|
|
|
|
* we're not already there, or to the beginning of the prompt text if we
|
|
|
|
* are. */
|
2005-11-01 17:37:44 +00:00
|
|
|
void do_statusbar_home(void)
|
|
|
|
{
|
2005-11-07 21:45:44 +00:00
|
|
|
size_t pww_save = statusbar_pww;
|
|
|
|
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2005-11-01 17:37:44 +00:00
|
|
|
if (ISSET(SMART_HOME)) {
|
|
|
|
size_t statusbar_x_save = statusbar_x;
|
|
|
|
|
|
|
|
statusbar_x = indent_length(answer);
|
|
|
|
|
|
|
|
if (statusbar_x == statusbar_x_save ||
|
|
|
|
statusbar_x == strlen(answer))
|
|
|
|
statusbar_x = 0;
|
2005-11-07 06:32:07 +00:00
|
|
|
|
|
|
|
statusbar_pww = statusbar_xplustabs();
|
|
|
|
} else {
|
2005-11-01 17:37:44 +00:00
|
|
|
#endif
|
|
|
|
statusbar_x = 0;
|
2005-11-07 06:32:07 +00:00
|
|
|
statusbar_pww = statusbar_xplustabs();
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2005-11-07 06:32:07 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2005-11-07 21:45:44 +00:00
|
|
|
if (need_statusbar_horizontal_update(pww_save))
|
|
|
|
update_statusbar_line(answer, statusbar_x);
|
2005-11-01 17:37:44 +00:00
|
|
|
}
|
|
|
|
|
2005-12-08 07:09:08 +00:00
|
|
|
/* Move to the end of the prompt text. */
|
2005-11-01 17:37:44 +00:00
|
|
|
void do_statusbar_end(void)
|
|
|
|
{
|
2005-11-07 21:45:44 +00:00
|
|
|
size_t pww_save = statusbar_pww;
|
|
|
|
|
2005-11-01 17:37:44 +00:00
|
|
|
statusbar_x = strlen(answer);
|
2005-11-07 06:32:07 +00:00
|
|
|
statusbar_pww = statusbar_xplustabs();
|
|
|
|
|
2005-11-07 21:45:44 +00:00
|
|
|
if (need_statusbar_horizontal_update(pww_save))
|
|
|
|
update_statusbar_line(answer, statusbar_x);
|
2005-11-01 17:37:44 +00:00
|
|
|
}
|
|
|
|
|
2005-12-08 07:09:08 +00:00
|
|
|
/* Move left one character. */
|
|
|
|
void do_statusbar_left(void)
|
2005-11-01 17:37:44 +00:00
|
|
|
{
|
2005-12-08 07:09:08 +00:00
|
|
|
if (statusbar_x > 0) {
|
2005-11-07 21:45:44 +00:00
|
|
|
size_t pww_save = statusbar_pww;
|
|
|
|
|
2005-12-08 07:09:08 +00:00
|
|
|
statusbar_x = move_mbleft(answer, statusbar_x);
|
2005-11-07 06:32:07 +00:00
|
|
|
statusbar_pww = statusbar_xplustabs();
|
|
|
|
|
2005-11-07 21:45:44 +00:00
|
|
|
if (need_statusbar_horizontal_update(pww_save))
|
|
|
|
update_statusbar_line(answer, statusbar_x);
|
2005-11-07 06:32:07 +00:00
|
|
|
}
|
2005-11-01 17:37:44 +00:00
|
|
|
}
|
|
|
|
|
2005-12-08 07:09:08 +00:00
|
|
|
/* Move right one character. */
|
|
|
|
void do_statusbar_right(void)
|
2005-11-01 17:37:44 +00:00
|
|
|
{
|
2005-12-08 07:09:08 +00:00
|
|
|
if (statusbar_x < strlen(answer)) {
|
2005-11-07 21:45:44 +00:00
|
|
|
size_t pww_save = statusbar_pww;
|
|
|
|
|
2005-12-08 07:09:08 +00:00
|
|
|
statusbar_x = move_mbright(answer, statusbar_x);
|
2005-11-07 06:32:07 +00:00
|
|
|
statusbar_pww = statusbar_xplustabs();
|
|
|
|
|
2005-11-07 21:45:44 +00:00
|
|
|
if (need_statusbar_horizontal_update(pww_save))
|
|
|
|
update_statusbar_line(answer, statusbar_x);
|
2005-11-07 06:32:07 +00:00
|
|
|
}
|
2005-11-01 17:37:44 +00:00
|
|
|
}
|
|
|
|
|
2005-12-08 07:09:08 +00:00
|
|
|
/* Backspace over one character. */
|
2005-11-01 17:37:44 +00:00
|
|
|
void do_statusbar_backspace(void)
|
|
|
|
{
|
|
|
|
if (statusbar_x > 0) {
|
|
|
|
do_statusbar_left();
|
|
|
|
do_statusbar_delete();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-12-08 07:09:08 +00:00
|
|
|
/* Delete one character. */
|
2005-11-01 17:37:44 +00:00
|
|
|
void do_statusbar_delete(void)
|
|
|
|
{
|
2005-11-07 06:32:07 +00:00
|
|
|
statusbar_pww = statusbar_xplustabs();
|
|
|
|
|
2005-11-01 17:37:44 +00:00
|
|
|
if (answer[statusbar_x] != '\0') {
|
|
|
|
int char_buf_len = parse_mbchar(answer + statusbar_x, NULL,
|
|
|
|
NULL);
|
|
|
|
size_t line_len = strlen(answer + statusbar_x);
|
|
|
|
|
|
|
|
assert(statusbar_x < strlen(answer));
|
|
|
|
|
|
|
|
charmove(answer + statusbar_x, answer + statusbar_x +
|
|
|
|
char_buf_len, strlen(answer) - statusbar_x -
|
|
|
|
char_buf_len + 1);
|
|
|
|
|
|
|
|
null_at(&answer, statusbar_x + line_len - char_buf_len);
|
2005-11-07 21:45:44 +00:00
|
|
|
|
|
|
|
update_statusbar_line(answer, statusbar_x);
|
2005-11-01 17:37:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-12-08 07:09:08 +00:00
|
|
|
/* Move text from the prompt into oblivion. */
|
2005-11-01 17:37:44 +00:00
|
|
|
void do_statusbar_cut_text(void)
|
|
|
|
{
|
|
|
|
assert(answer != NULL);
|
|
|
|
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2005-11-01 17:37:44 +00:00
|
|
|
if (ISSET(CUT_TO_END))
|
|
|
|
null_at(&answer, statusbar_x);
|
|
|
|
else {
|
|
|
|
#endif
|
|
|
|
null_at(&answer, 0);
|
|
|
|
statusbar_x = 0;
|
2005-11-07 06:32:07 +00:00
|
|
|
statusbar_pww = statusbar_xplustabs();
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2005-11-01 17:37:44 +00:00
|
|
|
}
|
|
|
|
#endif
|
2005-11-07 06:32:07 +00:00
|
|
|
|
2005-11-07 21:45:44 +00:00
|
|
|
update_statusbar_line(answer, statusbar_x);
|
2005-11-01 17:37:44 +00:00
|
|
|
}
|
|
|
|
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2005-12-08 07:09:08 +00:00
|
|
|
/* Move to the next word in the prompt text. If allow_punct is TRUE,
|
|
|
|
* treat punctuation as part of a word. Return TRUE if we started on a
|
|
|
|
* word, and FALSE otherwise. */
|
2005-11-01 17:37:44 +00:00
|
|
|
bool do_statusbar_next_word(bool allow_punct)
|
|
|
|
{
|
2005-11-07 21:45:44 +00:00
|
|
|
size_t pww_save = statusbar_pww;
|
2005-11-01 17:37:44 +00:00
|
|
|
char *char_mb;
|
|
|
|
int char_mb_len;
|
|
|
|
bool end_line = FALSE, started_on_word = FALSE;
|
|
|
|
|
|
|
|
assert(answer != NULL);
|
|
|
|
|
|
|
|
char_mb = charalloc(mb_cur_max());
|
|
|
|
|
|
|
|
/* Move forward until we find the character after the last letter of
|
|
|
|
* the current word. */
|
|
|
|
while (!end_line) {
|
|
|
|
char_mb_len = parse_mbchar(answer + statusbar_x, char_mb, NULL);
|
|
|
|
|
|
|
|
/* If we've found it, stop moving forward through the current
|
|
|
|
* line. */
|
|
|
|
if (!is_word_mbchar(char_mb, allow_punct))
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* If we haven't found it, then we've started on a word, so set
|
|
|
|
* started_on_word to TRUE. */
|
|
|
|
started_on_word = TRUE;
|
|
|
|
|
|
|
|
if (answer[statusbar_x] == '\0')
|
|
|
|
end_line = TRUE;
|
|
|
|
else
|
|
|
|
statusbar_x += char_mb_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Move forward until we find the first letter of the next word. */
|
|
|
|
if (answer[statusbar_x] == '\0')
|
|
|
|
end_line = TRUE;
|
|
|
|
else
|
|
|
|
statusbar_x += char_mb_len;
|
|
|
|
|
|
|
|
while (!end_line) {
|
|
|
|
char_mb_len = parse_mbchar(answer + statusbar_x, char_mb, NULL);
|
|
|
|
|
|
|
|
/* If we've found it, stop moving forward through the current
|
|
|
|
* line. */
|
|
|
|
if (is_word_mbchar(char_mb, allow_punct))
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (answer[statusbar_x] == '\0')
|
|
|
|
end_line = TRUE;
|
|
|
|
else
|
|
|
|
statusbar_x += char_mb_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(char_mb);
|
|
|
|
|
2005-11-07 06:32:07 +00:00
|
|
|
statusbar_pww = statusbar_xplustabs();
|
|
|
|
|
2005-11-07 21:45:44 +00:00
|
|
|
if (need_statusbar_horizontal_update(pww_save))
|
|
|
|
update_statusbar_line(answer, statusbar_x);
|
2005-11-07 06:32:07 +00:00
|
|
|
|
2005-11-01 17:37:44 +00:00
|
|
|
/* Return whether we started on a word. */
|
|
|
|
return started_on_word;
|
|
|
|
}
|
|
|
|
|
2005-12-08 07:09:08 +00:00
|
|
|
/* Move to the previous word in the prompt text. If allow_punct is
|
2005-11-01 17:37:44 +00:00
|
|
|
* TRUE, treat punctuation as part of a word. Return TRUE if we started
|
|
|
|
* on a word, and FALSE otherwise. */
|
|
|
|
bool do_statusbar_prev_word(bool allow_punct)
|
|
|
|
{
|
2005-11-07 21:45:44 +00:00
|
|
|
size_t pww_save = statusbar_pww;
|
2005-11-01 17:37:44 +00:00
|
|
|
char *char_mb;
|
|
|
|
int char_mb_len;
|
|
|
|
bool begin_line = FALSE, started_on_word = FALSE;
|
|
|
|
|
|
|
|
assert(answer != NULL);
|
|
|
|
|
|
|
|
char_mb = charalloc(mb_cur_max());
|
|
|
|
|
|
|
|
/* Move backward until we find the character before the first letter
|
|
|
|
* of the current word. */
|
|
|
|
while (!begin_line) {
|
|
|
|
char_mb_len = parse_mbchar(answer + statusbar_x, char_mb, NULL);
|
|
|
|
|
|
|
|
/* If we've found it, stop moving backward through the current
|
|
|
|
* line. */
|
|
|
|
if (!is_word_mbchar(char_mb, allow_punct))
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* If we haven't found it, then we've started on a word, so set
|
|
|
|
* started_on_word to TRUE. */
|
|
|
|
started_on_word = TRUE;
|
|
|
|
|
|
|
|
if (statusbar_x == 0)
|
|
|
|
begin_line = TRUE;
|
|
|
|
else
|
|
|
|
statusbar_x = move_mbleft(answer, statusbar_x);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Move backward until we find the last letter of the previous
|
|
|
|
* word. */
|
|
|
|
if (statusbar_x == 0)
|
|
|
|
begin_line = TRUE;
|
|
|
|
else
|
|
|
|
statusbar_x = move_mbleft(answer, statusbar_x);
|
|
|
|
|
|
|
|
while (!begin_line) {
|
|
|
|
char_mb_len = parse_mbchar(answer + statusbar_x, char_mb, NULL);
|
|
|
|
|
|
|
|
/* If we've found it, stop moving backward through the current
|
|
|
|
* line. */
|
|
|
|
if (is_word_mbchar(char_mb, allow_punct))
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (statusbar_x == 0)
|
|
|
|
begin_line = TRUE;
|
|
|
|
else
|
|
|
|
statusbar_x = move_mbleft(answer, statusbar_x);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If we've found it, move backward until we find the character
|
|
|
|
* before the first letter of the previous word. */
|
|
|
|
if (!begin_line) {
|
|
|
|
if (statusbar_x == 0)
|
|
|
|
begin_line = TRUE;
|
|
|
|
else
|
|
|
|
statusbar_x = move_mbleft(answer, statusbar_x);
|
|
|
|
|
|
|
|
while (!begin_line) {
|
|
|
|
char_mb_len = parse_mbchar(answer + statusbar_x, char_mb,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
/* If we've found it, stop moving backward through the
|
|
|
|
* current line. */
|
|
|
|
if (!is_word_mbchar(char_mb, allow_punct))
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (statusbar_x == 0)
|
|
|
|
begin_line = TRUE;
|
|
|
|
else
|
|
|
|
statusbar_x = move_mbleft(answer, statusbar_x);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If we've found it, move forward to the first letter of the
|
|
|
|
* previous word. */
|
|
|
|
if (!begin_line)
|
|
|
|
statusbar_x += char_mb_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(char_mb);
|
|
|
|
|
2005-11-07 06:32:07 +00:00
|
|
|
statusbar_pww = statusbar_xplustabs();
|
|
|
|
|
2005-11-07 21:45:44 +00:00
|
|
|
if (need_statusbar_horizontal_update(pww_save))
|
|
|
|
update_statusbar_line(answer, statusbar_x);
|
2005-11-07 06:32:07 +00:00
|
|
|
|
2005-11-01 17:37:44 +00:00
|
|
|
/* Return whether we started on a word. */
|
|
|
|
return started_on_word;
|
|
|
|
}
|
2005-11-15 03:17:35 +00:00
|
|
|
#endif /* !NANO_TINY */
|
2005-11-01 17:37:44 +00:00
|
|
|
|
2005-12-08 07:09:08 +00:00
|
|
|
/* Get verbatim input. Set got_enter to TRUE if we got the Enter key as
|
|
|
|
* part of the verbatim input. */
|
2005-11-01 17:37:44 +00:00
|
|
|
void do_statusbar_verbatim_input(bool *got_enter)
|
|
|
|
{
|
|
|
|
int *kbinput;
|
|
|
|
size_t kbinput_len, i;
|
|
|
|
char *output;
|
|
|
|
|
|
|
|
*got_enter = FALSE;
|
|
|
|
|
|
|
|
/* Read in all the verbatim characters. */
|
|
|
|
kbinput = get_verbatim_kbinput(bottomwin, &kbinput_len);
|
|
|
|
|
|
|
|
/* Display all the verbatim characters at once, not filtering out
|
|
|
|
* control characters. */
|
|
|
|
output = charalloc(kbinput_len + 1);
|
|
|
|
|
|
|
|
for (i = 0; i < kbinput_len; i++)
|
|
|
|
output[i] = (char)kbinput[i];
|
|
|
|
output[i] = '\0';
|
|
|
|
|
|
|
|
do_statusbar_output(output, kbinput_len, got_enter, TRUE);
|
|
|
|
|
|
|
|
free(output);
|
|
|
|
}
|
|
|
|
|
2005-11-16 04:14:03 +00:00
|
|
|
#ifndef NANO_TINY
|
2005-12-08 07:09:08 +00:00
|
|
|
/* Search for a match to one of the two characters in bracket_set. If
|
|
|
|
* reverse is TRUE, search backwards for the leftmost bracket.
|
|
|
|
* Otherwise, search forwards for the rightmost bracket. Return TRUE if
|
|
|
|
* we found a match, and FALSE otherwise. */
|
2005-11-16 13:45:41 +00:00
|
|
|
bool find_statusbar_bracket_match(bool reverse, const char
|
|
|
|
*bracket_set)
|
|
|
|
{
|
|
|
|
const char *rev_start = NULL, *found = NULL;
|
|
|
|
|
2006-01-06 07:10:30 +00:00
|
|
|
assert(mbstrlen(bracket_set) == 2);
|
2005-11-16 13:45:41 +00:00
|
|
|
|
|
|
|
/* rev_start might end up 1 character before the start or after the
|
|
|
|
* end of the line. This won't be a problem because we'll skip over
|
|
|
|
* it below in that case. */
|
|
|
|
rev_start = reverse ? answer + (statusbar_x - 1) : answer +
|
|
|
|
(statusbar_x + 1);
|
|
|
|
|
|
|
|
while (TRUE) {
|
|
|
|
/* Look for either of the two characters in bracket_set.
|
|
|
|
* rev_start can be 1 character before the start or after the
|
|
|
|
* end of the line. In either case, just act as though no match
|
|
|
|
* is found. */
|
|
|
|
found = ((rev_start > answer && *(rev_start - 1) == '\0') ||
|
|
|
|
rev_start < answer) ? NULL : (reverse ?
|
2006-01-06 07:10:30 +00:00
|
|
|
mbrevstrpbrk(answer, bracket_set, rev_start) :
|
|
|
|
mbstrpbrk(rev_start, bracket_set));
|
2005-11-16 13:45:41 +00:00
|
|
|
|
|
|
|
/* We've found a potential match. */
|
|
|
|
if (found != NULL)
|
|
|
|
break;
|
2005-11-16 13:57:21 +00:00
|
|
|
|
|
|
|
/* We've reached the start or end of the statusbar text, so
|
|
|
|
* get out. */
|
|
|
|
return FALSE;
|
2005-11-16 13:45:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* We've definitely found something. */
|
|
|
|
statusbar_x = found - answer;
|
|
|
|
statusbar_pww = statusbar_xplustabs();
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2005-12-08 07:09:08 +00:00
|
|
|
/* Search for a match to the bracket at the current cursor position, if
|
|
|
|
* there is one. */
|
2005-11-16 04:14:03 +00:00
|
|
|
void do_statusbar_find_bracket(void)
|
|
|
|
{
|
|
|
|
size_t statusbar_x_save, pww_save;
|
2006-01-06 07:10:30 +00:00
|
|
|
const char *ch;
|
2006-01-06 21:51:10 +00:00
|
|
|
/* The location in matchbrackets of the bracket at the current
|
2005-11-16 04:14:03 +00:00
|
|
|
* cursor position. */
|
2006-01-06 07:10:30 +00:00
|
|
|
int ch_len;
|
|
|
|
/* The length of ch in bytes. */
|
|
|
|
const char *wanted_ch;
|
2006-01-06 21:51:10 +00:00
|
|
|
/* The location in matchbrackets of the bracket complementing
|
|
|
|
* the bracket at the current cursor position. */
|
2006-01-06 07:10:30 +00:00
|
|
|
int wanted_ch_len;
|
|
|
|
/* The length of wanted_ch in bytes. */
|
|
|
|
char *bracket_set;
|
2005-11-16 04:14:03 +00:00
|
|
|
/* The pair of characters in ch and wanted_ch. */
|
2006-01-06 22:35:52 +00:00
|
|
|
size_t i;
|
|
|
|
/* Generic loop variable. */
|
2006-01-06 21:51:10 +00:00
|
|
|
size_t matchhalf;
|
2006-01-06 22:35:52 +00:00
|
|
|
/* The number of single-byte characters in one half of
|
|
|
|
* matchbrackets. */
|
|
|
|
size_t mbmatchhalf;
|
|
|
|
/* The number of multibyte characters in one half of
|
|
|
|
* matchbrackets. */
|
2005-11-16 04:14:03 +00:00
|
|
|
size_t count = 1;
|
|
|
|
/* The initial bracket count. */
|
|
|
|
bool reverse;
|
|
|
|
/* The direction we search. */
|
2006-01-06 07:10:30 +00:00
|
|
|
char *found_ch;
|
|
|
|
/* The character we find. */
|
2005-11-16 04:14:03 +00:00
|
|
|
|
2006-01-06 21:51:10 +00:00
|
|
|
assert(mbstrlen(matchbrackets) % 2 == 0);
|
2005-11-16 04:14:03 +00:00
|
|
|
|
2006-01-06 07:10:30 +00:00
|
|
|
ch = answer + statusbar_x;
|
2005-11-16 04:14:03 +00:00
|
|
|
|
2006-01-06 21:51:10 +00:00
|
|
|
if (ch == '\0' || (ch = mbstrchr(matchbrackets, ch)) == NULL)
|
2005-11-16 04:14:03 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
/* Save where we are. */
|
|
|
|
statusbar_x_save = statusbar_x;
|
|
|
|
pww_save = statusbar_pww;
|
|
|
|
|
2006-01-06 07:10:30 +00:00
|
|
|
/* If we're on an opening bracket, which must be in the first half
|
2006-01-06 21:51:10 +00:00
|
|
|
* of matchbrackets, we want to search forwards for a closing
|
2006-01-06 07:10:30 +00:00
|
|
|
* bracket. If we're on a closing bracket, which must be in the
|
2006-01-06 21:51:10 +00:00
|
|
|
* second half of matchbrackets, we want to search backwards for an
|
2006-01-06 07:10:30 +00:00
|
|
|
* opening bracket. */
|
2006-01-06 22:35:52 +00:00
|
|
|
matchhalf = 0;
|
|
|
|
mbmatchhalf = mbstrlen(matchbrackets) / 2;
|
|
|
|
|
|
|
|
for (i = 0; i < mbmatchhalf; i++)
|
|
|
|
matchhalf += parse_mbchar(matchbrackets + matchhalf, NULL,
|
|
|
|
NULL);
|
|
|
|
|
2006-01-28 06:04:59 +00:00
|
|
|
reverse = ((ch - matchbrackets) >= matchhalf);
|
2006-01-06 07:10:30 +00:00
|
|
|
|
|
|
|
/* If we're on an opening bracket, set wanted_ch to the character
|
2006-01-06 21:51:10 +00:00
|
|
|
* that's matchhalf characters after ch. If we're on a closing
|
|
|
|
* bracket, set wanted_ch to the character that's matchhalf
|
|
|
|
* characters before ch. */
|
2006-01-06 07:10:30 +00:00
|
|
|
wanted_ch = ch;
|
|
|
|
|
2006-01-06 22:35:52 +00:00
|
|
|
while (mbmatchhalf > 0) {
|
2006-01-06 07:10:30 +00:00
|
|
|
if (reverse)
|
2006-01-06 21:51:10 +00:00
|
|
|
wanted_ch = matchbrackets + move_mbleft(matchbrackets,
|
|
|
|
wanted_ch - matchbrackets);
|
2006-01-06 07:10:30 +00:00
|
|
|
else
|
|
|
|
wanted_ch += move_mbright(wanted_ch, 0);
|
|
|
|
|
2006-01-06 22:35:52 +00:00
|
|
|
mbmatchhalf--;
|
2006-01-06 07:10:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ch_len = parse_mbchar(ch, NULL, NULL);
|
|
|
|
wanted_ch_len = parse_mbchar(wanted_ch, NULL, NULL);
|
|
|
|
|
|
|
|
/* Fill bracket_set in with the values of ch and wanted_ch. */
|
|
|
|
bracket_set = charalloc((mb_cur_max() * 2) + 1);
|
|
|
|
strncpy(bracket_set, ch, ch_len);
|
|
|
|
strncpy(bracket_set + ch_len, wanted_ch, wanted_ch_len);
|
|
|
|
null_at(&bracket_set, ch_len + wanted_ch_len);
|
|
|
|
|
|
|
|
found_ch = charalloc(mb_cur_max() + 1);
|
2005-11-16 04:14:03 +00:00
|
|
|
|
|
|
|
while (TRUE) {
|
2005-11-16 13:45:41 +00:00
|
|
|
if (find_statusbar_bracket_match(reverse, bracket_set)) {
|
2005-11-16 04:14:03 +00:00
|
|
|
/* If we found an identical bracket, increment count. If we
|
|
|
|
* found a complementary bracket, decrement it. */
|
2006-01-06 07:10:30 +00:00
|
|
|
parse_mbchar(answer + statusbar_x, found_ch, NULL);
|
|
|
|
count += (strncmp(found_ch, ch, ch_len) == 0) ? 1 : -1;
|
2005-11-16 04:14:03 +00:00
|
|
|
|
|
|
|
/* If count is zero, we've found a matching bracket. Update
|
|
|
|
* the statusbar prompt and get out. */
|
|
|
|
if (count == 0) {
|
|
|
|
if (need_statusbar_horizontal_update(pww_save))
|
|
|
|
update_statusbar_line(answer, statusbar_x);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* We didn't find either an opening or closing bracket.
|
|
|
|
* Restore where we were, and get out. */
|
|
|
|
statusbar_x = statusbar_x_save;
|
|
|
|
statusbar_pww = pww_save;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2006-01-06 07:10:30 +00:00
|
|
|
|
|
|
|
/* Clean up. */
|
|
|
|
free(bracket_set);
|
|
|
|
free(found_ch);
|
2005-11-16 04:14:03 +00:00
|
|
|
}
|
|
|
|
#endif /* !NANO_TINY */
|
|
|
|
|
2005-11-01 17:37:44 +00:00
|
|
|
/* Return the placewewant associated with statusbar_x, i.e, the
|
|
|
|
* zero-based column position of the cursor. The value will be no
|
|
|
|
* smaller than statusbar_x. */
|
|
|
|
size_t statusbar_xplustabs(void)
|
|
|
|
{
|
|
|
|
return strnlenpt(answer, statusbar_x);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* nano scrolls horizontally within a line in chunks. This function
|
|
|
|
* returns the column number of the first character displayed in the
|
|
|
|
* statusbar prompt when the cursor is at the given column with the
|
|
|
|
* prompt ending at start_col. Note that (0 <= column -
|
|
|
|
* get_statusbar_page_start(column) < COLS). */
|
|
|
|
size_t get_statusbar_page_start(size_t start_col, size_t column)
|
|
|
|
{
|
|
|
|
if (column == start_col || column < COLS - 1)
|
|
|
|
return 0;
|
|
|
|
else
|
|
|
|
return column - start_col - (column - start_col) % (COLS -
|
|
|
|
start_col - 1);
|
|
|
|
}
|
|
|
|
|
2005-11-07 21:45:44 +00:00
|
|
|
/* Repaint the statusbar when getting a character in
|
|
|
|
* get_prompt_string(). The statusbar text line will be displayed
|
2006-04-12 14:34:08 +00:00
|
|
|
* starting with curranswer[index]. */
|
2005-11-07 21:45:44 +00:00
|
|
|
void update_statusbar_line(const char *curranswer, size_t index)
|
2005-11-01 17:37:44 +00:00
|
|
|
{
|
2005-11-07 21:45:44 +00:00
|
|
|
size_t start_col, page_start;
|
2005-11-01 17:37:44 +00:00
|
|
|
char *expanded;
|
|
|
|
|
2005-12-01 05:49:08 +00:00
|
|
|
assert(prompt != NULL && index <= strlen(curranswer));
|
2005-11-01 17:37:44 +00:00
|
|
|
|
|
|
|
start_col = strlenpt(prompt) + 1;
|
2005-11-07 21:45:44 +00:00
|
|
|
index = strnlenpt(curranswer, index);
|
|
|
|
page_start = get_statusbar_page_start(start_col, start_col + index);
|
2005-11-01 17:37:44 +00:00
|
|
|
|
2006-04-12 15:27:40 +00:00
|
|
|
wattron(bottomwin, reverse_attr);
|
2005-11-01 17:37:44 +00:00
|
|
|
|
|
|
|
blank_statusbar();
|
|
|
|
|
|
|
|
mvwaddnstr(bottomwin, 0, 0, prompt, actual_x(prompt, COLS - 2));
|
|
|
|
waddch(bottomwin, ':');
|
|
|
|
waddch(bottomwin, (page_start == 0) ? ' ' : '$');
|
|
|
|
|
2005-11-07 21:45:44 +00:00
|
|
|
expanded = display_string(curranswer, page_start, COLS - start_col -
|
|
|
|
1, FALSE);
|
2005-11-01 17:37:44 +00:00
|
|
|
waddstr(bottomwin, expanded);
|
|
|
|
free(expanded);
|
|
|
|
|
2005-11-07 21:45:44 +00:00
|
|
|
reset_statusbar_cursor();
|
2005-11-01 17:37:44 +00:00
|
|
|
|
2006-04-12 15:27:40 +00:00
|
|
|
wattroff(bottomwin, reverse_attr);
|
2005-11-01 17:37:44 +00:00
|
|
|
}
|
|
|
|
|
2005-11-07 21:45:44 +00:00
|
|
|
/* Put the cursor in the statusbar prompt at statusbar_x. */
|
|
|
|
void reset_statusbar_cursor(void)
|
|
|
|
{
|
|
|
|
size_t start_col = strlenpt(prompt) + 1;
|
2005-11-16 03:14:11 +00:00
|
|
|
size_t xpt = statusbar_xplustabs();
|
2005-11-07 21:45:44 +00:00
|
|
|
|
2005-11-16 03:14:11 +00:00
|
|
|
wmove(bottomwin, 0, start_col + 1 + xpt -
|
|
|
|
get_statusbar_page_start(start_col, start_col + xpt));
|
2005-11-07 21:45:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Return TRUE if we need an update after moving horizontally, and FALSE
|
|
|
|
* otherwise. We need one if old_pww and statusbar_pww are on different
|
|
|
|
* pages. */
|
|
|
|
bool need_statusbar_horizontal_update(size_t old_pww)
|
|
|
|
{
|
|
|
|
size_t start_col = strlenpt(prompt) + 1;
|
|
|
|
|
|
|
|
return get_statusbar_page_start(start_col, start_col + old_pww) !=
|
|
|
|
get_statusbar_page_start(start_col, start_col + statusbar_pww);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get a string of input at the statusbar prompt. This should only be
|
|
|
|
* called from do_prompt(). */
|
2006-02-07 21:11:05 +00:00
|
|
|
int get_prompt_string(bool allow_tabs,
|
|
|
|
#ifndef DISABLE_TABCOMP
|
|
|
|
bool allow_files,
|
|
|
|
#endif
|
|
|
|
const char *curranswer,
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2005-11-01 17:37:44 +00:00
|
|
|
filestruct **history_list,
|
|
|
|
#endif
|
2006-02-18 21:32:29 +00:00
|
|
|
void (*refresh_func)(void), const shortcut *s
|
2005-11-01 17:37:44 +00:00
|
|
|
#ifndef DISABLE_TABCOMP
|
|
|
|
, bool *list
|
|
|
|
#endif
|
|
|
|
)
|
|
|
|
{
|
2006-02-08 20:14:49 +00:00
|
|
|
int kbinput = ERR;
|
2006-02-09 22:42:14 +00:00
|
|
|
bool meta_key, func_key, s_or_t, ran_func, finished;
|
2005-11-01 17:37:44 +00:00
|
|
|
size_t curranswer_len;
|
|
|
|
#ifndef DISABLE_TABCOMP
|
|
|
|
bool tabbed = FALSE;
|
|
|
|
/* Whether we've pressed Tab. */
|
|
|
|
#endif
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2005-11-01 17:37:44 +00:00
|
|
|
char *history = NULL;
|
|
|
|
/* The current history string. */
|
|
|
|
char *magichistory = NULL;
|
|
|
|
/* The temporary string typed at the bottom of the history, if
|
|
|
|
* any. */
|
|
|
|
#ifndef DISABLE_TABCOMP
|
|
|
|
int last_kbinput = ERR;
|
|
|
|
/* The key we pressed before the current key. */
|
|
|
|
size_t complete_len = 0;
|
|
|
|
/* The length of the original string that we're trying to
|
|
|
|
* tab complete, if any. */
|
|
|
|
#endif
|
2005-11-15 03:17:35 +00:00
|
|
|
#endif /* !NANO_TINY */
|
2005-11-01 17:37:44 +00:00
|
|
|
|
|
|
|
answer = mallocstrcpy(answer, curranswer);
|
|
|
|
curranswer_len = strlen(answer);
|
|
|
|
|
2005-11-07 06:32:07 +00:00
|
|
|
/* Only put statusbar_x at the end of the string (and change
|
|
|
|
* statusbar_pww to match) if it's uninitialized, if it would be
|
|
|
|
* past the end of curranswer, or if reset_statusbar_x is TRUE.
|
|
|
|
* Otherwise, leave it alone. This is so the cursor position stays
|
|
|
|
* at the same place if a prompt-changing toggle is pressed. */
|
2005-11-01 17:37:44 +00:00
|
|
|
if (statusbar_x == (size_t)-1 || statusbar_x > curranswer_len ||
|
2005-11-07 06:32:07 +00:00
|
|
|
reset_statusbar_x) {
|
2005-11-01 17:37:44 +00:00
|
|
|
statusbar_x = curranswer_len;
|
2005-11-07 06:32:07 +00:00
|
|
|
statusbar_pww = statusbar_xplustabs();
|
|
|
|
}
|
2005-11-01 17:37:44 +00:00
|
|
|
|
|
|
|
currshortcut = s;
|
|
|
|
|
2005-11-07 21:45:44 +00:00
|
|
|
update_statusbar_line(answer, statusbar_x);
|
2005-11-01 17:37:44 +00:00
|
|
|
|
|
|
|
/* Refresh the edit window and the statusbar before getting
|
|
|
|
* input. */
|
|
|
|
wnoutrefresh(edit);
|
|
|
|
wnoutrefresh(bottomwin);
|
|
|
|
|
|
|
|
/* If we're using restricted mode, we aren't allowed to change the
|
|
|
|
* name of a file once it has one because that would allow writing
|
|
|
|
* to files not specified on the command line. In this case,
|
|
|
|
* disable all keys that would change the text if the filename isn't
|
|
|
|
* blank and we're at the "Write File" prompt. */
|
2006-02-09 22:42:14 +00:00
|
|
|
while ((kbinput = do_statusbar_input(&meta_key, &func_key, &s_or_t,
|
2006-02-18 21:32:29 +00:00
|
|
|
&ran_func, &finished, TRUE, refresh_func)) != NANO_CANCEL_KEY &&
|
|
|
|
kbinput != NANO_ENTER_KEY) {
|
2005-11-01 17:37:44 +00:00
|
|
|
assert(statusbar_x <= strlen(answer));
|
|
|
|
|
|
|
|
#ifndef DISABLE_TABCOMP
|
|
|
|
if (kbinput != NANO_TAB_KEY)
|
|
|
|
tabbed = FALSE;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
switch (kbinput) {
|
|
|
|
#ifndef DISABLE_TABCOMP
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2005-11-16 21:34:46 +00:00
|
|
|
case NANO_TAB_KEY:
|
2005-11-01 17:37:44 +00:00
|
|
|
if (history_list != NULL) {
|
|
|
|
if (last_kbinput != NANO_TAB_KEY)
|
|
|
|
complete_len = strlen(answer);
|
|
|
|
|
|
|
|
if (complete_len > 0) {
|
|
|
|
answer = mallocstrcpy(answer,
|
|
|
|
get_history_completion(history_list,
|
|
|
|
answer, complete_len));
|
|
|
|
statusbar_x = strlen(answer);
|
|
|
|
}
|
|
|
|
} else
|
2005-11-15 03:17:35 +00:00
|
|
|
#endif /* !NANO_TINY */
|
2005-11-01 17:37:44 +00:00
|
|
|
if (allow_tabs)
|
2006-02-07 21:11:05 +00:00
|
|
|
answer = input_tab(answer, allow_files,
|
2006-02-18 21:32:29 +00:00
|
|
|
&statusbar_x, &tabbed, refresh_func, list);
|
2005-11-08 01:49:14 +00:00
|
|
|
|
|
|
|
update_statusbar_line(answer, statusbar_x);
|
2005-11-01 17:37:44 +00:00
|
|
|
break;
|
2005-11-16 21:34:46 +00:00
|
|
|
#endif /* !DISABLE_TABCOMP */
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2005-11-16 21:34:46 +00:00
|
|
|
case NANO_PREVLINE_KEY:
|
2005-11-01 17:37:44 +00:00
|
|
|
if (history_list != NULL) {
|
|
|
|
/* If we're scrolling up at the bottom of the
|
|
|
|
* history list and answer isn't blank, save answer
|
|
|
|
* in magichistory. */
|
|
|
|
if ((*history_list)->next == NULL &&
|
|
|
|
answer[0] != '\0')
|
|
|
|
magichistory = mallocstrcpy(magichistory,
|
|
|
|
answer);
|
|
|
|
|
|
|
|
/* Get the older search from the history list and
|
|
|
|
* save it in answer. If there is no older search,
|
|
|
|
* don't do anything. */
|
|
|
|
if ((history =
|
|
|
|
get_history_older(history_list)) != NULL) {
|
|
|
|
answer = mallocstrcpy(answer, history);
|
|
|
|
statusbar_x = strlen(answer);
|
|
|
|
}
|
|
|
|
|
2005-11-08 01:49:14 +00:00
|
|
|
update_statusbar_line(answer, statusbar_x);
|
|
|
|
|
2005-11-01 17:37:44 +00:00
|
|
|
/* This key has a shortcut list entry when it's used
|
|
|
|
* to move to an older search, which means that
|
|
|
|
* finished has been set to TRUE. Set it back to
|
|
|
|
* FALSE here, so that we aren't kicked out of the
|
|
|
|
* statusbar prompt. */
|
|
|
|
finished = FALSE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case NANO_NEXTLINE_KEY:
|
|
|
|
if (history_list != NULL) {
|
|
|
|
/* Get the newer search from the history list and
|
|
|
|
* save it in answer. If there is no newer search,
|
|
|
|
* don't do anything. */
|
|
|
|
if ((history =
|
|
|
|
get_history_newer(history_list)) != NULL) {
|
|
|
|
answer = mallocstrcpy(answer, history);
|
|
|
|
statusbar_x = strlen(answer);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If, after scrolling down, we're at the bottom of
|
|
|
|
* the history list, answer is blank, and
|
|
|
|
* magichistory is set, save magichistory in
|
|
|
|
* answer. */
|
|
|
|
if ((*history_list)->next == NULL &&
|
|
|
|
answer[0] == '\0' && magichistory != NULL) {
|
|
|
|
answer = mallocstrcpy(answer, magichistory);
|
|
|
|
statusbar_x = strlen(answer);
|
|
|
|
}
|
2005-11-08 01:49:14 +00:00
|
|
|
|
|
|
|
update_statusbar_line(answer, statusbar_x);
|
2005-11-01 17:37:44 +00:00
|
|
|
}
|
|
|
|
break;
|
2005-11-16 21:34:46 +00:00
|
|
|
#endif /* !NANO_TINY */
|
2006-02-09 21:43:14 +00:00
|
|
|
#ifndef DISABLE_HELP
|
|
|
|
case NANO_HELP_KEY:
|
|
|
|
update_statusbar_line(answer, statusbar_x);
|
|
|
|
|
|
|
|
/* This key has a shortcut list entry when it's used to
|
|
|
|
* to go to the help browser, which means that finished
|
|
|
|
* has been set to TRUE. Set it back to FALSE here, so
|
|
|
|
* that we aren't kicked out of the statusbar prompt. */
|
|
|
|
finished = FALSE;
|
|
|
|
break;
|
|
|
|
#endif /* !DISABLE_HELP */
|
2005-11-01 17:37:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* If we have a shortcut with an associated function, break out
|
|
|
|
* if we're finished after running or trying to run the
|
|
|
|
* function. */
|
|
|
|
if (finished)
|
|
|
|
break;
|
|
|
|
|
2005-11-15 03:17:35 +00:00
|
|
|
#if !defined(NANO_TINY) && !defined(DISABLE_TABCOMP)
|
2005-11-01 17:37:44 +00:00
|
|
|
last_kbinput = kbinput;
|
|
|
|
#endif
|
|
|
|
|
2005-11-07 21:45:44 +00:00
|
|
|
reset_statusbar_cursor();
|
2006-02-09 22:42:14 +00:00
|
|
|
}
|
2005-11-01 17:37:44 +00:00
|
|
|
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2005-11-01 17:37:44 +00:00
|
|
|
/* Set the current position in the history list to the bottom and
|
|
|
|
* free magichistory, if we need to. */
|
|
|
|
if (history_list != NULL) {
|
|
|
|
history_reset(*history_list);
|
|
|
|
|
|
|
|
if (magichistory != NULL)
|
|
|
|
free(magichistory);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* We finished putting in an answer or ran a normal shortcut's
|
2005-11-07 06:32:07 +00:00
|
|
|
* associated function, so reset statusbar_x and statusbar_pww. */
|
2005-11-01 17:37:44 +00:00
|
|
|
if (kbinput == NANO_CANCEL_KEY || kbinput == NANO_ENTER_KEY ||
|
2005-11-07 06:32:07 +00:00
|
|
|
ran_func) {
|
2005-11-01 17:37:44 +00:00
|
|
|
statusbar_x = (size_t)-1;
|
2005-11-07 06:32:07 +00:00
|
|
|
statusbar_pww = (size_t)-1;
|
|
|
|
}
|
2005-11-01 17:37:44 +00:00
|
|
|
|
|
|
|
return kbinput;
|
|
|
|
}
|
|
|
|
|
2005-11-07 21:45:44 +00:00
|
|
|
/* Ask a question on the statusbar. The prompt will be stored in the
|
|
|
|
* static prompt, which should be NULL initially, and the answer will be
|
|
|
|
* stored in the answer global. Returns -1 on aborted enter, -2 on a
|
|
|
|
* blank string, and 0 otherwise, the valid shortcut key caught.
|
2006-02-18 21:32:29 +00:00
|
|
|
* curranswer is any editable text that we want to put up by default,
|
|
|
|
* and refresh_func is the function we want to call to refresh the edit
|
|
|
|
* window.
|
2005-11-01 17:37:44 +00:00
|
|
|
*
|
|
|
|
* The allow_tabs parameter indicates whether we should allow tabs to be
|
2006-02-07 21:11:05 +00:00
|
|
|
* interpreted. The allow_files parameter indicates whether we should
|
|
|
|
* allow all files (as opposed to just directories) to be tab
|
|
|
|
* completed. */
|
|
|
|
int do_prompt(bool allow_tabs,
|
|
|
|
#ifndef DISABLE_TABCOMP
|
|
|
|
bool allow_files,
|
|
|
|
#endif
|
|
|
|
const shortcut *s, const char *curranswer,
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2005-11-01 17:37:44 +00:00
|
|
|
filestruct **history_list,
|
|
|
|
#endif
|
2006-02-18 21:32:29 +00:00
|
|
|
void (*refresh_func)(void), const char *msg, ...)
|
2005-11-01 17:37:44 +00:00
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
int retval;
|
|
|
|
#ifndef DISABLE_TABCOMP
|
|
|
|
bool list = FALSE;
|
|
|
|
#endif
|
|
|
|
|
2005-11-01 19:06:01 +00:00
|
|
|
/* prompt has been freed and set to NULL unless the user resized
|
|
|
|
* while at the statusbar prompt. */
|
|
|
|
if (prompt != NULL)
|
|
|
|
free(prompt);
|
2005-11-01 18:35:47 +00:00
|
|
|
|
2005-11-01 18:39:07 +00:00
|
|
|
prompt = charalloc(((COLS - 4) * mb_cur_max()) + 1);
|
2005-11-01 17:37:44 +00:00
|
|
|
|
|
|
|
bottombars(s);
|
|
|
|
|
|
|
|
va_start(ap, msg);
|
|
|
|
vsnprintf(prompt, (COLS - 4) * mb_cur_max(), msg, ap);
|
|
|
|
va_end(ap);
|
|
|
|
null_at(&prompt, actual_x(prompt, COLS - 4));
|
|
|
|
|
2006-02-07 21:11:05 +00:00
|
|
|
retval = get_prompt_string(allow_tabs,
|
|
|
|
#ifndef DISABLE_TABCOMP
|
|
|
|
allow_files,
|
|
|
|
#endif
|
|
|
|
curranswer,
|
2005-11-15 03:17:35 +00:00
|
|
|
#ifndef NANO_TINY
|
2006-02-07 21:11:05 +00:00
|
|
|
history_list,
|
2005-11-01 17:37:44 +00:00
|
|
|
#endif
|
2006-02-18 21:32:29 +00:00
|
|
|
refresh_func, s
|
2005-11-01 17:37:44 +00:00
|
|
|
#ifndef DISABLE_TABCOMP
|
2006-02-07 21:11:05 +00:00
|
|
|
, &list
|
2005-11-01 17:37:44 +00:00
|
|
|
#endif
|
2006-02-07 21:11:05 +00:00
|
|
|
);
|
2005-11-01 17:37:44 +00:00
|
|
|
|
2005-11-01 18:35:47 +00:00
|
|
|
free(prompt);
|
|
|
|
prompt = NULL;
|
|
|
|
|
|
|
|
reset_statusbar_x = FALSE;
|
2005-11-01 17:37:44 +00:00
|
|
|
|
|
|
|
switch (retval) {
|
|
|
|
case NANO_CANCEL_KEY:
|
|
|
|
retval = -1;
|
2005-11-01 18:35:47 +00:00
|
|
|
reset_statusbar_x = TRUE;
|
2005-11-01 17:37:44 +00:00
|
|
|
break;
|
|
|
|
case NANO_ENTER_KEY:
|
|
|
|
retval = (answer[0] == '\0') ? -2 : 0;
|
2005-11-01 18:35:47 +00:00
|
|
|
reset_statusbar_x = TRUE;
|
2005-11-01 17:37:44 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
blank_statusbar();
|
|
|
|
wnoutrefresh(bottomwin);
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
fprintf(stderr, "answer = \"%s\"\n", answer);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef DISABLE_TABCOMP
|
|
|
|
/* If we've done tab completion, there might be a list of filename
|
|
|
|
* matches on the edit window at this point. Make sure that they're
|
|
|
|
* cleared off. */
|
|
|
|
if (list)
|
2006-02-18 21:32:29 +00:00
|
|
|
refresh_func();
|
2005-11-01 17:37:44 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2005-11-07 21:45:44 +00:00
|
|
|
/* This function forces a reset of the statusbar cursor position. It
|
|
|
|
* should only be called after do_prompt(), and is only needed if the
|
|
|
|
* user leaves the prompt via something other than Enter or Cancel. */
|
|
|
|
void do_prompt_abort(void)
|
2005-11-01 17:37:44 +00:00
|
|
|
{
|
2005-11-01 18:35:47 +00:00
|
|
|
reset_statusbar_x = TRUE;
|
2005-11-01 17:37:44 +00:00
|
|
|
}
|
2005-11-03 21:07:24 +00:00
|
|
|
|
|
|
|
/* Ask a simple Yes/No (and optionally All) question, specified in msg,
|
|
|
|
* on the statusbar. Return 1 for Yes, 0 for No, 2 for All (if all is
|
|
|
|
* TRUE when passed in), and -1 for Cancel. */
|
2005-11-07 21:45:44 +00:00
|
|
|
int do_yesno_prompt(bool all, const char *msg)
|
2005-11-03 21:07:24 +00:00
|
|
|
{
|
|
|
|
int ok = -2, width = 16;
|
|
|
|
const char *yesstr; /* String of Yes characters accepted. */
|
|
|
|
const char *nostr; /* Same for No. */
|
|
|
|
const char *allstr; /* And All, surprise! */
|
|
|
|
|
|
|
|
assert(msg != NULL);
|
|
|
|
|
|
|
|
/* yesstr, nostr, and allstr are strings of any length. Each string
|
|
|
|
* consists of all single-byte characters accepted as valid
|
|
|
|
* characters for that value. The first value will be the one
|
2006-04-09 18:27:42 +00:00
|
|
|
* displayed in the shortcuts. */
|
|
|
|
/* TRANSLATORS: For the next three strings, if possible, specify
|
2006-04-09 18:24:54 +00:00
|
|
|
* the single-byte shortcuts for both your language and English.
|
|
|
|
* For example, in French: "OoYy" for "Oui". */
|
2005-11-03 21:07:24 +00:00
|
|
|
yesstr = _("Yy");
|
|
|
|
nostr = _("Nn");
|
|
|
|
allstr = _("Aa");
|
|
|
|
|
|
|
|
if (!ISSET(NO_HELP)) {
|
|
|
|
char shortstr[3];
|
|
|
|
/* Temp string for Yes, No, All. */
|
|
|
|
|
|
|
|
if (COLS < 32)
|
|
|
|
width = COLS / 2;
|
|
|
|
|
|
|
|
/* Clear the shortcut list from the bottom of the screen. */
|
|
|
|
blank_bottombars();
|
|
|
|
|
|
|
|
sprintf(shortstr, " %c", yesstr[0]);
|
|
|
|
wmove(bottomwin, 1, 0);
|
|
|
|
onekey(shortstr, _("Yes"), width);
|
|
|
|
|
|
|
|
if (all) {
|
|
|
|
wmove(bottomwin, 1, width);
|
|
|
|
shortstr[1] = allstr[0];
|
|
|
|
onekey(shortstr, _("All"), width);
|
|
|
|
}
|
|
|
|
|
|
|
|
wmove(bottomwin, 2, 0);
|
|
|
|
shortstr[1] = nostr[0];
|
|
|
|
onekey(shortstr, _("No"), width);
|
|
|
|
|
|
|
|
wmove(bottomwin, 2, 16);
|
|
|
|
onekey("^C", _("Cancel"), width);
|
|
|
|
}
|
|
|
|
|
2006-04-12 15:27:40 +00:00
|
|
|
wattron(bottomwin, reverse_attr);
|
2005-11-03 21:07:24 +00:00
|
|
|
|
|
|
|
blank_statusbar();
|
|
|
|
mvwaddnstr(bottomwin, 0, 0, msg, actual_x(msg, COLS - 1));
|
|
|
|
|
2006-04-12 15:27:40 +00:00
|
|
|
wattroff(bottomwin, reverse_attr);
|
2005-11-03 21:07:24 +00:00
|
|
|
|
|
|
|
/* Refresh the edit window and the statusbar before getting
|
|
|
|
* input. */
|
|
|
|
wnoutrefresh(edit);
|
|
|
|
wnoutrefresh(bottomwin);
|
|
|
|
|
|
|
|
do {
|
|
|
|
int kbinput;
|
|
|
|
bool meta_key, func_key;
|
|
|
|
#ifndef DISABLE_MOUSE
|
|
|
|
int mouse_x, mouse_y;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
kbinput = get_kbinput(bottomwin, &meta_key, &func_key);
|
|
|
|
|
|
|
|
if (kbinput == NANO_REFRESH_KEY) {
|
|
|
|
total_redraw();
|
|
|
|
continue;
|
|
|
|
} else if (kbinput == NANO_CANCEL_KEY)
|
|
|
|
ok = -1;
|
|
|
|
#ifndef DISABLE_MOUSE
|
|
|
|
else if (kbinput == KEY_MOUSE) {
|
|
|
|
get_mouseinput(&mouse_x, &mouse_y, FALSE);
|
|
|
|
|
|
|
|
if (mouse_x != -1 && mouse_y != -1 && !ISSET(NO_HELP) &&
|
|
|
|
wenclose(bottomwin, mouse_y, mouse_x) &&
|
|
|
|
mouse_x < (width * 2) && mouse_y - (2 -
|
|
|
|
no_more_space()) - editwinrows - 1 >= 0) {
|
|
|
|
int x = mouse_x / width;
|
|
|
|
/* Calculate the x-coordinate relative to the
|
|
|
|
* two columns of the Yes/No/All shortcuts in
|
|
|
|
* bottomwin. */
|
|
|
|
int y = mouse_y - (2 - no_more_space()) -
|
|
|
|
editwinrows - 1;
|
|
|
|
/* Calculate the y-coordinate relative to the
|
|
|
|
* beginning of the Yes/No/All shortcuts in
|
|
|
|
* bottomwin, i.e, with the sizes of topwin,
|
|
|
|
* edit, and the first line of bottomwin
|
|
|
|
* subtracted out. */
|
|
|
|
|
|
|
|
assert(0 <= x && x <= 1 && 0 <= y && y <= 1);
|
|
|
|
|
|
|
|
/* x == 0 means they clicked Yes or No. y == 0 means
|
|
|
|
* Yes or All. */
|
|
|
|
ok = -2 * x * y + x - y + 1;
|
|
|
|
|
|
|
|
if (ok == 2 && !all)
|
|
|
|
ok = -2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
/* Look for the kbinput in the Yes, No and (optionally) All
|
|
|
|
* strings. */
|
|
|
|
else if (strchr(yesstr, kbinput) != NULL)
|
|
|
|
ok = 1;
|
|
|
|
else if (strchr(nostr, kbinput) != NULL)
|
|
|
|
ok = 0;
|
|
|
|
else if (all && strchr(allstr, kbinput) != NULL)
|
|
|
|
ok = 2;
|
|
|
|
} while (ok == -2);
|
|
|
|
|
|
|
|
return ok;
|
|
|
|
}
|