2000-08-07 01:13:45 +04:00
|
|
|
/* $Id$ */
|
2000-06-06 09:53:49 +04:00
|
|
|
/**************************************************************************
|
|
|
|
* nano.c *
|
|
|
|
* *
|
2005-01-01 10:28:15 +03:00
|
|
|
* Copyright (C) 1999-2005 Chris Allegretta *
|
2000-06-06 09:53:49 +04: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 *
|
2001-10-24 15:33:54 +04:00
|
|
|
* the Free Software Foundation; either version 2, or (at your option) *
|
2000-06-06 09:53:49 +04:00
|
|
|
* any later version. *
|
|
|
|
* *
|
2005-05-15 23:57:17 +04:00
|
|
|
* 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. *
|
2000-06-06 09:53:49 +04:00
|
|
|
* *
|
|
|
|
* You should have received a copy of the GNU General Public License *
|
|
|
|
* along with this program; if not, write to the Free Software *
|
2005-05-15 23:57:17 +04:00
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
|
|
|
|
* 02110-1301, USA. *
|
2000-06-06 09:53:49 +04:00
|
|
|
* *
|
|
|
|
**************************************************************************/
|
|
|
|
|
2004-11-18 02:17:05 +03:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include <config.h>
|
|
|
|
#endif
|
2001-04-28 22:03:52 +04:00
|
|
|
|
2000-06-06 09:53:49 +04:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <locale.h>
|
|
|
|
#include "proto.h"
|
|
|
|
|
|
|
|
#ifdef HAVE_TERMIOS_H
|
|
|
|
#include <termios.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_GETOPT_H
|
|
|
|
#include <getopt.h>
|
|
|
|
#endif
|
|
|
|
|
2004-05-18 05:20:36 +04:00
|
|
|
#ifndef NANO_SMALL
|
|
|
|
#include <setjmp.h>
|
|
|
|
#endif
|
|
|
|
|
2002-07-19 05:08:59 +04:00
|
|
|
static struct termios oldterm; /* The user's original term settings */
|
2001-05-05 21:45:54 +04:00
|
|
|
static struct sigaction act; /* For all our fun signal handlers */
|
2000-06-06 09:53:49 +04:00
|
|
|
|
2004-05-18 05:20:36 +04:00
|
|
|
#ifndef NANO_SMALL
|
2005-06-16 03:35:53 +04:00
|
|
|
static sigjmp_buf jmpbuf; /* Used to return to main() after a
|
|
|
|
SIGWINCH. */
|
2004-11-23 07:08:28 +03:00
|
|
|
#endif
|
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Create a new filestruct node. Note that we specifically do not set
|
|
|
|
* prevnode->next equal to the new line. */
|
|
|
|
filestruct *make_new_node(filestruct *prevnode)
|
2005-01-19 22:52:42 +03:00
|
|
|
{
|
2005-07-08 06:47:05 +04:00
|
|
|
filestruct *newnode = (filestruct *)nmalloc(sizeof(filestruct));
|
|
|
|
|
|
|
|
newnode->data = NULL;
|
|
|
|
newnode->prev = prevnode;
|
|
|
|
newnode->next = NULL;
|
|
|
|
newnode->lineno = (prevnode != NULL) ? prevnode->lineno + 1 : 1;
|
|
|
|
|
|
|
|
return newnode;
|
2005-01-19 22:52:42 +03:00
|
|
|
}
|
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Make a copy of a filestruct node. */
|
|
|
|
filestruct *copy_node(const filestruct *src)
|
2000-06-06 09:53:49 +04:00
|
|
|
{
|
2005-07-08 06:47:05 +04:00
|
|
|
filestruct *dst;
|
2000-06-06 09:53:49 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
assert(src != NULL);
|
2000-06-06 09:53:49 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
dst = (filestruct *)nmalloc(sizeof(filestruct));
|
2003-03-11 06:50:40 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
dst->data = mallocstrcpy(NULL, src->data);
|
|
|
|
dst->next = src->next;
|
|
|
|
dst->prev = src->prev;
|
|
|
|
dst->lineno = src->lineno;
|
2002-02-27 07:14:16 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
return dst;
|
2000-06-06 09:53:49 +04:00
|
|
|
}
|
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Splice a node into an existing filestruct. */
|
|
|
|
void splice_node(filestruct *begin, filestruct *newnode, filestruct
|
|
|
|
*end)
|
2000-06-06 09:53:49 +04:00
|
|
|
{
|
2005-07-08 06:47:05 +04:00
|
|
|
assert(newnode != NULL && begin != NULL);
|
2005-06-06 20:27:18 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
newnode->next = end;
|
|
|
|
newnode->prev = begin;
|
|
|
|
begin->next = newnode;
|
|
|
|
if (end != NULL)
|
|
|
|
end->prev = newnode;
|
|
|
|
}
|
2001-07-11 06:08:33 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Unlink a node from the rest of the filestruct. */
|
|
|
|
void unlink_node(const filestruct *fileptr)
|
|
|
|
{
|
|
|
|
assert(fileptr != NULL);
|
2001-07-11 06:08:33 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
if (fileptr->prev != NULL)
|
|
|
|
fileptr->prev->next = fileptr->next;
|
|
|
|
if (fileptr->next != NULL)
|
|
|
|
fileptr->next->prev = fileptr->prev;
|
|
|
|
}
|
2001-07-11 06:08:33 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Delete a node from the filestruct. */
|
|
|
|
void delete_node(filestruct *fileptr)
|
|
|
|
{
|
|
|
|
assert(fileptr != NULL && fileptr->data != NULL);
|
2001-07-11 06:08:33 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
if (fileptr->data != NULL)
|
|
|
|
free(fileptr->data);
|
2005-07-19 08:50:55 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
free(fileptr);
|
2001-07-11 06:08:33 +04:00
|
|
|
}
|
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Duplicate a whole filestruct. */
|
|
|
|
filestruct *copy_filestruct(const filestruct *src)
|
2001-07-11 06:08:33 +04:00
|
|
|
{
|
2005-07-08 06:47:05 +04:00
|
|
|
filestruct *head, *copy;
|
2001-07-11 06:08:33 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
assert(src != NULL);
|
2004-04-30 08:49:02 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
copy = copy_node(src);
|
|
|
|
copy->prev = NULL;
|
|
|
|
head = copy;
|
|
|
|
src = src->next;
|
2004-08-11 03:05:59 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
while (src != NULL) {
|
|
|
|
copy->next = copy_node(src);
|
|
|
|
copy->next->prev = copy;
|
|
|
|
copy = copy->next;
|
2000-06-06 09:53:49 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
src = src->next;
|
|
|
|
}
|
2005-07-19 08:50:55 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
copy->next = NULL;
|
2002-02-22 07:30:50 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
return head;
|
2000-06-06 09:53:49 +04:00
|
|
|
}
|
|
|
|
|
2005-07-09 00:09:16 +04:00
|
|
|
/* Free a filestruct. */
|
2005-07-08 06:47:05 +04:00
|
|
|
void free_filestruct(filestruct *src)
|
2001-01-14 08:18:27 +03:00
|
|
|
{
|
2005-07-08 06:47:05 +04:00
|
|
|
assert(src != NULL);
|
|
|
|
|
|
|
|
while (src->next != NULL) {
|
|
|
|
src = src->next;
|
|
|
|
delete_node(src->prev);
|
|
|
|
}
|
2005-07-19 08:50:55 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
delete_node(src);
|
2001-01-14 08:18:27 +03:00
|
|
|
}
|
|
|
|
|
2005-07-17 05:44:35 +04:00
|
|
|
/* Renumber all entries in a filestruct, starting with fileptr. */
|
2005-07-09 00:59:24 +04:00
|
|
|
void renumber(filestruct *fileptr)
|
2000-06-06 09:53:49 +04:00
|
|
|
{
|
2005-07-09 00:59:24 +04:00
|
|
|
ssize_t line;
|
2005-07-08 06:47:05 +04:00
|
|
|
|
2005-07-09 00:59:24 +04:00
|
|
|
assert(fileptr != NULL && fileptr->prev != NULL);
|
2000-06-06 09:53:49 +04:00
|
|
|
|
2005-07-15 04:08:23 +04:00
|
|
|
line = (fileptr->prev == NULL) ? 0 : fileptr->prev->lineno;
|
2001-01-14 08:18:27 +03:00
|
|
|
|
2005-07-09 00:59:24 +04:00
|
|
|
assert(fileptr != fileptr->next);
|
2005-07-08 06:47:05 +04:00
|
|
|
|
2005-07-09 00:59:24 +04:00
|
|
|
for (; fileptr != NULL; fileptr = fileptr->next)
|
2005-07-15 03:51:52 +04:00
|
|
|
fileptr->lineno = ++line;
|
2000-06-06 09:53:49 +04:00
|
|
|
}
|
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Partition a filestruct so it begins at (top, top_x) and ends at (bot,
|
|
|
|
* bot_x). */
|
|
|
|
partition *partition_filestruct(filestruct *top, size_t top_x,
|
|
|
|
filestruct *bot, size_t bot_x)
|
2002-09-07 00:35:28 +04:00
|
|
|
{
|
2005-07-08 06:47:05 +04:00
|
|
|
partition *p;
|
2003-01-26 07:15:56 +03:00
|
|
|
|
2005-07-09 00:09:16 +04:00
|
|
|
assert(top != NULL && bot != NULL && openfile->fileage != NULL && openfile->filebot != NULL);
|
2002-09-07 00:35:28 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Initialize the partition. */
|
|
|
|
p = (partition *)nmalloc(sizeof(partition));
|
2002-09-07 00:35:28 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* If the top and bottom of the partition are different from the top
|
|
|
|
* and bottom of the filestruct, save the latter and then set them
|
|
|
|
* to top and bot. */
|
2005-07-09 00:09:16 +04:00
|
|
|
if (top != openfile->fileage) {
|
|
|
|
p->fileage = openfile->fileage;
|
|
|
|
openfile->fileage = top;
|
2002-09-07 00:35:28 +04:00
|
|
|
} else
|
2005-07-08 06:47:05 +04:00
|
|
|
p->fileage = NULL;
|
2005-07-09 00:09:16 +04:00
|
|
|
if (bot != openfile->filebot) {
|
|
|
|
p->filebot = openfile->filebot;
|
|
|
|
openfile->filebot = bot;
|
2005-07-08 06:47:05 +04:00
|
|
|
} else
|
|
|
|
p->filebot = NULL;
|
2002-09-07 00:35:28 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Save the line above the top of the partition, detach the top of
|
|
|
|
* the partition from it, and save the text before top_x in
|
|
|
|
* top_data. */
|
|
|
|
p->top_prev = top->prev;
|
|
|
|
top->prev = NULL;
|
|
|
|
p->top_data = mallocstrncpy(NULL, top->data, top_x + 1);
|
|
|
|
p->top_data[top_x] = '\0';
|
2005-03-30 22:11:59 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Save the line below the bottom of the partition, detach the
|
|
|
|
* bottom of the partition from it, and save the text after bot_x in
|
|
|
|
* bot_data. */
|
|
|
|
p->bot_next = bot->next;
|
|
|
|
bot->next = NULL;
|
|
|
|
p->bot_data = mallocstrcpy(NULL, bot->data + bot_x);
|
2002-09-07 00:35:28 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Remove all text after bot_x at the bottom of the partition. */
|
|
|
|
null_at(&bot->data, bot_x);
|
2002-09-07 00:35:28 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Remove all text before top_x at the top of the partition. */
|
2005-07-21 09:56:42 +04:00
|
|
|
charmove(top->data, top->data + top_x, strlen(top->data) - top_x +
|
|
|
|
1);
|
2005-07-08 06:47:05 +04:00
|
|
|
align(&top->data);
|
2003-02-10 05:32:58 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Return the partition. */
|
|
|
|
return p;
|
|
|
|
}
|
2002-09-07 00:35:28 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Unpartition a filestruct so it begins at (fileage, 0) and ends at
|
|
|
|
* (filebot, strlen(filebot)) again. */
|
|
|
|
void unpartition_filestruct(partition **p)
|
|
|
|
{
|
|
|
|
char *tmp;
|
2002-09-07 00:35:28 +04:00
|
|
|
|
2005-07-09 00:09:16 +04:00
|
|
|
assert(p != NULL && openfile->fileage != NULL && openfile->filebot != NULL);
|
2002-09-07 00:35:28 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Reattach the line above the top of the partition, and restore the
|
|
|
|
* text before top_x from top_data. Free top_data when we're done
|
|
|
|
* with it. */
|
2005-07-09 00:09:16 +04:00
|
|
|
tmp = mallocstrcpy(NULL, openfile->fileage->data);
|
|
|
|
openfile->fileage->prev = (*p)->top_prev;
|
|
|
|
if (openfile->fileage->prev != NULL)
|
|
|
|
openfile->fileage->prev->next = openfile->fileage;
|
|
|
|
openfile->fileage->data = charealloc(openfile->fileage->data,
|
|
|
|
strlen((*p)->top_data) + strlen(openfile->fileage->data) + 1);
|
|
|
|
strcpy(openfile->fileage->data, (*p)->top_data);
|
2005-07-08 06:47:05 +04:00
|
|
|
free((*p)->top_data);
|
2005-07-09 00:09:16 +04:00
|
|
|
strcat(openfile->fileage->data, tmp);
|
2005-07-08 06:47:05 +04:00
|
|
|
free(tmp);
|
2005-03-30 22:11:59 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Reattach the line below the bottom of the partition, and restore
|
|
|
|
* the text after bot_x from bot_data. Free bot_data when we're
|
|
|
|
* done with it. */
|
2005-07-09 00:09:16 +04:00
|
|
|
openfile->filebot->next = (*p)->bot_next;
|
|
|
|
if (openfile->filebot->next != NULL)
|
|
|
|
openfile->filebot->next->prev = openfile->filebot;
|
|
|
|
openfile->filebot->data = charealloc(openfile->filebot->data,
|
|
|
|
strlen(openfile->filebot->data) + strlen((*p)->bot_data) + 1);
|
|
|
|
strcat(openfile->filebot->data, (*p)->bot_data);
|
2005-07-08 06:47:05 +04:00
|
|
|
free((*p)->bot_data);
|
2002-09-07 00:35:28 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Restore the top and bottom of the filestruct, if they were
|
|
|
|
* different from the top and bottom of the partition. */
|
|
|
|
if ((*p)->fileage != NULL)
|
2005-07-09 00:09:16 +04:00
|
|
|
openfile->fileage = (*p)->fileage;
|
2005-07-08 06:47:05 +04:00
|
|
|
if ((*p)->filebot != NULL)
|
2005-07-09 00:09:16 +04:00
|
|
|
openfile->filebot = (*p)->filebot;
|
2002-09-07 00:35:28 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Uninitialize the partition. */
|
|
|
|
free(*p);
|
|
|
|
*p = NULL;
|
|
|
|
}
|
2005-02-25 22:17:57 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Move all the text between (top, top_x) and (bot, bot_x) in the
|
|
|
|
* current filestruct to a filestruct beginning with file_top and ending
|
|
|
|
* with file_bot. If no text is between (top, top_x) and (bot, bot_x),
|
|
|
|
* don't do anything. */
|
|
|
|
void move_to_filestruct(filestruct **file_top, filestruct **file_bot,
|
|
|
|
filestruct *top, size_t top_x, filestruct *bot, size_t bot_x)
|
|
|
|
{
|
|
|
|
filestruct *top_save;
|
|
|
|
bool at_edittop;
|
|
|
|
#ifndef NANO_SMALL
|
|
|
|
bool mark_inside = FALSE;
|
|
|
|
#endif
|
2005-02-25 22:17:57 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
assert(file_top != NULL && file_bot != NULL && top != NULL && bot != NULL);
|
2002-09-07 00:35:28 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* If (top, top_x)-(bot, bot_x) doesn't cover any text, get out. */
|
|
|
|
if (top == bot && top_x == bot_x)
|
|
|
|
return;
|
2002-09-07 00:35:28 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Partition the filestruct so that it contains only the text from
|
|
|
|
* (top, top_x) to (bot, bot_x), keep track of whether the top of
|
|
|
|
* the partition is the top of the edit window, and keep track of
|
|
|
|
* whether the mark begins inside the partition. */
|
|
|
|
filepart = partition_filestruct(top, top_x, bot, bot_x);
|
2005-07-09 00:09:16 +04:00
|
|
|
at_edittop = (openfile->fileage == openfile->edittop);
|
2005-07-08 06:47:05 +04:00
|
|
|
#ifndef NANO_SMALL
|
2005-07-09 00:09:16 +04:00
|
|
|
if (openfile->mark_set)
|
2005-07-12 21:40:16 +04:00
|
|
|
mark_inside = (openfile->mark_begin->lineno >=
|
2005-07-09 00:09:16 +04:00
|
|
|
openfile->fileage->lineno &&
|
2005-07-12 21:40:16 +04:00
|
|
|
openfile->mark_begin->lineno <=
|
2005-07-09 00:09:16 +04:00
|
|
|
openfile->filebot->lineno &&
|
2005-07-12 21:40:16 +04:00
|
|
|
(openfile->mark_begin != openfile->fileage ||
|
|
|
|
openfile->mark_begin_x >= top_x) &&
|
|
|
|
(openfile->mark_begin != openfile->filebot ||
|
|
|
|
openfile->mark_begin_x <= bot_x));
|
2005-07-08 06:47:05 +04:00
|
|
|
#endif
|
2005-02-25 22:17:57 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Get the number of characters in the text, and subtract it from
|
|
|
|
* totsize. */
|
2005-07-17 05:44:35 +04:00
|
|
|
openfile->totsize -= get_totsize(top, bot);
|
2005-02-25 22:17:57 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
if (*file_top == NULL) {
|
|
|
|
/* If file_top is empty, just move all the text directly into
|
|
|
|
* it. This is equivalent to tacking the text in top onto the
|
|
|
|
* (lack of) text at the end of file_top. */
|
2005-07-09 00:09:16 +04:00
|
|
|
*file_top = openfile->fileage;
|
|
|
|
*file_bot = openfile->filebot;
|
2005-07-17 05:44:35 +04:00
|
|
|
|
|
|
|
/* Renumber starting with file_top. */
|
|
|
|
renumber(*file_top);
|
2005-07-08 06:47:05 +04:00
|
|
|
} else {
|
2005-07-17 05:44:35 +04:00
|
|
|
filestruct *file_bot_save = *file_bot;
|
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Otherwise, tack the text in top onto the text at the end of
|
|
|
|
* file_bot. */
|
|
|
|
(*file_bot)->data = charealloc((*file_bot)->data,
|
2005-07-09 00:09:16 +04:00
|
|
|
strlen((*file_bot)->data) +
|
|
|
|
strlen(openfile->fileage->data) + 1);
|
|
|
|
strcat((*file_bot)->data, openfile->fileage->data);
|
2002-09-07 00:35:28 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Attach the line after top to the line after file_bot. Then,
|
|
|
|
* if there's more than one line after top, move file_bot down
|
|
|
|
* to bot. */
|
2005-07-09 00:09:16 +04:00
|
|
|
(*file_bot)->next = openfile->fileage->next;
|
2005-07-08 06:47:05 +04:00
|
|
|
if ((*file_bot)->next != NULL) {
|
|
|
|
(*file_bot)->next->prev = *file_bot;
|
2005-07-09 00:09:16 +04:00
|
|
|
*file_bot = openfile->filebot;
|
2004-09-12 01:41:13 +04:00
|
|
|
}
|
2005-07-17 05:44:35 +04:00
|
|
|
|
|
|
|
/* Renumber starting with the line after the original
|
|
|
|
* file_bot. */
|
|
|
|
if (file_bot_save->next != NULL)
|
|
|
|
renumber(file_bot_save->next);
|
2005-07-08 06:47:05 +04:00
|
|
|
}
|
2002-09-07 00:35:28 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Since the text has now been saved, remove it from the filestruct.
|
|
|
|
* If the top of the partition was the top of the edit window, set
|
|
|
|
* edittop to where the text used to start. If the mark began
|
|
|
|
* inside the partition, set the beginning of the mark to where the
|
|
|
|
* text used to start. */
|
2005-07-09 00:09:16 +04:00
|
|
|
openfile->fileage = (filestruct *)nmalloc(sizeof(filestruct));
|
|
|
|
openfile->fileage->data = mallocstrcpy(NULL, "");
|
|
|
|
openfile->filebot = openfile->fileage;
|
2005-07-08 06:47:05 +04:00
|
|
|
if (at_edittop)
|
2005-07-09 00:09:16 +04:00
|
|
|
openfile->edittop = openfile->fileage;
|
2005-07-08 06:47:05 +04:00
|
|
|
#ifndef NANO_SMALL
|
|
|
|
if (mark_inside) {
|
2005-07-12 21:40:16 +04:00
|
|
|
openfile->mark_begin = openfile->fileage;
|
|
|
|
openfile->mark_begin_x = top_x;
|
2005-07-08 06:47:05 +04:00
|
|
|
}
|
|
|
|
#endif
|
2002-09-07 00:35:28 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Restore the current line and cursor position. */
|
2005-07-09 00:09:16 +04:00
|
|
|
openfile->current = openfile->fileage;
|
|
|
|
openfile->current_x = top_x;
|
2005-02-25 22:17:57 +03:00
|
|
|
|
2005-07-09 00:09:16 +04:00
|
|
|
top_save = openfile->fileage;
|
2005-02-25 22:17:57 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Unpartition the filestruct so that it contains all the text
|
|
|
|
* again, minus the saved text. */
|
|
|
|
unpartition_filestruct(&filepart);
|
2005-02-25 22:17:57 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Renumber starting with the beginning line of the old
|
|
|
|
* partition. */
|
|
|
|
renumber(top_save);
|
2005-06-13 18:00:22 +04:00
|
|
|
|
2005-07-09 00:09:16 +04:00
|
|
|
if (openfile->filebot->data[0] != '\0')
|
2005-07-08 06:47:05 +04:00
|
|
|
new_magicline();
|
|
|
|
}
|
2005-03-04 20:09:41 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Copy all the text from the filestruct beginning with file_top and
|
|
|
|
* ending with file_bot to the current filestruct at the current cursor
|
|
|
|
* position. */
|
|
|
|
void copy_from_filestruct(filestruct *file_top, filestruct *file_bot)
|
|
|
|
{
|
|
|
|
filestruct *top_save;
|
|
|
|
bool at_edittop;
|
2005-03-04 20:09:41 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
assert(file_top != NULL && file_bot != NULL);
|
2005-02-25 22:17:57 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Partition the filestruct so that it contains no text, and keep
|
|
|
|
* track of whether the top of the partition is the top of the edit
|
|
|
|
* window. */
|
2005-07-09 00:09:16 +04:00
|
|
|
filepart = partition_filestruct(openfile->current,
|
|
|
|
openfile->current_x, openfile->current, openfile->current_x);
|
|
|
|
at_edittop = (openfile->fileage == openfile->edittop);
|
2002-09-07 00:35:28 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Put the top and bottom of the filestruct at copies of file_top
|
|
|
|
* and file_bot. */
|
2005-07-09 00:09:16 +04:00
|
|
|
openfile->fileage = copy_filestruct(file_top);
|
|
|
|
openfile->filebot = openfile->fileage;
|
|
|
|
while (openfile->filebot->next != NULL)
|
|
|
|
openfile->filebot = openfile->filebot->next;
|
2002-09-07 00:35:28 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Restore the current line and cursor position. */
|
2005-07-09 00:09:16 +04:00
|
|
|
openfile->current = openfile->filebot;
|
|
|
|
openfile->current_x = strlen(openfile->filebot->data);
|
|
|
|
if (openfile->fileage == openfile->filebot)
|
|
|
|
openfile->current_x += strlen(filepart->top_data);
|
2005-05-15 00:52:20 +04:00
|
|
|
|
2005-07-17 05:44:35 +04:00
|
|
|
/* Get the number of characters in the text, and add it to
|
|
|
|
* totsize. */
|
|
|
|
openfile->totsize += get_totsize(openfile->fileage,
|
|
|
|
openfile->filebot);
|
2005-05-15 00:52:20 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* If the top of the partition was the top of the edit window, set
|
|
|
|
* edittop to where the saved text now starts, and update the
|
|
|
|
* current y-coordinate to account for the number of lines it
|
|
|
|
* has, less one since the first line will be tacked onto the
|
|
|
|
* current line. */
|
|
|
|
if (at_edittop)
|
2005-07-09 00:09:16 +04:00
|
|
|
openfile->edittop = openfile->fileage;
|
2005-07-17 05:44:35 +04:00
|
|
|
openfile->current_y += openfile->filebot->lineno - 1;
|
2002-09-07 00:35:28 +04:00
|
|
|
|
2005-07-09 00:09:16 +04:00
|
|
|
top_save = openfile->fileage;
|
2005-03-04 20:09:41 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Unpartition the filestruct so that it contains all the text
|
|
|
|
* again, minus the saved text. */
|
|
|
|
unpartition_filestruct(&filepart);
|
2005-03-04 20:09:41 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Renumber starting with the beginning line of the old
|
|
|
|
* partition. */
|
|
|
|
renumber(top_save);
|
2005-03-04 20:09:41 +03:00
|
|
|
|
2005-07-09 00:09:16 +04:00
|
|
|
if (openfile->filebot->data[0] != '\0')
|
2005-07-08 06:47:05 +04:00
|
|
|
new_magicline();
|
2000-06-06 09:53:49 +04:00
|
|
|
}
|
|
|
|
|
2005-07-21 01:08:38 +04:00
|
|
|
/* Create a new openfilestruct node. */
|
|
|
|
openfilestruct *make_new_opennode(void)
|
|
|
|
{
|
|
|
|
openfilestruct *newnode =
|
|
|
|
(openfilestruct *)nmalloc(sizeof(openfilestruct));
|
|
|
|
|
|
|
|
newnode->filename = NULL;
|
|
|
|
newnode->fileage = NULL;
|
|
|
|
newnode->filebot = NULL;
|
|
|
|
newnode->edittop = NULL;
|
|
|
|
newnode->current = NULL;
|
|
|
|
|
|
|
|
return newnode;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Splice a node into an existing openfilestruct. */
|
|
|
|
void splice_opennode(openfilestruct *begin, openfilestruct *newnode,
|
|
|
|
openfilestruct *end)
|
|
|
|
{
|
|
|
|
assert(newnode != NULL && begin != NULL);
|
|
|
|
|
|
|
|
newnode->next = end;
|
|
|
|
newnode->prev = begin;
|
|
|
|
begin->next = newnode;
|
|
|
|
|
|
|
|
if (end != NULL)
|
|
|
|
end->prev = newnode;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Unlink a node from the rest of the openfilestruct, and delete it. */
|
|
|
|
void unlink_opennode(openfilestruct *fileptr)
|
|
|
|
{
|
|
|
|
assert(fileptr != NULL && fileptr->prev != NULL && fileptr->next != NULL && fileptr != fileptr->prev && fileptr != fileptr->next);
|
|
|
|
|
|
|
|
fileptr->prev->next = fileptr->next;
|
|
|
|
fileptr->next->prev = fileptr->prev;
|
|
|
|
|
|
|
|
delete_opennode(fileptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Delete a node from the openfilestruct. */
|
|
|
|
void delete_opennode(openfilestruct *fileptr)
|
|
|
|
{
|
|
|
|
assert(fileptr != NULL && fileptr->filename != NULL && fileptr->fileage != NULL);
|
|
|
|
|
|
|
|
free(fileptr->filename);
|
|
|
|
free_filestruct(fileptr->fileage);
|
|
|
|
#ifndef NANO_SMALL
|
|
|
|
if (fileptr->current_stat != NULL)
|
|
|
|
free(fileptr->current_stat);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
free(fileptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
/* Deallocate all memory associated with this and later files, including
|
|
|
|
* the lines of text. */
|
|
|
|
void free_openfilestruct(openfilestruct *src)
|
|
|
|
{
|
|
|
|
assert(src != NULL);
|
|
|
|
|
|
|
|
while (src != src->next) {
|
|
|
|
src = src->next;
|
|
|
|
delete_opennode(src->prev);
|
|
|
|
}
|
|
|
|
|
|
|
|
delete_opennode(src);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
void print_view_warning(void)
|
2002-09-07 00:35:28 +04:00
|
|
|
{
|
2005-07-08 06:47:05 +04:00
|
|
|
statusbar(_("Key illegal in VIEW mode"));
|
2002-09-07 00:35:28 +04:00
|
|
|
}
|
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* What we do when we're all set to exit. */
|
|
|
|
void finish(void)
|
2000-06-06 09:53:49 +04:00
|
|
|
{
|
2005-07-08 06:47:05 +04:00
|
|
|
if (!ISSET(NO_HELP))
|
|
|
|
blank_bottombars();
|
|
|
|
else
|
|
|
|
blank_statusbar();
|
2005-03-04 20:09:41 +03:00
|
|
|
|
2005-07-29 07:28:09 +04:00
|
|
|
wrefresh(bottomwin);
|
2005-07-08 06:47:05 +04:00
|
|
|
endwin();
|
2002-04-10 06:31:20 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Restore the old terminal settings. */
|
|
|
|
tcsetattr(0, TCSANOW, &oldterm);
|
2005-03-04 20:09:41 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
#if !defined(NANO_SMALL) && defined(ENABLE_NANORC)
|
|
|
|
if (!ISSET(NO_RCFILE) && ISSET(HISTORYLOG))
|
|
|
|
save_history();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
thanks_for_all_the_fish();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
exit(0);
|
2002-04-10 06:31:20 +04:00
|
|
|
}
|
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Die (gracefully?). */
|
|
|
|
void die(const char *msg, ...)
|
2000-06-06 09:53:49 +04:00
|
|
|
{
|
2005-07-08 06:47:05 +04:00
|
|
|
va_list ap;
|
2000-06-06 09:53:49 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
endwin();
|
|
|
|
curses_ended = TRUE;
|
2000-06-06 09:53:49 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Restore the old terminal settings. */
|
|
|
|
tcsetattr(0, TCSANOW, &oldterm);
|
2005-05-15 00:52:20 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
va_start(ap, msg);
|
|
|
|
vfprintf(stderr, msg, ap);
|
|
|
|
va_end(ap);
|
2000-06-06 09:53:49 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Save the current file buffer if it's been modified. */
|
2005-07-09 00:09:16 +04:00
|
|
|
if (openfile->modified) {
|
2005-07-08 06:47:05 +04:00
|
|
|
/* If we've partitioned the filestruct, unpartition it now. */
|
|
|
|
if (filepart != NULL)
|
|
|
|
unpartition_filestruct(&filepart);
|
|
|
|
|
2005-07-09 00:09:16 +04:00
|
|
|
die_save_file(openfile->filename);
|
2000-06-06 09:53:49 +04:00
|
|
|
}
|
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
#ifdef ENABLE_MULTIBUFFER
|
|
|
|
/* Save all of the other modified file buffers, if any. */
|
2005-07-08 23:57:25 +04:00
|
|
|
if (openfile != NULL) {
|
|
|
|
openfilestruct *tmp = openfile;
|
2000-06-06 09:53:49 +04:00
|
|
|
|
2005-07-08 23:57:25 +04:00
|
|
|
while (tmp != openfile->next) {
|
|
|
|
openfile = openfile->next;
|
2004-11-25 07:39:07 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Save the current file buffer if it's been modified. */
|
2005-07-09 00:09:16 +04:00
|
|
|
if (openfile->modified)
|
2005-07-08 23:57:25 +04:00
|
|
|
die_save_file(openfile->filename);
|
2005-07-08 06:47:05 +04:00
|
|
|
}
|
2002-04-10 06:31:20 +04:00
|
|
|
}
|
2005-07-08 06:47:05 +04:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Get out. */
|
|
|
|
exit(1);
|
2002-04-10 06:31:20 +04:00
|
|
|
}
|
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
void die_save_file(const char *die_filename)
|
2004-11-04 01:03:41 +03:00
|
|
|
{
|
2005-07-08 06:47:05 +04:00
|
|
|
char *retval;
|
|
|
|
bool failed = TRUE;
|
2005-03-04 20:09:41 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* If we're using restricted mode, don't write any emergency backup
|
|
|
|
* files, since that would allow reading from or writing to files
|
|
|
|
* not specified on the command line. */
|
|
|
|
if (ISSET(RESTRICTED))
|
|
|
|
return;
|
2004-11-04 01:03:41 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* If we can't save, we have REAL bad problems, but we might as well
|
|
|
|
* TRY. */
|
|
|
|
if (die_filename[0] == '\0')
|
|
|
|
die_filename = "nano";
|
2004-11-04 01:03:41 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
retval = get_next_filename(die_filename, ".save");
|
|
|
|
if (retval[0] != '\0')
|
|
|
|
failed = (write_file(retval, NULL, TRUE, FALSE, TRUE) == -1);
|
2004-11-04 01:03:41 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
if (!failed)
|
|
|
|
fprintf(stderr, _("\nBuffer written to %s\n"), retval);
|
|
|
|
else if (retval[0] != '\0')
|
|
|
|
fprintf(stderr, _("\nBuffer not written to %s: %s\n"), retval,
|
|
|
|
strerror(errno));
|
|
|
|
else
|
|
|
|
fprintf(stderr, _("\nBuffer not written: %s\n"),
|
|
|
|
_("Too many backup files?"));
|
2004-11-04 01:03:41 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
free(retval);
|
|
|
|
}
|
2004-11-04 01:03:41 +03:00
|
|
|
|
2005-07-26 02:54:16 +04:00
|
|
|
void window_init(void)
|
2005-07-08 06:47:05 +04:00
|
|
|
{
|
2005-07-26 02:54:16 +04:00
|
|
|
/* If the screen height is too small, get out. */
|
2005-07-08 06:47:05 +04:00
|
|
|
editwinrows = LINES - 5 + no_more_space() + no_help();
|
|
|
|
if (editwinrows < MIN_EDITOR_ROWS)
|
|
|
|
die(_("Window size is too small for nano...\n"));
|
2005-07-10 06:37:38 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
#ifndef DISABLE_WRAPJUSTIFY
|
2005-07-26 02:54:16 +04:00
|
|
|
/* Set up fill, based on the screen width. */
|
2005-07-08 06:47:05 +04:00
|
|
|
fill = wrap_at;
|
|
|
|
if (fill <= 0)
|
|
|
|
fill += COLS;
|
|
|
|
if (fill < 0)
|
|
|
|
fill = 0;
|
|
|
|
#endif
|
2004-11-04 01:03:41 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
if (topwin != NULL)
|
|
|
|
delwin(topwin);
|
|
|
|
if (edit != NULL)
|
|
|
|
delwin(edit);
|
|
|
|
if (bottomwin != NULL)
|
|
|
|
delwin(bottomwin);
|
2004-11-04 01:03:41 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Set up the windows. */
|
|
|
|
topwin = newwin(2 - no_more_space(), COLS, 0, 0);
|
|
|
|
edit = newwin(editwinrows, COLS, 2 - no_more_space(), 0);
|
2005-07-21 09:56:42 +04:00
|
|
|
bottomwin = newwin(3 - no_help(), COLS, editwinrows + (2 -
|
|
|
|
no_more_space()), 0);
|
2004-11-04 01:03:41 +03:00
|
|
|
|
2005-07-26 09:20:02 +04:00
|
|
|
/* Turn the keypad on for the windows that get input. */
|
2005-07-08 06:47:05 +04:00
|
|
|
keypad(edit, TRUE);
|
|
|
|
keypad(bottomwin, TRUE);
|
2004-11-04 01:03:41 +03:00
|
|
|
}
|
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
#ifndef DISABLE_MOUSE
|
|
|
|
void mouse_init(void)
|
2004-11-23 07:08:28 +03:00
|
|
|
{
|
2005-07-08 06:47:05 +04:00
|
|
|
if (ISSET(USE_MOUSE)) {
|
|
|
|
mousemask(BUTTON1_RELEASED, NULL);
|
|
|
|
mouseinterval(50);
|
|
|
|
} else
|
|
|
|
mousemask(0, NULL);
|
|
|
|
}
|
2004-11-23 07:08:28 +03:00
|
|
|
#endif
|
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
#ifndef DISABLE_HELP
|
|
|
|
/* This function allocates help_text, and stores the help string in it.
|
|
|
|
* help_text should be NULL initially. */
|
|
|
|
void help_init(void)
|
|
|
|
{
|
|
|
|
size_t allocsize = 0; /* Space needed for help_text. */
|
|
|
|
const char *htx[3]; /* Untranslated help message. We break
|
|
|
|
* it up into three chunks in case the
|
|
|
|
* full string is too long for the
|
|
|
|
* compiler to handle. */
|
|
|
|
char *ptr;
|
|
|
|
const shortcut *s;
|
|
|
|
#ifndef NANO_SMALL
|
|
|
|
const toggle *t;
|
|
|
|
#ifdef ENABLE_NANORC
|
|
|
|
bool old_whitespace = ISSET(WHITESPACE_DISPLAY);
|
2004-11-23 07:08:28 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
UNSET(WHITESPACE_DISPLAY);
|
|
|
|
#endif
|
|
|
|
#endif
|
2004-11-23 07:08:28 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* First, set up the initial help text for the current function. */
|
2005-07-21 09:56:42 +04:00
|
|
|
if (currshortcut == whereis_list || currshortcut == replace_list ||
|
|
|
|
currshortcut == replace_list_2) {
|
2005-07-08 06:47:05 +04:00
|
|
|
htx[0] = N_("Search Command Help Text\n\n "
|
|
|
|
"Enter the words or characters you would like to "
|
|
|
|
"search for, and then press Enter. If there is a "
|
|
|
|
"match for the text you entered, the screen will be "
|
|
|
|
"updated to the location of the nearest match for the "
|
|
|
|
"search string.\n\n The previous search string will be "
|
|
|
|
"shown in brackets after the search prompt. Hitting "
|
|
|
|
"Enter without entering any text will perform the "
|
|
|
|
"previous search. ");
|
|
|
|
htx[1] = N_("If you have selected text with the mark and then "
|
|
|
|
"search to replace, only matches in the selected text "
|
|
|
|
"will be replaced.\n\n The following function keys are "
|
|
|
|
"available in Search mode:\n\n");
|
|
|
|
htx[2] = NULL;
|
|
|
|
} else if (currshortcut == gotoline_list) {
|
|
|
|
htx[0] = N_("Go To Line Help Text\n\n "
|
|
|
|
"Enter the line number that you wish to go to and hit "
|
|
|
|
"Enter. If there are fewer lines of text than the "
|
|
|
|
"number you entered, you will be brought to the last "
|
|
|
|
"line of the file.\n\n The following function keys are "
|
|
|
|
"available in Go To Line mode:\n\n");
|
|
|
|
htx[1] = NULL;
|
|
|
|
htx[2] = NULL;
|
|
|
|
} else if (currshortcut == insertfile_list) {
|
|
|
|
htx[0] = N_("Insert File Help Text\n\n "
|
|
|
|
"Type in the name of a file to be inserted into the "
|
|
|
|
"current file buffer at the current cursor "
|
|
|
|
"location.\n\n If you have compiled nano with multiple "
|
|
|
|
"file buffer support, and enable multiple file buffers "
|
|
|
|
"with the -F or --multibuffer command line flags, the "
|
|
|
|
"Meta-F toggle, or a nanorc file, inserting a file "
|
|
|
|
"will cause it to be loaded into a separate buffer "
|
|
|
|
"(use Meta-< and > to switch between file buffers). ");
|
|
|
|
htx[1] = N_("If you need another blank buffer, do not enter "
|
|
|
|
"any filename, or type in a nonexistent filename at "
|
|
|
|
"the prompt and press Enter.\n\n The following "
|
|
|
|
"function keys are available in Insert File mode:\n\n");
|
|
|
|
htx[2] = NULL;
|
|
|
|
} else if (currshortcut == writefile_list) {
|
|
|
|
htx[0] = N_("Write File Help Text\n\n "
|
|
|
|
"Type the name that you wish to save the current file "
|
|
|
|
"as and press Enter to save the file.\n\n If you have "
|
|
|
|
"selected text with the mark, you will be prompted to "
|
|
|
|
"save only the selected portion to a separate file. To "
|
|
|
|
"reduce the chance of overwriting the current file with "
|
|
|
|
"just a portion of it, the current filename is not the "
|
|
|
|
"default in this mode.\n\n The following function keys "
|
|
|
|
"are available in Write File mode:\n\n");
|
|
|
|
htx[1] = NULL;
|
|
|
|
htx[2] = NULL;
|
|
|
|
}
|
|
|
|
#ifndef DISABLE_BROWSER
|
|
|
|
else if (currshortcut == browser_list) {
|
|
|
|
htx[0] = N_("File Browser Help Text\n\n "
|
|
|
|
"The file browser is used to visually browse the "
|
|
|
|
"directory structure to select a file for reading "
|
|
|
|
"or writing. You may use the arrow keys or Page Up/"
|
|
|
|
"Down to browse through the files, and S or Enter to "
|
|
|
|
"choose the selected file or enter the selected "
|
|
|
|
"directory. To move up one level, select the "
|
|
|
|
"directory called \"..\" at the top of the file "
|
|
|
|
"list.\n\n The following function keys are available "
|
|
|
|
"in the file browser:\n\n");
|
|
|
|
htx[1] = NULL;
|
|
|
|
htx[2] = NULL;
|
|
|
|
} else if (currshortcut == gotodir_list) {
|
|
|
|
htx[0] = N_("Browser Go To Directory Help Text\n\n "
|
|
|
|
"Enter the name of the directory you would like to "
|
|
|
|
"browse to.\n\n If tab completion has not been "
|
|
|
|
"disabled, you can use the Tab key to (attempt to) "
|
|
|
|
"automatically complete the directory name.\n\n The "
|
|
|
|
"following function keys are available in Browser Go "
|
|
|
|
"To Directory mode:\n\n");
|
|
|
|
htx[1] = NULL;
|
|
|
|
htx[2] = NULL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifndef DISABLE_SPELLER
|
|
|
|
else if (currshortcut == spell_list) {
|
|
|
|
htx[0] = N_("Spell Check Help Text\n\n "
|
|
|
|
"The spell checker checks the spelling of all text in "
|
|
|
|
"the current file. When an unknown word is "
|
|
|
|
"encountered, it is highlighted and a replacement can "
|
|
|
|
"be edited. It will then prompt to replace every "
|
|
|
|
"instance of the given misspelled word in the current "
|
|
|
|
"file, or, if you have selected text with the mark, in "
|
|
|
|
"the selected text.\n\n The following other functions "
|
|
|
|
"are available in Spell Check mode:\n\n");
|
|
|
|
htx[1] = NULL;
|
|
|
|
htx[2] = NULL;
|
|
|
|
}
|
|
|
|
#endif
|
2004-11-23 07:08:28 +03:00
|
|
|
#ifndef NANO_SMALL
|
2005-07-08 06:47:05 +04:00
|
|
|
else if (currshortcut == extcmd_list) {
|
|
|
|
htx[0] = N_("Execute Command Help Text\n\n "
|
|
|
|
"This menu allows you to insert the output of a "
|
|
|
|
"command run by the shell into the current buffer (or "
|
|
|
|
"a new buffer in multiple file buffer mode). If you "
|
|
|
|
"need another blank buffer, do not enter any "
|
|
|
|
"command.\n\n The following keys are available in "
|
|
|
|
"Execute Command mode:\n\n");
|
|
|
|
htx[1] = NULL;
|
|
|
|
htx[2] = NULL;
|
|
|
|
}
|
2004-11-23 07:08:28 +03:00
|
|
|
#endif
|
2005-07-08 06:47:05 +04:00
|
|
|
else {
|
|
|
|
/* Default to the main help list. */
|
|
|
|
htx[0] = N_(" nano help text\n\n "
|
|
|
|
"The nano editor is designed to emulate the "
|
|
|
|
"functionality and ease-of-use of the UW Pico text "
|
|
|
|
"editor. There are four main sections of the editor. "
|
|
|
|
"The top line shows the program version, the current "
|
|
|
|
"filename being edited, and whether or not the file "
|
|
|
|
"has been modified. Next is the main editor window "
|
|
|
|
"showing the file being edited. The status line is "
|
|
|
|
"the third line from the bottom and shows important "
|
|
|
|
"messages. The bottom two lines show the most "
|
|
|
|
"commonly used shortcuts in the editor.\n\n ");
|
|
|
|
htx[1] = N_("The notation for shortcuts is as follows: "
|
|
|
|
"Control-key sequences are notated with a caret (^) "
|
|
|
|
"symbol and can be entered either by using the Control "
|
|
|
|
"(Ctrl) key or pressing the Escape (Esc) key twice. "
|
|
|
|
"Escape-key sequences are notated with the Meta (M) "
|
|
|
|
"symbol and can be entered using either the Esc, Alt, "
|
|
|
|
"or Meta key depending on your keyboard setup. ");
|
|
|
|
htx[2] = N_("Also, pressing Esc twice and then typing a "
|
|
|
|
"three-digit decimal number from 000 to 255 will enter "
|
|
|
|
"the character with the corresponding value. The "
|
|
|
|
"following keystrokes are available in the main editor "
|
|
|
|
"window. Alternative keys are shown in "
|
|
|
|
"parentheses:\n\n");
|
|
|
|
}
|
2004-11-23 07:08:28 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
htx[0] = _(htx[0]);
|
|
|
|
if (htx[1] != NULL)
|
|
|
|
htx[1] = _(htx[1]);
|
|
|
|
if (htx[2] != NULL)
|
|
|
|
htx[2] = _(htx[2]);
|
2004-11-23 07:08:28 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
allocsize += strlen(htx[0]);
|
|
|
|
if (htx[1] != NULL)
|
|
|
|
allocsize += strlen(htx[1]);
|
|
|
|
if (htx[2] != NULL)
|
|
|
|
allocsize += strlen(htx[2]);
|
2004-11-23 07:08:28 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* The space needed for the shortcut lists, at most COLS characters,
|
|
|
|
* plus '\n'. */
|
|
|
|
allocsize += (COLS < 24 ? (24 * mb_cur_max()) :
|
|
|
|
((COLS + 1) * mb_cur_max())) * length_of_list(currshortcut);
|
2004-11-23 07:08:28 +03:00
|
|
|
|
|
|
|
#ifndef NANO_SMALL
|
2005-07-08 06:47:05 +04:00
|
|
|
/* If we're on the main list, we also count the toggle help text.
|
|
|
|
* Each line has "M-%c\t\t\t", which fills 24 columns, plus a space,
|
|
|
|
* plus translated text, plus '\n'. */
|
|
|
|
if (currshortcut == main_list) {
|
|
|
|
size_t endis_len = strlen(_("enable/disable"));
|
|
|
|
|
|
|
|
for (t = toggles; t != NULL; t = t->next)
|
|
|
|
allocsize += 8 + strlen(t->desc) + endis_len;
|
2004-11-23 07:08:28 +03:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* help_text has been freed and set to NULL unless the user resized
|
|
|
|
* while in the help screen. */
|
|
|
|
free(help_text);
|
2004-11-23 07:08:28 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Allocate space for the help text. */
|
|
|
|
help_text = charalloc(allocsize + 1);
|
2004-11-23 07:08:28 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Now add the text we want. */
|
|
|
|
strcpy(help_text, htx[0]);
|
|
|
|
if (htx[1] != NULL)
|
|
|
|
strcat(help_text, htx[1]);
|
|
|
|
if (htx[2] != NULL)
|
|
|
|
strcat(help_text, htx[2]);
|
2004-11-23 07:08:28 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
ptr = help_text + strlen(help_text);
|
2004-11-23 07:08:28 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Now add our shortcut info. Assume that each shortcut has, at the
|
|
|
|
* very least, an equivalent control key, an equivalent primary meta
|
|
|
|
* key sequence, or both. Also assume that the meta key values are
|
|
|
|
* not control characters. We can display a maximum of 3 shortcut
|
|
|
|
* entries. */
|
|
|
|
for (s = currshortcut; s != NULL; s = s->next) {
|
|
|
|
int entries = 0;
|
2004-11-23 07:08:28 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Control key. */
|
|
|
|
if (s->ctrlval != NANO_NO_KEY) {
|
|
|
|
entries++;
|
|
|
|
/* Yucky sentinel values that we can't handle a better
|
|
|
|
* way. */
|
|
|
|
if (s->ctrlval == NANO_CONTROL_SPACE) {
|
|
|
|
char *space_ptr = display_string(_("Space"), 0, 6,
|
|
|
|
FALSE);
|
2004-11-23 07:08:28 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
ptr += sprintf(ptr, "^%s", space_ptr);
|
2004-11-23 07:08:28 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
free(space_ptr);
|
|
|
|
} else if (s->ctrlval == NANO_CONTROL_8)
|
|
|
|
ptr += sprintf(ptr, "^?");
|
|
|
|
/* Normal values. */
|
|
|
|
else
|
|
|
|
ptr += sprintf(ptr, "^%c", s->ctrlval + 64);
|
|
|
|
*(ptr++) = '\t';
|
|
|
|
}
|
2004-11-23 07:08:28 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Function key. */
|
|
|
|
if (s->funcval != NANO_NO_KEY) {
|
|
|
|
entries++;
|
|
|
|
/* If this is the first entry, put it in the middle. */
|
|
|
|
if (entries == 1) {
|
|
|
|
entries++;
|
|
|
|
*(ptr++) = '\t';
|
|
|
|
}
|
|
|
|
ptr += sprintf(ptr, "(F%d)", s->funcval - KEY_F0);
|
|
|
|
*(ptr++) = '\t';
|
|
|
|
}
|
2004-11-23 07:08:28 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Primary meta key sequence. If it's the first entry, don't
|
|
|
|
* put parentheses around it. */
|
|
|
|
if (s->metaval != NANO_NO_KEY) {
|
|
|
|
entries++;
|
|
|
|
/* If this is the last entry, put it at the end. */
|
|
|
|
if (entries == 2 && s->miscval == NANO_NO_KEY) {
|
|
|
|
entries++;
|
|
|
|
*(ptr++) = '\t';
|
|
|
|
}
|
|
|
|
/* Yucky sentinel values that we can't handle a better
|
|
|
|
* way. */
|
|
|
|
if (s->metaval == NANO_ALT_SPACE && entries == 1) {
|
|
|
|
char *space_ptr = display_string(_("Space"), 0, 5,
|
|
|
|
FALSE);
|
2004-11-23 07:08:28 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
ptr += sprintf(ptr, "M-%s", space_ptr);
|
2004-11-23 07:08:28 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
free(space_ptr);
|
|
|
|
} else
|
|
|
|
/* Normal values. */
|
|
|
|
ptr += sprintf(ptr, (entries == 1) ? "M-%c" : "(M-%c)",
|
|
|
|
toupper(s->metaval));
|
|
|
|
*(ptr++) = '\t';
|
|
|
|
}
|
2004-11-23 07:08:28 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Miscellaneous meta key sequence. */
|
|
|
|
if (entries < 3 && s->miscval != NANO_NO_KEY) {
|
|
|
|
entries++;
|
|
|
|
/* If this is the last entry, put it at the end. */
|
|
|
|
if (entries == 2) {
|
|
|
|
entries++;
|
|
|
|
*(ptr++) = '\t';
|
|
|
|
}
|
|
|
|
ptr += sprintf(ptr, "(M-%c)", toupper(s->miscval));
|
|
|
|
*(ptr++) = '\t';
|
|
|
|
}
|
2004-11-23 07:08:28 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* Make sure all the help text starts at the same place. */
|
|
|
|
while (entries < 3) {
|
|
|
|
entries++;
|
|
|
|
*(ptr++) = '\t';
|
|
|
|
}
|
2004-11-23 07:08:28 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
assert(s->help != NULL);
|
2004-11-23 07:08:28 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
if (COLS > 24) {
|
|
|
|
char *help_ptr = display_string(s->help, 0, COLS - 24,
|
|
|
|
FALSE);
|
2004-11-23 07:08:28 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
ptr += sprintf(ptr, help_ptr);
|
2004-11-23 07:08:28 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
free(help_ptr);
|
|
|
|
}
|
2004-11-23 07:08:28 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
ptr += sprintf(ptr, "\n");
|
|
|
|
}
|
2000-06-06 09:53:49 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
#ifndef NANO_SMALL
|
|
|
|
/* And the toggles... */
|
|
|
|
if (currshortcut == main_list) {
|
|
|
|
for (t = toggles; t != NULL; t = t->next) {
|
2005-03-04 20:09:41 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
assert(t->desc != NULL);
|
2000-06-06 09:53:49 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
ptr += sprintf(ptr, "M-%c\t\t\t%s %s\n", toupper(t->val),
|
|
|
|
t->desc, _("enable/disable"));
|
|
|
|
}
|
|
|
|
}
|
2001-10-23 03:22:19 +04:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
#ifdef ENABLE_NANORC
|
|
|
|
if (old_whitespace)
|
|
|
|
SET(WHITESPACE_DISPLAY);
|
|
|
|
#endif
|
|
|
|
#endif
|
2005-03-04 20:09:41 +03:00
|
|
|
|
2005-07-08 06:47:05 +04:00
|
|
|
/* If all went well, we didn't overwrite the allocated space for
|
|
|
|
* help_text. */
|
|
|
|
assert(strlen(help_text) <= allocsize + 1);
|
2000-07-28 05:41:29 +04:00
|
|
|
}
|
2005-07-08 06:47:05 +04:00
|
|
|
#endif
|
2000-07-28 05:41:29 +04:00
|
|
|
|
2005-03-22 23:17:38 +03:00
|
|
|
#ifdef HAVE_GETOPT_LONG
|
|
|
|
#define print1opt(shortflag, longflag, desc) print1opt_full(shortflag, longflag, desc)
|
|
|
|
#else
|
|
|
|
#define print1opt(shortflag, longflag, desc) print1opt_full(shortflag, desc)
|
|
|
|
#endif
|
|
|
|
|
2004-08-05 19:16:19 +04:00
|
|
|
/* Print one usage string to the screen. This cuts down on duplicate
|
2005-03-21 10:24:47 +03:00
|
|
|
* strings to translate, and leaves out the parts that shouldn't be
|
2002-07-19 05:08:59 +04:00
|
|
|
* translatable (the flag names). */
|
2005-03-21 10:24:47 +03:00
|
|
|
void print1opt_full(const char *shortflag
|
|
|
|
#ifdef HAVE_GETOPT_LONG
|
|
|
|
, const char *longflag
|
|
|
|
#endif
|
|
|
|
, const char *desc)
|
2002-03-09 21:51:58 +03:00
|
|
|
{
|
|
|
|
printf(" %s\t", shortflag);
|
|
|
|
if (strlen(shortflag) < 8)
|
|
|
|
printf("\t");
|
|
|
|
|
|
|
|
#ifdef HAVE_GETOPT_LONG
|
|
|
|
printf("%s\t", longflag);
|
|
|
|
if (strlen(longflag) < 8)
|
|
|
|
printf("\t\t");
|
|
|
|
else if (strlen(longflag) < 16)
|
|
|
|
printf("\t");
|
|
|
|
#endif
|
|
|
|
|
2005-04-14 07:13:49 +04:00
|
|
|
if (desc != NULL)
|
|
|
|
printf("%s", _(desc));
|
|
|
|
printf("\n");
|
2002-03-09 21:51:58 +03:00
|
|
|
}
|
|
|
|
|
2002-08-21 20:10:37 +04:00
|
|
|
void usage(void)
|
2000-06-06 09:53:49 +04:00
|
|
|
{
|
|
|
|
#ifdef HAVE_GETOPT_LONG
|
2005-05-21 21:15:46 +04:00
|
|
|
printf(
|
|
|
|
_("Usage: nano [+LINE,COLUMN] [GNU long option] [option] [file]\n\n"));
|
2002-07-19 05:08:59 +04:00
|
|
|
printf(_("Option\t\tLong option\t\tMeaning\n"));
|
2000-06-06 09:53:49 +04:00
|
|
|
#else
|
2005-07-12 00:19:59 +04:00
|
|
|
printf(_("Usage: nano [+LINE,COLUMN] [option] [file]\n\n"));
|
2002-07-19 05:08:59 +04:00
|
|
|
printf(_("Option\t\tMeaning\n"));
|
2004-08-08 02:00:02 +04:00
|
|
|
#endif
|
2002-03-09 21:51:58 +03:00
|
|
|
|
2004-08-05 19:45:09 +04:00
|
|
|
print1opt("-h, -?", "--help", N_("Show this message"));
|
2005-05-21 21:15:46 +04:00
|
|
|
print1opt(_("+LINE,COLUMN"), "",
|
|
|
|
N_("Start at line LINE, column COLUMN"));
|
2001-09-22 04:42:10 +04:00
|
|
|
#ifndef NANO_SMALL
|
2004-08-05 19:45:09 +04:00
|
|
|
print1opt("-A", "--smarthome", N_("Enable smart home key"));
|
2005-05-30 06:09:21 +04:00
|
|
|
print1opt("-B", "--backup", N_("Save backups of existing files"));
|
2005-06-16 03:20:56 +04:00
|
|
|
print1opt(_("-C [dir]"), _("--backupdir=[dir]"),
|
2005-05-30 06:09:21 +04:00
|
|
|
N_("Directory for saving unique backup files"));
|
2005-06-16 03:20:56 +04:00
|
|
|
print1opt("-E", "--tabstospaces",
|
|
|
|
N_("Convert typed tabs to spaces"));
|
2001-09-22 04:42:10 +04:00
|
|
|
#endif
|
2001-07-14 23:32:47 +04:00
|
|
|
#ifdef ENABLE_MULTIBUFFER
|
2004-08-05 19:45:09 +04:00
|
|
|
print1opt("-F", "--multibuffer", N_("Enable multiple file buffers"));
|
2002-07-19 05:08:59 +04:00
|
|
|
#endif
|
|
|
|
#ifdef ENABLE_NANORC
|
2003-09-07 01:44:37 +04:00
|
|
|
#ifndef NANO_SMALL
|
2005-05-21 21:15:46 +04:00
|
|
|
print1opt("-H", "--historylog",
|
|
|
|
N_("Log & read search/replace string history"));
|
2003-09-07 01:44:37 +04:00
|
|
|
#endif
|
2005-05-21 21:15:46 +04:00
|
|
|
print1opt("-I", "--ignorercfiles",
|
|
|
|
N_("Don't look at nanorc files"));
|
2001-09-22 08:20:25 +04:00
|
|
|
#endif
|
|
|
|
#ifndef NANO_SMALL
|
2005-05-21 21:15:46 +04:00
|
|
|
print1opt("-N", "--noconvert",
|
|
|
|
N_("Don't convert files from DOS/Mac format"));
|
2002-03-04 01:36:36 +03:00
|
|
|
#endif
|
2005-01-17 08:06:55 +03:00
|
|
|
print1opt("-O", "--morespace", N_("Use more space for editing"));
|
2002-03-04 01:36:36 +03:00
|
|
|
#ifndef DISABLE_JUSTIFY
|
2005-05-21 21:15:46 +04:00
|
|
|
print1opt(_("-Q [str]"), _("--quotestr=[str]"),
|
2005-06-16 21:26:01 +04:00
|
|
|
N_("Quoting string"));
|
2001-07-14 23:32:47 +04:00
|
|
|
#endif
|
2005-06-18 02:53:41 +04:00
|
|
|
print1opt("-R", "--restricted", N_("Restricted mode"));
|
2001-09-22 23:02:04 +04:00
|
|
|
#ifndef NANO_SMALL
|
2004-08-05 19:45:09 +04:00
|
|
|
print1opt("-S", "--smooth", N_("Smooth scrolling"));
|
2001-09-22 23:02:04 +04:00
|
|
|
#endif
|
2005-05-21 21:15:46 +04:00
|
|
|
print1opt(_("-T [#cols]"), _("--tabsize=[#cols]"),
|
|
|
|
N_("Set width of a tab in cols to #cols"));
|
2005-06-17 23:09:18 +04:00
|
|
|
#ifndef NANO_SMALL
|
2005-06-17 23:06:25 +04:00
|
|
|
print1opt("-U", _("--quickblank"),
|
|
|
|
N_("Do quick statusbar blanking"));
|
2005-06-17 23:09:18 +04:00
|
|
|
#endif
|
2005-05-21 21:15:46 +04:00
|
|
|
print1opt("-V", "--version",
|
|
|
|
N_("Print version information and exit"));
|
2002-05-04 08:23:30 +04:00
|
|
|
#ifdef ENABLE_COLOR
|
2005-05-21 21:15:46 +04:00
|
|
|
print1opt(_("-Y [str]"), _("--syntax=[str]"),
|
|
|
|
N_("Syntax definition to use"));
|
2002-05-04 08:23:30 +04:00
|
|
|
#endif
|
2004-08-05 19:45:09 +04:00
|
|
|
print1opt("-c", "--const", N_("Constantly show cursor position"));
|
2005-05-21 21:15:46 +04:00
|
|
|
print1opt("-d", "--rebinddelete",
|
|
|
|
N_("Fix Backspace/Delete confusion problem"));
|
2005-03-21 10:24:47 +03:00
|
|
|
#ifndef NANO_SMALL
|
2005-05-21 21:15:46 +04:00
|
|
|
print1opt("-i", "--autoindent",
|
|
|
|
N_("Automatically indent new lines"));
|
2005-03-21 10:24:47 +03:00
|
|
|
print1opt("-k", "--cut", N_("Cut from cursor to end of line"));
|
2005-03-27 01:49:46 +03:00
|
|
|
#endif
|
2005-05-21 21:15:46 +04:00
|
|
|
print1opt("-l", "--nofollow",
|
|
|
|
N_("Don't follow symbolic links, overwrite"));
|
2003-10-04 00:26:25 +04:00
|
|
|
#ifndef DISABLE_MOUSE
|
2004-08-05 19:45:09 +04:00
|
|
|
print1opt("-m", "--mouse", N_("Enable mouse"));
|
2000-06-06 09:53:49 +04:00
|
|
|
#endif
|
2001-09-19 07:19:43 +04:00
|
|
|
#ifndef DISABLE_OPERATINGDIR
|
2005-05-21 21:15:46 +04:00
|
|
|
print1opt(_("-o [dir]"), _("--operatingdir=[dir]"),
|
|
|
|
N_("Set operating directory"));
|
2000-06-06 09:53:49 +04:00
|
|
|
#endif
|
2005-05-21 21:15:46 +04:00
|
|
|
print1opt("-p", "--preserve",
|
|
|
|
N_("Preserve XON (^Q) and XOFF (^S) keys"));
|
2001-05-21 16:56:25 +04:00
|
|
|
#ifndef DISABLE_WRAPJUSTIFY
|
2005-05-21 21:15:46 +04:00
|
|
|
print1opt(_("-r [#cols]"), _("--fill=[#cols]"),
|
|
|
|
N_("Set fill cols to (wrap lines at) #cols"));
|
2001-05-21 16:56:25 +04:00
|
|
|
#endif
|
2001-01-12 10:51:05 +03:00
|
|
|
#ifndef DISABLE_SPELLER
|
2005-05-21 21:15:46 +04:00
|
|
|
print1opt(_("-s [prog]"), _("--speller=[prog]"),
|
|
|
|
N_("Enable alternate speller"));
|
2001-01-12 10:51:05 +03:00
|
|
|
#endif
|
2005-05-21 21:15:46 +04:00
|
|
|
print1opt("-t", "--tempfile",
|
|
|
|
N_("Auto save on exit, don't prompt"));
|
2004-08-05 19:45:09 +04:00
|
|
|
print1opt("-v", "--view", N_("View (read only) mode"));
|
2001-04-02 09:36:08 +04:00
|
|
|
#ifndef DISABLE_WRAPPING
|
2004-08-05 19:45:09 +04:00
|
|
|
print1opt("-w", "--nowrap", N_("Don't wrap long lines"));
|
2000-06-06 09:53:49 +04:00
|
|
|
#endif
|
2004-08-05 19:45:09 +04:00
|
|
|
print1opt("-x", "--nohelp", N_("Don't show help window"));
|
|
|
|
print1opt("-z", "--suspend", N_("Enable suspend"));
|
2002-07-19 05:08:59 +04:00
|
|
|
|
2004-08-05 19:16:19 +04:00
|
|
|
/* This is a special case. */
|
2005-04-14 07:13:49 +04:00
|
|
|
print1opt("-a, -b, -e,", "", NULL);
|
2005-05-21 21:15:46 +04:00
|
|
|
print1opt("-f, -g, -j", "", N_("(ignored, for Pico compatibility)"));
|
2002-03-09 21:51:58 +03:00
|
|
|
|
2000-06-06 09:53:49 +04:00
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2002-08-21 20:10:37 +04:00
|
|
|
void version(void)
|
2000-06-06 09:53:49 +04:00
|
|
|
{
|
2005-03-11 07:22:34 +03:00
|
|
|
printf(_(" GNU nano version %s (compiled %s, %s)\n"), VERSION,
|
|
|
|
__TIME__, __DATE__);
|
|
|
|
printf(
|
|
|
|
_(" Email: nano@nano-editor.org Web: http://www.nano-editor.org/"));
|
2000-11-24 23:45:14 +03:00
|
|
|
printf(_("\n Compiled options:"));
|
2000-12-01 21:46:01 +03:00
|
|
|
|
2001-04-12 07:01:53 +04:00
|
|
|
#ifdef DISABLE_BROWSER
|
2001-01-05 08:41:07 +03:00
|
|
|
printf(" --disable-browser");
|
2001-04-12 07:01:53 +04:00
|
|
|
#endif
|
2002-09-07 00:35:28 +04:00
|
|
|
#ifdef DISABLE_HELP
|
|
|
|
printf(" --disable-help");
|
2001-04-12 07:01:53 +04:00
|
|
|
#endif
|
|
|
|
#ifdef DISABLE_JUSTIFY
|
2000-12-01 21:46:01 +03:00
|
|
|
printf(" --disable-justify");
|
2001-04-12 07:01:53 +04:00
|
|
|
#endif
|
2003-10-04 00:26:25 +04:00
|
|
|
#ifdef DISABLE_MOUSE
|
2001-04-12 18:51:48 +04:00
|
|
|
printf(" --disable-mouse");
|
2000-12-18 08:36:51 +03:00
|
|
|
#endif
|
2005-06-29 21:10:58 +04:00
|
|
|
#ifndef ENABLE_NLS
|
|
|
|
printf(" --disable-nls");
|
|
|
|
#endif
|
2001-09-19 07:19:43 +04:00
|
|
|
#ifdef DISABLE_OPERATINGDIR
|
|
|
|
printf(" --disable-operatingdir");
|
|
|
|
#endif
|
2002-09-07 00:35:28 +04:00
|
|
|
#ifdef DISABLE_SPELLER
|
|
|
|
printf(" --disable-speller");
|
|
|
|
#endif
|
|
|
|
#ifdef DISABLE_TABCOMP
|
|
|
|
printf(" --disable-tabcomp");
|
|
|
|
#endif
|
|
|
|
#ifdef DISABLE_WRAPPING
|
|
|
|
printf(" --disable-wrapping");
|
|
|
|
#endif
|
2002-10-25 20:08:53 +04:00
|
|
|
#ifdef DISABLE_ROOTWRAP
|
|
|
|
printf(" --disable-wrapping-as-root");
|
|
|
|
#endif
|
2002-09-07 00:35:28 +04:00
|
|
|
#ifdef ENABLE_COLOR
|
|
|
|
printf(" --enable-color");
|
|
|
|
#endif
|
2005-06-29 21:10:58 +04:00
|
|
|
#ifdef DEBUG
|
|
|
|
printf(" --enable-debug");
|
|
|
|
#endif
|
|
|
|
#ifdef NANO_EXTRA
|
|
|
|
printf(" --enable-extra");
|
|
|
|
#endif
|
2002-09-07 00:35:28 +04:00
|
|
|
#ifdef ENABLE_MULTIBUFFER
|
|
|
|
printf(" --enable-multibuffer");
|
|
|
|
#endif
|
|
|
|
#ifdef ENABLE_NANORC
|
|
|
|
printf(" --enable-nanorc");
|
|
|
|
#endif
|
2005-06-29 21:10:58 +04:00
|
|
|
#ifdef NANO_SMALL
|
|
|
|
printf(" --enable-tiny");
|
|
|
|
#endif
|
2005-07-17 06:40:07 +04:00
|
|
|
#ifdef ENABLE_UTF8
|
2005-06-29 21:10:58 +04:00
|
|
|
printf(" --enable-utf8");
|
|
|
|
#endif
|
2000-11-24 23:45:14 +03:00
|
|
|
#ifdef USE_SLANG
|
|
|
|
printf(" --with-slang");
|
|
|
|
#endif
|
|
|
|
printf("\n");
|
2000-06-06 09:53:49 +04:00
|
|
|
}
|
|
|
|
|
2005-01-17 08:06:55 +03:00
|
|
|
int no_more_space(void)
|
|
|
|
{
|
|
|
|
return ISSET(MORE_SPACE) ? 1 : 0;
|
|
|
|
}
|
|
|
|
|
2000-06-06 09:53:49 +04:00
|
|
|
int no_help(void)
|
|
|
|
{
|
2002-07-19 05:08:59 +04:00
|
|
|
return ISSET(NO_HELP) ? 2 : 0;
|
2000-06-06 09:53:49 +04:00
|
|
|
}
|
|
|
|
|
2004-07-02 18:31:03 +04:00
|
|
|
void nano_disabled_msg(void)
|
2000-12-01 21:46:01 +03:00
|
|
|
{
|
2002-07-19 05:08:59 +04:00
|
|
|
statusbar(_("Sorry, support for this function has been disabled"));
|
2000-12-01 21:46:01 +03:00
|
|
|
}
|
|
|
|
|
2004-07-02 18:31:03 +04:00
|
|
|
void do_verbatim_input(void)
|
2003-11-28 22:47:42 +03:00
|
|
|
{
|
2005-01-12 06:25:57 +03:00
|
|
|
int *kbinput;
|
|
|
|
size_t kbinput_len, i;
|
|
|
|
char *output;
|
2003-11-28 22:47:42 +03:00
|
|
|
|
2005-06-14 06:24:25 +04:00
|
|
|
statusbar(_("Verbatim Input"));
|
2004-05-28 21:23:33 +04:00
|
|
|
|
2005-07-08 08:53:51 +04:00
|
|
|
/* If constant cursor position display is on, make sure the current
|
|
|
|
* cursor position will be properly displayed on the statusbar. */
|
|
|
|
if (ISSET(CONST_UPDATE))
|
|
|
|
do_cursorpos(TRUE);
|
|
|
|
|
2004-12-04 20:41:52 +03:00
|
|
|
/* Read in all the verbatim characters. */
|
|
|
|
kbinput = get_verbatim_kbinput(edit, &kbinput_len);
|
2003-11-28 22:47:42 +03:00
|
|
|
|
2005-03-17 06:52:08 +03:00
|
|
|
/* Display all the verbatim characters at once, not filtering out
|
|
|
|
* control characters. */
|
2005-01-12 06:25:57 +03:00
|
|
|
output = charalloc(kbinput_len + 1);
|
2003-11-28 22:47:42 +03:00
|
|
|
|
2005-01-12 06:25:57 +03:00
|
|
|
for (i = 0; i < kbinput_len; i++)
|
|
|
|
output[i] = (char)kbinput[i];
|
|
|
|
output[i] = '\0';
|
|
|
|
|
2005-03-17 06:52:08 +03:00
|
|
|
do_output(output, kbinput_len, TRUE);
|
2005-01-12 06:25:57 +03:00
|
|
|
|
|
|
|
free(output);
|
2003-11-28 22:47:42 +03:00
|
|
|
}
|
|
|
|
|
2004-07-02 18:31:03 +04:00
|
|
|
void do_exit(void)
|
2000-06-06 09:53:49 +04:00
|
|
|
{
|
2002-09-07 00:35:28 +04:00
|
|
|
int i;
|
|
|
|
|
2005-07-09 00:09:16 +04:00
|
|
|
if (!openfile->modified)
|
2004-07-02 18:31:03 +04:00
|
|
|
i = 0; /* Pretend the user chose not to save. */
|
2004-07-03 07:09:12 +04:00
|
|
|
else if (ISSET(TEMP_FILE))
|
2002-09-07 00:35:28 +04:00
|
|
|
i = 1;
|
2003-12-24 06:33:09 +03:00
|
|
|
else
|
2004-07-02 18:31:03 +04:00
|
|
|
i = do_yesno(FALSE,
|
|
|
|
_("Save modified buffer (ANSWERING \"No\" WILL DESTROY CHANGES) ? "));
|
|
|
|
|
2002-09-07 00:35:28 +04:00
|
|
|
#ifdef DEBUG
|
2005-07-09 00:09:16 +04:00
|
|
|
dump_filestruct(openfile->fileage);
|
2001-10-22 07:15:31 +04:00
|
|
|
#endif
|
2002-09-07 00:35:28 +04:00
|
|
|
|
2005-05-31 08:28:15 +04:00
|
|
|
if (i == 0 || (i == 1 && do_writeout(TRUE) == 0)) {
|
2002-09-07 00:35:28 +04:00
|
|
|
#ifdef ENABLE_MULTIBUFFER
|
2004-12-01 18:11:27 +03:00
|
|
|
/* Exit only if there are no more open file buffers. */
|
2005-07-09 00:09:16 +04:00
|
|
|
if (!close_buffer())
|
2002-09-07 00:35:28 +04:00
|
|
|
#endif
|
2004-05-25 23:41:11 +04:00
|
|
|
finish();
|
2004-07-02 18:31:03 +04:00
|
|
|
} else if (i != 1)
|
2002-09-07 00:35:28 +04:00
|
|
|
statusbar(_("Cancelled"));
|
|
|
|
|
|
|
|
display_main_list();
|
|
|
|
}
|
|
|
|
|
|
|
|
void signal_init(void)
|
|
|
|
{
|
2004-04-07 04:44:35 +04:00
|
|
|
/* Trap SIGINT and SIGQUIT because we want them to do useful
|
|
|
|
* things. */
|
2002-09-07 00:35:28 +04:00
|
|
|
memset(&act, 0, sizeof(struct sigaction));
|
|
|
|
act.sa_handler = SIG_IGN;
|
|
|
|
sigaction(SIGINT, &act, NULL);
|
2004-01-26 23:56:20 +03:00
|
|
|
sigaction(SIGQUIT, &act, NULL);
|
2002-09-07 00:35:28 +04:00
|
|
|
|
2004-04-07 04:44:35 +04:00
|
|
|
/* Trap SIGHUP and SIGTERM because we want to write the file out. */
|
2002-10-17 06:19:31 +04:00
|
|
|
act.sa_handler = handle_hupterm;
|
2002-09-07 00:35:28 +04:00
|
|
|
sigaction(SIGHUP, &act, NULL);
|
2002-10-17 06:19:31 +04:00
|
|
|
sigaction(SIGTERM, &act, NULL);
|
2002-09-07 00:35:28 +04:00
|
|
|
|
2002-03-21 08:07:28 +03:00
|
|
|
#ifndef NANO_SMALL
|
2004-04-07 04:44:35 +04:00
|
|
|
/* Trap SIGWINCH because we want to handle window resizes. */
|
2002-09-07 00:35:28 +04:00
|
|
|
act.sa_handler = handle_sigwinch;
|
|
|
|
sigaction(SIGWINCH, &act, NULL);
|
2004-02-16 23:32:40 +03:00
|
|
|
allow_pending_sigwinch(FALSE);
|
2002-03-21 08:07:28 +03:00
|
|
|
#endif
|
2000-06-06 09:53:49 +04:00
|
|
|
|
2004-05-18 05:20:36 +04:00
|
|
|
/* Trap normal suspend (^Z) so we can handle it ourselves. */
|
2002-09-07 00:35:28 +04:00
|
|
|
if (!ISSET(SUSPEND)) {
|
|
|
|
act.sa_handler = SIG_IGN;
|
|
|
|
sigaction(SIGTSTP, &act, NULL);
|
|
|
|
} else {
|
2004-04-07 04:44:35 +04:00
|
|
|
/* Block all other signals in the suspend and continue handlers.
|
|
|
|
* If we don't do this, other stuff interrupts them! */
|
2002-09-07 00:35:28 +04:00
|
|
|
sigfillset(&act.sa_mask);
|
2000-06-06 09:53:49 +04:00
|
|
|
|
2002-09-07 00:35:28 +04:00
|
|
|
act.sa_handler = do_suspend;
|
|
|
|
sigaction(SIGTSTP, &act, NULL);
|
2002-05-12 23:52:15 +04:00
|
|
|
|
2002-09-07 00:35:28 +04:00
|
|
|
act.sa_handler = do_cont;
|
|
|
|
sigaction(SIGCONT, &act, NULL);
|
|
|
|
}
|
|
|
|
}
|
2000-09-01 17:32:47 +04:00
|
|
|
|
2004-05-18 05:20:36 +04:00
|
|
|
/* Handler for SIGHUP (hangup) and SIGTERM (terminate). */
|
2005-01-19 22:52:42 +03:00
|
|
|
void handle_hupterm(int signal)
|
2002-09-07 00:35:28 +04:00
|
|
|
{
|
2003-02-03 06:32:08 +03:00
|
|
|
die(_("Received SIGHUP or SIGTERM\n"));
|
2002-09-07 00:35:28 +04:00
|
|
|
}
|
2002-06-21 07:20:06 +04:00
|
|
|
|
2004-05-18 05:20:36 +04:00
|
|
|
/* Handler for SIGTSTP (suspend). */
|
2005-01-19 22:52:42 +03:00
|
|
|
void do_suspend(int signal)
|
2002-09-07 00:35:28 +04:00
|
|
|
{
|
|
|
|
endwin();
|
2003-02-13 02:54:34 +03:00
|
|
|
printf("\n\n\n\n\n%s\n", _("Use \"fg\" to return to nano"));
|
2002-09-07 00:35:28 +04:00
|
|
|
fflush(stdout);
|
2000-09-01 17:32:47 +04:00
|
|
|
|
2004-05-18 05:20:36 +04:00
|
|
|
/* Restore the old terminal settings. */
|
2002-09-07 00:35:28 +04:00
|
|
|
tcsetattr(0, TCSANOW, &oldterm);
|
2002-02-15 22:17:02 +03:00
|
|
|
|
2003-09-29 11:21:11 +04:00
|
|
|
/* Trap SIGHUP and SIGTERM so we can properly deal with them while
|
2004-05-18 05:20:36 +04:00
|
|
|
* suspended. */
|
2003-09-29 11:21:11 +04:00
|
|
|
act.sa_handler = handle_hupterm;
|
|
|
|
sigaction(SIGHUP, &act, NULL);
|
|
|
|
sigaction(SIGTERM, &act, NULL);
|
|
|
|
|
2004-05-18 05:20:36 +04:00
|
|
|
/* Do what mutt does: send ourselves a SIGSTOP. */
|
2002-09-07 00:35:28 +04:00
|
|
|
kill(0, SIGSTOP);
|
|
|
|
}
|
2002-06-21 07:20:06 +04:00
|
|
|
|
2004-05-18 05:20:36 +04:00
|
|
|
/* Handler for SIGCONT (continue after suspend). */
|
2005-01-19 22:52:42 +03:00
|
|
|
void do_cont(int signal)
|
2002-09-07 00:35:28 +04:00
|
|
|
{
|
2002-04-23 14:56:06 +04:00
|
|
|
#ifndef NANO_SMALL
|
2004-05-18 05:20:36 +04:00
|
|
|
/* Perhaps the user resized the window while we slept. Handle it
|
|
|
|
* and update the screen in the process. */
|
2002-09-07 00:35:28 +04:00
|
|
|
handle_sigwinch(0);
|
2004-04-07 04:44:35 +04:00
|
|
|
#else
|
2004-05-18 05:20:36 +04:00
|
|
|
/* Just update the screen. */
|
|
|
|
doupdate();
|
2002-09-07 00:35:28 +04:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef NANO_SMALL
|
|
|
|
void handle_sigwinch(int s)
|
|
|
|
{
|
|
|
|
const char *tty = ttyname(0);
|
2005-03-08 19:41:53 +03:00
|
|
|
int fd, result = 0;
|
2002-09-07 00:35:28 +04:00
|
|
|
struct winsize win;
|
|
|
|
|
2002-12-22 19:30:00 +03:00
|
|
|
if (tty == NULL)
|
2002-09-07 00:35:28 +04:00
|
|
|
return;
|
|
|
|
fd = open(tty, O_RDWR);
|
|
|
|
if (fd == -1)
|
|
|
|
return;
|
|
|
|
result = ioctl(fd, TIOCGWINSZ, &win);
|
|
|
|
close(fd);
|
|
|
|
if (result == -1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Could check whether the COLS or LINES changed, and return
|
|
|
|
* otherwise. EXCEPT, that COLS and LINES are ncurses global
|
|
|
|
* variables, and in some cases ncurses has already updated them.
|
|
|
|
* But not in all cases, argh. */
|
|
|
|
COLS = win.ws_col;
|
|
|
|
LINES = win.ws_row;
|
|
|
|
|
2004-11-04 01:03:41 +03:00
|
|
|
/* If we've partitioned the filestruct, unpartition it now. */
|
|
|
|
if (filepart != NULL)
|
2004-11-22 03:16:23 +03:00
|
|
|
unpartition_filestruct(&filepart);
|
2004-11-04 01:03:41 +03:00
|
|
|
|
2004-11-23 07:08:28 +03:00
|
|
|
#ifndef DISABLE_JUSTIFY
|
2004-11-23 07:17:19 +03:00
|
|
|
/* If the justify buffer isn't empty, blow away the text in it and
|
|
|
|
* display the shortcut list with UnCut. */
|
2004-11-23 07:08:28 +03:00
|
|
|
if (jusbuffer != NULL) {
|
|
|
|
free_filestruct(jusbuffer);
|
|
|
|
jusbuffer = NULL;
|
|
|
|
shortcut_init(FALSE);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2004-05-18 05:20:36 +04:00
|
|
|
#ifdef USE_SLANG
|
|
|
|
/* Slang curses emulation brain damage, part 1: If we just do what
|
|
|
|
* curses does here, it'll only work properly if the resize made the
|
|
|
|
* window smaller. Do what mutt does: Leave and immediately reenter
|
|
|
|
* Slang screen management mode. */
|
|
|
|
SLsmg_reset_smg();
|
|
|
|
SLsmg_init_smg();
|
|
|
|
#else
|
|
|
|
/* Do the equivalent of what Minimum Profit does: Leave and
|
|
|
|
* immediately reenter curses mode. */
|
|
|
|
endwin();
|
|
|
|
refresh();
|
|
|
|
#endif
|
2002-09-07 00:35:28 +04:00
|
|
|
|
2004-07-27 20:46:35 +04:00
|
|
|
/* Restore the terminal to its previous state. */
|
|
|
|
terminal_init();
|
|
|
|
|
2005-03-21 00:20:47 +03:00
|
|
|
/* Turn the cursor back on for sure. */
|
|
|
|
curs_set(1);
|
|
|
|
|
2004-05-18 05:20:36 +04:00
|
|
|
/* Do the equivalent of what both mutt and Minimum Profit do:
|
|
|
|
* Reinitialize all the windows based on the new screen
|
|
|
|
* dimensions. */
|
|
|
|
window_init();
|
|
|
|
|
2004-11-12 03:09:20 +03:00
|
|
|
/* Redraw the contents of the windows that need it. */
|
2002-09-07 00:35:28 +04:00
|
|
|
blank_statusbar();
|
2005-01-17 08:06:55 +03:00
|
|
|
currshortcut = main_list;
|
2002-09-07 00:35:28 +04:00
|
|
|
total_refresh();
|
|
|
|
|
2004-05-28 21:23:33 +04:00
|
|
|
/* Reset all the input routines that rely on character sequences. */
|
|
|
|
reset_kbinput();
|
|
|
|
|
2004-01-30 07:20:28 +03:00
|
|
|
/* Jump back to the main loop. */
|
2002-09-07 00:35:28 +04:00
|
|
|
siglongjmp(jmpbuf, 1);
|
|
|
|
}
|
2004-02-16 23:32:40 +03:00
|
|
|
|
2004-08-06 02:10:22 +04:00
|
|
|
void allow_pending_sigwinch(bool allow)
|
2004-02-16 23:32:40 +03:00
|
|
|
{
|
|
|
|
sigset_t winch;
|
|
|
|
sigemptyset(&winch);
|
|
|
|
sigaddset(&winch, SIGWINCH);
|
2005-07-02 02:58:47 +04:00
|
|
|
sigprocmask(allow ? SIG_UNBLOCK : SIG_BLOCK, &winch, NULL);
|
2004-02-16 23:32:40 +03:00
|
|
|
}
|
2002-04-23 14:56:06 +04:00
|
|
|
#endif /* !NANO_SMALL */
|
2002-06-21 07:20:06 +04:00
|
|
|
|
2002-04-23 14:56:06 +04:00
|
|
|
#ifndef NANO_SMALL
|
2002-08-21 20:10:37 +04:00
|
|
|
void do_toggle(const toggle *which)
|
2000-09-01 17:32:47 +04:00
|
|
|
{
|
2004-08-06 02:10:22 +04:00
|
|
|
bool enabled;
|
2000-09-02 22:44:21 +04:00
|
|
|
|
2002-02-15 22:17:02 +03:00
|
|
|
TOGGLE(which->flag);
|
2000-09-13 03:02:49 +04:00
|
|
|
|
2002-02-15 22:17:02 +03:00
|
|
|
switch (which->val) {
|
2003-10-04 00:26:25 +04:00
|
|
|
#ifndef DISABLE_MOUSE
|
2004-11-27 19:54:00 +03:00
|
|
|
case TOGGLE_MOUSE_KEY:
|
|
|
|
mouse_init();
|
|
|
|
break;
|
2002-12-22 19:30:00 +03:00
|
|
|
#endif
|
2005-01-17 08:06:55 +03:00
|
|
|
case TOGGLE_MORESPACE_KEY:
|
2004-11-27 19:54:00 +03:00
|
|
|
case TOGGLE_NOHELP_KEY:
|
|
|
|
window_init();
|
2005-01-17 08:06:55 +03:00
|
|
|
total_refresh();
|
2004-11-27 19:54:00 +03:00
|
|
|
break;
|
2005-01-17 08:06:55 +03:00
|
|
|
case TOGGLE_SUSPEND_KEY:
|
|
|
|
signal_init();
|
2004-11-27 19:54:00 +03:00
|
|
|
break;
|
2004-05-29 20:25:30 +04:00
|
|
|
#ifdef ENABLE_NANORC
|
2004-11-27 19:54:00 +03:00
|
|
|
case TOGGLE_WHITESPACE_KEY:
|
2004-12-05 07:18:26 +03:00
|
|
|
titlebar(NULL);
|
2004-11-27 19:54:00 +03:00
|
|
|
edit_refresh();
|
|
|
|
break;
|
2005-01-17 08:06:55 +03:00
|
|
|
#endif
|
|
|
|
#ifdef ENABLE_COLOR
|
|
|
|
case TOGGLE_SYNTAX_KEY:
|
|
|
|
edit_refresh();
|
|
|
|
break;
|
2002-12-22 19:30:00 +03:00
|
|
|
#endif
|
2000-09-01 17:32:47 +04:00
|
|
|
}
|
2000-09-13 03:02:49 +04:00
|
|
|
|
2002-07-19 05:08:59 +04:00
|
|
|
enabled = ISSET(which->flag);
|
2005-06-09 08:00:03 +04:00
|
|
|
|
2005-06-27 00:05:01 +04:00
|
|
|
if (which->val == TOGGLE_NOHELP_KEY
|
|
|
|
#ifndef DISABLE_WRAPPING
|
|
|
|
|| which->val == TOGGLE_WRAP_KEY
|
|
|
|
#endif
|
|
|
|
#ifdef ENABLE_COLOR
|
|
|
|
|| which->val == TOGGLE_SYNTAX_KEY
|
|
|
|
#endif
|
|
|
|
)
|
2002-07-19 05:08:59 +04:00
|
|
|
enabled = !enabled;
|
2005-06-09 08:00:03 +04:00
|
|
|
|
|
|
|
statusbar("%s %s", which->desc, enabled ? _("enabled") :
|
|
|
|
_("disabled"));
|
2000-06-06 09:53:49 +04:00
|
|
|
}
|
2002-04-23 14:56:06 +04:00
|
|
|
#endif /* !NANO_SMALL */
|
2000-06-06 09:53:49 +04:00
|
|
|
|
2005-06-09 08:02:57 +04:00
|
|
|
void disable_extended_io(void)
|
2004-09-23 02:45:08 +04:00
|
|
|
{
|
|
|
|
struct termios term;
|
|
|
|
|
|
|
|
tcgetattr(0, &term);
|
|
|
|
term.c_lflag &= ~IEXTEN;
|
2005-06-09 08:02:57 +04:00
|
|
|
term.c_oflag &= ~OPOST;
|
2004-09-23 02:45:08 +04:00
|
|
|
tcsetattr(0, TCSANOW, &term);
|
|
|
|
}
|
|
|
|
|
2004-05-18 05:20:36 +04:00
|
|
|
void disable_signals(void)
|
|
|
|
{
|
|
|
|
struct termios term;
|
|
|
|
|
|
|
|
tcgetattr(0, &term);
|
|
|
|
term.c_lflag &= ~ISIG;
|
|
|
|
tcsetattr(0, TCSANOW, &term);
|
|
|
|
}
|
|
|
|
|
|
|
|
#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);
|
2005-06-24 02:28:56 +04:00
|
|
|
term.c_iflag &= ~IXON;
|
2004-05-18 05:20:36 +04:00
|
|
|
tcsetattr(0, TCSANOW, &term);
|
|
|
|
}
|
|
|
|
|
|
|
|
void enable_flow_control(void)
|
|
|
|
{
|
|
|
|
struct termios term;
|
|
|
|
|
|
|
|
tcgetattr(0, &term);
|
2005-06-24 02:28:56 +04:00
|
|
|
term.c_iflag |= IXON;
|
2004-05-18 05:20:36 +04:00
|
|
|
tcsetattr(0, TCSANOW, &term);
|
|
|
|
}
|
|
|
|
|
2004-07-27 20:46:35 +04:00
|
|
|
/* Set up the terminal state. Put the terminal in cbreak mode (read one
|
|
|
|
* character at a time and interpret the special control keys), disable
|
|
|
|
* translation of carriage return (^M) into newline (^J) so that we can
|
|
|
|
* tell the difference between the Enter key and Ctrl-J, and disable
|
2004-09-23 02:45:08 +04:00
|
|
|
* echoing of characters as they're typed. Finally, disable extended
|
2005-06-09 08:02:57 +04:00
|
|
|
* input and output processing, disable interpretation of the special
|
|
|
|
* control keys, and if we're not in preserve mode, disable
|
|
|
|
* interpretation of the flow control characters too. */
|
2004-07-27 20:46:35 +04:00
|
|
|
void terminal_init(void)
|
|
|
|
{
|
|
|
|
cbreak();
|
|
|
|
nonl();
|
|
|
|
noecho();
|
2005-06-09 08:02:57 +04:00
|
|
|
disable_extended_io();
|
2004-07-27 20:46:35 +04:00
|
|
|
disable_signals();
|
|
|
|
if (!ISSET(PRESERVE))
|
|
|
|
disable_flow_control();
|
|
|
|
}
|
|
|
|
|
2004-12-04 20:41:52 +03:00
|
|
|
int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
|
2005-01-12 02:05:05 +03:00
|
|
|
*ran_func, bool *finished, bool allow_funcs)
|
2004-12-04 20:41:52 +03: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;
|
|
|
|
#ifndef NANO_SMALL
|
|
|
|
const toggle *t;
|
|
|
|
bool have_toggle;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
*s_or_t = FALSE;
|
2005-01-12 02:05:05 +03:00
|
|
|
*ran_func = FALSE;
|
2005-01-01 10:28:15 +03:00
|
|
|
*finished = FALSE;
|
2004-12-04 20:41:52 +03:00
|
|
|
|
|
|
|
/* Read in a character. */
|
|
|
|
input = get_kbinput(edit, meta_key, func_key);
|
|
|
|
|
|
|
|
#ifndef DISABLE_MOUSE
|
|
|
|
/* If we got a mouse click and it was on a shortcut, read in the
|
|
|
|
* shortcut character. */
|
2005-01-03 00:13:36 +03:00
|
|
|
if (allow_funcs && *func_key == TRUE && input == KEY_MOUSE) {
|
2004-12-04 20:41:52 +03:00
|
|
|
if (do_mouse())
|
|
|
|
input = get_kbinput(edit, meta_key, func_key);
|
|
|
|
else
|
|
|
|
input = ERR;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Check for a shortcut in the main list. */
|
|
|
|
s = get_shortcut(main_list, &input, meta_key, func_key);
|
|
|
|
|
|
|
|
/* If we got a shortcut from the main list, or a "universal"
|
|
|
|
* edit window shortcut, set have_shortcut to TRUE. */
|
|
|
|
have_shortcut = (s != NULL || input == NANO_XON_KEY ||
|
|
|
|
input == NANO_XOFF_KEY || input == NANO_SUSPEND_KEY);
|
|
|
|
|
|
|
|
#ifndef NANO_SMALL
|
|
|
|
/* Check for a toggle in the main list. */
|
|
|
|
t = get_toggle(input, *meta_key);
|
|
|
|
|
|
|
|
/* If we got a toggle from the main list, set have_toggle to
|
|
|
|
* TRUE. */
|
|
|
|
have_toggle = (t != NULL);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Set s_or_t to TRUE if we got a shortcut or toggle. */
|
|
|
|
*s_or_t = (have_shortcut
|
|
|
|
#ifndef NANO_SMALL
|
|
|
|
|| have_toggle
|
|
|
|
#endif
|
|
|
|
);
|
|
|
|
|
|
|
|
if (allow_funcs) {
|
2005-03-17 06:52:08 +03:00
|
|
|
/* 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) {
|
2004-12-04 20:41:52 +03:00
|
|
|
if (ISSET(VIEW_MODE))
|
|
|
|
print_view_warning();
|
|
|
|
else {
|
|
|
|
kbinput_len++;
|
|
|
|
kbinput = (int *)nrealloc(kbinput, kbinput_len *
|
|
|
|
sizeof(int));
|
|
|
|
kbinput[kbinput_len - 1] = input;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If we got a shortcut or toggle, 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. Note that it should be empty if we're in view
|
|
|
|
* mode. */
|
2005-07-14 00:18:46 +04:00
|
|
|
if (*s_or_t == TRUE || get_key_buffer_len() == 0) {
|
2004-12-04 20:41:52 +03:00
|
|
|
if (kbinput != NULL) {
|
|
|
|
/* Display all the characters in the input buffer at
|
2005-03-17 06:52:08 +03:00
|
|
|
* once, filtering out control characters. */
|
2005-01-12 06:25:57 +03:00
|
|
|
char *output = charalloc(kbinput_len + 1);
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
for (i = 0; i < kbinput_len; i++)
|
|
|
|
output[i] = (char)kbinput[i];
|
|
|
|
output[i] = '\0';
|
|
|
|
|
2005-03-17 06:52:08 +03:00
|
|
|
do_output(output, kbinput_len, FALSE);
|
2005-01-12 06:25:57 +03:00
|
|
|
|
|
|
|
free(output);
|
2004-12-04 20:41:52 +03:00
|
|
|
|
|
|
|
/* Empty the input buffer. */
|
|
|
|
kbinput_len = 0;
|
|
|
|
free(kbinput);
|
|
|
|
kbinput = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (have_shortcut) {
|
|
|
|
switch (input) {
|
2005-07-02 02:58:47 +04:00
|
|
|
/* Handle the "universal" edit window shortcuts. */
|
2004-12-04 20:41:52 +03:00
|
|
|
case NANO_XON_KEY:
|
|
|
|
statusbar(_("XON ignored, mumble mumble."));
|
|
|
|
break;
|
|
|
|
case NANO_XOFF_KEY:
|
|
|
|
statusbar(_("XOFF ignored, mumble mumble."));
|
|
|
|
break;
|
|
|
|
#ifndef NANO_SMALL
|
|
|
|
case NANO_SUSPEND_KEY:
|
|
|
|
if (ISSET(SUSPEND))
|
|
|
|
do_suspend(0);
|
|
|
|
break;
|
|
|
|
#endif
|
2005-01-01 10:28:15 +03:00
|
|
|
/* Handle the normal edit window shortcuts, setting
|
2005-01-12 02:05:05 +03:00
|
|
|
* ran_func to TRUE if we try to run their associated
|
|
|
|
* functions and setting finished to TRUE to indicate
|
|
|
|
* that we're done after trying to run their associated
|
2005-01-01 10:28:15 +03:00
|
|
|
* functions. */
|
2004-12-04 20:41:52 +03:00
|
|
|
default:
|
|
|
|
/* Blow away the text in the cutbuffer if we aren't
|
|
|
|
* cutting text. */
|
|
|
|
if (s->func != do_cut_text)
|
|
|
|
cutbuffer_reset();
|
|
|
|
|
2004-12-20 04:13:55 +03:00
|
|
|
if (s->func != NULL) {
|
2005-01-12 02:05:05 +03:00
|
|
|
*ran_func = TRUE;
|
2004-12-20 04:13:55 +03:00
|
|
|
if (ISSET(VIEW_MODE) && !s->viewok)
|
|
|
|
print_view_warning();
|
|
|
|
else
|
|
|
|
s->func();
|
2004-12-04 20:41:52 +03:00
|
|
|
}
|
2005-01-01 10:28:15 +03:00
|
|
|
*finished = TRUE;
|
2004-12-04 20:41:52 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#ifndef NANO_SMALL
|
|
|
|
else if (have_toggle) {
|
|
|
|
/* Blow away the text in the cutbuffer, since we aren't
|
|
|
|
* cutting text. */
|
|
|
|
cutbuffer_reset();
|
|
|
|
/* Toggle the flag associated with this shortcut. */
|
|
|
|
if (allow_funcs)
|
|
|
|
do_toggle(t);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
else
|
|
|
|
/* Blow away the text in the cutbuffer, since we aren't
|
|
|
|
* cutting text. */
|
|
|
|
cutbuffer_reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
return input;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef DISABLE_MOUSE
|
|
|
|
bool do_mouse(void)
|
|
|
|
{
|
|
|
|
int mouse_x, mouse_y;
|
2005-07-26 00:01:57 +04:00
|
|
|
bool retval = get_mouseinput(&mouse_x, &mouse_y, TRUE);
|
2004-12-04 20:41:52 +03:00
|
|
|
|
|
|
|
if (!retval) {
|
|
|
|
/* We can click in the edit window to move the cursor. */
|
|
|
|
if (wenclose(edit, mouse_y, mouse_x)) {
|
|
|
|
bool sameline;
|
|
|
|
/* Did they click on the line with the cursor? If they
|
|
|
|
* clicked on the cursor, we set the mark. */
|
2005-07-25 23:04:20 +04:00
|
|
|
const filestruct *current_save = openfile->current;
|
2005-07-26 00:36:27 +04:00
|
|
|
size_t current_x_save = openfile->current_x;
|
|
|
|
size_t pww_save = openfile->placewewant;
|
2004-12-04 20:41:52 +03:00
|
|
|
|
2005-06-15 11:38:25 +04:00
|
|
|
/* Subtract out the size of topwin. */
|
2005-06-15 11:34:09 +04:00
|
|
|
mouse_y -= 2 - no_more_space();
|
2004-12-04 20:41:52 +03:00
|
|
|
|
2005-07-09 00:09:16 +04:00
|
|
|
sameline = (mouse_y == openfile->current_y);
|
2004-12-04 20:41:52 +03:00
|
|
|
|
|
|
|
/* Move to where the click occurred. */
|
2005-07-09 00:09:16 +04:00
|
|
|
for (; openfile->current_y < mouse_y &&
|
|
|
|
openfile->current->next != NULL; openfile->current_y++)
|
|
|
|
openfile->current = openfile->current->next;
|
|
|
|
for (; openfile->current_y > mouse_y &&
|
|
|
|
openfile->current->prev != NULL; openfile->current_y--)
|
|
|
|
openfile->current = openfile->current->prev;
|
|
|
|
|
2005-07-26 00:36:27 +04:00
|
|
|
openfile->current_x = actual_x(openfile->current->data,
|
|
|
|
get_page_start(xplustabs()) + mouse_x);
|
|
|
|
openfile->placewewant = xplustabs();
|
2004-12-04 20:41:52 +03:00
|
|
|
|
|
|
|
#ifndef NANO_SMALL
|
|
|
|
/* Clicking where the cursor is toggles the mark, as does
|
|
|
|
* clicking beyond the line length with the cursor at the
|
|
|
|
* end of the line. */
|
2005-07-26 00:36:27 +04:00
|
|
|
if (sameline && openfile->current_x == current_x_save)
|
2004-12-04 20:41:52 +03:00
|
|
|
do_mark();
|
|
|
|
#endif
|
|
|
|
|
2005-07-25 23:04:20 +04:00
|
|
|
edit_redraw(current_save, pww_save);
|
2004-12-04 20:41:52 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
#endif /* !DISABLE_MOUSE */
|
|
|
|
|
2005-06-26 00:56:36 +04:00
|
|
|
/* The user typed ouuput_len multibyte characters. Add them to the edit
|
|
|
|
* buffer, filtering out all control characters if allow_cntrls is
|
2005-03-17 06:52:08 +03:00
|
|
|
* TRUE. */
|
|
|
|
void do_output(char *output, size_t output_len, bool allow_cntrls)
|
2004-12-04 20:41:52 +03:00
|
|
|
{
|
2005-05-26 09:17:13 +04:00
|
|
|
size_t current_len, i = 0;
|
2004-12-04 20:41:52 +03:00
|
|
|
bool do_refresh = FALSE;
|
|
|
|
/* Do we have to call edit_refresh(), or can we get away with
|
|
|
|
* update_line()? */
|
|
|
|
|
2005-01-12 06:25:57 +03:00
|
|
|
char *char_buf = charalloc(mb_cur_max());
|
|
|
|
int char_buf_len;
|
2004-12-04 20:41:52 +03:00
|
|
|
|
2005-07-09 00:09:16 +04:00
|
|
|
assert(openfile->current != NULL && openfile->current->data != NULL);
|
2004-12-04 20:41:52 +03:00
|
|
|
|
2005-07-09 00:09:16 +04:00
|
|
|
current_len = strlen(openfile->current->data);
|
2005-05-26 09:17:13 +04:00
|
|
|
|
2005-01-12 06:25:57 +03:00
|
|
|
while (i < output_len) {
|
2005-03-17 06:52:08 +03:00
|
|
|
/* 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') {
|
|
|
|
do_enter();
|
|
|
|
i++;
|
|
|
|
continue;
|
|
|
|
}
|
2004-12-09 02:24:31 +03:00
|
|
|
}
|
|
|
|
|
2005-07-26 10:13:45 +04:00
|
|
|
/* Interpret the next multibyte character. */
|
|
|
|
char_buf_len = parse_mbchar(output + i, char_buf, NULL);
|
2005-01-12 06:25:57 +03:00
|
|
|
|
|
|
|
i += char_buf_len;
|
2004-12-04 20:41:52 +03:00
|
|
|
|
2005-03-17 06:52:08 +03:00
|
|
|
/* If allow_cntrls is FALSE, filter out a control character. */
|
|
|
|
if (!allow_cntrls && is_cntrl_mbchar(output + i - char_buf_len))
|
|
|
|
continue;
|
|
|
|
|
2004-12-04 20:41:52 +03:00
|
|
|
/* When a character is inserted on the current magicline, it
|
|
|
|
* means we need a new one! */
|
2005-07-09 00:09:16 +04:00
|
|
|
if (openfile->filebot == openfile->current)
|
2004-12-04 20:41:52 +03:00
|
|
|
new_magicline();
|
|
|
|
|
|
|
|
/* More dangerousness fun =) */
|
2005-07-09 00:09:16 +04:00
|
|
|
openfile->current->data = charealloc(openfile->current->data,
|
2005-06-28 21:51:28 +04:00
|
|
|
current_len + (char_buf_len * 2));
|
2004-12-31 07:10:28 +03:00
|
|
|
|
2005-07-09 00:09:16 +04:00
|
|
|
assert(openfile->current_x <= current_len);
|
2004-12-31 07:10:28 +03:00
|
|
|
|
2005-07-09 00:09:16 +04:00
|
|
|
charmove(&openfile->current->data[openfile->current_x +
|
|
|
|
char_buf_len],
|
|
|
|
&openfile->current->data[openfile->current_x],
|
|
|
|
current_len - openfile->current_x + char_buf_len);
|
|
|
|
strncpy(&openfile->current->data[openfile->current_x], char_buf,
|
|
|
|
char_buf_len);
|
2005-01-12 06:25:57 +03:00
|
|
|
current_len += char_buf_len;
|
2005-07-09 00:09:16 +04:00
|
|
|
openfile->totsize++;
|
2004-12-04 20:41:52 +03:00
|
|
|
set_modified();
|
|
|
|
|
|
|
|
#ifndef NANO_SMALL
|
|
|
|
/* Note that current_x has not yet been incremented. */
|
2005-07-09 00:09:16 +04:00
|
|
|
if (openfile->mark_set && openfile->current ==
|
2005-07-12 21:40:16 +04:00
|
|
|
openfile->mark_begin && openfile->current_x <
|
|
|
|
openfile->mark_begin_x)
|
|
|
|
openfile->mark_begin_x += char_buf_len;
|
2004-12-04 20:41:52 +03:00
|
|
|
#endif
|
|
|
|
|
2005-07-17 03:36:10 +04:00
|
|
|
openfile->current_x += char_buf_len;
|
2004-12-04 20:41:52 +03:00
|
|
|
|
|
|
|
#ifndef DISABLE_WRAPPING
|
2005-04-26 21:21:47 +04:00
|
|
|
/* If we're wrapping text, we need to call edit_refresh(). */
|
|
|
|
if (!ISSET(NO_WRAP)) {
|
2004-12-04 20:41:52 +03:00
|
|
|
bool do_refresh_save = do_refresh;
|
|
|
|
|
2005-07-09 00:09:16 +04:00
|
|
|
do_refresh = do_wrap(openfile->current);
|
2004-12-04 20:41:52 +03:00
|
|
|
|
|
|
|
/* If we needed to call edit_refresh() before this, we'll
|
|
|
|
* still need to after this. */
|
|
|
|
if (do_refresh_save)
|
|
|
|
do_refresh = TRUE;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef ENABLE_COLOR
|
2005-07-14 00:18:46 +04:00
|
|
|
/* If color syntaxes are available and turned on, we need to
|
|
|
|
* call edit_refresh(). */
|
|
|
|
if (openfile->colorstrings != NULL && !ISSET(NO_COLOR_SYNTAX))
|
2004-12-04 20:41:52 +03:00
|
|
|
do_refresh = TRUE;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2005-01-12 06:25:57 +03:00
|
|
|
free(char_buf);
|
2004-12-12 22:04:56 +03:00
|
|
|
|
2005-07-17 03:36:10 +04:00
|
|
|
openfile->placewewant = xplustabs();
|
|
|
|
|
2004-12-04 20:41:52 +03:00
|
|
|
if (do_refresh)
|
|
|
|
edit_refresh();
|
|
|
|
else
|
2005-07-09 00:09:16 +04:00
|
|
|
update_line(openfile->current, openfile->current_x);
|
2004-12-04 20:41:52 +03:00
|
|
|
}
|
|
|
|
|
2004-08-17 09:23:38 +04:00
|
|
|
int main(int argc, char **argv)
|
2000-06-06 09:53:49 +04:00
|
|
|
{
|
|
|
|
int optchr;
|
2005-06-28 10:25:34 +04:00
|
|
|
ssize_t startline = 1;
|
2004-09-06 01:40:31 +04:00
|
|
|
/* Line to try and start at. */
|
2005-05-16 22:38:16 +04:00
|
|
|
ssize_t startcol = 1;
|
|
|
|
/* Column to try and start at. */
|
2004-08-12 23:48:21 +04:00
|
|
|
#ifndef DISABLE_WRAPJUSTIFY
|
2005-07-26 02:54:16 +04:00
|
|
|
bool fill_used = FALSE;
|
2004-09-06 01:40:31 +04:00
|
|
|
/* Was the fill option used? */
|
2004-08-12 23:48:21 +04:00
|
|
|
#endif
|
2004-09-06 01:40:31 +04:00
|
|
|
#ifdef ENABLE_MULTIBUFFER
|
|
|
|
bool old_multibuffer;
|
|
|
|
/* The old value of the multibuffer option, restored after we
|
|
|
|
* load all files on the command line. */
|
|
|
|
#endif
|
2000-06-06 09:53:49 +04:00
|
|
|
#ifdef HAVE_GETOPT_LONG
|
2002-12-22 19:30:00 +03:00
|
|
|
const struct option long_options[] = {
|
2005-03-27 01:49:08 +03:00
|
|
|
{"help", 0, NULL, 'h'},
|
2002-06-29 02:45:14 +04:00
|
|
|
#ifdef ENABLE_MULTIBUFFER
|
2005-03-27 01:49:08 +03:00
|
|
|
{"multibuffer", 0, NULL, 'F'},
|
2002-07-19 05:08:59 +04:00
|
|
|
#endif
|
|
|
|
#ifdef ENABLE_NANORC
|
2005-03-27 01:49:08 +03:00
|
|
|
{"ignorercfiles", 0, NULL, 'I'},
|
2002-06-29 02:45:14 +04:00
|
|
|
#endif
|
2005-03-27 01:49:08 +03:00
|
|
|
{"morespace", 0, NULL, 'O'},
|
2002-06-29 02:45:14 +04:00
|
|
|
#ifndef DISABLE_JUSTIFY
|
2005-03-27 01:49:08 +03:00
|
|
|
{"quotestr", 1, NULL, 'Q'},
|
2000-07-07 06:35:34 +04:00
|
|
|
#endif
|
2005-06-18 02:53:41 +04:00
|
|
|
{"restricted", 0, NULL, 'R'},
|
2005-03-27 01:49:08 +03:00
|
|
|
{"tabsize", 1, NULL, 'T'},
|
|
|
|
{"version", 0, NULL, 'V'},
|
2002-06-29 02:45:14 +04:00
|
|
|
#ifdef ENABLE_COLOR
|
2005-03-27 01:49:08 +03:00
|
|
|
{"syntax", 1, NULL, 'Y'},
|
2001-05-21 16:56:25 +04:00
|
|
|
#endif
|
2005-03-27 01:49:08 +03:00
|
|
|
{"const", 0, NULL, 'c'},
|
|
|
|
{"rebinddelete", 0, NULL, 'd'},
|
|
|
|
{"nofollow", 0, NULL, 'l'},
|
2003-10-04 00:26:25 +04:00
|
|
|
#ifndef DISABLE_MOUSE
|
2005-03-27 01:49:08 +03:00
|
|
|
{"mouse", 0, NULL, 'm'},
|
2002-12-22 19:30:00 +03:00
|
|
|
#endif
|
2001-09-19 07:19:43 +04:00
|
|
|
#ifndef DISABLE_OPERATINGDIR
|
2005-03-27 01:49:08 +03:00
|
|
|
{"operatingdir", 1, NULL, 'o'},
|
2001-09-19 07:19:43 +04:00
|
|
|
#endif
|
2005-03-27 01:49:08 +03:00
|
|
|
{"preserve", 0, NULL, 'p'},
|
2002-06-29 02:45:14 +04:00
|
|
|
#ifndef DISABLE_WRAPJUSTIFY
|
2005-03-27 01:49:08 +03:00
|
|
|
{"fill", 1, NULL, 'r'},
|
2002-06-29 02:45:14 +04:00
|
|
|
#endif
|
|
|
|
#ifndef DISABLE_SPELLER
|
2005-03-27 01:49:08 +03:00
|
|
|
{"speller", 1, NULL, 's'},
|
2001-07-11 06:08:33 +04:00
|
|
|
#endif
|
2005-03-27 01:49:08 +03:00
|
|
|
{"tempfile", 0, NULL, 't'},
|
|
|
|
{"view", 0, NULL, 'v'},
|
2002-10-17 06:19:31 +04:00
|
|
|
#ifndef DISABLE_WRAPPING
|
2005-03-27 01:49:08 +03:00
|
|
|
{"nowrap", 0, NULL, 'w'},
|
2002-10-17 06:19:31 +04:00
|
|
|
#endif
|
2005-03-27 01:49:08 +03:00
|
|
|
{"nohelp", 0, NULL, 'x'},
|
|
|
|
{"suspend", 0, NULL, 'z'},
|
2001-09-22 23:02:04 +04:00
|
|
|
#ifndef NANO_SMALL
|
2005-03-27 01:49:08 +03:00
|
|
|
{"smarthome", 0, NULL, 'A'},
|
|
|
|
{"backup", 0, NULL, 'B'},
|
2005-06-16 03:20:56 +04:00
|
|
|
{"backupdir", 1, NULL, 'C'},
|
|
|
|
{"tabstospaces", 0, NULL, 'E'},
|
2005-06-17 21:37:46 +04:00
|
|
|
{"historylog", 0, NULL, 'H'},
|
2005-03-27 01:49:08 +03:00
|
|
|
{"noconvert", 0, NULL, 'N'},
|
|
|
|
{"smooth", 0, NULL, 'S'},
|
2005-06-17 23:06:25 +04:00
|
|
|
{"quickblank", 0, NULL, 'U'},
|
2005-03-27 01:49:08 +03:00
|
|
|
{"autoindent", 0, NULL, 'i'},
|
|
|
|
{"cut", 0, NULL, 'k'},
|
2002-05-04 08:23:30 +04:00
|
|
|
#endif
|
2005-03-27 01:49:08 +03:00
|
|
|
{NULL, 0, NULL, 0}
|
2000-06-06 09:53:49 +04:00
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2005-07-17 06:40:07 +04:00
|
|
|
#ifdef ENABLE_UTF8
|
2004-12-23 20:43:27 +03:00
|
|
|
{
|
2005-06-16 06:09:57 +04:00
|
|
|
/* If the locale set exists and includes the case-insensitive
|
|
|
|
* string "UTF8" or "UTF-8", we should use UTF-8. */
|
2004-12-23 20:43:27 +03:00
|
|
|
char *locale = setlocale(LC_ALL, "");
|
|
|
|
|
2005-06-16 06:09:57 +04:00
|
|
|
if (locale != NULL && (strcasestr(locale, "UTF8") != NULL ||
|
|
|
|
strcasestr(locale, "UTF-8") != NULL)) {
|
|
|
|
SET(USE_UTF8);
|
2005-01-28 22:37:23 +03:00
|
|
|
#ifdef USE_SLANG
|
2005-03-11 20:46:01 +03:00
|
|
|
SLutf8_enable(TRUE);
|
2005-01-28 22:37:23 +03:00
|
|
|
#endif
|
2005-06-16 06:09:57 +04:00
|
|
|
}
|
2004-12-23 20:43:27 +03:00
|
|
|
}
|
|
|
|
#else
|
2000-06-06 09:53:49 +04:00
|
|
|
setlocale(LC_ALL, "");
|
2004-12-23 20:43:27 +03:00
|
|
|
#endif
|
|
|
|
|
2004-07-27 19:46:58 +04:00
|
|
|
#ifdef ENABLE_NLS
|
2000-06-06 09:53:49 +04:00
|
|
|
bindtextdomain(PACKAGE, LOCALEDIR);
|
|
|
|
textdomain(PACKAGE);
|
|
|
|
#endif
|
|
|
|
|
2003-01-13 04:35:15 +03:00
|
|
|
#if !defined(ENABLE_NANORC) && defined(DISABLE_ROOTWRAP) && !defined(DISABLE_WRAPPING)
|
2004-09-06 01:40:31 +04:00
|
|
|
/* If we don't have rcfile support, we're root, and
|
|
|
|
* --disable-wrapping-as-root is used, turn wrapping off. */
|
2004-03-04 09:33:52 +03:00
|
|
|
if (geteuid() == NANO_ROOT_UID)
|
2002-10-25 20:08:53 +04:00
|
|
|
SET(NO_WRAP);
|
|
|
|
#endif
|
2001-04-18 08:28:54 +04:00
|
|
|
|
2004-08-08 02:00:02 +04:00
|
|
|
while ((optchr =
|
2000-06-06 09:53:49 +04:00
|
|
|
#ifdef HAVE_GETOPT_LONG
|
2005-06-12 20:13:44 +04:00
|
|
|
getopt_long(argc, argv,
|
2005-06-18 02:53:41 +04:00
|
|
|
"h?ABC:EFHINOQ:RST:UVY:abcdefgijklmo:pr:s:tvwxz",
|
2005-06-12 20:13:44 +04:00
|
|
|
long_options, NULL)
|
2000-06-06 09:53:49 +04:00
|
|
|
#else
|
2005-06-12 20:13:44 +04:00
|
|
|
getopt(argc, argv,
|
2005-06-18 02:53:41 +04:00
|
|
|
"h?ABC:EFHINOQ:RST:UVY:abcdefgijklmo:pr:s:tvwxz")
|
2000-06-06 09:53:49 +04:00
|
|
|
#endif
|
2004-08-08 02:00:02 +04:00
|
|
|
) != -1) {
|
2000-06-06 09:53:49 +04:00
|
|
|
switch (optchr) {
|
2004-08-08 02:00:02 +04:00
|
|
|
case 'a':
|
|
|
|
case 'b':
|
|
|
|
case 'e':
|
|
|
|
case 'f':
|
|
|
|
case 'g':
|
|
|
|
case 'j':
|
|
|
|
/* Pico compatibility flags. */
|
|
|
|
break;
|
2001-09-22 04:42:10 +04:00
|
|
|
#ifndef NANO_SMALL
|
2004-08-08 02:00:02 +04:00
|
|
|
case 'A':
|
|
|
|
SET(SMART_HOME);
|
|
|
|
break;
|
|
|
|
case 'B':
|
|
|
|
SET(BACKUP_FILE);
|
|
|
|
break;
|
2005-06-16 03:20:56 +04:00
|
|
|
case 'C':
|
2004-08-08 02:00:02 +04:00
|
|
|
backup_dir = mallocstrcpy(backup_dir, optarg);
|
|
|
|
break;
|
2005-06-16 03:20:56 +04:00
|
|
|
case 'E':
|
|
|
|
SET(TABS_TO_SPACES);
|
|
|
|
break;
|
2001-09-22 04:42:10 +04:00
|
|
|
#endif
|
2001-07-14 23:32:47 +04:00
|
|
|
#ifdef ENABLE_MULTIBUFFER
|
2004-08-08 02:00:02 +04:00
|
|
|
case 'F':
|
|
|
|
SET(MULTIBUFFER);
|
|
|
|
break;
|
2002-07-19 05:08:59 +04:00
|
|
|
#endif
|
|
|
|
#ifdef ENABLE_NANORC
|
2003-09-07 01:44:37 +04:00
|
|
|
#ifndef NANO_SMALL
|
2004-08-08 02:00:02 +04:00
|
|
|
case 'H':
|
|
|
|
SET(HISTORYLOG);
|
|
|
|
break;
|
2003-09-07 01:44:37 +04:00
|
|
|
#endif
|
2004-08-08 02:00:02 +04:00
|
|
|
case 'I':
|
|
|
|
SET(NO_RCFILE);
|
|
|
|
break;
|
2001-07-11 06:08:33 +04:00
|
|
|
#endif
|
2001-09-22 08:20:25 +04:00
|
|
|
#ifndef NANO_SMALL
|
2004-08-08 02:00:02 +04:00
|
|
|
case 'N':
|
|
|
|
SET(NO_CONVERT);
|
|
|
|
break;
|
2002-03-04 01:36:36 +03:00
|
|
|
#endif
|
2005-01-17 08:06:55 +03:00
|
|
|
case 'O':
|
|
|
|
SET(MORE_SPACE);
|
|
|
|
break;
|
2002-03-04 01:36:36 +03:00
|
|
|
#ifndef DISABLE_JUSTIFY
|
2004-08-08 02:00:02 +04:00
|
|
|
case 'Q':
|
|
|
|
quotestr = mallocstrcpy(quotestr, optarg);
|
|
|
|
break;
|
2002-02-15 22:17:02 +03:00
|
|
|
#endif
|
2005-06-18 02:53:41 +04:00
|
|
|
case 'R':
|
|
|
|
SET(RESTRICTED);
|
|
|
|
break;
|
2001-09-22 23:02:04 +04:00
|
|
|
#ifndef NANO_SMALL
|
2004-08-08 02:00:02 +04:00
|
|
|
case 'S':
|
2005-06-16 06:13:10 +04:00
|
|
|
SET(SMOOTH_SCROLL);
|
2004-08-08 02:00:02 +04:00
|
|
|
break;
|
2000-07-07 06:35:34 +04:00
|
|
|
#endif
|
2004-08-08 02:00:02 +04:00
|
|
|
case 'T':
|
|
|
|
if (!parse_num(optarg, &tabsize) || tabsize <= 0) {
|
2004-08-11 09:13:08 +04:00
|
|
|
fprintf(stderr, _("Requested tab size %s invalid"), optarg);
|
|
|
|
fprintf(stderr, "\n");
|
2004-08-08 02:00:02 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
2005-06-17 23:06:25 +04:00
|
|
|
#ifndef NANO_SMALL
|
|
|
|
case 'U':
|
|
|
|
SET(QUICK_BLANK);
|
|
|
|
break;
|
|
|
|
#endif
|
2004-08-08 02:00:02 +04:00
|
|
|
case 'V':
|
|
|
|
version();
|
|
|
|
exit(0);
|
2002-05-04 08:23:30 +04:00
|
|
|
#ifdef ENABLE_COLOR
|
2004-08-08 02:00:02 +04:00
|
|
|
case 'Y':
|
|
|
|
syntaxstr = mallocstrcpy(syntaxstr, optarg);
|
|
|
|
break;
|
2002-05-04 08:23:30 +04:00
|
|
|
#endif
|
2004-08-08 02:00:02 +04:00
|
|
|
case 'c':
|
2005-06-18 01:08:13 +04:00
|
|
|
SET(CONST_UPDATE);
|
2004-08-08 02:00:02 +04:00
|
|
|
break;
|
|
|
|
case 'd':
|
|
|
|
SET(REBIND_DELETE);
|
|
|
|
break;
|
2001-09-17 17:48:00 +04:00
|
|
|
#ifndef NANO_SMALL
|
2004-08-08 02:00:02 +04:00
|
|
|
case 'i':
|
|
|
|
SET(AUTOINDENT);
|
|
|
|
break;
|
|
|
|
case 'k':
|
|
|
|
SET(CUT_TO_END);
|
|
|
|
break;
|
2000-07-12 22:14:51 +04:00
|
|
|
#endif
|
2004-08-08 02:00:02 +04:00
|
|
|
case 'l':
|
|
|
|
SET(NOFOLLOW_SYMLINKS);
|
|
|
|
break;
|
2003-10-04 00:26:25 +04:00
|
|
|
#ifndef DISABLE_MOUSE
|
2004-08-08 02:00:02 +04:00
|
|
|
case 'm':
|
|
|
|
SET(USE_MOUSE);
|
|
|
|
break;
|
2002-12-22 19:30:00 +03:00
|
|
|
#endif
|
2001-09-19 07:19:43 +04:00
|
|
|
#ifndef DISABLE_OPERATINGDIR
|
2004-08-08 02:00:02 +04:00
|
|
|
case 'o':
|
|
|
|
operating_dir = mallocstrcpy(operating_dir, optarg);
|
|
|
|
break;
|
2001-09-19 07:19:43 +04:00
|
|
|
#endif
|
2004-08-08 02:00:02 +04:00
|
|
|
case 'p':
|
|
|
|
SET(PRESERVE);
|
|
|
|
break;
|
2001-05-21 16:56:25 +04:00
|
|
|
#ifndef DISABLE_WRAPJUSTIFY
|
2004-08-08 02:00:02 +04:00
|
|
|
case 'r':
|
|
|
|
if (!parse_num(optarg, &wrap_at)) {
|
2004-08-11 09:13:08 +04:00
|
|
|
fprintf(stderr, _("Requested fill size %s invalid"), optarg);
|
|
|
|
fprintf(stderr, "\n");
|
2004-08-08 02:00:02 +04:00
|
|
|
exit(1);
|
|
|
|
}
|
2005-07-26 02:54:16 +04:00
|
|
|
fill_used = TRUE;
|
2004-08-08 02:00:02 +04:00
|
|
|
break;
|
2001-05-21 16:56:25 +04:00
|
|
|
#endif
|
2001-01-12 10:51:05 +03:00
|
|
|
#ifndef DISABLE_SPELLER
|
2004-08-08 02:00:02 +04:00
|
|
|
case 's':
|
|
|
|
alt_speller = mallocstrcpy(alt_speller, optarg);
|
|
|
|
break;
|
2001-01-12 10:51:05 +03:00
|
|
|
#endif
|
2004-08-08 02:00:02 +04:00
|
|
|
case 't':
|
|
|
|
SET(TEMP_FILE);
|
|
|
|
break;
|
|
|
|
case 'v':
|
|
|
|
SET(VIEW_MODE);
|
|
|
|
break;
|
2003-01-02 19:32:20 +03:00
|
|
|
#ifndef DISABLE_WRAPPING
|
2004-08-08 02:00:02 +04:00
|
|
|
case 'w':
|
|
|
|
SET(NO_WRAP);
|
|
|
|
break;
|
2002-12-22 19:30:00 +03:00
|
|
|
#endif
|
2004-08-08 02:00:02 +04:00
|
|
|
case 'x':
|
|
|
|
SET(NO_HELP);
|
|
|
|
break;
|
|
|
|
case 'z':
|
|
|
|
SET(SUSPEND);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
usage();
|
2000-06-06 09:53:49 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-05-29 05:20:17 +04:00
|
|
|
/* If the executable filename starts with 'r', we use restricted
|
|
|
|
* mode. */
|
2004-04-30 08:49:02 +04:00
|
|
|
if (*(tail(argv[0])) == 'r')
|
|
|
|
SET(RESTRICTED);
|
|
|
|
|
2004-05-29 05:20:17 +04:00
|
|
|
/* If we're using restricted mode, disable suspending, backups, and
|
|
|
|
* reading rcfiles, since they all would allow reading from or
|
|
|
|
* writing to files not specified on the command line. */
|
2004-04-30 08:49:02 +04:00
|
|
|
if (ISSET(RESTRICTED)) {
|
|
|
|
UNSET(SUSPEND);
|
|
|
|
UNSET(BACKUP_FILE);
|
|
|
|
SET(NO_RCFILE);
|
|
|
|
}
|
|
|
|
|
2003-01-13 04:35:15 +03:00
|
|
|
/* We've read through the command line options. Now back up the flags
|
2004-09-06 01:40:31 +04:00
|
|
|
* and values that are set, and read the rcfile(s). If the values
|
|
|
|
* haven't changed afterward, restore the backed-up values. */
|
2003-01-13 04:35:15 +03:00
|
|
|
#ifdef ENABLE_NANORC
|
|
|
|
if (!ISSET(NO_RCFILE)) {
|
|
|
|
#ifndef DISABLE_OPERATINGDIR
|
|
|
|
char *operating_dir_cpy = operating_dir;
|
|
|
|
#endif
|
2004-08-13 00:06:20 +04:00
|
|
|
#ifndef DISABLE_WRAPJUSTIFY
|
2004-07-12 20:07:14 +04:00
|
|
|
ssize_t wrap_at_cpy = wrap_at;
|
2003-01-13 04:35:15 +03:00
|
|
|
#endif
|
2004-02-28 19:24:31 +03:00
|
|
|
#ifndef NANO_SMALL
|
|
|
|
char *backup_dir_cpy = backup_dir;
|
|
|
|
#endif
|
2003-01-13 04:35:15 +03:00
|
|
|
#ifndef DISABLE_JUSTIFY
|
|
|
|
char *quotestr_cpy = quotestr;
|
|
|
|
#endif
|
|
|
|
#ifndef DISABLE_SPELLER
|
|
|
|
char *alt_speller_cpy = alt_speller;
|
|
|
|
#endif
|
2004-07-12 20:07:14 +04:00
|
|
|
ssize_t tabsize_cpy = tabsize;
|
2005-07-14 00:18:46 +04:00
|
|
|
long flags_cpy = flags;
|
2003-01-13 04:35:15 +03:00
|
|
|
|
2003-02-05 05:39:34 +03:00
|
|
|
#ifndef DISABLE_OPERATINGDIR
|
2003-01-13 04:35:15 +03:00
|
|
|
operating_dir = NULL;
|
2003-02-05 05:39:34 +03:00
|
|
|
#endif
|
2004-02-28 19:24:31 +03:00
|
|
|
#ifndef NANO_SMALL
|
|
|
|
backup_dir = NULL;
|
|
|
|
#endif
|
2003-02-05 05:39:34 +03:00
|
|
|
#ifndef DISABLE_JUSTIFY
|
2003-01-13 04:35:15 +03:00
|
|
|
quotestr = NULL;
|
2003-02-05 05:39:34 +03:00
|
|
|
#endif
|
|
|
|
#ifndef DISABLE_SPELLER
|
2003-01-13 04:35:15 +03:00
|
|
|
alt_speller = NULL;
|
2003-02-05 05:39:34 +03:00
|
|
|
#endif
|
2003-01-13 04:35:15 +03:00
|
|
|
|
|
|
|
do_rcfile();
|
|
|
|
|
|
|
|
#ifndef DISABLE_OPERATINGDIR
|
|
|
|
if (operating_dir_cpy != NULL) {
|
|
|
|
free(operating_dir);
|
|
|
|
operating_dir = operating_dir_cpy;
|
|
|
|
}
|
|
|
|
#endif
|
2004-08-12 23:48:21 +04:00
|
|
|
#ifndef DISABLE_WRAPJUSTIFY
|
2005-07-26 02:54:16 +04:00
|
|
|
if (fill_used)
|
2003-01-13 04:35:15 +03:00
|
|
|
wrap_at = wrap_at_cpy;
|
|
|
|
#endif
|
2004-02-28 19:24:31 +03:00
|
|
|
#ifndef NANO_SMALL
|
|
|
|
if (backup_dir_cpy != NULL) {
|
|
|
|
free(backup_dir);
|
|
|
|
backup_dir = backup_dir_cpy;
|
|
|
|
}
|
|
|
|
#endif
|
2003-01-13 04:35:15 +03:00
|
|
|
#ifndef DISABLE_JUSTIFY
|
|
|
|
if (quotestr_cpy != NULL) {
|
|
|
|
free(quotestr);
|
|
|
|
quotestr = quotestr_cpy;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifndef DISABLE_SPELLER
|
|
|
|
if (alt_speller_cpy != NULL) {
|
|
|
|
free(alt_speller);
|
|
|
|
alt_speller = alt_speller_cpy;
|
|
|
|
}
|
|
|
|
#endif
|
2004-07-18 22:13:54 +04:00
|
|
|
if (tabsize_cpy != -1)
|
2003-01-13 04:35:15 +03:00
|
|
|
tabsize = tabsize_cpy;
|
|
|
|
flags |= flags_cpy;
|
|
|
|
}
|
|
|
|
#if defined(DISABLE_ROOTWRAP) && !defined(DISABLE_WRAPPING)
|
2004-03-04 09:33:52 +03:00
|
|
|
else if (geteuid() == NANO_ROOT_UID)
|
2003-01-13 04:35:15 +03:00
|
|
|
SET(NO_WRAP);
|
|
|
|
#endif
|
|
|
|
#endif /* ENABLE_NANORC */
|
|
|
|
|
2003-03-11 06:50:40 +03:00
|
|
|
#ifndef NANO_SMALL
|
|
|
|
history_init();
|
|
|
|
#ifdef ENABLE_NANORC
|
|
|
|
if (!ISSET(NO_RCFILE) && ISSET(HISTORYLOG))
|
|
|
|
load_history();
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2004-02-28 19:24:31 +03:00
|
|
|
#ifndef NANO_SMALL
|
2004-05-29 03:45:25 +04:00
|
|
|
/* Set up the backup directory (unless we're using restricted mode,
|
2004-05-29 05:20:17 +04:00
|
|
|
* in which case backups are disabled, since they would allow
|
|
|
|
* reading from or writing to files not specified on the command
|
|
|
|
* line). This entails making sure it exists and is a directory, so
|
|
|
|
* that backup files will be saved there. */
|
2004-05-29 03:45:25 +04:00
|
|
|
if (!ISSET(RESTRICTED))
|
|
|
|
init_backup_dir();
|
2004-02-28 19:24:31 +03:00
|
|
|
#endif
|
|
|
|
|
2002-09-13 22:14:04 +04:00
|
|
|
#ifndef DISABLE_OPERATINGDIR
|
2003-01-13 04:35:15 +03:00
|
|
|
/* Set up the operating directory. This entails chdir()ing there,
|
2004-05-29 03:45:25 +04:00
|
|
|
* so that file reads and writes will be based there. */
|
2002-09-13 22:14:04 +04:00
|
|
|
init_operating_dir();
|
|
|
|
#endif
|
|
|
|
|
2003-01-13 04:35:15 +03:00
|
|
|
#ifndef DISABLE_JUSTIFY
|
2004-05-29 20:38:57 +04:00
|
|
|
if (punct == NULL)
|
2005-07-17 02:35:11 +04:00
|
|
|
punct = mallocstrcpy(NULL, ".?!");
|
2004-05-29 20:38:57 +04:00
|
|
|
|
|
|
|
if (brackets == NULL)
|
2005-07-17 02:35:11 +04:00
|
|
|
brackets = mallocstrcpy(NULL, "'\")}]>");
|
2004-05-29 20:38:57 +04:00
|
|
|
|
2003-01-13 04:35:15 +03:00
|
|
|
if (quotestr == NULL)
|
2004-06-13 01:03:14 +04:00
|
|
|
quotestr = mallocstrcpy(NULL,
|
2003-01-13 04:35:15 +03:00
|
|
|
#ifdef HAVE_REGEX_H
|
2004-06-13 01:03:14 +04:00
|
|
|
"^([ \t]*[|>:}#])+"
|
2003-01-13 04:35:15 +03:00
|
|
|
#else
|
2004-06-13 01:03:14 +04:00
|
|
|
"> "
|
2003-01-13 04:35:15 +03:00
|
|
|
#endif
|
2004-06-13 01:03:14 +04:00
|
|
|
);
|
2004-07-30 07:54:34 +04:00
|
|
|
#ifdef HAVE_REGEX_H
|
|
|
|
quoterc = regcomp("ereg, quotestr, REG_EXTENDED);
|
|
|
|
|
|
|
|
if (quoterc == 0) {
|
|
|
|
/* We no longer need quotestr, just quotereg. */
|
|
|
|
free(quotestr);
|
|
|
|
quotestr = NULL;
|
|
|
|
} else {
|
|
|
|
size_t size = regerror(quoterc, "ereg, NULL, 0);
|
|
|
|
|
|
|
|
quoteerr = charalloc(size);
|
|
|
|
regerror(quoterc, "ereg, quoteerr, size);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
quotelen = strlen(quotestr);
|
|
|
|
#endif /* !HAVE_REGEX_H */
|
2003-01-13 04:35:15 +03:00
|
|
|
#endif /* !DISABLE_JUSTIFY */
|
2004-02-28 19:24:31 +03:00
|
|
|
|
2004-05-29 02:42:41 +04:00
|
|
|
#ifndef DISABLE_SPELLER
|
|
|
|
/* If we don't have an alternative spell checker after reading the
|
2004-05-29 05:20:17 +04:00
|
|
|
* command line and/or rcfile(s), check $SPELL for one, as Pico
|
2004-05-29 03:45:25 +04:00
|
|
|
* does (unless we're using restricted mode, in which case spell
|
2004-05-29 05:20:17 +04:00
|
|
|
* checking is disabled, since it would allow reading from or
|
|
|
|
* writing to files not specified on the command line). */
|
2004-05-29 03:45:25 +04:00
|
|
|
if (!ISSET(RESTRICTED) && alt_speller == NULL) {
|
2004-05-29 02:42:41 +04:00
|
|
|
char *spellenv = getenv("SPELL");
|
|
|
|
if (spellenv != NULL)
|
|
|
|
alt_speller = mallocstrcpy(NULL, spellenv);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2004-05-29 20:25:30 +04:00
|
|
|
#if !defined(NANO_SMALL) && defined(ENABLE_NANORC)
|
2004-09-06 01:40:31 +04:00
|
|
|
/* If whitespace wasn't specified, set its default value. */
|
2005-03-11 01:52:21 +03:00
|
|
|
if (whitespace == NULL) {
|
2004-05-29 20:25:30 +04:00
|
|
|
whitespace = mallocstrcpy(NULL, " ");
|
2005-03-11 01:52:21 +03:00
|
|
|
whitespace_len[0] = 1;
|
|
|
|
whitespace_len[1] = 1;
|
|
|
|
}
|
2004-05-29 20:25:30 +04:00
|
|
|
#endif
|
|
|
|
|
2004-09-06 01:40:31 +04:00
|
|
|
/* If tabsize wasn't specified, set its default value. */
|
2003-01-13 04:35:15 +03:00
|
|
|
if (tabsize == -1)
|
2004-09-06 01:40:31 +04:00
|
|
|
tabsize = WIDTH_OF_TAB;
|
2002-06-13 04:40:19 +04:00
|
|
|
|
2004-05-18 05:20:36 +04:00
|
|
|
/* Back up the old terminal settings so that they can be restored. */
|
2002-03-29 19:00:59 +03:00
|
|
|
tcgetattr(0, &oldterm);
|
2002-03-29 18:38:17 +03:00
|
|
|
|
2005-07-10 06:37:38 +04:00
|
|
|
/* Initialize curses mode. */
|
2000-06-06 09:53:49 +04:00
|
|
|
initscr();
|
2005-07-10 06:37:38 +04:00
|
|
|
|
|
|
|
/* Set up the terminal state. */
|
2004-07-27 20:46:35 +04:00
|
|
|
terminal_init();
|
2004-01-12 06:28:06 +03:00
|
|
|
|
2005-03-21 00:20:47 +03:00
|
|
|
/* Turn the cursor on for sure. */
|
|
|
|
curs_set(1);
|
|
|
|
|
2005-07-26 02:54:16 +04:00
|
|
|
#ifdef DEBUG
|
|
|
|
fprintf(stderr, "Main: set up windows\n");
|
|
|
|
#endif
|
2005-07-10 06:37:38 +04:00
|
|
|
|
2005-07-26 02:54:16 +04:00
|
|
|
/* Initialize all the windows based on the current screen
|
|
|
|
* dimensions. */
|
|
|
|
window_init();
|
2004-02-16 23:32:40 +03:00
|
|
|
|
|
|
|
/* Set up the signal handlers. */
|
2002-03-29 19:00:59 +03:00
|
|
|
signal_init();
|
2000-06-06 09:53:49 +04:00
|
|
|
|
2005-07-26 02:54:16 +04:00
|
|
|
/* Set up the shortcut lists. */
|
|
|
|
shortcut_init(FALSE);
|
2000-06-06 09:53:49 +04:00
|
|
|
|
2003-10-04 00:26:25 +04:00
|
|
|
#ifndef DISABLE_MOUSE
|
2001-11-29 05:42:27 +03:00
|
|
|
mouse_init();
|
2002-12-22 19:30:00 +03:00
|
|
|
#endif
|
2001-11-29 05:42:27 +03:00
|
|
|
|
2000-06-06 09:53:49 +04:00
|
|
|
#ifdef DEBUG
|
2003-08-05 23:31:12 +04:00
|
|
|
fprintf(stderr, "Main: open file\n");
|
2000-06-06 09:53:49 +04:00
|
|
|
#endif
|
2004-09-06 01:40:31 +04:00
|
|
|
|
2005-05-16 22:38:16 +04:00
|
|
|
/* If there's a +LINE or +LINE,COLUMN flag here, it is the first
|
|
|
|
* non-option argument, and it is followed by at least one other
|
|
|
|
* argument, the filename it applies to. */
|
2004-10-23 00:25:56 +04:00
|
|
|
if (0 < optind && optind < argc - 1 && argv[optind][0] == '+') {
|
2005-05-17 03:23:15 +04:00
|
|
|
parse_line_column(&argv[optind][1], &startline, &startcol);
|
2004-10-23 00:25:56 +04:00
|
|
|
optind++;
|
|
|
|
}
|
|
|
|
|
2003-01-13 04:35:15 +03:00
|
|
|
#ifdef ENABLE_MULTIBUFFER
|
2004-09-06 01:40:31 +04:00
|
|
|
old_multibuffer = ISSET(MULTIBUFFER);
|
|
|
|
SET(MULTIBUFFER);
|
|
|
|
|
|
|
|
/* Read all the files after the first one on the command line into
|
|
|
|
* new buffers. */
|
|
|
|
{
|
2005-06-28 10:25:34 +04:00
|
|
|
int i = optind + 1;
|
|
|
|
ssize_t iline = 1, icol = 1;
|
2005-05-16 22:38:16 +04:00
|
|
|
|
2004-10-23 00:25:56 +04:00
|
|
|
for (; i < argc; i++) {
|
2005-05-16 22:38:16 +04:00
|
|
|
/* If there's a +LINE or +LINE,COLUMN flag here, it is
|
|
|
|
* followed by at least one other argument, the filename it
|
|
|
|
* applies to. */
|
|
|
|
if (i < argc - 1 && argv[i][0] == '+' && iline == 1 &&
|
2005-05-17 22:06:26 +04:00
|
|
|
icol == 1)
|
2005-05-17 03:23:15 +04:00
|
|
|
parse_line_column(&argv[i][1], &iline, &icol);
|
2005-05-17 22:06:26 +04:00
|
|
|
else {
|
2005-07-09 00:09:16 +04:00
|
|
|
open_buffer(argv[i]);
|
2005-05-16 22:38:16 +04:00
|
|
|
|
2005-05-17 22:06:26 +04:00
|
|
|
if (iline > 1 || icol > 1) {
|
2005-07-16 11:06:36 +04:00
|
|
|
do_gotolinecolumn(iline, icol, FALSE, FALSE, FALSE,
|
|
|
|
FALSE);
|
2005-05-16 22:38:16 +04:00
|
|
|
iline = 1;
|
|
|
|
icol = 1;
|
2004-10-23 00:25:56 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-09-06 01:40:31 +04:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Read the first file on the command line into either the current
|
|
|
|
* buffer or a new buffer, depending on whether multibuffer mode is
|
|
|
|
* enabled. */
|
|
|
|
if (optind < argc)
|
2005-07-09 00:09:16 +04:00
|
|
|
open_buffer(argv[optind]);
|
2004-09-06 01:40:31 +04:00
|
|
|
|
|
|
|
/* We didn't open any files if all the command line arguments were
|
|
|
|
* invalid files like directories or if there were no command line
|
|
|
|
* arguments given. In this case, we have to load a blank buffer.
|
|
|
|
* Also, we unset view mode to allow editing. */
|
2005-07-09 00:09:16 +04:00
|
|
|
if (openfile == NULL) {
|
|
|
|
open_buffer("");
|
2004-09-06 01:40:31 +04:00
|
|
|
UNSET(VIEW_MODE);
|
2003-01-13 04:35:15 +03:00
|
|
|
}
|
2004-09-06 01:40:31 +04:00
|
|
|
|
|
|
|
#ifdef ENABLE_MULTIBUFFER
|
|
|
|
if (!old_multibuffer)
|
|
|
|
UNSET(MULTIBUFFER);
|
2003-01-13 04:35:15 +03:00
|
|
|
#endif
|
2000-06-06 09:53:49 +04:00
|
|
|
|
2004-09-06 01:40:31 +04:00
|
|
|
#ifdef DEBUG
|
|
|
|
fprintf(stderr, "Main: top and bottom win\n");
|
|
|
|
#endif
|
|
|
|
|
2005-05-17 22:06:26 +04:00
|
|
|
if (startline > 1 || startcol > 1)
|
2005-07-16 11:06:36 +04:00
|
|
|
do_gotolinecolumn(startline, startcol, FALSE, FALSE, FALSE,
|
|
|
|
FALSE);
|
2005-05-16 22:38:16 +04:00
|
|
|
|
2005-07-09 09:52:08 +04:00
|
|
|
display_main_list();
|
|
|
|
|
2004-05-18 05:20:36 +04:00
|
|
|
#ifndef NANO_SMALL
|
|
|
|
/* Return here after a SIGWINCH. */
|
2001-04-12 07:01:53 +04:00
|
|
|
sigsetjmp(jmpbuf, 1);
|
2004-05-18 05:20:36 +04:00
|
|
|
#endif
|
2001-01-30 02:37:54 +03:00
|
|
|
|
2005-07-13 03:06:22 +04:00
|
|
|
display_buffer();
|
2000-07-08 18:23:32 +04:00
|
|
|
|
2004-03-15 23:26:30 +03:00
|
|
|
while (TRUE) {
|
2005-01-12 02:05:05 +03:00
|
|
|
bool meta_key, func_key, s_or_t, ran_func, finished;
|
2004-12-04 20:41:52 +03:00
|
|
|
|
|
|
|
/* Make sure the cursor is in the edit window. */
|
2004-07-13 21:09:24 +04:00
|
|
|
reset_cursor();
|
2004-12-04 20:41:52 +03:00
|
|
|
|
2005-07-26 18:42:57 +04:00
|
|
|
/* If constant cursor position display is on, and there are no
|
|
|
|
* keys waiting in the input buffer, display the current cursor
|
|
|
|
* position on the statusbar. */
|
|
|
|
if (ISSET(CONST_UPDATE) && get_key_buffer_len() == 0)
|
2004-07-01 23:41:09 +04:00
|
|
|
do_cursorpos(TRUE);
|
2003-01-28 04:16:47 +03:00
|
|
|
|
2001-04-12 07:01:53 +04:00
|
|
|
currshortcut = main_list;
|
|
|
|
|
2004-12-04 20:41:52 +03:00
|
|
|
/* Read in and interpret characters. */
|
2005-01-12 02:05:05 +03:00
|
|
|
do_input(&meta_key, &func_key, &s_or_t, &ran_func, &finished,
|
|
|
|
TRUE);
|
2000-06-06 09:53:49 +04:00
|
|
|
}
|
2005-03-04 20:09:41 +03:00
|
|
|
|
2004-03-20 00:57:56 +03:00
|
|
|
assert(FALSE);
|
2000-06-06 09:53:49 +04:00
|
|
|
}
|