mirror of
git://git.sv.gnu.org/nano.git
synced 2025-03-03 15:21:29 +03:00
minor overhaul of terminal-related things
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1745 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
This commit is contained in:
parent
36e363f525
commit
d7fd200a6a
68
ChangeLog
68
ChangeLog
@ -6,6 +6,8 @@ CVS code -
|
|||||||
- Make sure the special control keys are handled the same way
|
- Make sure the special control keys are handled the same way
|
||||||
after the window is resized or we come out of suspend mode.
|
after the window is resized or we come out of suspend mode.
|
||||||
Changes to do_cont() and handle_sigwinch(). (DLR)
|
Changes to do_cont() and handle_sigwinch(). (DLR)
|
||||||
|
- Change some instances of ints that can never be negative to
|
||||||
|
size_t's. (DLR)
|
||||||
- Add better explanations for and in the "Terminal breakage"
|
- Add better explanations for and in the "Terminal breakage"
|
||||||
comments, and handle missing key #ifdefs inside the functions
|
comments, and handle missing key #ifdefs inside the functions
|
||||||
that use those keys. (DLR)
|
that use those keys. (DLR)
|
||||||
@ -48,6 +50,9 @@ CVS code -
|
|||||||
justify_format() may get a space tacked onto the end of it
|
justify_format() may get a space tacked onto the end of it
|
||||||
later, so now the entire original paragraph is always backed
|
later, so now the entire original paragraph is always backed
|
||||||
up.) (DLR)
|
up.) (DLR)
|
||||||
|
- Wrap the long jump code in NANO_SMALL #ifdefs, since we only
|
||||||
|
use it if we're resizing the window, which is disabled when
|
||||||
|
NANO_SMALL is defined. (DLR)
|
||||||
- files.c:
|
- files.c:
|
||||||
add_open_file()
|
add_open_file()
|
||||||
- Rearrange the NANO_SMALL #ifdef so that the code to set the
|
- Rearrange the NANO_SMALL #ifdef so that the code to set the
|
||||||
@ -57,6 +62,15 @@ CVS code -
|
|||||||
- Refactor so that no recursion is needed if we try to exit with
|
- Refactor so that no recursion is needed if we try to exit with
|
||||||
a modified file that has no name when TEMP_OPT is set. (DLR)
|
a modified file that has no name when TEMP_OPT is set. (DLR)
|
||||||
- nano.c:
|
- nano.c:
|
||||||
|
do_toggle(), finish()
|
||||||
|
- Call blank_statusbar() and blank_bottombars() to blank out
|
||||||
|
the statusbar and shortcut list in bottomwin. (DLR)
|
||||||
|
do_early_abort()
|
||||||
|
- Removed, as it's no longer called anywhere. (David Benbennick)
|
||||||
|
open_pipe()
|
||||||
|
- Call enable_signals() at the beginning and disable_signals()
|
||||||
|
at the end, so that we get a SIGINT when Ctrl-C is pressed
|
||||||
|
during wait() and can then call cancel_fork() properly. (DLR)
|
||||||
do_delete()
|
do_delete()
|
||||||
- Tweak for efficiency. (David Benbennick)
|
- Tweak for efficiency. (David Benbennick)
|
||||||
justify_format()
|
justify_format()
|
||||||
@ -72,10 +86,32 @@ CVS code -
|
|||||||
print_numlock_warning()
|
print_numlock_warning()
|
||||||
- Removed, as it's no longer needed and was never called
|
- Removed, as it's no longer needed and was never called
|
||||||
anywhere after the input overhaul. (DLR)
|
anywhere after the input overhaul. (DLR)
|
||||||
|
signal_init()
|
||||||
|
- Don't use termios and _POSIX_VDISABLE to disable keys anymore,
|
||||||
|
as there's no real equivalent of it when the latter isn't
|
||||||
|
defined. (DLR)
|
||||||
|
handle_sigwinch()
|
||||||
|
- Call resetty() to get the original terminal settings back.
|
||||||
|
(DLR)
|
||||||
|
- Rework so that nano properly redraws the screen on systems
|
||||||
|
that don't have resizeterm() and/or wresize(). In curses, we
|
||||||
|
now leave and immediately reenter curses mode via endwin() and
|
||||||
|
refresh(), and then reinitialize all windows via
|
||||||
|
window_init(). In slang, the above routine will only work if
|
||||||
|
the resize made the window smaller, so we now leave and
|
||||||
|
immediately reenter screen management mode via
|
||||||
|
SLsmg_reset_smg() and SLsmg_init_smg(), and then reinitialize
|
||||||
|
all windows via window_init(). (DLR, adapted from code in
|
||||||
|
Minimum Profit 3.3.0 and mutt 1.4.2.1, respectively)
|
||||||
do_verbatim_input()
|
do_verbatim_input()
|
||||||
- Use size_t's instead of ints for the get_verbatim_kbinput()
|
- If PRESERVE is set, disable flow control characters before
|
||||||
call and the loop that ungetch()es its returned int*,
|
getting input and reenable them after getting input. (DLR)
|
||||||
respectively. (DLR)
|
disable_signals(), enable_signals(), disable_flow_control(),
|
||||||
|
enable_flow_control()
|
||||||
|
- New functions that allow more fine-grained control of the
|
||||||
|
terminal: disabling and enabling signals without having to use
|
||||||
|
_POSIX_VDISABLE and disabling and enabling flow control
|
||||||
|
characters. (DLR)
|
||||||
main()
|
main()
|
||||||
- Don't open the first file in quiet mode, since if we do, an
|
- Don't open the first file in quiet mode, since if we do, an
|
||||||
error message won't be shown if it's unreadable. (DLR; found
|
error message won't be shown if it's unreadable. (DLR; found
|
||||||
@ -88,6 +124,17 @@ CVS code -
|
|||||||
the nanorc first, both of which are unintuitive. Multibuffer
|
the nanorc first, both of which are unintuitive. Multibuffer
|
||||||
mode should only affect how the "Read File" command behaves
|
mode should only affect how the "Read File" command behaves
|
||||||
anyway. (DLR)
|
anyway. (DLR)
|
||||||
|
- Remove the disabling of implementation-defined input
|
||||||
|
processing, as raw mode appears to turn it off anyway. (DLR)
|
||||||
|
- Use raw mode instead of cbreak mode, since it comes closest to
|
||||||
|
what we need by automatically disabling the special control
|
||||||
|
keys. (DLR)
|
||||||
|
- After noecho(), call disable_signals() and
|
||||||
|
disable_flow_control(), the latter only if PRESERVE is not
|
||||||
|
set. (DLR)
|
||||||
|
- Move the savetty() call down from just after initscr() to just
|
||||||
|
after the terminal is properly set up, so that we can restore
|
||||||
|
it easily after a resize. (DLR)
|
||||||
- nano.h:
|
- nano.h:
|
||||||
- Since REGEXP_COMPILED is only used in search.c, convert it
|
- Since REGEXP_COMPILED is only used in search.c, convert it
|
||||||
from a flag to a static int there. (DLR)
|
from a flag to a static int there. (DLR)
|
||||||
@ -131,8 +178,6 @@ CVS code -
|
|||||||
- Refactor the output in the DEBUG #ifdef. It didn't work
|
- Refactor the output in the DEBUG #ifdef. It didn't work
|
||||||
properly ever since this function was changed to use an int*
|
properly ever since this function was changed to use an int*
|
||||||
instead of a char*. (DLR)
|
instead of a char*. (DLR)
|
||||||
- Change kbinput_len from an int* to a size_t*, since it should
|
|
||||||
never be negative. (DLR)
|
|
||||||
- When reading characters from input, properly reallocate
|
- When reading characters from input, properly reallocate
|
||||||
verbatim_kbinput via (int*)nrealloc() instead of an uncast
|
verbatim_kbinput via (int*)nrealloc() instead of an uncast
|
||||||
realloc(). (DLR)
|
realloc(). (DLR)
|
||||||
@ -140,8 +185,6 @@ CVS code -
|
|||||||
- Add proper support for the keypad values and escape sequences
|
- Add proper support for the keypad values and escape sequences
|
||||||
generated by the NumLock glitch. (DLR)
|
generated by the NumLock glitch. (DLR)
|
||||||
get_escape_seq_kbinput()
|
get_escape_seq_kbinput()
|
||||||
- Change escape_seq_len from an int to a size_t, since it should
|
|
||||||
never be negative. (DLR)
|
|
||||||
- Add proper support for the keypad values and escape sequences
|
- Add proper support for the keypad values and escape sequences
|
||||||
generated by the NumLock glitch. (DLR)
|
generated by the NumLock glitch. (DLR)
|
||||||
bottombars()
|
bottombars()
|
||||||
@ -152,6 +195,14 @@ CVS code -
|
|||||||
edit_add()
|
edit_add()
|
||||||
- Minor cosmetic reformatting. Also remove unused int
|
- Minor cosmetic reformatting. Also remove unused int
|
||||||
searched_later_lines. (DLR)
|
searched_later_lines. (DLR)
|
||||||
|
blank_bottomwin()
|
||||||
|
- Removed, as it does the same thing as blank_bottombars().
|
||||||
|
(David Benbennick)
|
||||||
|
blank_titlebar()
|
||||||
|
- New function used to blank the titlebar in topwin. (DLR)
|
||||||
|
bottombars()
|
||||||
|
- Call blank_bottombars() instead of blank_bottomwin(). (David
|
||||||
|
Benbennick)
|
||||||
edit_refresh()
|
edit_refresh()
|
||||||
- Remove apparently unneeded leaveok() calls. (David Benbennick)
|
- Remove apparently unneeded leaveok() calls. (David Benbennick)
|
||||||
statusbar()
|
statusbar()
|
||||||
@ -163,6 +214,7 @@ CVS code -
|
|||||||
- Use napms() instead of nanosleep(), as it does the same thing
|
- Use napms() instead of nanosleep(), as it does the same thing
|
||||||
(aside from taking an argument in milliseconds instead of
|
(aside from taking an argument in milliseconds instead of
|
||||||
microseconds) and curses includes it. (DLR)
|
microseconds) and curses includes it. (DLR)
|
||||||
|
- Overhaul for efficiency. (David Benbennick)
|
||||||
- configure.ac:
|
- configure.ac:
|
||||||
- Add tests for isblank() and strcasestr(), and define
|
- Add tests for isblank() and strcasestr(), and define
|
||||||
_GNU_SOURCE so that the tests work properly. Increase the
|
_GNU_SOURCE so that the tests work properly. Increase the
|
||||||
@ -171,6 +223,8 @@ CVS code -
|
|||||||
fewer lines than usual, so as to make them easier to read, and
|
fewer lines than usual, so as to make them easier to read, and
|
||||||
remove unnecessary inclusion of stdio.h in the slang test
|
remove unnecessary inclusion of stdio.h in the slang test
|
||||||
programs. (DLR)
|
programs. (DLR)
|
||||||
|
- Remove the checks for resizeterm() and wresize(), as they're
|
||||||
|
no longer needed. (DLR)
|
||||||
- faq.html:
|
- faq.html:
|
||||||
- Removed question about the NumLock glitch, as it's no longer
|
- Removed question about the NumLock glitch, as it's no longer
|
||||||
needed. (DLR)
|
needed. (DLR)
|
||||||
|
@ -105,7 +105,8 @@ void new_file(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
filestruct *read_line(char *buf, filestruct *prev, int *line1ins, int len)
|
filestruct *read_line(char *buf, filestruct *prev, int *line1ins, size_t
|
||||||
|
len)
|
||||||
{
|
{
|
||||||
filestruct *fileptr = (filestruct *)nmalloc(sizeof(filestruct));
|
filestruct *fileptr = (filestruct *)nmalloc(sizeof(filestruct));
|
||||||
|
|
||||||
@ -2454,7 +2455,7 @@ int diralphasort(const void *va, const void *vb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Free our malloc()ed memory */
|
/* Free our malloc()ed memory */
|
||||||
void free_charptrarray(char **array, int len)
|
void free_charptrarray(char **array, size_t len)
|
||||||
{
|
{
|
||||||
for (; len > 0; len--)
|
for (; len > 0; len--)
|
||||||
free(array[len - 1]);
|
free(array[len - 1]);
|
||||||
|
271
src/nano.c
271
src/nano.c
@ -25,7 +25,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <setjmp.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -54,6 +53,10 @@
|
|||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef NANO_SMALL
|
||||||
|
#include <setjmp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef DISABLE_WRAPJUSTIFY
|
#ifndef DISABLE_WRAPJUSTIFY
|
||||||
static int fill = 0; /* Fill - where to wrap lines, basically */
|
static int fill = 0; /* Fill - where to wrap lines, basically */
|
||||||
#endif
|
#endif
|
||||||
@ -65,21 +68,22 @@ static int same_line_wrap = 0; /* Whether wrapped text should be
|
|||||||
static struct termios oldterm; /* The user's original term settings */
|
static struct termios oldterm; /* The user's original term settings */
|
||||||
static struct sigaction act; /* For all our fun signal handlers */
|
static struct sigaction act; /* For all our fun signal handlers */
|
||||||
|
|
||||||
|
#ifndef NANO_SMALL
|
||||||
static sigjmp_buf jmpbuf; /* Used to return to mainloop after SIGWINCH */
|
static sigjmp_buf jmpbuf; /* Used to return to mainloop after SIGWINCH */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* What we do when we're all set to exit */
|
/* What we do when we're all set to exit */
|
||||||
RETSIGTYPE finish(int sigage)
|
RETSIGTYPE finish(int sigage)
|
||||||
{
|
{
|
||||||
if (!ISSET(NO_HELP)) {
|
if (!ISSET(NO_HELP))
|
||||||
mvwaddstr(bottomwin, 1, 0, hblank);
|
blank_bottombars();
|
||||||
mvwaddstr(bottomwin, 2, 0, hblank);
|
else
|
||||||
} else
|
blank_statusbar();
|
||||||
mvwaddstr(bottomwin, 0, 0, hblank);
|
|
||||||
|
|
||||||
wrefresh(bottomwin);
|
wrefresh(bottomwin);
|
||||||
endwin();
|
endwin();
|
||||||
|
|
||||||
/* Restore the old term settings */
|
/* Restore the old terminal settings. */
|
||||||
tcsetattr(0, TCSANOW, &oldterm);
|
tcsetattr(0, TCSANOW, &oldterm);
|
||||||
|
|
||||||
#if !defined(NANO_SMALL) && defined(ENABLE_NANORC)
|
#if !defined(NANO_SMALL) && defined(ENABLE_NANORC)
|
||||||
@ -102,7 +106,7 @@ void die(const char *msg, ...)
|
|||||||
endwin();
|
endwin();
|
||||||
curses_ended = TRUE;
|
curses_ended = TRUE;
|
||||||
|
|
||||||
/* Restore the old term settings */
|
/* Restore the old terminal settings. */
|
||||||
tcsetattr(0, TCSANOW, &oldterm);
|
tcsetattr(0, TCSANOW, &oldterm);
|
||||||
|
|
||||||
va_start(ap, msg);
|
va_start(ap, msg);
|
||||||
@ -241,7 +245,7 @@ void window_init(void)
|
|||||||
edit = newwin(editwinrows, COLS, 2, 0);
|
edit = newwin(editwinrows, COLS, 2, 0);
|
||||||
bottomwin = newwin(3 - no_help(), COLS, LINES - 3 + no_help(), 0);
|
bottomwin = newwin(3 - no_help(), COLS, LINES - 3 + no_help(), 0);
|
||||||
|
|
||||||
/* Turn the keypad on in the windows we'll be reading input from. */
|
/* Turn the keypad back on. */
|
||||||
keypad(edit, TRUE);
|
keypad(edit, TRUE);
|
||||||
keypad(bottomwin, TRUE);
|
keypad(bottomwin, TRUE);
|
||||||
}
|
}
|
||||||
@ -758,13 +762,6 @@ void version(void)
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stuff we do when we abort from programs and want to clean up the
|
|
||||||
* screen. This doesn't do much right now. */
|
|
||||||
void do_early_abort(void)
|
|
||||||
{
|
|
||||||
blank_statusbar_refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
int no_help(void)
|
int no_help(void)
|
||||||
{
|
{
|
||||||
return ISSET(NO_HELP) ? 2 : 0;
|
return ISSET(NO_HELP) ? 2 : 0;
|
||||||
@ -792,13 +789,10 @@ int open_pipe(const char *command)
|
|||||||
FILE *f;
|
FILE *f;
|
||||||
struct sigaction oldaction, newaction;
|
struct sigaction oldaction, newaction;
|
||||||
/* original and temporary handlers for SIGINT */
|
/* original and temporary handlers for SIGINT */
|
||||||
#ifdef _POSIX_VDISABLE
|
|
||||||
struct termios term, newterm;
|
|
||||||
#endif /* _POSIX_VDISABLE */
|
|
||||||
int cancel_sigs = 0;
|
int cancel_sigs = 0;
|
||||||
/* cancel_sigs == 1 means that sigaction() failed without changing
|
/* cancel_sigs == 1 means that sigaction() failed without changing
|
||||||
* the signal handlers. cancel_sigs == 2 means the signal handler
|
* the signal handlers. cancel_sigs == 2 means the signal handler
|
||||||
* was changed, but the tcsetattr didn't succeed.
|
* was changed, but the tcsetattr() didn't succeed.
|
||||||
*
|
*
|
||||||
* I use this variable since it is important to put things back when
|
* I use this variable since it is important to put things back when
|
||||||
* we finish, even if we get errors. */
|
* we finish, even if we get errors. */
|
||||||
@ -834,6 +828,9 @@ int open_pipe(const char *command)
|
|||||||
|
|
||||||
/* Before we start reading the forked command's output, we set
|
/* Before we start reading the forked command's output, we set
|
||||||
* things up so that ^C will cancel the new process. */
|
* things up so that ^C will cancel the new process. */
|
||||||
|
|
||||||
|
enable_signals();
|
||||||
|
|
||||||
if (sigaction(SIGINT, NULL, &newaction) == -1) {
|
if (sigaction(SIGINT, NULL, &newaction) == -1) {
|
||||||
cancel_sigs = 1;
|
cancel_sigs = 1;
|
||||||
nperror("sigaction");
|
nperror("sigaction");
|
||||||
@ -847,24 +844,6 @@ int open_pipe(const char *command)
|
|||||||
/* Note that now oldaction is the previous SIGINT signal handler,
|
/* Note that now oldaction is the previous SIGINT signal handler,
|
||||||
* to be restored later. */
|
* to be restored later. */
|
||||||
|
|
||||||
/* See if the platform supports disabling individual control
|
|
||||||
* characters. */
|
|
||||||
#ifdef _POSIX_VDISABLE
|
|
||||||
if (cancel_sigs == 0 && tcgetattr(0, &term) == -1) {
|
|
||||||
cancel_sigs = 2;
|
|
||||||
nperror("tcgetattr");
|
|
||||||
}
|
|
||||||
if (cancel_sigs == 0) {
|
|
||||||
newterm = term;
|
|
||||||
/* Grab oldterm's VINTR key :-) */
|
|
||||||
newterm.c_cc[VINTR] = oldterm.c_cc[VINTR];
|
|
||||||
if (tcsetattr(0, TCSANOW, &newterm) == -1) {
|
|
||||||
cancel_sigs = 2;
|
|
||||||
nperror("tcsetattr");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* _POSIX_VDISABLE */
|
|
||||||
|
|
||||||
f = fdopen(fd[0], "rb");
|
f = fdopen(fd[0], "rb");
|
||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
nperror("fdopen");
|
nperror("fdopen");
|
||||||
@ -878,14 +857,11 @@ int open_pipe(const char *command)
|
|||||||
if (wait(NULL) == -1)
|
if (wait(NULL) == -1)
|
||||||
nperror("wait");
|
nperror("wait");
|
||||||
|
|
||||||
#ifdef _POSIX_VDISABLE
|
|
||||||
if (cancel_sigs == 0 && tcsetattr(0, TCSANOW, &term) == -1)
|
|
||||||
nperror("tcsetattr");
|
|
||||||
#endif /* _POSIX_VDISABLE */
|
|
||||||
|
|
||||||
if (cancel_sigs != 1 && sigaction(SIGINT, &oldaction, NULL) == -1)
|
if (cancel_sigs != 1 && sigaction(SIGINT, &oldaction, NULL) == -1)
|
||||||
nperror("sigaction");
|
nperror("sigaction");
|
||||||
|
|
||||||
|
disable_signals();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* !NANO_SMALL */
|
#endif /* !NANO_SMALL */
|
||||||
@ -2769,10 +2745,6 @@ int do_exit(void)
|
|||||||
|
|
||||||
void signal_init(void)
|
void signal_init(void)
|
||||||
{
|
{
|
||||||
#ifdef _POSIX_VDISABLE
|
|
||||||
struct termios term;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Trap SIGINT and SIGQUIT because we want them to do useful
|
/* Trap SIGINT and SIGQUIT because we want them to do useful
|
||||||
* things. */
|
* things. */
|
||||||
memset(&act, 0, sizeof(struct sigaction));
|
memset(&act, 0, sizeof(struct sigaction));
|
||||||
@ -2792,31 +2764,10 @@ void signal_init(void)
|
|||||||
allow_pending_sigwinch(FALSE);
|
allow_pending_sigwinch(FALSE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _POSIX_VDISABLE
|
/* Trap normal suspend (^Z) so we can handle it ourselves. */
|
||||||
tcgetattr(0, &term);
|
|
||||||
|
|
||||||
if (!ISSET(PRESERVE)) {
|
|
||||||
/* Trap XOFF (^S) and XON (^Q), much to Chris' chagrin, because
|
|
||||||
* we want to block them. */
|
|
||||||
term.c_cc[VSTOP] = _POSIX_VDISABLE;
|
|
||||||
term.c_cc[VSTART] = _POSIX_VDISABLE;
|
|
||||||
}
|
|
||||||
#ifdef VDSUSP
|
|
||||||
/* Trap delayed suspend (^Y) so we can handle it ourselves. */
|
|
||||||
term.c_cc[VDSUSP] = _POSIX_VDISABLE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _POSIX_VDISABLE */
|
|
||||||
|
|
||||||
if (!ISSET(SUSPEND)) {
|
if (!ISSET(SUSPEND)) {
|
||||||
/* Trap normal suspend (^Z) so we can handle it ourselves. If
|
|
||||||
* we can't trap the key, trap the signal instead. Insane! */
|
|
||||||
#ifdef _POSIX_VDISABLE
|
|
||||||
term.c_cc[VSUSP] = _POSIX_VDISABLE;
|
|
||||||
#else
|
|
||||||
act.sa_handler = SIG_IGN;
|
act.sa_handler = SIG_IGN;
|
||||||
sigaction(SIGTSTP, &act, NULL);
|
sigaction(SIGTSTP, &act, NULL);
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
/* Block all other signals in the suspend and continue handlers.
|
/* Block all other signals in the suspend and continue handlers.
|
||||||
* If we don't do this, other stuff interrupts them! */
|
* If we don't do this, other stuff interrupts them! */
|
||||||
@ -2828,54 +2779,44 @@ void signal_init(void)
|
|||||||
act.sa_handler = do_cont;
|
act.sa_handler = do_cont;
|
||||||
sigaction(SIGCONT, &act, NULL);
|
sigaction(SIGCONT, &act, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _POSIX_VDISABLE
|
|
||||||
tcsetattr(0, TCSANOW, &term);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handler for SIGHUP and SIGTERM. */
|
/* Handler for SIGHUP (hangup) and SIGTERM (terminate). */
|
||||||
RETSIGTYPE handle_hupterm(int signal)
|
RETSIGTYPE handle_hupterm(int signal)
|
||||||
{
|
{
|
||||||
die(_("Received SIGHUP or SIGTERM\n"));
|
die(_("Received SIGHUP or SIGTERM\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* What do we do when we catch the suspend signal */
|
/* Handler for SIGTSTP (suspend). */
|
||||||
RETSIGTYPE do_suspend(int signal)
|
RETSIGTYPE do_suspend(int signal)
|
||||||
{
|
{
|
||||||
endwin();
|
endwin();
|
||||||
printf("\n\n\n\n\n%s\n", _("Use \"fg\" to return to nano"));
|
printf("\n\n\n\n\n%s\n", _("Use \"fg\" to return to nano"));
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
/* Restore the terminal settings for the disabled keys */
|
/* Restore the old terminal settings. */
|
||||||
tcsetattr(0, TCSANOW, &oldterm);
|
tcsetattr(0, TCSANOW, &oldterm);
|
||||||
|
|
||||||
/* Trap SIGHUP and SIGTERM so we can properly deal with them while
|
/* Trap SIGHUP and SIGTERM so we can properly deal with them while
|
||||||
suspended */
|
* suspended. */
|
||||||
act.sa_handler = handle_hupterm;
|
act.sa_handler = handle_hupterm;
|
||||||
sigaction(SIGHUP, &act, NULL);
|
sigaction(SIGHUP, &act, NULL);
|
||||||
sigaction(SIGTERM, &act, NULL);
|
sigaction(SIGTERM, &act, NULL);
|
||||||
|
|
||||||
/* We used to re-enable the default SIG_DFL and raise SIGTSTP, but
|
/* Do what mutt does: send ourselves a SIGSTOP. */
|
||||||
then we could be (and were) interrupted in the middle of the call.
|
|
||||||
So we do it the mutt way instead */
|
|
||||||
kill(0, SIGSTOP);
|
kill(0, SIGSTOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore the suspend handler when we come back into the prog */
|
/* Handler for SIGCONT (continue after suspend). */
|
||||||
RETSIGTYPE do_cont(int signal)
|
RETSIGTYPE do_cont(int signal)
|
||||||
{
|
{
|
||||||
/* Now we just update the screen instead of having to reenable the
|
|
||||||
* SIGTSTP handler. */
|
|
||||||
doupdate();
|
|
||||||
|
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
/* Perhaps the user resized the window while we slept. */
|
/* Perhaps the user resized the window while we slept. Handle it
|
||||||
|
* and update the screen in the process. */
|
||||||
handle_sigwinch(0);
|
handle_sigwinch(0);
|
||||||
#else
|
#else
|
||||||
/* Set up the signal handlers again, so that the special control
|
/* Just update the screen. */
|
||||||
* keys all work the same as before. */
|
doupdate();
|
||||||
signal_init();
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2919,45 +2860,35 @@ void handle_sigwinch(int s)
|
|||||||
memset(hblank, ' ', COLS);
|
memset(hblank, ' ', COLS);
|
||||||
hblank[COLS] = '\0';
|
hblank[COLS] = '\0';
|
||||||
|
|
||||||
#ifdef HAVE_RESIZETERM
|
#ifdef USE_SLANG
|
||||||
resizeterm(LINES, COLS);
|
/* Slang curses emulation brain damage, part 1: If we just do what
|
||||||
#ifdef HAVE_WRESIZE
|
* curses does here, it'll only work properly if the resize made the
|
||||||
if (wresize(topwin, 2, COLS) == ERR)
|
* window smaller. Do what mutt does: Leave and immediately reenter
|
||||||
die(_("Cannot resize top win"));
|
* Slang screen management mode. */
|
||||||
if (mvwin(topwin, 0, 0) == ERR)
|
SLsmg_reset_smg();
|
||||||
die(_("Cannot move top win"));
|
SLsmg_init_smg();
|
||||||
if (wresize(edit, editwinrows, COLS) == ERR)
|
#else
|
||||||
die(_("Cannot resize edit win"));
|
/* Do the equivalent of what Minimum Profit does: Leave and
|
||||||
if (mvwin(edit, 2, 0) == ERR)
|
* immediately reenter curses mode. */
|
||||||
die(_("Cannot move edit win"));
|
endwin();
|
||||||
if (wresize(bottomwin, 3 - no_help(), COLS) == ERR)
|
refresh();
|
||||||
die(_("Cannot resize bottom win"));
|
#endif
|
||||||
if (mvwin(bottomwin, LINES - 3 + no_help(), 0) == ERR)
|
|
||||||
die(_("Cannot move bottom win"));
|
|
||||||
#endif /* HAVE_WRESIZE */
|
|
||||||
#endif /* HAVE_RESIZETERM */
|
|
||||||
|
|
||||||
display_main_list();
|
/* Do the equivalent of what both mutt and Minimum Profit do:
|
||||||
|
* Reinitialize all the windows based on the new screen
|
||||||
|
* dimensions. */
|
||||||
|
window_init();
|
||||||
|
|
||||||
|
/* Redraw the contents of the windows that need it. */
|
||||||
blank_statusbar();
|
blank_statusbar();
|
||||||
|
display_main_list();
|
||||||
total_refresh();
|
total_refresh();
|
||||||
|
|
||||||
/* Turn cursor back on for sure. */
|
/* Turn cursor back on for sure. */
|
||||||
curs_set(1);
|
curs_set(1);
|
||||||
|
|
||||||
/* Put the terminal in cbreak mode (read one character at a time and
|
/* Restore the terminal to its previously saved state. */
|
||||||
* interpret the special control keys) if we can selectively disable
|
resetty();
|
||||||
* the special control keys. */
|
|
||||||
#ifdef _POSIX_VDISABLE
|
|
||||||
cbreak();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Set up the signal handlers again, so that the special control
|
|
||||||
* keys all work the same as before. */
|
|
||||||
signal_init();
|
|
||||||
|
|
||||||
/* Turn the keypad on in the windows we'll be reading input from. */
|
|
||||||
keypad(edit, TRUE);
|
|
||||||
keypad(bottomwin, TRUE);
|
|
||||||
|
|
||||||
/* Jump back to the main loop. */
|
/* Jump back to the main loop. */
|
||||||
siglongjmp(jmpbuf, 1);
|
siglongjmp(jmpbuf, 1);
|
||||||
@ -2993,7 +2924,8 @@ void do_toggle(const toggle *which)
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case TOGGLE_NOHELP_KEY:
|
case TOGGLE_NOHELP_KEY:
|
||||||
wclear(bottomwin);
|
blank_statusbar();
|
||||||
|
blank_bottombars();
|
||||||
wrefresh(bottomwin);
|
wrefresh(bottomwin);
|
||||||
window_init();
|
window_init();
|
||||||
edit_refresh();
|
edit_refresh();
|
||||||
@ -3022,6 +2954,46 @@ void do_toggle(const toggle *which)
|
|||||||
}
|
}
|
||||||
#endif /* !NANO_SMALL */
|
#endif /* !NANO_SMALL */
|
||||||
|
|
||||||
|
#if !defined(NANO_SMALL) || defined(USE_SLANG)
|
||||||
|
void disable_signals(void)
|
||||||
|
{
|
||||||
|
struct termios term;
|
||||||
|
|
||||||
|
tcgetattr(0, &term);
|
||||||
|
term.c_lflag &= ~ISIG;
|
||||||
|
tcsetattr(0, TCSANOW, &term);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NANO_SMALL
|
||||||
|
void enable_signals(void)
|
||||||
|
{
|
||||||
|
struct termios term;
|
||||||
|
|
||||||
|
tcgetattr(0, &term);
|
||||||
|
term.c_lflag |= ISIG;
|
||||||
|
tcsetattr(0, TCSANOW, &term);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void disable_flow_control(void)
|
||||||
|
{
|
||||||
|
struct termios term;
|
||||||
|
|
||||||
|
tcgetattr(0, &term);
|
||||||
|
term.c_iflag &= ~(IXON|IXOFF);
|
||||||
|
tcsetattr(0, TCSANOW, &term);
|
||||||
|
}
|
||||||
|
|
||||||
|
void enable_flow_control(void)
|
||||||
|
{
|
||||||
|
struct termios term;
|
||||||
|
|
||||||
|
tcgetattr(0, &term);
|
||||||
|
term.c_iflag |= (IXON|IXOFF);
|
||||||
|
tcsetattr(0, TCSANOW, &term);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int optchr;
|
int optchr;
|
||||||
@ -3036,9 +3008,6 @@ int main(int argc, char *argv[])
|
|||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
const toggle *t;
|
const toggle *t;
|
||||||
#endif
|
#endif
|
||||||
#ifdef _POSIX_VDISABLE
|
|
||||||
struct termios term;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_GETOPT_LONG
|
#ifdef HAVE_GETOPT_LONG
|
||||||
const struct option long_options[] = {
|
const struct option long_options[] = {
|
||||||
{"help", 0, 0, 'h'},
|
{"help", 0, 0, 'h'},
|
||||||
@ -3428,36 +3397,35 @@ int main(int argc, char *argv[])
|
|||||||
filename = mallocstrcpy(filename, argv[optind]);
|
filename = mallocstrcpy(filename, argv[optind]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Termios initialization stuff: Back up the old settings so that
|
/* Back up the old terminal settings so that they can be restored. */
|
||||||
* they can be restored, disable SIGINT on ^C and SIGQUIT on ^\,
|
|
||||||
* since we need them for Cancel and Replace, and disable
|
|
||||||
* implementation-defined input processing. */
|
|
||||||
tcgetattr(0, &oldterm);
|
tcgetattr(0, &oldterm);
|
||||||
#ifdef _POSIX_VDISABLE
|
|
||||||
term = oldterm;
|
|
||||||
term.c_cc[VINTR] = _POSIX_VDISABLE;
|
|
||||||
term.c_cc[VQUIT] = _POSIX_VDISABLE;
|
|
||||||
term.c_lflag &= ~IEXTEN;
|
|
||||||
tcsetattr(0, TCSANOW, &term);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Curses initialization stuff: Start curses, save the state of the
|
/* Curses initialization stuff: Start curses, save the state of the
|
||||||
* the terminal mode, disable translation of carriage return (^M)
|
* terminal mode, put the terminal in raw mode (read one character at
|
||||||
* into newline (^J) so we can catch the Enter key and use ^J for
|
* a time and don't interpret the special control keys), disable
|
||||||
* Justify, put the terminal in cbreak mode (read one character at a
|
* translation of carriage return (^M) into newline (^J) so that we
|
||||||
* time and interpret the special control keys) if we can selectively
|
* can tell the difference between the Enter key and ^J, and disable
|
||||||
* disable the special control keys or raw mode (read one character
|
* echoing of characters as they're typed. Finally, if we're in
|
||||||
* at a time and don't interpret the special control keys) if we
|
* preserve mode, turn the flow control characters back on. */
|
||||||
* can't, and turn off echoing of characters as they're typed. */
|
|
||||||
initscr();
|
initscr();
|
||||||
savetty();
|
|
||||||
nonl();
|
|
||||||
#ifdef _POSIX_VDISABLE
|
|
||||||
cbreak();
|
|
||||||
#else
|
|
||||||
raw();
|
raw();
|
||||||
|
#ifdef USE_SLANG
|
||||||
|
/* Slang curses emulation brain damage, part 2: Raw mode acts just
|
||||||
|
* like cbreak mode here and doesn't disable interpretation of the
|
||||||
|
* special control keys. Work around this by manually disabling
|
||||||
|
* interpretation of the special control keys. */
|
||||||
|
disable_signals();
|
||||||
#endif
|
#endif
|
||||||
|
nonl();
|
||||||
noecho();
|
noecho();
|
||||||
|
if (ISSET(PRESERVE))
|
||||||
|
enable_flow_control();
|
||||||
|
|
||||||
|
#ifndef NANO_SMALL
|
||||||
|
/* Save the terminal's current state, so that we can restore it
|
||||||
|
* after a resize. */
|
||||||
|
savetty();
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Set up the global variables and the shortcuts. */
|
/* Set up the global variables and the shortcuts. */
|
||||||
global_init(0);
|
global_init(0);
|
||||||
@ -3511,8 +3479,10 @@ int main(int argc, char *argv[])
|
|||||||
if (startline > 0)
|
if (startline > 0)
|
||||||
do_gotoline(startline, 0);
|
do_gotoline(startline, 0);
|
||||||
|
|
||||||
/* Return here after a sigwinch */
|
#ifndef NANO_SMALL
|
||||||
|
/* Return here after a SIGWINCH. */
|
||||||
sigsetjmp(jmpbuf, 1);
|
sigsetjmp(jmpbuf, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* SHUT UP GCC! */
|
/* SHUT UP GCC! */
|
||||||
startline = 0;
|
startline = 0;
|
||||||
@ -3598,13 +3568,12 @@ int main(int argc, char *argv[])
|
|||||||
if (!keyhandled)
|
if (!keyhandled)
|
||||||
UNSET(KEEP_CUTBUFFER);
|
UNSET(KEEP_CUTBUFFER);
|
||||||
|
|
||||||
#ifdef _POSIX_VDISABLE
|
|
||||||
/* Don't even think about changing this string */
|
/* Don't even think about changing this string */
|
||||||
if (kbinput == NANO_CONTROL_Q)
|
if (kbinput == NANO_CONTROL_Q)
|
||||||
statusbar(_("XON ignored, mumble mumble."));
|
statusbar(_("XON ignored, mumble mumble."));
|
||||||
if (kbinput == NANO_CONTROL_S)
|
if (kbinput == NANO_CONTROL_S)
|
||||||
statusbar(_("XOFF ignored, mumble mumble."));
|
statusbar(_("XOFF ignored, mumble mumble."));
|
||||||
#endif
|
|
||||||
/* If we're in raw mode or using Alt-Alt-x, we have to catch
|
/* If we're in raw mode or using Alt-Alt-x, we have to catch
|
||||||
Control-S and Control-Q */
|
Control-S and Control-Q */
|
||||||
if (kbinput == NANO_CONTROL_Q || kbinput == NANO_CONTROL_S)
|
if (kbinput == NANO_CONTROL_Q || kbinput == NANO_CONTROL_S)
|
||||||
|
@ -54,9 +54,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_SLANG
|
#ifdef USE_SLANG
|
||||||
/* Slang support enabled. Work around Slang's not defining KEY_DC or
|
/* Slang support enabled. */
|
||||||
* KEY_IC. */
|
|
||||||
#include <slcurses.h>
|
#include <slcurses.h>
|
||||||
|
/* Slang curses emulation brain damage, part 3: Slang doesn't define the
|
||||||
|
* curses equivalents of the Insert or Delete keys. */
|
||||||
#define KEY_DC SL_KEY_DELETE
|
#define KEY_DC SL_KEY_DELETE
|
||||||
#define KEY_IC SL_KEY_IC
|
#define KEY_IC SL_KEY_IC
|
||||||
#elif defined(HAVE_NCURSES_H)
|
#elif defined(HAVE_NCURSES_H)
|
||||||
|
26
src/proto.h
26
src/proto.h
@ -54,7 +54,7 @@ extern char *quotestr;
|
|||||||
extern char *backup_dir;
|
extern char *backup_dir;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern WINDOW *edit, *topwin, *bottomwin;
|
extern WINDOW *topwin, *edit, *bottomwin;
|
||||||
extern char *filename;
|
extern char *filename;
|
||||||
extern struct stat originalfilestat;
|
extern struct stat originalfilestat;
|
||||||
extern char *answer;
|
extern char *answer;
|
||||||
@ -151,7 +151,8 @@ int do_uncut_text(void);
|
|||||||
/* Public functions in files.c */
|
/* Public functions in files.c */
|
||||||
void load_file(int update);
|
void load_file(int update);
|
||||||
void new_file(void);
|
void new_file(void);
|
||||||
filestruct *read_line(char *buf, filestruct *prev, int *line1ins, int len);
|
filestruct *read_line(char *buf, filestruct *prev, int *line1ins, size_t
|
||||||
|
len);
|
||||||
int read_file(FILE *f, const char *filename, int quiet);
|
int read_file(FILE *f, const char *filename, int quiet);
|
||||||
int open_file(const char *filename, int insert, int quiet);
|
int open_file(const char *filename, int insert, int quiet);
|
||||||
char *get_next_filename(const char *name);
|
char *get_next_filename(const char *name);
|
||||||
@ -202,7 +203,7 @@ char *input_tab(char *buf, int place, int *lastwastab, int *newplace, int *list)
|
|||||||
const char *tail(const char *foo);
|
const char *tail(const char *foo);
|
||||||
#ifndef DISABLE_BROWSER
|
#ifndef DISABLE_BROWSER
|
||||||
int diralphasort(const void *va, const void *vb);
|
int diralphasort(const void *va, const void *vb);
|
||||||
void free_charptrarray(char **array, int len);
|
void free_charptrarray(char **array, size_t len);
|
||||||
void striponedir(char *foo);
|
void striponedir(char *foo);
|
||||||
int readable_dir(const char *path);
|
int readable_dir(const char *path);
|
||||||
char **browser_init(const char *path, int *longest, int *numents);
|
char **browser_init(const char *path, int *longest, int *numents);
|
||||||
@ -268,7 +269,6 @@ void print1opt(const char *shortflag, const char *longflag,
|
|||||||
const char *desc);
|
const char *desc);
|
||||||
void usage(void);
|
void usage(void);
|
||||||
void version(void);
|
void version(void);
|
||||||
void do_early_abort(void);
|
|
||||||
int no_help(void);
|
int no_help(void);
|
||||||
int nano_disabled_msg(void);
|
int nano_disabled_msg(void);
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
@ -342,6 +342,14 @@ void allow_pending_sigwinch(int allow);
|
|||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
void do_toggle(const toggle *which);
|
void do_toggle(const toggle *which);
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(NANO_SMALL) || defined(USE_SLANG)
|
||||||
|
void disable_signals(void);
|
||||||
|
#endif
|
||||||
|
#ifndef NANO_SMALL
|
||||||
|
void enable_signals(void);
|
||||||
|
#endif
|
||||||
|
void disable_flow_control(void);
|
||||||
|
void enable_flow_control(void);
|
||||||
|
|
||||||
/* Public functions in rcfile.c */
|
/* Public functions in rcfile.c */
|
||||||
#ifdef ENABLE_NANORC
|
#ifdef ENABLE_NANORC
|
||||||
@ -469,13 +477,13 @@ size_t xplustabs(void);
|
|||||||
size_t actual_x(const char *str, size_t xplus);
|
size_t actual_x(const char *str, size_t xplus);
|
||||||
size_t strnlenpt(const char *buf, size_t size);
|
size_t strnlenpt(const char *buf, size_t size);
|
||||||
size_t strlenpt(const char *buf);
|
size_t strlenpt(const char *buf);
|
||||||
void blank_bottombars(void);
|
void blank_titlebar(void);
|
||||||
void blank_bottomwin(void);
|
|
||||||
void blank_edit(void);
|
void blank_edit(void);
|
||||||
void blank_statusbar(void);
|
void blank_statusbar(void);
|
||||||
void blank_statusbar_refresh(void);
|
void blank_statusbar_refresh(void);
|
||||||
void check_statblank(void);
|
void check_statblank(void);
|
||||||
char *display_string(const char *buf, size_t start_col, int len);
|
void blank_bottombars(void);
|
||||||
|
char *display_string(const char *buf, size_t start_col, size_t len);
|
||||||
void nanoget_repaint(const char *buf, const char *inputbuf, size_t x);
|
void nanoget_repaint(const char *buf, const char *inputbuf, size_t x);
|
||||||
int nanogetstr(int allowtabs, const char *buf, const char *def,
|
int nanogetstr(int allowtabs, const char *buf, const char *def,
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
@ -486,8 +494,9 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
|
|||||||
, int *list
|
, int *list
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
void set_modified(void);
|
|
||||||
void titlebar(const char *path);
|
void titlebar(const char *path);
|
||||||
|
void set_modified(void);
|
||||||
|
void statusbar(const char *msg, ...);
|
||||||
void bottombars(const shortcut *s);
|
void bottombars(const shortcut *s);
|
||||||
void onekey(const char *keystroke, const char *desc, int len);
|
void onekey(const char *keystroke, const char *desc, int len);
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
@ -511,7 +520,6 @@ int statusq(int allowtabs, const shortcut *s, const char *def,
|
|||||||
int do_yesno(int all, const char *msg);
|
int do_yesno(int all, const char *msg);
|
||||||
int total_refresh(void);
|
int total_refresh(void);
|
||||||
void display_main_list(void);
|
void display_main_list(void);
|
||||||
void statusbar(const char *msg, ...);
|
|
||||||
int do_cursorpos(int constant);
|
int do_cursorpos(int constant);
|
||||||
int do_cursorpos_void(void);
|
int do_cursorpos_void(void);
|
||||||
int line_len(const char *ptr);
|
int line_len(const char *ptr);
|
||||||
|
303
src/winio.c
303
src/winio.c
@ -129,14 +129,11 @@ int *get_verbatim_kbinput(WINDOW *win, size_t *kbinput_len, int
|
|||||||
allow_pending_sigwinch(TRUE);
|
allow_pending_sigwinch(TRUE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Switch to raw mode if necessary so that we can type ^C, ^Q, ^S,
|
/* Turn off flow control characters if necessary so that we can type
|
||||||
* ^Z, and ^\ (and ^Y on systems supporting delayed suspend) without
|
* them in verbatim, and turn the keypad off so that we don't get
|
||||||
* getting interrupts, and turn the keypad off so that we don't get
|
* extended keypad values outside the ASCII range. */
|
||||||
* extended keypad values, all of which are outside the ASCII
|
if (ISSET(PRESERVE))
|
||||||
* range. */
|
disable_flow_control();
|
||||||
#ifdef _POSIX_VDISABLE
|
|
||||||
raw();
|
|
||||||
#endif
|
|
||||||
keypad(win, FALSE);
|
keypad(win, FALSE);
|
||||||
|
|
||||||
kbinput = wgetch(win);
|
kbinput = wgetch(win);
|
||||||
@ -165,11 +162,10 @@ int *get_verbatim_kbinput(WINDOW *win, size_t *kbinput_len, int
|
|||||||
nodelay(win, FALSE);
|
nodelay(win, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Switch back to cbreak mode if necessary and turn the keypad back
|
/* Turn flow control characters back on if necessary and turn the
|
||||||
* on now that we're done. */
|
* keypad back on now that we're done. */
|
||||||
#ifdef _POSIX_VDISABLE
|
if (ISSET(PRESERVE))
|
||||||
cbreak();
|
enable_flow_control();
|
||||||
#endif
|
|
||||||
keypad(win, TRUE);
|
keypad(win, TRUE);
|
||||||
|
|
||||||
#ifndef NANO_SMALL
|
#ifndef NANO_SMALL
|
||||||
@ -1096,26 +1092,14 @@ size_t strlenpt(const char *buf)
|
|||||||
return strnlenpt(buf, (size_t)-1);
|
return strnlenpt(buf, (size_t)-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void blank_bottombars(void)
|
void blank_titlebar(void)
|
||||||
{
|
{
|
||||||
if (!ISSET(NO_HELP)) {
|
mvwaddstr(topwin, 0, 0, hblank);
|
||||||
mvwaddstr(bottomwin, 1, 0, hblank);
|
|
||||||
mvwaddstr(bottomwin, 2, 0, hblank);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void blank_bottomwin(void)
|
|
||||||
{
|
|
||||||
if (ISSET(NO_HELP))
|
|
||||||
return;
|
|
||||||
|
|
||||||
mvwaddstr(bottomwin, 1, 0, hblank);
|
|
||||||
mvwaddstr(bottomwin, 2, 0, hblank);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void blank_edit(void)
|
void blank_edit(void)
|
||||||
{
|
{
|
||||||
int i;
|
size_t i;
|
||||||
for (i = 0; i < editwinrows; i++)
|
for (i = 0; i < editwinrows; i++)
|
||||||
mvwaddstr(edit, i, 0, hblank);
|
mvwaddstr(edit, i, 0, hblank);
|
||||||
}
|
}
|
||||||
@ -1141,12 +1125,20 @@ void check_statblank(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void blank_bottombars(void)
|
||||||
|
{
|
||||||
|
if (!ISSET(NO_HELP)) {
|
||||||
|
mvwaddstr(bottomwin, 1, 0, hblank);
|
||||||
|
mvwaddstr(bottomwin, 2, 0, hblank);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Convert buf into a string that can be displayed on screen. The
|
/* Convert buf into a string that can be displayed on screen. The
|
||||||
* caller wants to display buf starting with column start_col, and
|
* caller wants to display buf starting with column start_col, and
|
||||||
* extending for at most len columns. start_col is zero-based. len is
|
* extending for at most len columns. start_col is zero-based. len is
|
||||||
* one-based, so len == 0 means you get "" returned. The returned
|
* one-based, so len == 0 means you get "" returned. The returned
|
||||||
* string is dynamically allocated, and should be freed. */
|
* string is dynamically allocated, and should be freed. */
|
||||||
char *display_string(const char *buf, size_t start_col, int len)
|
char *display_string(const char *buf, size_t start_col, size_t len)
|
||||||
{
|
{
|
||||||
size_t start_index;
|
size_t start_index;
|
||||||
/* Index in buf of first character shown in return value. */
|
/* Index in buf of first character shown in return value. */
|
||||||
@ -1539,16 +1531,6 @@ int nanogetstr(int allowtabs, const char *buf, const char *def,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If modified is not already set, set it and update titlebar. */
|
|
||||||
void set_modified(void)
|
|
||||||
{
|
|
||||||
if (!ISSET(MODIFIED)) {
|
|
||||||
SET(MODIFIED);
|
|
||||||
titlebar(NULL);
|
|
||||||
wrefresh(topwin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void titlebar(const char *path)
|
void titlebar(const char *path)
|
||||||
{
|
{
|
||||||
int namelen, space;
|
int namelen, space;
|
||||||
@ -1559,7 +1541,7 @@ void titlebar(const char *path)
|
|||||||
|
|
||||||
wattron(topwin, A_REVERSE);
|
wattron(topwin, A_REVERSE);
|
||||||
|
|
||||||
mvwaddstr(topwin, 0, 0, hblank);
|
blank_titlebar();
|
||||||
mvwaddnstr(topwin, 0, 2, VERMSG, COLS - 3);
|
mvwaddnstr(topwin, 0, 2, VERMSG, COLS - 3);
|
||||||
|
|
||||||
space = COLS - sizeof(VERMSG) - 23;
|
space = COLS - sizeof(VERMSG) - 23;
|
||||||
@ -1597,6 +1579,64 @@ void titlebar(const char *path)
|
|||||||
reset_cursor();
|
reset_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If modified is not already set, set it and update titlebar. */
|
||||||
|
void set_modified(void)
|
||||||
|
{
|
||||||
|
if (!ISSET(MODIFIED)) {
|
||||||
|
SET(MODIFIED);
|
||||||
|
titlebar(NULL);
|
||||||
|
wrefresh(topwin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void statusbar(const char *msg, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, msg);
|
||||||
|
|
||||||
|
/* Curses mode is turned off. If we use wmove() now, it will muck
|
||||||
|
* up the terminal settings. So we just use vfprintf(). */
|
||||||
|
if (curses_ended) {
|
||||||
|
vfprintf(stderr, msg, ap);
|
||||||
|
va_end(ap);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Blank out the line. */
|
||||||
|
blank_statusbar();
|
||||||
|
|
||||||
|
if (COLS >= 4) {
|
||||||
|
char *bar;
|
||||||
|
char *foo;
|
||||||
|
size_t start_x = 0, foo_len;
|
||||||
|
bar = charalloc(COLS - 3);
|
||||||
|
vsnprintf(bar, COLS - 3, msg, ap);
|
||||||
|
va_end(ap);
|
||||||
|
foo = display_string(bar, 0, COLS - 4);
|
||||||
|
free(bar);
|
||||||
|
foo_len = strlen(foo);
|
||||||
|
start_x = (COLS - foo_len - 4) / 2;
|
||||||
|
|
||||||
|
wmove(bottomwin, 0, start_x);
|
||||||
|
wattron(bottomwin, A_REVERSE);
|
||||||
|
|
||||||
|
waddstr(bottomwin, "[ ");
|
||||||
|
waddstr(bottomwin, foo);
|
||||||
|
free(foo);
|
||||||
|
waddstr(bottomwin, " ]");
|
||||||
|
wattroff(bottomwin, A_REVERSE);
|
||||||
|
wnoutrefresh(bottomwin);
|
||||||
|
reset_cursor();
|
||||||
|
wrefresh(edit);
|
||||||
|
/* Leave the cursor at its position in the edit window, not
|
||||||
|
* in the statusbar. */
|
||||||
|
}
|
||||||
|
|
||||||
|
SET(DISABLE_CURPOS);
|
||||||
|
statblank = 26;
|
||||||
|
}
|
||||||
|
|
||||||
void bottombars(const shortcut *s)
|
void bottombars(const shortcut *s)
|
||||||
{
|
{
|
||||||
int i, j, numcols;
|
int i, j, numcols;
|
||||||
@ -1620,7 +1660,7 @@ void bottombars(const shortcut *s)
|
|||||||
/* There will be this many columns of shortcuts */
|
/* There will be this many columns of shortcuts */
|
||||||
numcols = (slen + (slen % 2)) / 2;
|
numcols = (slen + (slen % 2)) / 2;
|
||||||
|
|
||||||
blank_bottomwin();
|
blank_bottombars();
|
||||||
|
|
||||||
for (i = 0; i < numcols; i++) {
|
for (i = 0; i < numcols; i++) {
|
||||||
for (j = 0; j <= 1; j++) {
|
for (j = 0; j <= 1; j++) {
|
||||||
@ -2370,15 +2410,15 @@ int do_yesno(int all, const char *msg)
|
|||||||
|
|
||||||
int total_refresh(void)
|
int total_refresh(void)
|
||||||
{
|
{
|
||||||
clearok(edit, TRUE);
|
|
||||||
clearok(topwin, TRUE);
|
clearok(topwin, TRUE);
|
||||||
|
clearok(edit, TRUE);
|
||||||
clearok(bottomwin, TRUE);
|
clearok(bottomwin, TRUE);
|
||||||
wnoutrefresh(edit);
|
|
||||||
wnoutrefresh(topwin);
|
wnoutrefresh(topwin);
|
||||||
|
wnoutrefresh(edit);
|
||||||
wnoutrefresh(bottomwin);
|
wnoutrefresh(bottomwin);
|
||||||
doupdate();
|
doupdate();
|
||||||
clearok(edit, FALSE);
|
|
||||||
clearok(topwin, FALSE);
|
clearok(topwin, FALSE);
|
||||||
|
clearok(edit, FALSE);
|
||||||
clearok(bottomwin, FALSE);
|
clearok(bottomwin, FALSE);
|
||||||
edit_refresh();
|
edit_refresh();
|
||||||
titlebar(NULL);
|
titlebar(NULL);
|
||||||
@ -2390,62 +2430,13 @@ void display_main_list(void)
|
|||||||
bottombars(main_list);
|
bottombars(main_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
void statusbar(const char *msg, ...)
|
/* If constant is FALSE, the user typed ^C so we unconditionally display
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
|
|
||||||
va_start(ap, msg);
|
|
||||||
|
|
||||||
/* Curses mode is turned off. If we use wmove() now, it will muck
|
|
||||||
* up the terminal settings. So we just use vfprintf(). */
|
|
||||||
if (curses_ended) {
|
|
||||||
vfprintf(stderr, msg, ap);
|
|
||||||
va_end(ap);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Blank out the line. */
|
|
||||||
blank_statusbar();
|
|
||||||
|
|
||||||
if (COLS >= 4) {
|
|
||||||
char *bar;
|
|
||||||
char *foo;
|
|
||||||
int start_x = 0;
|
|
||||||
size_t foo_len;
|
|
||||||
bar = charalloc(COLS - 3);
|
|
||||||
vsnprintf(bar, COLS - 3, msg, ap);
|
|
||||||
va_end(ap);
|
|
||||||
foo = display_string(bar, 0, COLS - 4);
|
|
||||||
free(bar);
|
|
||||||
foo_len = strlen(foo);
|
|
||||||
start_x = (COLS - foo_len - 4) / 2;
|
|
||||||
|
|
||||||
wmove(bottomwin, 0, start_x);
|
|
||||||
wattron(bottomwin, A_REVERSE);
|
|
||||||
|
|
||||||
waddstr(bottomwin, "[ ");
|
|
||||||
waddstr(bottomwin, foo);
|
|
||||||
free(foo);
|
|
||||||
waddstr(bottomwin, " ]");
|
|
||||||
wattroff(bottomwin, A_REVERSE);
|
|
||||||
wnoutrefresh(bottomwin);
|
|
||||||
reset_cursor();
|
|
||||||
wrefresh(edit);
|
|
||||||
/* Leave the cursor at its position in the edit window, not
|
|
||||||
* in the statusbar. */
|
|
||||||
}
|
|
||||||
|
|
||||||
SET(DISABLE_CURPOS);
|
|
||||||
statblank = 26;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If constant is false, the user typed ^C so we unconditionally display
|
|
||||||
* the cursor position. Otherwise, we display it only if the character
|
* the cursor position. Otherwise, we display it only if the character
|
||||||
* position changed, and DISABLE_CURPOS is not set.
|
* position changed, and DISABLE_CURPOS is not set.
|
||||||
*
|
*
|
||||||
* If constant and DISABLE_CURPOS is set, we unset it and update old_i and
|
* If constant is TRUE and DISABLE_CURPOS is set, we unset it and update
|
||||||
* old_totsize. That way, we leave the current statusbar alone, but next
|
* old_i and old_totsize. That way, we leave the current statusbar
|
||||||
* time we will display. */
|
* alone, but next time we will display. */
|
||||||
int do_cursorpos(int constant)
|
int do_cursorpos(int constant)
|
||||||
{
|
{
|
||||||
const filestruct *fileptr;
|
const filestruct *fileptr;
|
||||||
@ -2533,7 +2524,7 @@ int line_len(const char *ptr)
|
|||||||
int do_help(void)
|
int do_help(void)
|
||||||
{
|
{
|
||||||
int i, page = 0, kbinput = ERR, meta_key, no_more = 0;
|
int i, page = 0, kbinput = ERR, meta_key, no_more = 0;
|
||||||
int no_help_flag = 0;
|
int no_help_flag = FALSE;
|
||||||
const shortcut *oldshortcut;
|
const shortcut *oldshortcut;
|
||||||
|
|
||||||
blank_edit();
|
blank_edit();
|
||||||
@ -2553,7 +2544,7 @@ int do_help(void)
|
|||||||
|
|
||||||
/* Well, if we're going to do this, we should at least do it the
|
/* Well, if we're going to do this, we should at least do it the
|
||||||
* right way. */
|
* right way. */
|
||||||
no_help_flag = 1;
|
no_help_flag = TRUE;
|
||||||
UNSET(NO_HELP);
|
UNSET(NO_HELP);
|
||||||
window_init();
|
window_init();
|
||||||
bottombars(help_list);
|
bottombars(help_list);
|
||||||
@ -2701,17 +2692,13 @@ void dump_buffer_reverse(void)
|
|||||||
/* Easter egg: Display credits. Assume nodelay(edit) is FALSE. */
|
/* Easter egg: Display credits. Assume nodelay(edit) is FALSE. */
|
||||||
void do_credits(void)
|
void do_credits(void)
|
||||||
{
|
{
|
||||||
int i, j = 0, k, place = 0, start_x;
|
int crpos = 0, xlpos = 0;
|
||||||
|
const char *credits[CREDIT_LEN] = {
|
||||||
const char *what;
|
NULL, /* "The nano text editor" */
|
||||||
const char *xlcredits[XLCREDIT_LEN];
|
NULL, /* "version" */
|
||||||
|
|
||||||
const char *credits[CREDIT_LEN] = {
|
|
||||||
"0", /* "The nano text editor" */
|
|
||||||
"1", /* "version" */
|
|
||||||
VERSION,
|
VERSION,
|
||||||
"",
|
"",
|
||||||
"2", /* "Brought to you by:" */
|
NULL, /* "Brought to you by:" */
|
||||||
"Chris Allegretta",
|
"Chris Allegretta",
|
||||||
"Jordi Mallach",
|
"Jordi Mallach",
|
||||||
"Adam Rogoyski",
|
"Adam Rogoyski",
|
||||||
@ -2734,80 +2721,82 @@ void do_credits(void)
|
|||||||
"Ryan Krebs",
|
"Ryan Krebs",
|
||||||
"Albert Chin",
|
"Albert Chin",
|
||||||
"",
|
"",
|
||||||
"3", /* "Special thanks to:" */
|
NULL, /* "Special thanks to:" */
|
||||||
"Plattsburgh State University",
|
"Plattsburgh State University",
|
||||||
"Benet Laboratories",
|
"Benet Laboratories",
|
||||||
"Amy Allegretta",
|
"Amy Allegretta",
|
||||||
"Linda Young",
|
"Linda Young",
|
||||||
"Jeremy Robichaud",
|
"Jeremy Robichaud",
|
||||||
"Richard Kolb II",
|
"Richard Kolb II",
|
||||||
"4", /* "The Free Software Foundation" */
|
NULL, /* "The Free Software Foundation" */
|
||||||
"Linus Torvalds",
|
"Linus Torvalds",
|
||||||
"5", /* "For ncurses:" */
|
NULL, /* "For ncurses:" */
|
||||||
"Thomas Dickey",
|
"Thomas Dickey",
|
||||||
"Pavel Curtis",
|
"Pavel Curtis",
|
||||||
"Zeyd Ben-Halim",
|
"Zeyd Ben-Halim",
|
||||||
"Eric S. Raymond",
|
"Eric S. Raymond",
|
||||||
"6", /* "and anyone else we forgot..." */
|
NULL, /* "and anyone else we forgot..." */
|
||||||
"7", /* "Thank you for using nano!\n" */
|
NULL, /* "Thank you for using nano!" */
|
||||||
"", "", "", "",
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
"(c) 1999-2004 Chris Allegretta",
|
"(c) 1999-2004 Chris Allegretta",
|
||||||
"", "", "", "",
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
"http://www.nano-editor.org/"
|
"http://www.nano-editor.org/"
|
||||||
};
|
};
|
||||||
|
|
||||||
xlcredits[0] = _("The nano text editor");
|
const char *xlcredits[XLCREDIT_LEN] = {
|
||||||
xlcredits[1] = _("version ");
|
_("The nano text editor"),
|
||||||
xlcredits[2] = _("Brought to you by:");
|
_("version"),
|
||||||
xlcredits[3] = _("Special thanks to:");
|
_("Brought to you by:"),
|
||||||
xlcredits[4] = _("The Free Software Foundation");
|
_("Special thanks to:"),
|
||||||
xlcredits[5] = _("For ncurses:");
|
_("The Free Software Foundation"),
|
||||||
xlcredits[6] = _("and anyone else we forgot...");
|
_("For ncurses:"),
|
||||||
xlcredits[7] = _("Thank you for using nano!\n");
|
_("and anyone else we forgot..."),
|
||||||
|
_("Thank you for using nano!")
|
||||||
|
};
|
||||||
|
|
||||||
curs_set(0);
|
curs_set(0);
|
||||||
nodelay(edit, TRUE);
|
nodelay(edit, TRUE);
|
||||||
blank_bottombars();
|
scrollok(edit, TRUE);
|
||||||
mvwaddstr(topwin, 0, 0, hblank);
|
blank_titlebar();
|
||||||
blank_edit();
|
blank_edit();
|
||||||
|
blank_statusbar();
|
||||||
|
blank_bottombars();
|
||||||
|
wrefresh(topwin);
|
||||||
wrefresh(edit);
|
wrefresh(edit);
|
||||||
wrefresh(bottomwin);
|
wrefresh(bottomwin);
|
||||||
wrefresh(topwin);
|
|
||||||
|
|
||||||
while (wgetch(edit) == ERR) {
|
for (crpos = 0; crpos < CREDIT_LEN + editwinrows / 2; crpos++) {
|
||||||
for (k = 0; k <= 1; k++) {
|
if (wgetch(edit) != ERR)
|
||||||
blank_edit();
|
|
||||||
for (i = editwinrows / 2 - 1; i >= (editwinrows / 2 - 1 - j);
|
|
||||||
i--) {
|
|
||||||
mvwaddstr(edit, i * 2 - k, 0, hblank);
|
|
||||||
|
|
||||||
if (place - (editwinrows / 2 - 1 - i) < CREDIT_LEN) {
|
|
||||||
what = credits[place - (editwinrows / 2 - 1 - i)];
|
|
||||||
|
|
||||||
/* God I've missed hacking. If what is exactly
|
|
||||||
1 char long, it's a sentinel for a translated
|
|
||||||
string, so use that instead. This means no
|
|
||||||
thanking people with 1 character long names ;-) */
|
|
||||||
if (strlen(what) == 1)
|
|
||||||
what = xlcredits[atoi(what)];
|
|
||||||
} else
|
|
||||||
what = "";
|
|
||||||
|
|
||||||
start_x = COLS / 2 - strlen(what) / 2 - 1;
|
|
||||||
mvwaddstr(edit, i * 2 - k, start_x, what);
|
|
||||||
}
|
|
||||||
napms(700);
|
|
||||||
wrefresh(edit);
|
|
||||||
}
|
|
||||||
if (j < editwinrows / 2 - 1)
|
|
||||||
j++;
|
|
||||||
|
|
||||||
place++;
|
|
||||||
|
|
||||||
if (place >= CREDIT_LEN + editwinrows / 2)
|
|
||||||
break;
|
break;
|
||||||
|
if (crpos < CREDIT_LEN) {
|
||||||
|
const char *what = credits[crpos];
|
||||||
|
size_t start_x;
|
||||||
|
|
||||||
|
if (what == NULL) {
|
||||||
|
assert(0 <= xlpos && xlpos < XLCREDIT_LEN);
|
||||||
|
what = xlcredits[xlpos];
|
||||||
|
xlpos++;
|
||||||
|
}
|
||||||
|
start_x = COLS / 2 - strlen(what) / 2 - 1;
|
||||||
|
mvwaddstr(edit, editwinrows - 1 - editwinrows % 2, start_x, what);
|
||||||
|
}
|
||||||
|
napms(700);
|
||||||
|
scroll(edit);
|
||||||
|
wrefresh(edit);
|
||||||
|
if (wgetch(edit) != ERR)
|
||||||
|
break;
|
||||||
|
napms(700);
|
||||||
|
scroll(edit);
|
||||||
|
wrefresh(edit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scrollok(edit, FALSE);
|
||||||
nodelay(edit, FALSE);
|
nodelay(edit, FALSE);
|
||||||
curs_set(1);
|
curs_set(1);
|
||||||
display_main_list();
|
display_main_list();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user