mirror of
https://github.com/darlinghq/darling-nano.git
synced 2024-11-23 03:49:46 +00:00
nano-12
This commit is contained in:
commit
ca5fd02bb5
233
config.h
Normal file
233
config.h
Normal file
@ -0,0 +1,233 @@
|
||||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define this to enable debug messages and assert warnings. */
|
||||
/* #undef DEBUG */
|
||||
|
||||
/* Define this to disable the built-in file browser. */
|
||||
/* #undef DISABLE_BROWSER */
|
||||
|
||||
/* Define this to disable the help text display. */
|
||||
/* #undef DISABLE_HELP */
|
||||
|
||||
/* Define this to disable the justify routines. */
|
||||
/* #undef DISABLE_JUSTIFY */
|
||||
|
||||
/* Define this to disable the mouse support. */
|
||||
/* #undef DISABLE_MOUSE */
|
||||
|
||||
/* Define this to disable the setting of the operating directory (chroot of
|
||||
sorts). */
|
||||
/* #undef DISABLE_OPERATINGDIR */
|
||||
|
||||
/* Define this to disable text wrapping as root by default. */
|
||||
/* #undef DISABLE_ROOTWRAPPING */
|
||||
|
||||
/* Define this to disable the spell checker functions. */
|
||||
/* #undef DISABLE_SPELLER */
|
||||
|
||||
/* Define to disable the tab completion functions for files and search
|
||||
strings. */
|
||||
/* #undef DISABLE_TABCOMP */
|
||||
|
||||
/* Define this to disable all text wrapping. */
|
||||
/* #undef DISABLE_WRAPPING */
|
||||
|
||||
/* Define this to have syntax highlighting, requires regex.h and ENABLE_NANORC
|
||||
too! */
|
||||
#define ENABLE_COLOR 1
|
||||
|
||||
/* Define this to enable multiple file buffers. */
|
||||
#define ENABLE_MULTIBUFFER 1
|
||||
|
||||
/* Define this to use .nanorc files. */
|
||||
#define ENABLE_NANORC 1
|
||||
|
||||
/* Define to 1 if translation of program messages to the user's native
|
||||
language is requested. */
|
||||
/* #undef ENABLE_NLS */
|
||||
|
||||
/* Define this if your system has sufficient UTF-8 support (a wide curses
|
||||
library, iswalnum(), iswpunct(), iswblank() or iswspace(), mblen(),
|
||||
mbstowcs(), mbtowc(), wctomb(), and wcwidth()). */
|
||||
#define ENABLE_UTF8 1
|
||||
|
||||
/* Define to 1 if you have the <curses.h> header file. */
|
||||
/* #undef HAVE_CURSES_H */
|
||||
|
||||
/* Define if the GNU dcgettext() function is already present or preinstalled.
|
||||
*/
|
||||
/* #undef HAVE_DCGETTEXT */
|
||||
|
||||
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
|
||||
/* #undef HAVE_DOPRNT */
|
||||
|
||||
/* Define to 1 if you have the `getdelim' function. */
|
||||
/* #undef HAVE_GETDELIM */
|
||||
|
||||
/* Define to 1 if you have the `getline' function. */
|
||||
/* #undef HAVE_GETLINE */
|
||||
|
||||
/* Define to 1 if you have the <getopt.h> header file. */
|
||||
#define HAVE_GETOPT_H 1
|
||||
|
||||
/* Define to 1 if you have the `getopt_long' function. */
|
||||
#define HAVE_GETOPT_LONG 1
|
||||
|
||||
/* Define if the GNU gettext() function is already present or preinstalled. */
|
||||
/* #undef HAVE_GETTEXT */
|
||||
|
||||
/* Define if you have the iconv() function. */
|
||||
#define HAVE_ICONV 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the `isblank' function. */
|
||||
#define HAVE_ISBLANK 1
|
||||
|
||||
/* Define to 1 if you have the `iswalnum' function. */
|
||||
#define HAVE_ISWALNUM 1
|
||||
|
||||
/* Define to 1 if you have the `iswblank' function. */
|
||||
#define HAVE_ISWBLANK 1
|
||||
|
||||
/* Define to 1 if you have the `iswpunct' function. */
|
||||
#define HAVE_ISWPUNCT 1
|
||||
|
||||
/* Define to 1 if you have the `iswspace' function. */
|
||||
#define HAVE_ISWSPACE 1
|
||||
|
||||
/* Define to 1 if you have the <libintl.h> header file. */
|
||||
/* #undef HAVE_LIBINTL_H */
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* Define to 1 if you have the `mblen' function. */
|
||||
#define HAVE_MBLEN 1
|
||||
|
||||
/* Define to 1 if you have the `mbstowcs' function. */
|
||||
#define HAVE_MBSTOWCS 1
|
||||
|
||||
/* Define to 1 if you have the `mbtowc' function. */
|
||||
#define HAVE_MBTOWC 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the <ncurses.h> header file. */
|
||||
#define HAVE_NCURSES_H 1
|
||||
|
||||
/* Define to 1 if you have the <regex.h> header file. */
|
||||
#define HAVE_REGEX_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the `strcasecmp' function. */
|
||||
#define HAVE_STRCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the `strcasestr' function. */
|
||||
#define HAVE_STRCASESTR 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strncasecmp' function. */
|
||||
#define HAVE_STRNCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the `strnlen' function. */
|
||||
/* #undef HAVE_STRNLEN */
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define this if your curses library has the use_default_colors() command. */
|
||||
#define HAVE_USE_DEFAULT_COLORS 1
|
||||
|
||||
/* Define to 1 if you have the `vprintf' function. */
|
||||
#define HAVE_VPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `vsnprintf' function. */
|
||||
#define HAVE_VSNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the <wchar.h> header file. */
|
||||
#define HAVE_WCHAR_H 1
|
||||
|
||||
/* Define to 1 if you have the `wctomb' function. */
|
||||
#define HAVE_WCTOMB 1
|
||||
|
||||
/* Define to 1 if you have the <wctype.h> header file. */
|
||||
#define HAVE_WCTYPE_H 1
|
||||
|
||||
/* Define to 1 if you have the `wcwidth' function. */
|
||||
#define HAVE_WCWIDTH 1
|
||||
|
||||
/* Define this to enable extra stuff. */
|
||||
#define NANO_EXTRA 1
|
||||
|
||||
/* Define this to make the nano executable as small as possible. */
|
||||
/* #undef NANO_TINY */
|
||||
|
||||
/* Shut up assert warnings :-) */
|
||||
#define NDEBUG 1
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "nano"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "nano-devel@gnu.org"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "GNU nano"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "GNU nano 2.0.6"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "nano"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "2.0.6"
|
||||
|
||||
/* Where data are placed to. */
|
||||
#define PKGDATADIR "/usr/share/nano"
|
||||
|
||||
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||
#define RETSIGTYPE void
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define to use the slang wrappers for curses instead of native curses. */
|
||||
/* #undef USE_SLANG */
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "2.0.6"
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
/* #undef _FILE_OFFSET_BITS */
|
||||
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
/* #undef _LARGE_FILES */
|
340
doc/COPYING
Normal file
340
doc/COPYING
Normal file
@ -0,0 +1,340 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
234
doc/nano.1
Normal file
234
doc/nano.1
Normal file
@ -0,0 +1,234 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.\" nano.1 is Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
.\" 2006 by Chris Allegretta <chrisa@asty.org>
|
||||
.\"
|
||||
.\" This is free documentation, see the latest version of the GNU
|
||||
.\" General Public License for copying conditions. There is NO
|
||||
.\" warranty.
|
||||
.\"
|
||||
.\" $Id: nano.1,v 1.50 2006/10/28 19:21:12 dolorous Exp $
|
||||
.TH NANO 1 "version 2.0.0" "October 28, 2006"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
|
||||
.SH NAME
|
||||
nano \- Nano's ANOther editor, an enhanced free Pico clone
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B nano
|
||||
.I [OPTIONS]\ [[\+LINE,COLUMN]\ FILE]...
|
||||
.br
|
||||
|
||||
.SH DESCRIPTION
|
||||
This manual page briefly documents the \fBnano\fP command.
|
||||
.PP
|
||||
.\" TeX users may be more comfortable with the \fB<whatever>\fP and
|
||||
.\" \fI<whatever>\fP escape sequences to invoke bold face and italics,
|
||||
.\" respectively.
|
||||
\fBnano\fP is a small, free and friendly editor which aims to replace
|
||||
Pico, the default editor included in the non-free Pine package. Rather
|
||||
than just copying Pico's look and feel, \fBnano\fP also implements some
|
||||
missing (or disabled by default) features in Pico, such as "search and
|
||||
replace" and "go to line and column number".
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \+\fILINE\fP,\fICOLUMN\fP
|
||||
Places cursor at line number \fILINE\fP and column number \fICOLUMN\fP
|
||||
(at least one of which must be specified) on startup, instead of the
|
||||
default of line 1, column 1.
|
||||
.TP
|
||||
.B \-?
|
||||
Same as \fB-h (\-\-help)\fP.
|
||||
.TP
|
||||
.B \-A (\-\-smarthome)
|
||||
Make the Home key smarter. When Home is pressed anywhere but at the
|
||||
very beginning of non-whitespace characters on a line, the cursor will
|
||||
jump to that beginning (either forwards or backwards). If the cursor is
|
||||
already at that position, it will jump to the true beginning of the
|
||||
line.
|
||||
.TP
|
||||
.B \-B (\-\-backup)
|
||||
When saving a file, back up the previous version of it to the current
|
||||
filename suffixed with a ~.
|
||||
.TP
|
||||
.B \-C \fIdir\fP (\-\-backupdir=\fIdir\fP)
|
||||
Set the directory where \fBnano\fP puts unique backup files if file
|
||||
backups are enabled.
|
||||
.TP
|
||||
.B \-D (\-\-boldtext)
|
||||
Use bold text instead of reverse video text.
|
||||
.TP
|
||||
.B \-E (\-\-tabstospaces)
|
||||
Convert typed tabs to spaces.
|
||||
.TP
|
||||
.B \-F (\-\-multibuffer)
|
||||
Enable multiple file buffers, if available.
|
||||
.TP
|
||||
.B \-H (\-\-historylog)
|
||||
Log search and replace strings to \fI~/.nano_history\fP, so they can be
|
||||
retrieved in later sessions, if nanorc support is available.
|
||||
.TP
|
||||
.B \-I (\-\-ignorercfiles)
|
||||
Don't look at \fISYSCONFDIR/nanorc\fP or \fI~/.nanorc\fP, if nanorc
|
||||
support is available.
|
||||
.TP
|
||||
.B \-K (\-\-rebindkeypad)
|
||||
Interpret the numeric keypad keys so that they all work properly. You
|
||||
should only need to use this option if they don't, as mouse support
|
||||
won't work properly with this option enabled.
|
||||
.TP
|
||||
.B \-L (\-\-nonewlines)
|
||||
Don't add newlines to the ends of files.
|
||||
.TP
|
||||
.B \-N (\-\-noconvert)
|
||||
Disable automatic conversion of files from DOS/Mac format.
|
||||
.TP
|
||||
.B \-O (\-\-morespace)
|
||||
Use the blank line below the titlebar as extra editing space.
|
||||
.TP
|
||||
.B \-Q \fIstr\fP (\-\-quotestr=\fIstr\fP)
|
||||
Set the quoting string for justifying. The default is
|
||||
"\fI^([\ \\t]*[#:>\\|}])+\fP" if extended regular expression support is
|
||||
available, or "\fI>\ \fP" otherwise. Note that \fI\\t\fP stands for a
|
||||
Tab.
|
||||
.TP
|
||||
.B \-R (\-\-restricted)
|
||||
Restricted mode: don't read or write to any file not specified on the
|
||||
command line; read any nanorc files; allow suspending; allow a file
|
||||
to be appended to, prepended to, or saved under a different name if it
|
||||
already has one; or use backup files or spell checking. Also accessible
|
||||
by invoking \fBnano\fP with any name beginning with 'r' (e.g. "rnano").
|
||||
.TP
|
||||
.B \-S (\-\-smooth)
|
||||
Enable smooth scrolling. Text will scroll line-by-line, instead of the
|
||||
usual chunk-by-chunk behavior.
|
||||
.TP
|
||||
.B \-T \fIcols\fP (\-\-tabsize=\fIcols\fP)
|
||||
Set the size (width) of a tab to \fIcols\fP columns. The value of
|
||||
\fIcols\fP must be greater than 0. The default value is 8.
|
||||
.TP
|
||||
.B \-U (\-\-quickblank)
|
||||
Do quick statusbar blanking. Statusbar messages will disappear after 1
|
||||
keystroke instead of 25. Note that \fB-c\fP overrides this.
|
||||
.TP
|
||||
.B \-V (\-\-version)
|
||||
Show the current version number and exit.
|
||||
.TP
|
||||
.B \-W (\-\-wordbounds)
|
||||
Detect word boundaries more accurately by treating punctuation
|
||||
characters as part of a word.
|
||||
.TP
|
||||
.B \-Y \fIstr\fP (\-\-syntax=\fIstr\fP)
|
||||
Specify a specific syntax highlighting from the \fInanorc\fP to use, if
|
||||
available.
|
||||
.TP
|
||||
.B \-c (\-\-const)
|
||||
Constantly show the cursor position. Note that this overrides \fB-U\fP.
|
||||
.TP
|
||||
.B \-d (\-\-rebinddelete)
|
||||
Interpret the Delete key differently so that both Backspace and Delete
|
||||
work properly. You should only need to use this option if Backspace
|
||||
acts like Delete on your system.
|
||||
.TP
|
||||
.B \-h (\-\-help)
|
||||
Show a summary of command line options and exit.
|
||||
.TP
|
||||
.B \-i (\-\-autoindent)
|
||||
Indent new lines to the previous line's indentation. Useful when
|
||||
editing source code.
|
||||
.TP
|
||||
.B \-k (\-\-cut)
|
||||
Enable cut from cursor to end of line.
|
||||
.TP
|
||||
.B \-l (\-\-nofollow)
|
||||
If the file being edited is a symbolic link, replace the link with
|
||||
a new file instead of following it. Good for editing files in
|
||||
\fI/tmp\fP, perhaps?
|
||||
.TP
|
||||
.B \-m (\-\-mouse)
|
||||
Enable mouse support, if available for your system. When enabled, mouse
|
||||
clicks can be used to place the cursor, set the mark (with a double
|
||||
click), and execute shortcuts. The mouse will work in the X Window
|
||||
System, and on the console when gpm is running.
|
||||
.TP
|
||||
.B \-o \fIdir\fP (\-\-operatingdir=\fIdir\fP)
|
||||
Set operating directory. Makes \fBnano\fP set up something similar to a
|
||||
chroot.
|
||||
.TP
|
||||
.B \-p (\-\-preserve)
|
||||
Preserve the XON and XOFF sequences (^Q and ^S) so they will be caught
|
||||
by the terminal.
|
||||
.TP
|
||||
.B \-r \fIcols\fP (\-\-fill=\fIcols\fP)
|
||||
Wrap lines at column \fIcols\fP. If this value is 0 or less, wrapping
|
||||
will occur at the width of the screen less \fIcols\fP columns, allowing
|
||||
the wrap point to vary along with the width of the screen if the screen
|
||||
is resized. The default value is -8.
|
||||
.TP
|
||||
.B \-s \fIprog\fP (\-\-speller=\fIprog\fP)
|
||||
Enable alternative spell checker command.
|
||||
.TP
|
||||
.B \-t (\-\-tempfile)
|
||||
Always save changed buffer without prompting. Same as Pico's \fB-t\fP
|
||||
option.
|
||||
.TP
|
||||
.B \-v (\-\-view)
|
||||
View file (read only) mode.
|
||||
.TP
|
||||
.B \-w (\-\-nowrap)
|
||||
Disable wrapping of long lines.
|
||||
.TP
|
||||
.B \-x (\-\-nohelp)
|
||||
Disable help screen at bottom of editor.
|
||||
.TP
|
||||
.B \-z (\-\-suspend)
|
||||
Enable suspend ability.
|
||||
.TP
|
||||
.B \-a, \-b, \-e, \-f, \-g, \-j
|
||||
Ignored, for compatibility with Pico.
|
||||
|
||||
.SH INITIALIZATION FILE
|
||||
\fBnano\fP will read initialization files in the following order:
|
||||
\fISYSCONFDIR/nanorc\fP, then \fI~/.nanorc\fP. Please see
|
||||
\fBnanorc(5)\fP and the example file \fBnanorc.sample\fP, both of which
|
||||
should be provided with \fBnano\fP.
|
||||
|
||||
.SH NOTES
|
||||
If no alternative spell checker command is specified on the command
|
||||
line or in one of the nanorc files, \fBnano\fP will check the
|
||||
\fBSPELL\fP environment variable for one.
|
||||
|
||||
In some cases \fBnano\fP will try to dump the buffer into an emergency
|
||||
file. This will happen mainly if \fBnano\fP receives a SIGHUP or
|
||||
SIGTERM or runs out of memory. It will write the buffer into a file
|
||||
named \fInano.save\fP if the buffer didn't have a name already, or will
|
||||
add a ".save" suffix to the current filename. If an emergency file with
|
||||
that name already exists in the current directory, it will add ".save"
|
||||
plus a number (e.g. ".save.1") to the current filename in order to make
|
||||
it unique. In multibuffer mode, \fBnano\fP will write all the open
|
||||
buffers to their respective emergency files.
|
||||
|
||||
.SH BUGS
|
||||
Please send any comments or bug reports to \fBnano@nano-editor.org\fP.
|
||||
|
||||
The \fBnano\fP mailing list is available from \fBnano-devel@gnu.org\fP.
|
||||
|
||||
To subscribe, email to \fBnano-devel-request@gnu.org\fP with a subject
|
||||
of "subscribe".
|
||||
|
||||
.SH HOMEPAGE
|
||||
http://www.nano-editor.org/
|
||||
|
||||
.SH SEE ALSO
|
||||
.PD 0
|
||||
.TP
|
||||
\fBnanorc\fP(5)
|
||||
.PP
|
||||
\fI/usr/share/doc/nano/\fP (or equivalent on your system)
|
||||
|
||||
.SH AUTHOR
|
||||
Chris Allegretta <chrisa@asty.org>, et al (see \fIAUTHORS\fP and
|
||||
\fITHANKS\fP for details). This manual page was originally written by
|
||||
Jordi Mallach <jordi@gnu.org>, for the Debian system (but may be used by
|
||||
others).
|
259
doc/nanorc.5
Normal file
259
doc/nanorc.5
Normal file
@ -0,0 +1,259 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.\" nanorc.5 is Copyright (C) 2003, 2004, 2005, 2006 by the Free
|
||||
.\" Software Foundation, Inc.
|
||||
.\"
|
||||
.\" This is free documentation, see the latest version of the GNU
|
||||
.\" General Public License for copying conditions. There is NO
|
||||
.\" warranty.
|
||||
.\"
|
||||
.\" $Id: nanorc.5,v 1.53 2006/10/28 19:21:12 dolorous Exp $
|
||||
.TH NANORC 5 "version 2.0.0" "October 28, 2006"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.SH NAME
|
||||
nanorc \- GNU nano's rcfile
|
||||
.SH DESCRIPTION
|
||||
This manual page briefly documents GNU \fBnano\fP's rcfile.
|
||||
.PP
|
||||
\fBnano\fP is a small, free and friendly editor which aims to replace
|
||||
Pico, the default editor included in the non-free Pine package. Rather
|
||||
than just copying Pico's look and feel, \fBnano\fP also implements some
|
||||
missing (or disabled by default) features in Pico, such as "search and
|
||||
replace" and "go to line and column number".
|
||||
.PP
|
||||
The \fInanorc\fP file contains the default settings for \fBnano\fP. It
|
||||
should not be in DOS or Mac format. During startup, \fBnano\fP will
|
||||
first read its system-wide settings from \fISYSCONFDIR/nanorc\fP, and
|
||||
then user-specific settings from \fI~/.nanorc\fP.
|
||||
|
||||
.SH OPTIONS
|
||||
The configuration file accepts a series of \fBset\fP and \fBunset\fP
|
||||
commands, which can be used to configure nano on startup without using
|
||||
the command line options. Additionally, the \fBsyntax\fP, \fBcolor\fP,
|
||||
and \fBicolor\fP keywords are used to define syntax highlighting rules
|
||||
for different text patterns. \fBnano\fP will read one command per line.
|
||||
|
||||
Options in nanorc files take precedence over nano's defaults, and
|
||||
command line options override nanorc settings. Also, options are unset
|
||||
by default, except for those that take arguments.
|
||||
|
||||
Quotes inside string parameters don't have to be escaped with
|
||||
backslashes. The last double quote in the string will be treated as its
|
||||
end. For example, for the \fBbrackets\fP option, "\fI"')>]}\fP" will
|
||||
match \fI"\fP, \fI'\fP, \fI)\fP, \fI>\fP, \fI]\fP, and \fI}\fP.
|
||||
|
||||
The supported commands and arguments are:
|
||||
|
||||
.TP 3
|
||||
.B set/unset autoindent
|
||||
Use auto-indentation.
|
||||
.TP
|
||||
.B set/unset backup
|
||||
Create backup files in \fIfilename~\fP.
|
||||
.TP
|
||||
.B set backupdir "\fIdirectory\fP"
|
||||
Set the directory where \fBnano\fP puts unique backup files if file
|
||||
backups are enabled.
|
||||
.TP
|
||||
.B set/unset backwards
|
||||
Do backwards searches by default.
|
||||
.TP
|
||||
.B set/unset boldtext
|
||||
Use bold text instead of reverse video text.
|
||||
.TP
|
||||
.B set brackets "\fIstring\fP"
|
||||
Set the characters treated as closing brackets when justifying
|
||||
paragraphs. They cannot contain blank characters. Only closing
|
||||
punctuation, optionally followed by closing brackets, can end sentences.
|
||||
The default value is "\fI"')>]}\fP".
|
||||
.TP
|
||||
.B set/unset casesensitive
|
||||
Do case sensitive searches by default.
|
||||
.TP
|
||||
.B set/unset const
|
||||
Constantly display the cursor position in the status bar.
|
||||
.TP
|
||||
.B set/unset cut
|
||||
Use cut to end of line by default.
|
||||
.TP
|
||||
.B set fill \fIn\fP
|
||||
Wrap lines at column number \fIn\fP. If \fIn\fP is 0 or less, the
|
||||
maximum line length will be the screen width less \fIn\fP columns. The
|
||||
default value is -8.
|
||||
.TP
|
||||
.B set/unset historylog
|
||||
Enable \fI~/.nano_history\fP for saving and reading search/replace
|
||||
strings.
|
||||
.TP
|
||||
.B set matchbrackets "\fIstring\fP"
|
||||
Set the opening and closing brackets that can be found by bracket
|
||||
searches. They cannot contain blank characters. The former set must
|
||||
come before the latter set, and both must be in the same order. The
|
||||
default value is "\fI(<[{)>]}\fP".
|
||||
.TP
|
||||
.B set/unset morespace
|
||||
Use the blank line below the titlebar as extra editing space.
|
||||
.TP
|
||||
.B set/unset mouse
|
||||
Enable mouse support, if available for your system. When enabled, mouse
|
||||
clicks can be used to place the cursor, set the mark (with a double
|
||||
click), and execute shortcuts. The mouse will work in the X Window
|
||||
System, and on the console when gpm is running.
|
||||
.TP
|
||||
.B set/unset multibuffer
|
||||
Allow inserting files into their own buffers.
|
||||
.TP
|
||||
.B set/unset noconvert
|
||||
Don't convert files from DOS/Mac format.
|
||||
.TP
|
||||
.B set/unset nofollow
|
||||
Don't follow symlinks when writing files.
|
||||
.TP
|
||||
.B set/unset nohelp
|
||||
Don't display the help lists at the bottom of the screen.
|
||||
.TP
|
||||
.B set/unset nonewlines
|
||||
Don't add newlines to the ends of files.
|
||||
.TP
|
||||
.B set/unset nowrap
|
||||
Don't wrap text at all.
|
||||
.TP
|
||||
.B set operatingdir "\fIdirectory\fP"
|
||||
\fBnano\fP will only read and write files inside \fIdirectory\fP and its
|
||||
subdirectories. Also, the current directory is changed to here, so
|
||||
files are inserted from this diractory. By default, the operating
|
||||
directory feature is turned off.
|
||||
.TP
|
||||
.B set/unset preserve
|
||||
Preserve the XON and XOFF keys (^Q and ^S).
|
||||
.TP
|
||||
.B set punct "\fIstring\fP"
|
||||
Set the characters treated as closing punctuation when justifying
|
||||
paragraphs. They cannot contain blank characters. Only closing
|
||||
punctuation, optionally followed by closing brackets, can end sentences.
|
||||
The default value is "\fI!.?\fP".
|
||||
.TP
|
||||
.B set/unset quickblank
|
||||
Do quick statusbar blanking. Statusbar messages will disappear after 1
|
||||
keystroke instead of 25.
|
||||
.TP
|
||||
.B set quotestr "\fIstring\fP"
|
||||
The email-quote string, used to justify email-quoted paragraphs. This
|
||||
is an extended regular expression if your system supports them,
|
||||
otherwise a literal string. The default value is
|
||||
"\fI^([\ \\t]*[#:>\\|}])+\fP" if you have extended regular expression
|
||||
support, or "\fI>\ \fP" otherwise. Note that '\\t' stands for a literal
|
||||
Tab character.
|
||||
.TP
|
||||
.B set/unset rebinddelete
|
||||
Interpret the Delete key differently so that both Backspace and Delete
|
||||
work properly. You should only need to use this option if Backspace
|
||||
acts like Delete on your system.
|
||||
.TP
|
||||
.B set/unset rebindkeypad
|
||||
Interpret the numeric keypad keys so that they all work properly. You
|
||||
should only need to use this option if they don't, as mouse support
|
||||
won't work properly with this option enabled.
|
||||
.TP
|
||||
.B set/unset regexp
|
||||
Do extended regular expression searches by default.
|
||||
.TP
|
||||
.B set/unset smarthome
|
||||
Make the Home key smarter. When Home is pressed anywhere but at the
|
||||
very beginning of non-whitespace characters on a line, the cursor will
|
||||
jump to that beginning (either forwards or backwards). If the cursor is
|
||||
already at that position, it will jump to the true beginning of the
|
||||
line.
|
||||
.TP
|
||||
.B set/unset smooth
|
||||
Use smooth scrolling by default.
|
||||
.TP
|
||||
.B set speller "\fIspellprog\fP"
|
||||
Use spelling checker \fIspellprog\fP instead of the built-in one, which
|
||||
calls \fIspell\fP.
|
||||
.TP
|
||||
.B set/unset suspend
|
||||
Allow \fBnano\fP to be suspended.
|
||||
.TP
|
||||
.B set tabsize \fIn\fP
|
||||
Use a tab size of \fIn\fP columns. The value of \fIn\fP must be greater
|
||||
than 0. The default value is 8.
|
||||
.TP
|
||||
.B set/unset tabstospaces
|
||||
Convert typed tabs to spaces.
|
||||
.TP
|
||||
.B set/unset tempfile
|
||||
Save automatically on exit, don't prompt.
|
||||
.TP
|
||||
.B set/unset view
|
||||
Disallow file modification.
|
||||
.TP
|
||||
.B set whitespace "\fIstring\fP"
|
||||
Set the two characters used to display the first characters of tabs and
|
||||
spaces. They must be single-column characters.
|
||||
.TP
|
||||
.B set/unset wordbounds
|
||||
Detect word boundaries more accurately by treating punctuation
|
||||
characters as parts of words.
|
||||
.TP
|
||||
.B syntax "\fIstr\fP" ["\fIfileregex\fP" ... ]
|
||||
Defines a syntax named \fIstr\fP which can be activated via the
|
||||
-Y/--syntax command line option, or will be automatically activated if
|
||||
the current filename matches the extended regular expression
|
||||
\fIfileregex\fP. All following \fBcolor\fP and \fBicolor\fP statements
|
||||
will apply to \fIsyntax\fP until a new syntax is defined.
|
||||
|
||||
The \fInone\fP syntax is reserved; specifying it on the command line is
|
||||
the same as not having a syntax at all. The \fIdefault\fP syntax is
|
||||
special: it takes no \fIfileregex\fP, and applies to files that don't
|
||||
match any other syntax's \fIfileregex\fP.
|
||||
.TP
|
||||
.B color \fIfgcolor\fP,\fIbgcolor\fP "\fIregex\fP" ...
|
||||
For the currently defined syntax, display all expressions matching
|
||||
the extended regular expression \fIregex\fP with foreground color
|
||||
\fIfgcolor\fP and background color \fIbgcolor\fP, at least one of which
|
||||
must be specified. Legal colors for foreground and background color
|
||||
are: white, black, red, blue, green, yellow, magenta, and cyan. You may
|
||||
use the prefix "bright" to force a stronger color highlight for the
|
||||
foreground. If your terminal supports transparency, not specifying a
|
||||
\fIbgcolor\fP tells \fBnano\fP to attempt to use a transparent
|
||||
background.
|
||||
.TP
|
||||
.B icolor \fIfgcolor\fP,\fIbgcolor\fP "\fIregex\fP" ...
|
||||
Same as above, except that the expression matching is case insensitive.
|
||||
.TP
|
||||
.B color \fIfgcolor\fP,\fIbgcolor\fP start="\fIsr\fP" end="\fIer\fP"
|
||||
Display expressions which start with the extended regular expression
|
||||
\fIsr\fP and end with the extended regular expression \fIer\fP with
|
||||
foreground color \fIfgcolor\fP and background color \fIbgcolor\fP,
|
||||
at least one of which must be specified. This allows syntax
|
||||
highlighting to span multiple lines. Note that all subsequent instances
|
||||
of \fIsr\fP after an initial \fIsr\fP is found will be highlighted until
|
||||
the first instance of \fIer\fP.
|
||||
.TP
|
||||
.B icolor \fIfgcolor\fP,\fIbgcolor\fP start="\fIsr\fP" end="\fIer\fP"
|
||||
Same as above, except that the expression matching is case insensitive.
|
||||
.TP
|
||||
.B include "\fIsyntaxfile\fP"
|
||||
Read in self-contained color syntaxes from \fIsyntaxfile\fP. Note that
|
||||
\fIsyntaxfile\fP can only contain \fBsyntax\fP, \fBcolor\fP, and
|
||||
\fBicolor\fP commands.
|
||||
.SH FILES
|
||||
.TP
|
||||
.I SYSCONFDIR/nanorc
|
||||
System-wide configuration file
|
||||
.TP
|
||||
.I ~/.nanorc
|
||||
Per-user configuration file
|
||||
.SH SEE ALSO
|
||||
.PD 0
|
||||
.TP
|
||||
\fBnano\fP(1)
|
||||
.PP
|
||||
\fI/usr/share/doc/nano/examples/nanorc.sample\fP (or equivalent on your
|
||||
system)
|
||||
.SH AUTHOR
|
||||
Chris Allegretta <chrisa@asty.org>, et al (see \fIAUTHORS\fP and
|
||||
\fITHANKS\fP for details). This manual page was originally written by
|
||||
Jordi Mallach <jordi@gnu.org>, for the Debian system (but may be used by
|
||||
others).
|
86
doc/rnano.1
Normal file
86
doc/rnano.1
Normal file
@ -0,0 +1,86 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.\" rnano.1 is Copyright (C) 2005, 2006 by Thijs Kinkhorst
|
||||
.\" <thijs@kinkhorst.com>; skeleton based on nano-tiny.1 by Jordi
|
||||
.\" Mallach <jordi@gnu.org>.
|
||||
.\"
|
||||
.\" This is free documentation, see the latest version of the GNU
|
||||
.\" General Public License for copying conditions. There is NO
|
||||
.\" warranty.
|
||||
.\"
|
||||
.\" $Id: rnano.1,v 1.15 2006/11/10 02:47:11 dolorous Exp $
|
||||
.TH RNANO 1 "version 2.0.0" "October 28, 2006"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.SH NAME
|
||||
rnano \- Restricted mode for Nano's ANOther editor, an enhanced free
|
||||
Pico clone
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B rnano
|
||||
.I [OPTIONS]\ [[\+LINE,COLUMN]\ FILE]...
|
||||
.br
|
||||
|
||||
.SH DESCRIPTION
|
||||
This manual page briefly documents the \fBrnano\fP command.
|
||||
.PP
|
||||
.\" TeX users may be more comfortable with the \fB<whatever>\fP and
|
||||
.\" \fI<whatever>\fP escape sequences to invoke bold face and italics,
|
||||
.\" respectively.
|
||||
\fBnano\fP is a small, free and friendly editor which aims to replace
|
||||
Pico, the default editor included in the non-free Pine package. Rather
|
||||
than just copying Pico's look and feel, \fBnano\fP also implements some
|
||||
missing (or disabled by default) features in Pico, such as "search and
|
||||
replace" and "go to line and column number".
|
||||
.PP
|
||||
\fBrnano\fP is a restricted version of \fBnano\fP, which only edits
|
||||
specific files and doesn't allow the user access to the filesystem or a
|
||||
command shell.
|
||||
.PP
|
||||
In restricted mode, \fBnano\fP will \fInot\fP:
|
||||
.IP \[bu] 2
|
||||
read or write to any file not specified on the command line;
|
||||
.IP \[bu]
|
||||
read any nanorc files;
|
||||
.IP \[bu]
|
||||
allow suspending;
|
||||
.IP \[bu]
|
||||
allow a file to be appended to, prepended to, or saved under a different
|
||||
name;
|
||||
.IP \[bu]
|
||||
use backup files or spell checking.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \+\fILINE\fP,\fICOLUMN\fP
|
||||
Places cursor at line number \fILINE\fP and column number \fICOLUMN\fP
|
||||
(at least one of which must be specified) on startup, instead of the
|
||||
default of line 1, column 1.
|
||||
.TP
|
||||
.B \-?
|
||||
Same as \fB-h (\-\-help)\fP.
|
||||
.TP
|
||||
.B \-h (\-\-help)
|
||||
Show a summary of command line options and exit.
|
||||
.TP
|
||||
.B \-V (\-\-version)
|
||||
Show the current version number and exit.
|
||||
.PP
|
||||
See the \fBnano\fP(1) manpage for the complete documentation of
|
||||
\fBnano\fP.
|
||||
|
||||
.SH BUGS
|
||||
Please send any comments or bug reports to \fBnano@nano-editor.org\fP.
|
||||
|
||||
The \fBnano\fP mailing list is available from \fBnano-devel@gnu.org\fP.
|
||||
|
||||
To subscribe, email to \fBnano-devel-request@gnu.org\fP with a subject
|
||||
of "subscribe".
|
||||
|
||||
.SH HOMEPAGE
|
||||
http://www.nano-editor.org/
|
||||
|
||||
.SH AUTHOR
|
||||
Chris Allegretta <chrisa@asty.org>, et al (see AUTHORS for details).
|
||||
This manual page was originally written by Thijs Kinkhorst
|
||||
<thijs@kinkhorst.com>, for the Debian system (but may be used by
|
||||
others).
|
28
nano.plist
Normal file
28
nano.plist
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>OpenSourceProject</key>
|
||||
<string>nano</string>
|
||||
<key>OpenSourceVersion</key>
|
||||
<string>2.0.6</string>
|
||||
<key>OpenSourceWebsiteURL</key>
|
||||
<string>http://www.nano-editor.org/</string>
|
||||
<key>OpenSourceURL</key>
|
||||
<string>http://www.nano-editor.org/dist/v2.0/nano-2.0.6.tar.gz</string>
|
||||
<key>OpenSourceSHA1</key>
|
||||
<string>00102580404cdb1c8594e5f6193000d5acac2249</string>
|
||||
<key>OpenSourceImportDate</key>
|
||||
<string>2007-11-01</string>
|
||||
<key>OpenSourceModifications</key>
|
||||
<array>
|
||||
<string>7477012</string>
|
||||
<string>12988489</string>
|
||||
<string>16401178</string>
|
||||
</array>
|
||||
<key>OpenSourceLicense</key>
|
||||
<string>GPL</string>
|
||||
<key>OpenSourceLicenseFile</key>
|
||||
<string>nano.txt</string>
|
||||
</dict>
|
||||
</plist>
|
328
nano.xcodeproj/project.pbxproj
Normal file
328
nano.xcodeproj/project.pbxproj
Normal file
@ -0,0 +1,328 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 45;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
FDF793C70F992EA80016724F /* browser.c in Sources */ = {isa = PBXBuildFile; fileRef = FDF793A70F992E100016724F /* browser.c */; };
|
||||
FDF793C80F992EA80016724F /* chars.c in Sources */ = {isa = PBXBuildFile; fileRef = FDF793A80F992E100016724F /* chars.c */; };
|
||||
FDF793C90F992EA80016724F /* color.c in Sources */ = {isa = PBXBuildFile; fileRef = FDF793A90F992E100016724F /* color.c */; };
|
||||
FDF793CA0F992EA80016724F /* cut.c in Sources */ = {isa = PBXBuildFile; fileRef = FDF793AA0F992E100016724F /* cut.c */; };
|
||||
FDF793CB0F992EA80016724F /* files.c in Sources */ = {isa = PBXBuildFile; fileRef = FDF793AB0F992E100016724F /* files.c */; };
|
||||
FDF793CC0F992EA80016724F /* global.c in Sources */ = {isa = PBXBuildFile; fileRef = FDF793AC0F992E100016724F /* global.c */; };
|
||||
FDF793CD0F992EA80016724F /* help.c in Sources */ = {isa = PBXBuildFile; fileRef = FDF793AD0F992E100016724F /* help.c */; };
|
||||
FDF793CE0F992EA80016724F /* move.c in Sources */ = {isa = PBXBuildFile; fileRef = FDF793AE0F992E100016724F /* move.c */; };
|
||||
FDF793CF0F992EA80016724F /* nano.c in Sources */ = {isa = PBXBuildFile; fileRef = FDF793AF0F992E100016724F /* nano.c */; };
|
||||
FDF793D00F992EA80016724F /* prompt.c in Sources */ = {isa = PBXBuildFile; fileRef = FDF793B10F992E110016724F /* prompt.c */; };
|
||||
FDF793D10F992EA80016724F /* rcfile.c in Sources */ = {isa = PBXBuildFile; fileRef = FDF793B30F992E110016724F /* rcfile.c */; };
|
||||
FDF793D20F992EA80016724F /* search.c in Sources */ = {isa = PBXBuildFile; fileRef = FDF793B40F992E110016724F /* search.c */; };
|
||||
FDF793D30F992EA80016724F /* text.c in Sources */ = {isa = PBXBuildFile; fileRef = FDF793B50F992E110016724F /* text.c */; };
|
||||
FDF793D40F992EA80016724F /* utils.c in Sources */ = {isa = PBXBuildFile; fileRef = FDF793B60F992E110016724F /* utils.c */; };
|
||||
FDF793D50F992EA80016724F /* winio.c in Sources */ = {isa = PBXBuildFile; fileRef = FDF793B70F992E110016724F /* winio.c */; };
|
||||
FDF794260F9931E60016724F /* libncurses.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FDF794250F9931E60016724F /* libncurses.dylib */; };
|
||||
FDF794460F9933940016724F /* nano.1 in Install man1 (1) */ = {isa = PBXBuildFile; fileRef = FDF793F60F992FAA0016724F /* nano.1 */; };
|
||||
FDF794480F9933B40016724F /* nanorc.5 in Install man5 (1) */ = {isa = PBXBuildFile; fileRef = FDF793F70F992FAA0016724F /* nanorc.5 */; };
|
||||
FDF7944C0F9934000016724F /* nanorc in Install etc */ = {isa = PBXBuildFile; fileRef = FDF793FC0F992FF80016724F /* nanorc */; };
|
||||
FDF7944F0F99343D0016724F /* COPYING in Install OpenSourceLicenses */ = {isa = PBXBuildFile; fileRef = FDF793FB0F992FF80016724F /* COPYING */; };
|
||||
FDF794500F9934430016724F /* nano.plist in Install OpenSourceVersions */ = {isa = PBXBuildFile; fileRef = FDF793E40F992F070016724F /* nano.plist */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
FDF794610F99344A0016724F /* Install man1 (1) */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 8;
|
||||
dstPath = /usr/share/man/man1;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
FDF794460F9933940016724F /* nano.1 in Install man1 (1) */,
|
||||
);
|
||||
name = "Install man1 (1)";
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
FDF794620F99344A0016724F /* Install man5 (1) */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 8;
|
||||
dstPath = /usr/share/man/man5;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
FDF794480F9933B40016724F /* nanorc.5 in Install man5 (1) */,
|
||||
);
|
||||
name = "Install man5 (1)";
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
FDF794640F99344A0016724F /* Install etc */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 8;
|
||||
dstPath = /private/etc;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
FDF7944C0F9934000016724F /* nanorc in Install etc */,
|
||||
);
|
||||
name = "Install etc";
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
FDF794650F99344A0016724F /* Install OpenSourceVersions */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 8;
|
||||
dstPath = /usr/local/OpenSourceVersions;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
FDF794500F9934430016724F /* nano.plist in Install OpenSourceVersions */,
|
||||
);
|
||||
name = "Install OpenSourceVersions";
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
FDF794660F99344A0016724F /* Install OpenSourceLicenses */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 8;
|
||||
dstPath = /usr/local/OpenSourceLicenses;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
FDF7944F0F99343D0016724F /* COPYING in Install OpenSourceLicenses */,
|
||||
);
|
||||
name = "Install OpenSourceLicenses";
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
FDF793A70F992E100016724F /* browser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = browser.c; path = src/browser.c; sourceTree = "<group>"; };
|
||||
FDF793A80F992E100016724F /* chars.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = chars.c; path = src/chars.c; sourceTree = "<group>"; };
|
||||
FDF793A90F992E100016724F /* color.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = color.c; path = src/color.c; sourceTree = "<group>"; };
|
||||
FDF793AA0F992E100016724F /* cut.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cut.c; path = src/cut.c; sourceTree = "<group>"; };
|
||||
FDF793AB0F992E100016724F /* files.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = files.c; path = src/files.c; sourceTree = "<group>"; };
|
||||
FDF793AC0F992E100016724F /* global.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = global.c; path = src/global.c; sourceTree = "<group>"; };
|
||||
FDF793AD0F992E100016724F /* help.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = help.c; path = src/help.c; sourceTree = "<group>"; };
|
||||
FDF793AE0F992E100016724F /* move.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = move.c; path = src/move.c; sourceTree = "<group>"; };
|
||||
FDF793AF0F992E100016724F /* nano.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = nano.c; path = src/nano.c; sourceTree = "<group>"; };
|
||||
FDF793B00F992E100016724F /* nano.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = nano.h; path = src/nano.h; sourceTree = "<group>"; };
|
||||
FDF793B10F992E110016724F /* prompt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = prompt.c; path = src/prompt.c; sourceTree = "<group>"; };
|
||||
FDF793B20F992E110016724F /* proto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = proto.h; path = src/proto.h; sourceTree = "<group>"; };
|
||||
FDF793B30F992E110016724F /* rcfile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = rcfile.c; path = src/rcfile.c; sourceTree = "<group>"; };
|
||||
FDF793B40F992E110016724F /* search.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = search.c; path = src/search.c; sourceTree = "<group>"; };
|
||||
FDF793B50F992E110016724F /* text.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = text.c; path = src/text.c; sourceTree = "<group>"; };
|
||||
FDF793B60F992E110016724F /* utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = utils.c; path = src/utils.c; sourceTree = "<group>"; };
|
||||
FDF793B70F992E110016724F /* winio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = winio.c; path = src/winio.c; sourceTree = "<group>"; };
|
||||
FDF793C10F992E950016724F /* nano */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = nano; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
FDF793E20F992F070016724F /* config.h */ = {isa = PBXFileReference; comments = "This file was generated by running:\n\n./configure --prefix=/usr --sysconfdir=/etc --enable-all\n\nNote that ENABLE_UTF8 was forced on, as the standard configure script does correctly detect the ncurses in Mac OS X."; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
|
||||
FDF793E40F992F070016724F /* nano.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = nano.plist; sourceTree = "<group>"; };
|
||||
FDF793F60F992FAA0016724F /* nano.1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.man; name = nano.1; path = doc/nano.1; sourceTree = "<group>"; };
|
||||
FDF793F70F992FAA0016724F /* nanorc.5 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = nanorc.5; path = doc/nanorc.5; sourceTree = "<group>"; };
|
||||
FDF793F80F992FAA0016724F /* rnano.1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.man; name = rnano.1; path = doc/rnano.1; sourceTree = "<group>"; };
|
||||
FDF793FB0F992FF80016724F /* COPYING */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = COPYING; path = doc/COPYING; sourceTree = "<group>"; };
|
||||
FDF793FC0F992FF80016724F /* nanorc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = nanorc; sourceTree = "<group>"; };
|
||||
FDF794250F9931E60016724F /* libncurses.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libncurses.dylib; path = /usr/lib/libncurses.dylib; sourceTree = "<absolute>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
FDF793BF0F992E950016724F /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
FDF794260F9931E60016724F /* libncurses.dylib in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
FDF793970F992DAB0016724F = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FDF793E20F992F070016724F /* config.h */,
|
||||
FDF793E40F992F070016724F /* nano.plist */,
|
||||
FDF793E60F992F3D0016724F /* doc */,
|
||||
FDF793A40F992DBE0016724F /* src */,
|
||||
FDF793C20F992E950016724F /* Products */,
|
||||
FDF794250F9931E60016724F /* libncurses.dylib */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FDF793A40F992DBE0016724F /* src */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FDF793B00F992E100016724F /* nano.h */,
|
||||
FDF793B20F992E110016724F /* proto.h */,
|
||||
FDF793A70F992E100016724F /* browser.c */,
|
||||
FDF793A80F992E100016724F /* chars.c */,
|
||||
FDF793A90F992E100016724F /* color.c */,
|
||||
FDF793AA0F992E100016724F /* cut.c */,
|
||||
FDF793AB0F992E100016724F /* files.c */,
|
||||
FDF793AC0F992E100016724F /* global.c */,
|
||||
FDF793AD0F992E100016724F /* help.c */,
|
||||
FDF793AE0F992E100016724F /* move.c */,
|
||||
FDF793AF0F992E100016724F /* nano.c */,
|
||||
FDF793B10F992E110016724F /* prompt.c */,
|
||||
FDF793B30F992E110016724F /* rcfile.c */,
|
||||
FDF793B40F992E110016724F /* search.c */,
|
||||
FDF793B50F992E110016724F /* text.c */,
|
||||
FDF793B60F992E110016724F /* utils.c */,
|
||||
FDF793B70F992E110016724F /* winio.c */,
|
||||
);
|
||||
name = src;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FDF793C20F992E950016724F /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FDF793C10F992E950016724F /* nano */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FDF793E60F992F3D0016724F /* doc */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FDF793FB0F992FF80016724F /* COPYING */,
|
||||
FDF793FC0F992FF80016724F /* nanorc */,
|
||||
FDF793F70F992FAA0016724F /* nanorc.5 */,
|
||||
FDF793F60F992FAA0016724F /* nano.1 */,
|
||||
FDF793F80F992FAA0016724F /* rnano.1 */,
|
||||
);
|
||||
name = doc;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
FDF793C00F992E950016724F /* nano */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = FDF793C60F992E960016724F /* Build configuration list for PBXNativeTarget "nano" */;
|
||||
buildPhases = (
|
||||
FDF793BE0F992E950016724F /* Sources */,
|
||||
FDF793BF0F992E950016724F /* Frameworks */,
|
||||
FDF794610F99344A0016724F /* Install man1 (1) */,
|
||||
FDF794620F99344A0016724F /* Install man5 (1) */,
|
||||
FDF794640F99344A0016724F /* Install etc */,
|
||||
FDF794650F99344A0016724F /* Install OpenSourceVersions */,
|
||||
FDF794660F99344A0016724F /* Install OpenSourceLicenses */,
|
||||
FDF794700F9935650016724F /* Rename COPYING, Link pico */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = nano;
|
||||
productName = nano;
|
||||
productReference = FDF793C10F992E950016724F /* nano */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
FDF793990F992DAB0016724F /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
buildConfigurationList = FDF7939C0F992DAB0016724F /* Build configuration list for PBXProject "nano" */;
|
||||
compatibilityVersion = "Xcode 2.4";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = FDF793970F992DAB0016724F;
|
||||
productRefGroup = FDF793C20F992E950016724F /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
FDF793C00F992E950016724F /* nano */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
FDF794700F9935650016724F /* Rename COPYING, Link pico */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 8;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Rename COPYING, Link pico";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "mv ${DSTROOT}/usr/local/OpenSourceLicenses/COPYING ${DSTROOT}/usr/local/OpenSourceLicenses/nano.txt\nln -s nano ${DSTROOT}/usr/bin/pico\nln -s nano.1 ${DSTROOT}/usr/share/man/man1/pico.1";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
FDF793BE0F992E950016724F /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
FDF793C70F992EA80016724F /* browser.c in Sources */,
|
||||
FDF793C80F992EA80016724F /* chars.c in Sources */,
|
||||
FDF793C90F992EA80016724F /* color.c in Sources */,
|
||||
FDF793CA0F992EA80016724F /* cut.c in Sources */,
|
||||
FDF793CB0F992EA80016724F /* files.c in Sources */,
|
||||
FDF793CC0F992EA80016724F /* global.c in Sources */,
|
||||
FDF793CD0F992EA80016724F /* help.c in Sources */,
|
||||
FDF793CE0F992EA80016724F /* move.c in Sources */,
|
||||
FDF793CF0F992EA80016724F /* nano.c in Sources */,
|
||||
FDF793D00F992EA80016724F /* prompt.c in Sources */,
|
||||
FDF793D10F992EA80016724F /* rcfile.c in Sources */,
|
||||
FDF793D20F992EA80016724F /* search.c in Sources */,
|
||||
FDF793D30F992EA80016724F /* text.c in Sources */,
|
||||
FDF793D40F992EA80016724F /* utils.c in Sources */,
|
||||
FDF793D50F992EA80016724F /* winio.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
FDF7939B0F992DAB0016724F /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
CURRENT_PROJECT_VERSION = "$(RC_ProjectSourceVersion)";
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
PREBINDING = NO;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
FDF793C50F992E960016724F /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"$(GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_TARGET_1)",
|
||||
HAVE_CONFIG_H,
|
||||
);
|
||||
GCC_PREPROCESSOR_DEFINITIONS_QUOTED_FOR_TARGET_1 = "SYSCONFDIR=\\\"/etc\\\"";
|
||||
HEADER_SEARCH_PATHS = "$(SRCROOT)";
|
||||
INSTALL_PATH = /usr/bin;
|
||||
PRODUCT_NAME = nano;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
FDF7939C0F992DAB0016724F /* Build configuration list for PBXProject "nano" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
FDF7939B0F992DAB0016724F /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
FDF793C60F992E960016724F /* Build configuration list for PBXNativeTarget "nano" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
FDF793C50F992E960016724F /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = FDF793990F992DAB0016724F /* Project object */;
|
||||
}
|
1087
src/browser.c
Normal file
1087
src/browser.c
Normal file
File diff suppressed because it is too large
Load Diff
1028
src/chars.c
Normal file
1028
src/chars.c
Normal file
File diff suppressed because it is too large
Load Diff
203
src/color.c
Normal file
203
src/color.c
Normal file
@ -0,0 +1,203 @@
|
||||
/* $Id: color.c,v 1.42 2007/01/01 05:15:32 dolorous Exp $ */
|
||||
/**************************************************************************
|
||||
* color.c *
|
||||
* *
|
||||
* Copyright (C) 2001, 2002, 2003, 2004 Chris Allegretta *
|
||||
* Copyright (C) 2005, 2006, 2007 David Lawrence Ramsey *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2, or (at your option) *
|
||||
* any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
|
||||
* 02110-1301, USA. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#include "proto.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
|
||||
/* For each syntax list entry, go through the list of colors and assign
|
||||
* the color pairs. */
|
||||
void set_colorpairs(void)
|
||||
{
|
||||
const syntaxtype *this_syntax = syntaxes;
|
||||
|
||||
for (; this_syntax != NULL; this_syntax = this_syntax->next) {
|
||||
colortype *this_color = this_syntax->color;
|
||||
int color_pair = 1;
|
||||
|
||||
for (; this_color != NULL; this_color = this_color->next) {
|
||||
const colortype *beforenow = this_syntax->color;
|
||||
|
||||
for (; beforenow != this_color &&
|
||||
(beforenow->fg != this_color->fg ||
|
||||
beforenow->bg != this_color->bg ||
|
||||
beforenow->bright != this_color->bright);
|
||||
beforenow = beforenow->next)
|
||||
;
|
||||
|
||||
if (beforenow != this_color)
|
||||
this_color->pairnum = beforenow->pairnum;
|
||||
else {
|
||||
this_color->pairnum = color_pair;
|
||||
color_pair++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize the color information. */
|
||||
void color_init(void)
|
||||
{
|
||||
assert(openfile != NULL);
|
||||
|
||||
if (has_colors()) {
|
||||
const colortype *tmpcolor;
|
||||
#ifdef HAVE_USE_DEFAULT_COLORS
|
||||
bool defok;
|
||||
#endif
|
||||
|
||||
start_color();
|
||||
|
||||
#ifdef HAVE_USE_DEFAULT_COLORS
|
||||
/* Use the default colors, if available. */
|
||||
defok = (use_default_colors() != ERR);
|
||||
#endif
|
||||
|
||||
for (tmpcolor = openfile->colorstrings; tmpcolor != NULL;
|
||||
tmpcolor = tmpcolor->next) {
|
||||
short foreground = tmpcolor->fg, background = tmpcolor->bg;
|
||||
if (foreground == -1) {
|
||||
#ifdef HAVE_USE_DEFAULT_COLORS
|
||||
if (!defok)
|
||||
#endif
|
||||
foreground = COLOR_WHITE;
|
||||
}
|
||||
|
||||
if (background == -1) {
|
||||
#ifdef HAVE_USE_DEFAULT_COLORS
|
||||
if (!defok)
|
||||
#endif
|
||||
background = COLOR_BLACK;
|
||||
}
|
||||
|
||||
init_pair(tmpcolor->pairnum, foreground, background);
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "init_pair(): fg = %hd, bg = %hd\n", tmpcolor->fg, tmpcolor->bg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the color information based on the current filename. */
|
||||
void color_update(void)
|
||||
{
|
||||
const syntaxtype *tmpsyntax;
|
||||
colortype *tmpcolor, *defcolor = NULL;
|
||||
|
||||
assert(openfile != NULL);
|
||||
|
||||
openfile->colorstrings = NULL;
|
||||
|
||||
/* If we specified a syntax override string, use it. */
|
||||
if (syntaxstr != NULL) {
|
||||
/* If the syntax override is "none", it's the same as not having
|
||||
* a syntax at all, so get out. */
|
||||
if (strcmp(syntaxstr, "none") == 0)
|
||||
return;
|
||||
|
||||
for (tmpsyntax = syntaxes; tmpsyntax != NULL;
|
||||
tmpsyntax = tmpsyntax->next) {
|
||||
if (strcmp(tmpsyntax->desc, syntaxstr) == 0)
|
||||
openfile->colorstrings = tmpsyntax->color;
|
||||
|
||||
if (openfile->colorstrings != NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we didn't specify a syntax override string, or if we did and
|
||||
* there was no syntax by that name, get the syntax based on the
|
||||
* file extension. */
|
||||
if (openfile->colorstrings == NULL) {
|
||||
for (tmpsyntax = syntaxes; tmpsyntax != NULL;
|
||||
tmpsyntax = tmpsyntax->next) {
|
||||
exttype *e;
|
||||
|
||||
/* If this is the default syntax, it has no associated
|
||||
* extensions, which we've checked for elsewhere. Skip over
|
||||
* it here, but keep track of its color regexes. */
|
||||
if (strcmp(tmpsyntax->desc, "default") == 0) {
|
||||
defcolor = tmpsyntax->color;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (e = tmpsyntax->extensions; e != NULL; e = e->next) {
|
||||
bool not_compiled = (e->ext == NULL);
|
||||
|
||||
/* e->ext_regex has already been checked for validity
|
||||
* elsewhere. Compile its specified regex if we haven't
|
||||
* already. */
|
||||
if (not_compiled) {
|
||||
e->ext = (regex_t *)nmalloc(sizeof(regex_t));
|
||||
regcomp(e->ext, e->ext_regex, REG_EXTENDED);
|
||||
}
|
||||
|
||||
/* Set colorstrings if we matched the extension
|
||||
* regex. */
|
||||
if (regexec(e->ext, openfile->filename, 0, NULL,
|
||||
0) == 0)
|
||||
openfile->colorstrings = tmpsyntax->color;
|
||||
|
||||
if (openfile->colorstrings != NULL)
|
||||
break;
|
||||
|
||||
/* Decompile e->ext_regex's specified regex if we aren't
|
||||
* going to use it. */
|
||||
if (not_compiled) {
|
||||
regfree(e->ext);
|
||||
free(e->ext);
|
||||
e->ext = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If we didn't get a syntax based on the file extension, and we
|
||||
* have a default syntax, use it. */
|
||||
if (openfile->colorstrings == NULL && defcolor != NULL)
|
||||
openfile->colorstrings = defcolor;
|
||||
|
||||
for (tmpcolor = openfile->colorstrings; tmpcolor != NULL;
|
||||
tmpcolor = tmpcolor->next) {
|
||||
/* tmpcolor->start_regex and tmpcolor->end_regex have already
|
||||
* been checked for validity elsewhere. Compile their specified
|
||||
* regexes if we haven't already. */
|
||||
if (tmpcolor->start == NULL) {
|
||||
tmpcolor->start = (regex_t *)nmalloc(sizeof(regex_t));
|
||||
regcomp(tmpcolor->start, tmpcolor->start_regex,
|
||||
REG_EXTENDED | (tmpcolor->icase ? REG_ICASE : 0));
|
||||
}
|
||||
|
||||
if (tmpcolor->end_regex != NULL && tmpcolor->end == NULL) {
|
||||
tmpcolor->end = (regex_t *)nmalloc(sizeof(regex_t));
|
||||
regcomp(tmpcolor->end, tmpcolor->end_regex,
|
||||
REG_EXTENDED | (tmpcolor->icase ? REG_ICASE : 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ENABLE_COLOR */
|
272
src/cut.c
Normal file
272
src/cut.c
Normal file
@ -0,0 +1,272 @@
|
||||
/* $Id: cut.c,v 1.61 2007/01/01 05:15:32 dolorous Exp $ */
|
||||
/**************************************************************************
|
||||
* cut.c *
|
||||
* *
|
||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Chris Allegretta *
|
||||
* Copyright (C) 2005, 2006, 2007 David Lawrence Ramsey *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2, or (at your option) *
|
||||
* any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
|
||||
* 02110-1301, USA. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#include "proto.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static bool keep_cutbuffer = FALSE;
|
||||
/* Should we keep the contents of the cutbuffer? */
|
||||
static filestruct *cutbottom = NULL;
|
||||
/* Pointer to the end of the cutbuffer. */
|
||||
|
||||
/* Indicate that we should no longer keep the contents of the
|
||||
* cutbuffer. */
|
||||
void cutbuffer_reset(void)
|
||||
{
|
||||
keep_cutbuffer = FALSE;
|
||||
}
|
||||
|
||||
/* If we aren't on the last line of the file, move all the text of the
|
||||
* current line, plus the newline at the end, into the cutbuffer. If we
|
||||
* are, move all of the text of the current line into the cutbuffer. In
|
||||
* both cases, set the current place we want to the beginning of the
|
||||
* current line. */
|
||||
void cut_line(void)
|
||||
{
|
||||
if (openfile->current != openfile->filebot)
|
||||
move_to_filestruct(&cutbuffer, &cutbottom, openfile->current, 0,
|
||||
openfile->current->next, 0);
|
||||
else
|
||||
move_to_filestruct(&cutbuffer, &cutbottom, openfile->current, 0,
|
||||
openfile->current, strlen(openfile->current->data));
|
||||
openfile->placewewant = 0;
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Move all currently marked text into the cutbuffer, and set the
|
||||
* current place we want to where the text used to start. */
|
||||
void cut_marked(void)
|
||||
{
|
||||
filestruct *top, *bot;
|
||||
size_t top_x, bot_x;
|
||||
|
||||
mark_order((const filestruct **)&top, &top_x,
|
||||
(const filestruct **)&bot, &bot_x, NULL);
|
||||
|
||||
move_to_filestruct(&cutbuffer, &cutbottom, top, top_x, bot, bot_x);
|
||||
openfile->placewewant = xplustabs();
|
||||
}
|
||||
|
||||
/* If we aren't at the end of the current line, move all the text from
|
||||
* the current cursor position to the end of the current line, not
|
||||
* counting the newline at the end, into the cutbuffer. If we are, and
|
||||
* we're not on the last line of the file, move the newline at the end
|
||||
* into the cutbuffer, and set the current place we want to where the
|
||||
* newline used to be. */
|
||||
void cut_to_eol(void)
|
||||
{
|
||||
size_t data_len = strlen(openfile->current->data);
|
||||
|
||||
assert(openfile->current_x <= data_len);
|
||||
|
||||
if (openfile->current_x < data_len)
|
||||
/* If we're not at the end of the line, move all the text from
|
||||
* the current position up to it, not counting the newline at
|
||||
* the end, into the cutbuffer. */
|
||||
move_to_filestruct(&cutbuffer, &cutbottom, openfile->current,
|
||||
openfile->current_x, openfile->current, data_len);
|
||||
else if (openfile->current != openfile->filebot) {
|
||||
/* If we're at the end of the line, and it isn't the last line
|
||||
* of the file, move all the text from the current position up
|
||||
* to the beginning of the next line, i.e. the newline at the
|
||||
* end, into the cutbuffer. */
|
||||
move_to_filestruct(&cutbuffer, &cutbottom, openfile->current,
|
||||
openfile->current_x, openfile->current->next, 0);
|
||||
openfile->placewewant = xplustabs();
|
||||
}
|
||||
}
|
||||
|
||||
/* Move all the text from the current cursor position to the end of the
|
||||
* file into the cutbuffer. */
|
||||
void cut_to_eof(void)
|
||||
{
|
||||
move_to_filestruct(&cutbuffer, &cutbottom, openfile->current,
|
||||
openfile->current_x, openfile->filebot,
|
||||
strlen(openfile->filebot->data));
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* Move text from the current filestruct into the cutbuffer. If
|
||||
* copy_text is TRUE, copy the text back into the filestruct afterward.
|
||||
* If cut_till_end is TRUE, move all text from the current cursor
|
||||
* position to the end of the file into the cutbuffer. */
|
||||
void do_cut_text(
|
||||
#ifndef NANO_TINY
|
||||
bool copy_text, bool cut_till_end
|
||||
#else
|
||||
void
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#ifndef NANO_TINY
|
||||
filestruct *cb_save = NULL;
|
||||
/* The current end of the cutbuffer, before we add text to
|
||||
* it. */
|
||||
size_t cb_save_len = 0;
|
||||
/* The length of the string at the current end of the cutbuffer,
|
||||
* before we add text to it. */
|
||||
bool old_no_newlines = ISSET(NO_NEWLINES);
|
||||
#endif
|
||||
|
||||
assert(openfile->current != NULL && openfile->current->data != NULL);
|
||||
|
||||
/* If keep_cutbuffer is FALSE and the cutbuffer isn't empty, blow
|
||||
* away the text in the cutbuffer. */
|
||||
if (!keep_cutbuffer && cutbuffer != NULL) {
|
||||
free_filestruct(cutbuffer);
|
||||
cutbuffer = NULL;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Blew away cutbuffer =)\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (copy_text) {
|
||||
if (cutbuffer != NULL) {
|
||||
/* If the cutbuffer isn't empty, save where it currently
|
||||
* ends. This is where we'll add the new text. */
|
||||
cb_save = cutbottom;
|
||||
cb_save_len = strlen(cutbottom->data);
|
||||
}
|
||||
|
||||
/* Set NO_NEWLINES to TRUE, so that we don't disturb the last
|
||||
* line of the file when moving text to the cutbuffer. */
|
||||
SET(NO_NEWLINES);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set keep_cutbuffer to TRUE, so that the text we're going to move
|
||||
* into the cutbuffer will be added to the text already in the
|
||||
* cutbuffer instead of replacing it. */
|
||||
keep_cutbuffer = TRUE;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (cut_till_end) {
|
||||
/* If cut_till_end is TRUE, move all text up to the end of the
|
||||
* file into the cutbuffer. */
|
||||
cut_to_eof();
|
||||
} else if (openfile->mark_set) {
|
||||
/* If the mark is on, move the marked text to the cutbuffer, and
|
||||
* turn the mark off. */
|
||||
cut_marked();
|
||||
openfile->mark_set = FALSE;
|
||||
} else if (ISSET(CUT_TO_END))
|
||||
/* If the CUT_TO_END flag is set, move all text up to the end of
|
||||
* the line into the cutbuffer. */
|
||||
cut_to_eol();
|
||||
else
|
||||
#endif
|
||||
/* Move the entire line into the cutbuffer. */
|
||||
cut_line();
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (copy_text) {
|
||||
/* Copy the text in the cutbuffer, starting at its saved end if
|
||||
* there is one, back into the filestruct. This effectively
|
||||
* uncuts the text we just cut without marking the file as
|
||||
* modified. */
|
||||
if (cutbuffer != NULL) {
|
||||
if (cb_save != NULL) {
|
||||
cb_save->data += cb_save_len;
|
||||
copy_from_filestruct(cb_save, cutbottom);
|
||||
cb_save->data -= cb_save_len;
|
||||
} else
|
||||
copy_from_filestruct(cutbuffer, cutbottom);
|
||||
|
||||
/* Set the current place we want to where the text from the
|
||||
* cutbuffer ends. */
|
||||
openfile->placewewant = xplustabs();
|
||||
}
|
||||
|
||||
/* Set NO_NEWLINES back to what it was before, since we're done
|
||||
* disturbing the text. */
|
||||
if (!old_no_newlines)
|
||||
UNSET(NO_NEWLINES);
|
||||
} else
|
||||
#endif
|
||||
/* Leave the text in the cutbuffer, and mark the file as
|
||||
* modified. */
|
||||
set_modified();
|
||||
|
||||
/* Update the screen. */
|
||||
edit_refresh();
|
||||
|
||||
#ifdef DEBUG
|
||||
dump_filestruct(cutbuffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Move text from the current filestruct into the cutbuffer. */
|
||||
void do_cut_text_void(void)
|
||||
{
|
||||
do_cut_text(
|
||||
#ifndef NANO_TINY
|
||||
FALSE, FALSE
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Move text from the current filestruct into the cutbuffer, and copy it
|
||||
* back into the filestruct afterward. */
|
||||
void do_copy_text(void)
|
||||
{
|
||||
do_cut_text(TRUE, FALSE);
|
||||
}
|
||||
|
||||
/* Cut from the current cursor position to the end of the file. */
|
||||
void do_cut_till_end(void)
|
||||
{
|
||||
do_cut_text(FALSE, TRUE);
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* Copy text from the cutbuffer into the current filestruct. */
|
||||
void do_uncut_text(void)
|
||||
{
|
||||
assert(openfile->current != NULL && openfile->current->data != NULL);
|
||||
|
||||
/* If the cutbuffer is empty, get out. */
|
||||
if (cutbuffer == NULL)
|
||||
return;
|
||||
|
||||
/* Add a copy of the text in the cutbuffer to the current filestruct
|
||||
* at the current cursor position. */
|
||||
copy_from_filestruct(cutbuffer, cutbottom);
|
||||
|
||||
/* Set the current place we want to where the text from the
|
||||
* cutbuffer ends. */
|
||||
openfile->placewewant = xplustabs();
|
||||
|
||||
/* Mark the file as modified. */
|
||||
set_modified();
|
||||
|
||||
/* Update the screen. */
|
||||
edit_refresh();
|
||||
|
||||
#ifdef DEBUG
|
||||
dump_filestruct_reverse();
|
||||
#endif
|
||||
}
|
2556
src/files.c
Normal file
2556
src/files.c
Normal file
File diff suppressed because it is too large
Load Diff
1508
src/global.c
Normal file
1508
src/global.c
Normal file
File diff suppressed because it is too large
Load Diff
621
src/help.c
Normal file
621
src/help.c
Normal file
@ -0,0 +1,621 @@
|
||||
/* $Id: help.c,v 1.58.2.1 2007/04/19 03:15:04 dolorous Exp $ */
|
||||
/**************************************************************************
|
||||
* help.c *
|
||||
* *
|
||||
* Copyright (C) 2000, 2001, 2002, 2003, 2004 Chris Allegretta *
|
||||
* Copyright (C) 2005, 2006, 2007 David Lawrence Ramsey *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2, or (at your option) *
|
||||
* any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
|
||||
* 02110-1301, USA. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#include "proto.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef DISABLE_HELP
|
||||
|
||||
static char *help_text = NULL;
|
||||
/* The text displayed in the help window. */
|
||||
|
||||
/* Our main help browser function. refresh_func is the function we will
|
||||
* call to refresh the edit window. */
|
||||
void do_help(void (*refresh_func)(void))
|
||||
{
|
||||
int kbinput = ERR;
|
||||
bool meta_key, func_key, old_no_help = ISSET(NO_HELP);
|
||||
bool abort = FALSE;
|
||||
/* Whether we should abort the help browser. */
|
||||
size_t line = 0;
|
||||
/* The line number in help_text of the first displayed help
|
||||
* line. This variable is zero-based. */
|
||||
size_t last_line = 0;
|
||||
/* The line number in help_text of the last help line. This
|
||||
* variable is zero-based. */
|
||||
#ifndef DISABLE_MOUSE
|
||||
const shortcut *oldshortcut = currshortcut;
|
||||
/* The current shortcut list. */
|
||||
#endif
|
||||
const char *ptr;
|
||||
/* The current line of the help text. */
|
||||
size_t old_line = (size_t)-1;
|
||||
/* The line we were on before the current line. */
|
||||
|
||||
curs_set(0);
|
||||
blank_edit();
|
||||
wattroff(bottomwin, reverse_attr);
|
||||
blank_statusbar();
|
||||
|
||||
/* Set help_text as the string to display. */
|
||||
help_init();
|
||||
|
||||
assert(help_text != NULL);
|
||||
|
||||
#ifndef DISABLE_MOUSE
|
||||
/* Set currshortcut to allow clicking on the help screen's shortcut
|
||||
* list, after help_init() is called. */
|
||||
currshortcut = help_list;
|
||||
#endif
|
||||
|
||||
if (ISSET(NO_HELP)) {
|
||||
/* Make sure that the help screen's shortcut list will actually
|
||||
* be displayed. */
|
||||
UNSET(NO_HELP);
|
||||
window_init();
|
||||
}
|
||||
|
||||
bottombars(help_list);
|
||||
wnoutrefresh(bottomwin);
|
||||
|
||||
/* Get the last line of the help text. */
|
||||
ptr = help_text;
|
||||
|
||||
for (; *ptr != '\0'; last_line++) {
|
||||
ptr += help_line_len(ptr);
|
||||
if (*ptr == '\n')
|
||||
ptr++;
|
||||
}
|
||||
if (last_line > 0)
|
||||
last_line--;
|
||||
|
||||
while (!abort) {
|
||||
size_t i;
|
||||
|
||||
/* Display the help text if we don't have a key, or if the help
|
||||
* text has moved. */
|
||||
if (kbinput == ERR || line != old_line) {
|
||||
blank_edit();
|
||||
|
||||
ptr = help_text;
|
||||
|
||||
/* Calculate where in the text we should be, based on the
|
||||
* page. */
|
||||
for (i = 0; i < line; i++) {
|
||||
ptr += help_line_len(ptr);
|
||||
if (*ptr == '\n')
|
||||
ptr++;
|
||||
}
|
||||
|
||||
for (i = 0; i < editwinrows && *ptr != '\0'; i++) {
|
||||
size_t j = help_line_len(ptr);
|
||||
|
||||
mvwaddnstr(edit, i, 0, ptr, j);
|
||||
ptr += j;
|
||||
if (*ptr == '\n')
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
wnoutrefresh(edit);
|
||||
|
||||
old_line = line;
|
||||
|
||||
kbinput = get_kbinput(edit, &meta_key, &func_key);
|
||||
parse_help_input(&kbinput, &meta_key, &func_key);
|
||||
|
||||
switch (kbinput) {
|
||||
#ifndef DISABLE_MOUSE
|
||||
case KEY_MOUSE:
|
||||
{
|
||||
int mouse_x, mouse_y;
|
||||
|
||||
get_mouseinput(&mouse_x, &mouse_y, TRUE);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
/* Redraw the screen. */
|
||||
case NANO_REFRESH_KEY:
|
||||
total_redraw();
|
||||
break;
|
||||
case NANO_PREVPAGE_KEY:
|
||||
if (line > editwinrows - 2)
|
||||
line -= editwinrows - 2;
|
||||
else
|
||||
line = 0;
|
||||
break;
|
||||
case NANO_NEXTPAGE_KEY:
|
||||
if (line + (editwinrows - 1) < last_line)
|
||||
line += editwinrows - 2;
|
||||
break;
|
||||
case NANO_PREVLINE_KEY:
|
||||
if (line > 0)
|
||||
line--;
|
||||
break;
|
||||
case NANO_NEXTLINE_KEY:
|
||||
if (line + (editwinrows - 1) < last_line)
|
||||
line++;
|
||||
break;
|
||||
case NANO_FIRSTLINE_METAKEY:
|
||||
if (meta_key)
|
||||
line = 0;
|
||||
break;
|
||||
case NANO_LASTLINE_METAKEY:
|
||||
if (meta_key) {
|
||||
if (line + (editwinrows - 1) < last_line)
|
||||
line = last_line - (editwinrows - 1);
|
||||
}
|
||||
break;
|
||||
/* Abort the help browser. */
|
||||
case NANO_EXIT_KEY:
|
||||
abort = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef DISABLE_MOUSE
|
||||
currshortcut = oldshortcut;
|
||||
#endif
|
||||
|
||||
if (old_no_help) {
|
||||
blank_bottombars();
|
||||
wnoutrefresh(bottomwin);
|
||||
SET(NO_HELP);
|
||||
window_init();
|
||||
} else
|
||||
bottombars(currshortcut);
|
||||
|
||||
curs_set(1);
|
||||
refresh_func();
|
||||
|
||||
/* The help_init() at the beginning allocated help_text. Since
|
||||
* help_text has now been written to the screen, we don't need it
|
||||
* anymore. */
|
||||
free(help_text);
|
||||
help_text = NULL;
|
||||
}
|
||||
|
||||
/* Start the help browser for the edit window. */
|
||||
void do_help_void(void)
|
||||
{
|
||||
do_help(&edit_refresh);
|
||||
}
|
||||
|
||||
#ifndef DISABLE_BROWSER
|
||||
/* Start the help browser for the file browser. */
|
||||
void do_browser_help(void)
|
||||
{
|
||||
do_help(&browser_refresh);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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_TINY
|
||||
const toggle *t;
|
||||
#ifdef ENABLE_NANORC
|
||||
bool old_whitespace = ISSET(WHITESPACE_DISPLAY);
|
||||
|
||||
UNSET(WHITESPACE_DISPLAY);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* First, set up the initial help text for the current function. */
|
||||
if (currshortcut == whereis_list || currshortcut == replace_list ||
|
||||
currshortcut == replace_list_2) {
|
||||
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 == whereis_file_list) {
|
||||
htx[0] = N_("Browser 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.\n\n");
|
||||
htx[1] = N_(" The following function keys are available in "
|
||||
"Browser Search mode:\n\n");
|
||||
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 /* !DISABLE_BROWSER */
|
||||
#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 function keys "
|
||||
"are available in Spell Check mode:\n\n");
|
||||
htx[1] = NULL;
|
||||
htx[2] = NULL;
|
||||
}
|
||||
#endif /* !DISABLE_SPELLER */
|
||||
#ifndef NANO_TINY
|
||||
else if (currshortcut == extcmd_list) {
|
||||
htx[0] = N_("Execute Command Help Text\n\n "
|
||||
"This mode 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 function keys are "
|
||||
"available in Execute Command mode:\n\n");
|
||||
htx[1] = NULL;
|
||||
htx[2] = NULL;
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
else {
|
||||
/* Default to the main help list. */
|
||||
htx[0] = N_("Main 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. ");
|
||||
htx[1] = N_("The bottom two lines show the most commonly used "
|
||||
"shortcuts in the editor.\n\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");
|
||||
}
|
||||
|
||||
htx[0] = _(htx[0]);
|
||||
if (htx[1] != NULL)
|
||||
htx[1] = _(htx[1]);
|
||||
if (htx[2] != NULL)
|
||||
htx[2] = _(htx[2]);
|
||||
|
||||
allocsize += strlen(htx[0]);
|
||||
if (htx[1] != NULL)
|
||||
allocsize += strlen(htx[1]);
|
||||
if (htx[2] != NULL)
|
||||
allocsize += strlen(htx[2]);
|
||||
|
||||
/* Count the shortcut help text. Each entry has up to three keys,
|
||||
* which fill 24 columns, plus translated text, plus one or two
|
||||
* \n's. */
|
||||
for (s = currshortcut; s != NULL; s = s->next)
|
||||
allocsize += (24 * mb_cur_max()) + strlen(s->help) + 2;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* If we're on the main list, we also count the toggle help text.
|
||||
* Each entry has "M-%c\t\t\t", which fills 24 columns, plus a
|
||||
* space, plus translated text, plus one or two '\n's. */
|
||||
if (currshortcut == main_list) {
|
||||
size_t endis_len = strlen(_("enable/disable"));
|
||||
|
||||
for (t = toggles; t != NULL; t = t->next)
|
||||
allocsize += strlen(t->desc) + endis_len + 9;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* help_text has been freed and set to NULL unless the user resized
|
||||
* while in the help screen. */
|
||||
if (help_text != NULL)
|
||||
free(help_text);
|
||||
|
||||
/* Allocate space for the help text. */
|
||||
help_text = charalloc(allocsize + 1);
|
||||
|
||||
/* 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]);
|
||||
|
||||
ptr = help_text + strlen(help_text);
|
||||
|
||||
/* 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 three
|
||||
* shortcut entries. */
|
||||
for (s = currshortcut; s != NULL; s = s->next) {
|
||||
int entries = 0;
|
||||
|
||||
/* 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, 14,
|
||||
FALSE);
|
||||
|
||||
if (s->funcval == NANO_NO_KEY && (s->metaval ==
|
||||
NANO_NO_KEY || s->miscval == NANO_NO_KEY)) {
|
||||
/* If we're here, we have at least two entries worth
|
||||
* of blank space. If this entry takes up more than
|
||||
* one entry's worth of space, use two to display
|
||||
* it. */
|
||||
if (mbstrlen(space_ptr) > 6)
|
||||
entries++;
|
||||
} else
|
||||
/* Otherwise, truncate it so that it takes up only
|
||||
* one entry's worth of space. */
|
||||
space_ptr[6] = '\0';
|
||||
|
||||
ptr += sprintf(ptr, "^%s", space_ptr);
|
||||
|
||||
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';
|
||||
}
|
||||
|
||||
/* 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';
|
||||
}
|
||||
|
||||
/* 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_META_SPACE && entries == 1) {
|
||||
char *space_ptr = display_string(_("Space"), 0, 13,
|
||||
FALSE);
|
||||
|
||||
/* If we're here, we have at least two entries worth of
|
||||
* blank space. If this entry takes up more than one
|
||||
* entry's worth of space, use two to display it. */
|
||||
if (mbstrlen(space_ptr) > 5)
|
||||
entries++;
|
||||
|
||||
ptr += sprintf(ptr, "M-%s", space_ptr);
|
||||
|
||||
free(space_ptr);
|
||||
} else
|
||||
/* Normal values. */
|
||||
ptr += sprintf(ptr, (entries == 1) ? "M-%c" : "(M-%c)",
|
||||
toupper(s->metaval));
|
||||
*(ptr++) = '\t';
|
||||
}
|
||||
|
||||
/* 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';
|
||||
}
|
||||
|
||||
/* If this entry isn't blank, make sure all the help text starts
|
||||
* at the same place. */
|
||||
if (s->ctrlval != NANO_NO_KEY || s->funcval != NANO_NO_KEY ||
|
||||
s->metaval != NANO_NO_KEY || s->miscval !=
|
||||
NANO_NO_KEY) {
|
||||
while (entries < 3) {
|
||||
entries++;
|
||||
*(ptr++) = '\t';
|
||||
}
|
||||
}
|
||||
|
||||
/* The shortcut's help text. */
|
||||
ptr += sprintf(ptr, "%s\n", s->help);
|
||||
|
||||
if (s->blank_after)
|
||||
ptr += sprintf(ptr, "\n");
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* And the toggles... */
|
||||
if (currshortcut == main_list) {
|
||||
for (t = toggles; t != NULL; t = t->next) {
|
||||
ptr += sprintf(ptr, "M-%c\t\t\t%s %s\n",
|
||||
toupper(t->val), t->desc, _("enable/disable"));
|
||||
|
||||
if (t->blank_after)
|
||||
ptr += sprintf(ptr, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_NANORC
|
||||
if (old_whitespace)
|
||||
SET(WHITESPACE_DISPLAY);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* If all went well, we didn't overwrite the allocated space for
|
||||
* help_text. */
|
||||
assert(strlen(help_text) <= allocsize + 1);
|
||||
}
|
||||
|
||||
/* Determine the shortcut key corresponding to the values of kbinput
|
||||
* (the key itself), meta_key (whether the key is a meta sequence), and
|
||||
* func_key (whether the key is a function key), if any. In the
|
||||
* process, convert certain non-shortcut keys into their corresponding
|
||||
* shortcut keys. */
|
||||
void parse_help_input(int *kbinput, bool *meta_key, bool *func_key)
|
||||
{
|
||||
get_shortcut(help_list, kbinput, meta_key, func_key);
|
||||
|
||||
if (!*meta_key) {
|
||||
switch (*kbinput) {
|
||||
/* For consistency with the file browser. */
|
||||
case ' ':
|
||||
*kbinput = NANO_NEXTPAGE_KEY;
|
||||
break;
|
||||
case '-':
|
||||
*kbinput = NANO_PREVPAGE_KEY;
|
||||
break;
|
||||
/* Cancel is equivalent to Exit here. */
|
||||
case NANO_CANCEL_KEY:
|
||||
case 'E':
|
||||
case 'e':
|
||||
*kbinput = NANO_EXIT_KEY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate the next line of help_text, starting at ptr. */
|
||||
size_t help_line_len(const char *ptr)
|
||||
{
|
||||
int help_cols = (COLS > 24) ? COLS - 1 : 24;
|
||||
|
||||
/* Try to break the line at (COLS - 1) columns if we have more than
|
||||
* 24 columns, and at 24 columns otherwise. */
|
||||
ssize_t wrap_loc = break_line(ptr, help_cols, TRUE);
|
||||
size_t retval = (wrap_loc < 0) ? 0 : wrap_loc;
|
||||
size_t retval_save = retval;
|
||||
|
||||
/* Get the length of the entire line up to a null or a newline. */
|
||||
while (*(ptr + retval) != '\0' && *(ptr + retval) != '\n')
|
||||
retval += move_mbright(ptr + retval, 0);
|
||||
|
||||
/* If the entire line doesn't go more than one column beyond where
|
||||
* we tried to break it, we should display it as-is. Otherwise, we
|
||||
* should display it only up to the break. */
|
||||
if (strnlenpt(ptr, retval) > help_cols + 1)
|
||||
retval = retval_save;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif /* !DISABLE_HELP */
|
647
src/move.c
Normal file
647
src/move.c
Normal file
@ -0,0 +1,647 @@
|
||||
/* $Id: move.c,v 1.67 2007/01/01 05:15:32 dolorous Exp $ */
|
||||
/**************************************************************************
|
||||
* move.c *
|
||||
* *
|
||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Chris Allegretta *
|
||||
* Copyright (C) 2005, 2006, 2007 David Lawrence Ramsey *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2, or (at your option) *
|
||||
* any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
|
||||
* 02110-1301, USA. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#include "proto.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/* Move to the first line of the file. */
|
||||
void do_first_line(void)
|
||||
{
|
||||
const filestruct *current_save = openfile->current;
|
||||
size_t pww_save = openfile->placewewant;
|
||||
|
||||
openfile->current = openfile->fileage;
|
||||
openfile->current_x = 0;
|
||||
openfile->placewewant = 0;
|
||||
|
||||
edit_redraw(current_save, pww_save);
|
||||
}
|
||||
|
||||
/* Move to the last line of the file. */
|
||||
void do_last_line(void)
|
||||
{
|
||||
const filestruct *current_save = openfile->current;
|
||||
size_t pww_save = openfile->placewewant;
|
||||
|
||||
openfile->current = openfile->filebot;
|
||||
openfile->current_x = strlen(openfile->filebot->data);
|
||||
openfile->placewewant = xplustabs();
|
||||
openfile->current_y = editwinrows - 1;
|
||||
|
||||
edit_redraw(current_save, pww_save);
|
||||
}
|
||||
|
||||
/* Move up one page. */
|
||||
void do_page_up(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* If there's less than a page of text left on the screen, put the
|
||||
* cursor at the beginning of the first line of the file, and then
|
||||
* update the edit window. */
|
||||
if (openfile->current->lineno <= editwinrows - 2) {
|
||||
do_first_line();
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we're not in smooth scrolling mode, put the cursor at the
|
||||
* beginning of the top line of the edit window, as Pico does. */
|
||||
#ifndef NANO_TINY
|
||||
if (!ISSET(SMOOTH_SCROLL)) {
|
||||
#endif
|
||||
openfile->current = openfile->edittop;
|
||||
openfile->placewewant = 0;
|
||||
#ifndef NANO_TINY
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = editwinrows - 2; i > 0 && openfile->current !=
|
||||
openfile->fileage; i--)
|
||||
openfile->current = openfile->current->prev;
|
||||
|
||||
openfile->current_x = actual_x(openfile->current->data,
|
||||
openfile->placewewant);
|
||||
|
||||
/* Scroll the edit window up a page. */
|
||||
edit_scroll(UP_DIR, editwinrows - 2);
|
||||
}
|
||||
|
||||
/* Move down one page. */
|
||||
void do_page_down(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* If there's less than a page of text left on the screen, put the
|
||||
* cursor at the beginning of the last line of the file, and then
|
||||
* update the edit window. */
|
||||
if (openfile->current->lineno + editwinrows - 2 >=
|
||||
openfile->filebot->lineno) {
|
||||
do_last_line();
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we're not in smooth scrolling mode, put the cursor at the
|
||||
* beginning of the top line of the edit window, as Pico does. */
|
||||
#ifndef NANO_TINY
|
||||
if (!ISSET(SMOOTH_SCROLL)) {
|
||||
#endif
|
||||
openfile->current = openfile->edittop;
|
||||
openfile->placewewant = 0;
|
||||
#ifndef NANO_TINY
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = editwinrows - 2; i > 0 && openfile->current !=
|
||||
openfile->filebot; i--)
|
||||
openfile->current = openfile->current->next;
|
||||
|
||||
openfile->current_x = actual_x(openfile->current->data,
|
||||
openfile->placewewant);
|
||||
|
||||
/* Scroll the edit window down a page. */
|
||||
edit_scroll(DOWN_DIR, editwinrows - 2);
|
||||
}
|
||||
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
/* Move up to the beginning of the last beginning-of-paragraph line
|
||||
* before the current line. If allow_update is TRUE, update the screen
|
||||
* afterwards. */
|
||||
void do_para_begin(bool allow_update)
|
||||
{
|
||||
const filestruct *current_save = openfile->current;
|
||||
const size_t pww_save = openfile->placewewant;
|
||||
|
||||
if (openfile->current != openfile->fileage) {
|
||||
do {
|
||||
openfile->current = openfile->current->prev;
|
||||
openfile->current_y--;
|
||||
} while (!begpar(openfile->current));
|
||||
}
|
||||
|
||||
openfile->current_x = 0;
|
||||
openfile->placewewant = 0;
|
||||
|
||||
if (allow_update)
|
||||
edit_redraw(current_save, pww_save);
|
||||
}
|
||||
|
||||
/* Move up to the beginning of the last beginning-of-paragraph line
|
||||
* before the current line, and update the screen afterwards. */
|
||||
void do_para_begin_void(void)
|
||||
{
|
||||
do_para_begin(TRUE);
|
||||
}
|
||||
|
||||
/* Move down to the beginning of the last line of the current paragraph.
|
||||
* Then move down one line farther if there is such a line, or to the
|
||||
* end of the current line if not. If allow_update is TRUE, update the
|
||||
* screen afterwards. A line is the last line of a paragraph if it is
|
||||
* in a paragraph, and the next line either is the beginning line of a
|
||||
* paragraph or isn't in a paragraph. */
|
||||
void do_para_end(bool allow_update)
|
||||
{
|
||||
const filestruct *const current_save = openfile->current;
|
||||
const size_t pww_save = openfile->placewewant;
|
||||
|
||||
while (openfile->current != openfile->filebot &&
|
||||
!inpar(openfile->current))
|
||||
openfile->current = openfile->current->next;
|
||||
|
||||
while (openfile->current != openfile->filebot &&
|
||||
inpar(openfile->current->next) &&
|
||||
!begpar(openfile->current->next)) {
|
||||
openfile->current = openfile->current->next;
|
||||
openfile->current_y++;
|
||||
}
|
||||
|
||||
if (openfile->current != openfile->filebot) {
|
||||
openfile->current = openfile->current->next;
|
||||
openfile->current_x = 0;
|
||||
openfile->placewewant = 0;
|
||||
} else {
|
||||
openfile->current_x = strlen(openfile->current->data);
|
||||
openfile->placewewant = xplustabs();
|
||||
}
|
||||
|
||||
if (allow_update)
|
||||
edit_redraw(current_save, pww_save);
|
||||
}
|
||||
|
||||
/* Move down to the beginning of the last line of the current paragraph.
|
||||
* Then move down one line farther if there is such a line, or to the
|
||||
* end of the current line if not, and update the screen afterwards. */
|
||||
void do_para_end_void(void)
|
||||
{
|
||||
do_para_end(TRUE);
|
||||
}
|
||||
#endif /* !DISABLE_JUSTIFY */
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Move to the next word in the file. If allow_punct is TRUE, treat
|
||||
* punctuation as part of a word. If allow_update is TRUE, update the
|
||||
* screen afterwards. Return TRUE if we started on a word, and FALSE
|
||||
* otherwise. */
|
||||
bool do_next_word(bool allow_punct, bool allow_update)
|
||||
{
|
||||
size_t pww_save = openfile->placewewant;
|
||||
const filestruct *current_save = openfile->current;
|
||||
char *char_mb;
|
||||
int char_mb_len;
|
||||
bool end_line = FALSE, started_on_word = FALSE;
|
||||
|
||||
assert(openfile->current != NULL && openfile->current->data != NULL);
|
||||
|
||||
char_mb = charalloc(mb_cur_max());
|
||||
|
||||
/* Move forward until we find the character after the last letter of
|
||||
* the current word. */
|
||||
while (!end_line) {
|
||||
char_mb_len = parse_mbchar(openfile->current->data +
|
||||
openfile->current_x, char_mb, NULL);
|
||||
|
||||
/* If we've found it, stop moving forward through the current
|
||||
* line. */
|
||||
if (!is_word_mbchar(char_mb, allow_punct))
|
||||
break;
|
||||
|
||||
/* If we haven't found it, then we've started on a word, so set
|
||||
* started_on_word to TRUE. */
|
||||
started_on_word = TRUE;
|
||||
|
||||
if (openfile->current->data[openfile->current_x] == '\0')
|
||||
end_line = TRUE;
|
||||
else
|
||||
openfile->current_x += char_mb_len;
|
||||
}
|
||||
|
||||
/* Move forward until we find the first letter of the next word. */
|
||||
if (openfile->current->data[openfile->current_x] == '\0')
|
||||
end_line = TRUE;
|
||||
else
|
||||
openfile->current_x += char_mb_len;
|
||||
|
||||
for (; openfile->current != NULL;
|
||||
openfile->current = openfile->current->next) {
|
||||
while (!end_line) {
|
||||
char_mb_len = parse_mbchar(openfile->current->data +
|
||||
openfile->current_x, char_mb, NULL);
|
||||
|
||||
/* If we've found it, stop moving forward through the
|
||||
* current line. */
|
||||
if (is_word_mbchar(char_mb, allow_punct))
|
||||
break;
|
||||
|
||||
if (openfile->current->data[openfile->current_x] == '\0')
|
||||
end_line = TRUE;
|
||||
else
|
||||
openfile->current_x += char_mb_len;
|
||||
}
|
||||
|
||||
/* If we've found it, stop moving forward to the beginnings of
|
||||
* subsequent lines. */
|
||||
if (!end_line)
|
||||
break;
|
||||
|
||||
if (openfile->current != openfile->filebot) {
|
||||
end_line = FALSE;
|
||||
openfile->current_x = 0;
|
||||
}
|
||||
}
|
||||
|
||||
free(char_mb);
|
||||
|
||||
/* If we haven't found it, move to the end of the file. */
|
||||
if (openfile->current == NULL)
|
||||
openfile->current = openfile->filebot;
|
||||
|
||||
openfile->placewewant = xplustabs();
|
||||
|
||||
/* If allow_update is TRUE, update the screen. */
|
||||
if (allow_update)
|
||||
edit_redraw(current_save, pww_save);
|
||||
|
||||
/* Return whether we started on a word. */
|
||||
return started_on_word;
|
||||
}
|
||||
|
||||
/* Move to the next word in the file, treating punctuation as part of a
|
||||
* word if the WORD_BOUNDS flag is set, and update the screen
|
||||
* afterwards. */
|
||||
void do_next_word_void(void)
|
||||
{
|
||||
do_next_word(ISSET(WORD_BOUNDS), TRUE);
|
||||
}
|
||||
|
||||
/* Move to the previous word in the file. If allow_punct is TRUE, treat
|
||||
* punctuation as part of a word. If allow_update is TRUE, update the
|
||||
* screen afterwards. Return TRUE if we started on a word, and FALSE
|
||||
* otherwise. */
|
||||
bool do_prev_word(bool allow_punct, bool allow_update)
|
||||
{
|
||||
size_t pww_save = openfile->placewewant;
|
||||
const filestruct *current_save = openfile->current;
|
||||
char *char_mb;
|
||||
int char_mb_len;
|
||||
bool begin_line = FALSE, started_on_word = FALSE;
|
||||
|
||||
assert(openfile->current != NULL && openfile->current->data != NULL);
|
||||
|
||||
char_mb = charalloc(mb_cur_max());
|
||||
|
||||
/* Move backward until we find the character before the first letter
|
||||
* of the current word. */
|
||||
while (!begin_line) {
|
||||
char_mb_len = parse_mbchar(openfile->current->data +
|
||||
openfile->current_x, char_mb, NULL);
|
||||
|
||||
/* If we've found it, stop moving backward through the current
|
||||
* line. */
|
||||
if (!is_word_mbchar(char_mb, allow_punct))
|
||||
break;
|
||||
|
||||
/* If we haven't found it, then we've started on a word, so set
|
||||
* started_on_word to TRUE. */
|
||||
started_on_word = TRUE;
|
||||
|
||||
if (openfile->current_x == 0)
|
||||
begin_line = TRUE;
|
||||
else
|
||||
openfile->current_x = move_mbleft(openfile->current->data,
|
||||
openfile->current_x);
|
||||
}
|
||||
|
||||
/* Move backward until we find the last letter of the previous
|
||||
* word. */
|
||||
if (openfile->current_x == 0)
|
||||
begin_line = TRUE;
|
||||
else
|
||||
openfile->current_x = move_mbleft(openfile->current->data,
|
||||
openfile->current_x);
|
||||
|
||||
for (; openfile->current != NULL;
|
||||
openfile->current = openfile->current->prev) {
|
||||
while (!begin_line) {
|
||||
char_mb_len = parse_mbchar(openfile->current->data +
|
||||
openfile->current_x, char_mb, NULL);
|
||||
|
||||
/* If we've found it, stop moving backward through the
|
||||
* current line. */
|
||||
if (is_word_mbchar(char_mb, allow_punct))
|
||||
break;
|
||||
|
||||
if (openfile->current_x == 0)
|
||||
begin_line = TRUE;
|
||||
else
|
||||
openfile->current_x =
|
||||
move_mbleft(openfile->current->data,
|
||||
openfile->current_x);
|
||||
}
|
||||
|
||||
/* If we've found it, stop moving backward to the ends of
|
||||
* previous lines. */
|
||||
if (!begin_line)
|
||||
break;
|
||||
|
||||
if (openfile->current != openfile->fileage) {
|
||||
begin_line = FALSE;
|
||||
openfile->current_x = strlen(openfile->current->prev->data);
|
||||
}
|
||||
}
|
||||
|
||||
/* If we haven't found it, move to the beginning of the file. */
|
||||
if (openfile->current == NULL)
|
||||
openfile->current = openfile->fileage;
|
||||
/* If we've found it, move backward until we find the character
|
||||
* before the first letter of the previous word. */
|
||||
else if (!begin_line) {
|
||||
if (openfile->current_x == 0)
|
||||
begin_line = TRUE;
|
||||
else
|
||||
openfile->current_x = move_mbleft(openfile->current->data,
|
||||
openfile->current_x);
|
||||
|
||||
while (!begin_line) {
|
||||
char_mb_len = parse_mbchar(openfile->current->data +
|
||||
openfile->current_x, char_mb, NULL);
|
||||
|
||||
/* If we've found it, stop moving backward through the
|
||||
* current line. */
|
||||
if (!is_word_mbchar(char_mb, allow_punct))
|
||||
break;
|
||||
|
||||
if (openfile->current_x == 0)
|
||||
begin_line = TRUE;
|
||||
else
|
||||
openfile->current_x =
|
||||
move_mbleft(openfile->current->data,
|
||||
openfile->current_x);
|
||||
}
|
||||
|
||||
/* If we've found it, move forward to the first letter of the
|
||||
* previous word. */
|
||||
if (!begin_line)
|
||||
openfile->current_x += char_mb_len;
|
||||
}
|
||||
|
||||
free(char_mb);
|
||||
|
||||
openfile->placewewant = xplustabs();
|
||||
|
||||
/* If allow_update is TRUE, update the screen. */
|
||||
if (allow_update)
|
||||
edit_redraw(current_save, pww_save);
|
||||
|
||||
/* Return whether we started on a word. */
|
||||
return started_on_word;
|
||||
}
|
||||
|
||||
/* Move to the previous word in the file, treating punctuation as part
|
||||
* of a word if the WORD_BOUNDS flag is set, and update the screen
|
||||
* afterwards. */
|
||||
void do_prev_word_void(void)
|
||||
{
|
||||
do_prev_word(ISSET(WORD_BOUNDS), TRUE);
|
||||
}
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
/* Move to the beginning of the current line. If the SMART_HOME flag is
|
||||
* set, move to the first non-whitespace character of the current line
|
||||
* if we aren't already there, or to the beginning of the current line
|
||||
* if we are. */
|
||||
void do_home(void)
|
||||
{
|
||||
size_t pww_save = openfile->placewewant;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(SMART_HOME)) {
|
||||
size_t current_x_save = openfile->current_x;
|
||||
|
||||
openfile->current_x = indent_length(openfile->current->data);
|
||||
|
||||
if (openfile->current_x == current_x_save ||
|
||||
openfile->current->data[openfile->current_x] == '\0')
|
||||
openfile->current_x = 0;
|
||||
|
||||
openfile->placewewant = xplustabs();
|
||||
} else {
|
||||
#endif
|
||||
openfile->current_x = 0;
|
||||
openfile->placewewant = 0;
|
||||
#ifndef NANO_TINY
|
||||
}
|
||||
#endif
|
||||
|
||||
if (need_horizontal_update(pww_save))
|
||||
update_line(openfile->current, openfile->current_x);
|
||||
}
|
||||
|
||||
/* Move to the end of the current line. */
|
||||
void do_end(void)
|
||||
{
|
||||
size_t pww_save = openfile->placewewant;
|
||||
|
||||
openfile->current_x = strlen(openfile->current->data);
|
||||
openfile->placewewant = xplustabs();
|
||||
|
||||
if (need_horizontal_update(pww_save))
|
||||
update_line(openfile->current, openfile->current_x);
|
||||
}
|
||||
|
||||
/* If scroll_only is FALSE, move up one line. If scroll_only is TRUE,
|
||||
* scroll up one line without scrolling the cursor. */
|
||||
void do_up(
|
||||
#ifndef NANO_TINY
|
||||
bool scroll_only
|
||||
#else
|
||||
void
|
||||
#endif
|
||||
)
|
||||
{
|
||||
/* If we're at the top of the file, or if scroll_only is TRUE and
|
||||
* the top of the file is onscreen, get out. */
|
||||
if (openfile->current == openfile->fileage
|
||||
#ifndef NANO_TINY
|
||||
|| (scroll_only && openfile->edittop == openfile->fileage)
|
||||
#endif
|
||||
)
|
||||
return;
|
||||
|
||||
assert(openfile->current_y == openfile->current->lineno - openfile->edittop->lineno);
|
||||
|
||||
/* Move the current line of the edit window up. */
|
||||
openfile->current = openfile->current->prev;
|
||||
openfile->current_x = actual_x(openfile->current->data,
|
||||
openfile->placewewant);
|
||||
|
||||
/* If scroll_only is FALSE and if we're on the first line of the
|
||||
* edit window, scroll the edit window up one line if we're in
|
||||
* smooth scrolling mode, or up half a page if we're not. If
|
||||
* scroll_only is TRUE, scroll the edit window up one line
|
||||
* unconditionally. */
|
||||
if (openfile->current_y == 0
|
||||
#ifndef NANO_TINY
|
||||
|| scroll_only
|
||||
#endif
|
||||
)
|
||||
edit_scroll(UP_DIR,
|
||||
#ifndef NANO_TINY
|
||||
(ISSET(SMOOTH_SCROLL) || scroll_only) ? 1 :
|
||||
#endif
|
||||
editwinrows / 2);
|
||||
|
||||
/* If we're below the first line of the edit window, update the
|
||||
* line we were on before and the line we're on now. The former
|
||||
* needs to be redrawn if we're not on the first page, and the
|
||||
* latter needs to be drawn unconditionally. */
|
||||
if (openfile->current_y > 0) {
|
||||
if (need_vertical_update(0))
|
||||
update_line(openfile->current->next, 0);
|
||||
update_line(openfile->current, openfile->current_x);
|
||||
}
|
||||
}
|
||||
|
||||
/* Move up one line. */
|
||||
void do_up_void(void)
|
||||
{
|
||||
do_up(
|
||||
#ifndef NANO_TINY
|
||||
FALSE
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Scroll up one line without scrolling the cursor. */
|
||||
void do_scroll_up(void)
|
||||
{
|
||||
do_up(TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If scroll_only is FALSE, move down one line. If scroll_only is TRUE,
|
||||
* scroll down one line without scrolling the cursor. */
|
||||
void do_down(
|
||||
#ifndef NANO_TINY
|
||||
bool scroll_only
|
||||
#else
|
||||
void
|
||||
#endif
|
||||
)
|
||||
{
|
||||
/* If we're at the bottom of the file, get out. */
|
||||
if (openfile->current == openfile->filebot)
|
||||
return;
|
||||
|
||||
assert(openfile->current_y == openfile->current->lineno - openfile->edittop->lineno);
|
||||
|
||||
/* Move the current line of the edit window down. */
|
||||
openfile->current = openfile->current->next;
|
||||
openfile->current_x = actual_x(openfile->current->data,
|
||||
openfile->placewewant);
|
||||
|
||||
/* If scroll_only is FALSE and if we're on the first line of the
|
||||
* edit window, scroll the edit window down one line if we're in
|
||||
* smooth scrolling mode, or down half a page if we're not. If
|
||||
* scroll_only is TRUE, scroll the edit window down one line
|
||||
* unconditionally. */
|
||||
if (openfile->current_y == editwinrows - 1
|
||||
#ifndef NANO_TINY
|
||||
|| scroll_only
|
||||
#endif
|
||||
)
|
||||
edit_scroll(DOWN_DIR,
|
||||
#ifndef NANO_TINY
|
||||
(ISSET(SMOOTH_SCROLL) || scroll_only) ? 1 :
|
||||
#endif
|
||||
editwinrows / 2);
|
||||
|
||||
/* If we're above the last line of the edit window, update the line
|
||||
* we were on before and the line we're on now. The former needs to
|
||||
* be redrawn if we're not on the first page, and the latter needs
|
||||
* to be drawn unconditionally. */
|
||||
if (openfile->current_y < editwinrows - 1) {
|
||||
if (need_vertical_update(0))
|
||||
update_line(openfile->current->prev, 0);
|
||||
update_line(openfile->current, openfile->current_x);
|
||||
}
|
||||
}
|
||||
|
||||
/* Move down one line. */
|
||||
void do_down_void(void)
|
||||
{
|
||||
do_down(
|
||||
#ifndef NANO_TINY
|
||||
FALSE
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Scroll down one line without scrolling the cursor. */
|
||||
void do_scroll_down(void)
|
||||
{
|
||||
do_down(TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Move left one character. */
|
||||
void do_left(void)
|
||||
{
|
||||
size_t pww_save = openfile->placewewant;
|
||||
|
||||
if (openfile->current_x > 0)
|
||||
openfile->current_x = move_mbleft(openfile->current->data,
|
||||
openfile->current_x);
|
||||
else if (openfile->current != openfile->fileage) {
|
||||
do_up_void();
|
||||
openfile->current_x = strlen(openfile->current->data);
|
||||
}
|
||||
|
||||
openfile->placewewant = xplustabs();
|
||||
|
||||
if (need_horizontal_update(pww_save))
|
||||
update_line(openfile->current, openfile->current_x);
|
||||
}
|
||||
|
||||
/* Move right one character. */
|
||||
void do_right(void)
|
||||
{
|
||||
size_t pww_save = openfile->placewewant;
|
||||
|
||||
assert(openfile->current_x <= strlen(openfile->current->data));
|
||||
|
||||
if (openfile->current->data[openfile->current_x] != '\0')
|
||||
openfile->current_x = move_mbright(openfile->current->data,
|
||||
openfile->current_x);
|
||||
else if (openfile->current != openfile->filebot) {
|
||||
do_down_void();
|
||||
openfile->current_x = 0;
|
||||
}
|
||||
|
||||
openfile->placewewant = xplustabs();
|
||||
|
||||
if (need_horizontal_update(pww_save))
|
||||
update_line(openfile->current, openfile->current_x);
|
||||
}
|
2264
src/nano.c
Normal file
2264
src/nano.c
Normal file
File diff suppressed because it is too large
Load Diff
631
src/nano.h
Normal file
631
src/nano.h
Normal file
@ -0,0 +1,631 @@
|
||||
/* $Id: nano.h,v 1.188 2007/01/01 05:15:32 dolorous Exp $ */
|
||||
/**************************************************************************
|
||||
* nano.h *
|
||||
* *
|
||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Chris Allegretta *
|
||||
* Copyright (C) 2005, 2006, 2007 David Lawrence Ramsey *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2, or (at your option) *
|
||||
* any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
|
||||
* 02110-1301, USA. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef NANO_H
|
||||
#define NANO_H 1
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef __TANDEM
|
||||
/* Tandem NonStop Kernel support. */
|
||||
#include <floss.h>
|
||||
#define NANO_ROOT_UID 65535
|
||||
#else
|
||||
#define NANO_ROOT_UID 0
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
/* Macros for flags. */
|
||||
#define SET(bit) flags |= bit
|
||||
#define UNSET(bit) flags &= ~bit
|
||||
#define ISSET(bit) ((flags & bit) != 0)
|
||||
#define TOGGLE(bit) flags ^= bit
|
||||
|
||||
/* Macros for character allocation and more. */
|
||||
#define charalloc(howmuch) (char *)nmalloc((howmuch) * sizeof(char))
|
||||
#define charealloc(ptr, howmuch) (char *)nrealloc(ptr, (howmuch) * sizeof(char))
|
||||
#define charmove(dest, src, n) memmove(dest, src, (n) * sizeof(char))
|
||||
#define charset(dest, src, n) memset(dest, src, (n) * sizeof(char))
|
||||
|
||||
/* Set a default value for PATH_MAX if there isn't one. */
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 4096
|
||||
#endif
|
||||
|
||||
#ifdef USE_SLANG
|
||||
/* Slang support. */
|
||||
#include <slcurses.h>
|
||||
/* Slang curses emulation brain damage, part 3: Slang doesn't define the
|
||||
* curses equivalents of the Insert or Delete keys. */
|
||||
#define KEY_DC SL_KEY_DELETE
|
||||
#define KEY_IC SL_KEY_IC
|
||||
/* Ncurses support. */
|
||||
#elif defined(HAVE_NCURSES_H)
|
||||
#include <ncurses.h>
|
||||
#else
|
||||
/* Curses support. */
|
||||
#include <curses.h>
|
||||
#endif /* CURSES_H */
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
/* Native language support. */
|
||||
#ifdef HAVE_LIBINTL_H
|
||||
#include <libintl.h>
|
||||
#endif
|
||||
#define _(string) gettext(string)
|
||||
#define P_(singular, plural, number) ngettext(singular, plural, number)
|
||||
#else
|
||||
#define _(string) (string)
|
||||
#define P_(singular, plural, number) (number == 1 ? singular : plural)
|
||||
#endif
|
||||
#define gettext_noop(string) (string)
|
||||
#define N_(string) gettext_noop(string)
|
||||
/* Mark a string that will be sent to gettext() later. */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#ifdef HAVE_REGEX_H
|
||||
#include <regex.h>
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
#include <setjmp.h>
|
||||
#endif
|
||||
#include <assert.h>
|
||||
|
||||
/* If no vsnprintf(), use the version from glib 2.x. */
|
||||
#ifndef HAVE_VSNPRINTF
|
||||
#include <glib.h>
|
||||
#define vsnprintf g_vsnprintf
|
||||
#endif
|
||||
|
||||
/* If no isblank(), iswblank(), strcasecmp(), strncasecmp(),
|
||||
* strcasestr(), strnlen(), getdelim(), or getline(), use the versions
|
||||
* we have. */
|
||||
#ifndef HAVE_ISBLANK
|
||||
#define isblank nisblank
|
||||
#endif
|
||||
#ifndef HAVE_ISWBLANK
|
||||
#define iswblank niswblank
|
||||
#endif
|
||||
#ifndef HAVE_STRCASECMP
|
||||
#define strcasecmp nstrcasecmp
|
||||
#endif
|
||||
#ifndef HAVE_STRNCASECMP
|
||||
#define strncasecmp nstrncasecmp
|
||||
#endif
|
||||
#ifndef HAVE_STRCASESTR
|
||||
#define strcasestr nstrcasestr
|
||||
#endif
|
||||
#ifndef HAVE_STRNLEN
|
||||
#define strnlen nstrnlen
|
||||
#endif
|
||||
#ifndef HAVE_GETDELIM
|
||||
#define getdelim ngetdelim
|
||||
#endif
|
||||
#ifndef HAVE_GETLINE
|
||||
#define getline ngetline
|
||||
#endif
|
||||
|
||||
/* If we aren't using ncurses with mouse support, turn the mouse support
|
||||
* off, as it's useless then. */
|
||||
#ifndef NCURSES_MOUSE_VERSION
|
||||
#define DISABLE_MOUSE 1
|
||||
#endif
|
||||
|
||||
#if defined(DISABLE_WRAPPING) && defined(DISABLE_JUSTIFY)
|
||||
#define DISABLE_WRAPJUSTIFY 1
|
||||
#endif
|
||||
|
||||
/* Enumeration types. */
|
||||
typedef enum {
|
||||
NIX_FILE, DOS_FILE, MAC_FILE
|
||||
} file_format;
|
||||
|
||||
typedef enum {
|
||||
OVERWRITE, APPEND, PREPEND
|
||||
} append_type;
|
||||
|
||||
typedef enum {
|
||||
UP_DIR, DOWN_DIR
|
||||
} scroll_dir;
|
||||
|
||||
typedef enum {
|
||||
CENTER, NONE
|
||||
} update_type;
|
||||
|
||||
/* Structure types. */
|
||||
typedef struct filestruct {
|
||||
char *data;
|
||||
/* The text of this line. */
|
||||
ssize_t lineno;
|
||||
/* The number of this line. */
|
||||
struct filestruct *next;
|
||||
/* Next node. */
|
||||
struct filestruct *prev;
|
||||
/* Previous node. */
|
||||
} filestruct;
|
||||
|
||||
typedef struct partition {
|
||||
filestruct *fileage;
|
||||
/* The top line of this portion of the file. */
|
||||
filestruct *top_prev;
|
||||
/* The line before the top line of this portion of the file. */
|
||||
char *top_data;
|
||||
/* The text before the beginning of the top line of this portion
|
||||
* of the file. */
|
||||
filestruct *filebot;
|
||||
/* The bottom line of this portion of the file. */
|
||||
filestruct *bot_next;
|
||||
/* The line after the bottom line of this portion of the
|
||||
* file. */
|
||||
char *bot_data;
|
||||
/* The text after the end of the bottom line of this portion of
|
||||
* the file. */
|
||||
} partition;
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
typedef struct colortype {
|
||||
short fg;
|
||||
/* This syntax's foreground color. */
|
||||
short bg;
|
||||
/* This syntax's background color. */
|
||||
bool bright;
|
||||
/* Is this color A_BOLD? */
|
||||
bool icase;
|
||||
/* Is this regex string case insensitive? */
|
||||
int pairnum;
|
||||
/* The color pair number used for this foreground color and
|
||||
* background color. */
|
||||
char *start_regex;
|
||||
/* The start (or all) of the regex string. */
|
||||
regex_t *start;
|
||||
/* The compiled start (or all) of the regex string. */
|
||||
char *end_regex;
|
||||
/* The end (if any) of the regex string. */
|
||||
regex_t *end;
|
||||
/* The compiled end (if any) of the regex string. */
|
||||
struct colortype *next;
|
||||
/* Next set of colors. */
|
||||
} colortype;
|
||||
|
||||
typedef struct exttype {
|
||||
char *ext_regex;
|
||||
/* The extensions that match this syntax. */
|
||||
regex_t *ext;
|
||||
/* The compiled extensions that match this syntax. */
|
||||
struct exttype *next;
|
||||
/* Next set of extensions. */
|
||||
} exttype;
|
||||
|
||||
typedef struct syntaxtype {
|
||||
char *desc;
|
||||
/* The name of this syntax. */
|
||||
exttype *extensions;
|
||||
/* The list of extensions that this syntax applies to. */
|
||||
colortype *color;
|
||||
/* The colors used in this syntax. */
|
||||
struct syntaxtype *next;
|
||||
/* Next syntax. */
|
||||
} syntaxtype;
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
typedef struct openfilestruct {
|
||||
char *filename;
|
||||
/* The current file's name. */
|
||||
filestruct *fileage;
|
||||
/* The current file's first line. */
|
||||
filestruct *filebot;
|
||||
/* The current file's last line. */
|
||||
filestruct *edittop;
|
||||
/* The current top of the edit window. */
|
||||
filestruct *current;
|
||||
/* The current file's current line. */
|
||||
size_t totsize;
|
||||
/* The current file's total number of characters. */
|
||||
size_t current_x;
|
||||
/* The current file's x-coordinate position. */
|
||||
size_t placewewant;
|
||||
/* The current file's place we want. */
|
||||
ssize_t current_y;
|
||||
/* The current file's y-coordinate position. */
|
||||
bool modified;
|
||||
/* Whether the current file has been modified. */
|
||||
#ifndef NANO_TINY
|
||||
bool mark_set;
|
||||
/* Whether the mark is on in the current file. */
|
||||
filestruct *mark_begin;
|
||||
/* The current file's beginning marked line, if any. */
|
||||
size_t mark_begin_x;
|
||||
/* The current file's beginning marked line's x-coordinate
|
||||
* position, if any. */
|
||||
file_format fmt;
|
||||
/* The current file's format. */
|
||||
struct stat *current_stat;
|
||||
/* The current file's stat. */
|
||||
#endif
|
||||
#ifdef ENABLE_COLOR
|
||||
colortype *colorstrings;
|
||||
/* The current file's associated colors. */
|
||||
#endif
|
||||
struct openfilestruct *next;
|
||||
/* Next node. */
|
||||
struct openfilestruct *prev;
|
||||
/* Previous node. */
|
||||
} openfilestruct;
|
||||
|
||||
typedef struct shortcut {
|
||||
const char *desc;
|
||||
/* The function's description, e.g. "Page Up". */
|
||||
#ifndef DISABLE_HELP
|
||||
const char *help;
|
||||
/* The help file entry text for this function. */
|
||||
bool blank_after;
|
||||
/* Whether there should be a blank line after the help entry
|
||||
* text for this function. */
|
||||
#endif
|
||||
/* Note: Key values that aren't used should be set to
|
||||
* NANO_NO_KEY. */
|
||||
int ctrlval;
|
||||
/* The special sentinel key or control key we want bound, if
|
||||
* any. */
|
||||
int metaval;
|
||||
/* The meta key we want bound, if any. */
|
||||
int funcval;
|
||||
/* The function key we want bound, if any. */
|
||||
int miscval;
|
||||
/* The other meta key we want bound, if any. */
|
||||
bool viewok;
|
||||
/* Is this function allowed when in view mode? */
|
||||
void (*func)(void);
|
||||
/* The function to call when we get this key. */
|
||||
struct shortcut *next;
|
||||
/* Next shortcut. */
|
||||
} shortcut;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
typedef struct toggle {
|
||||
int val;
|
||||
/* The sequence to toggle the key. We should only need one. */
|
||||
const char *desc;
|
||||
/* The description of the toggle, e.g. "Cut to end"; we'll
|
||||
* append Enabled or Disabled to it. */
|
||||
#ifndef DISABLE_HELP
|
||||
bool blank_after;
|
||||
/* Whether there should be a blank line after the description of
|
||||
* the toggle. */
|
||||
#endif
|
||||
long flag;
|
||||
/* Which flag actually gets toggled. */
|
||||
struct toggle *next;
|
||||
/* Next toggle. */
|
||||
} toggle;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_NANORC
|
||||
typedef struct rcoption {
|
||||
const char *name;
|
||||
/* The name of the rcfile option. */
|
||||
long flag;
|
||||
/* The flag associated with it, if any. */
|
||||
} rcoption;
|
||||
#endif
|
||||
|
||||
/* Bitwise flags so that we can save space (or, more correctly, not
|
||||
* waste it). */
|
||||
#define CASE_SENSITIVE (1<<0)
|
||||
#define CONST_UPDATE (1<<1)
|
||||
#define NO_HELP (1<<2)
|
||||
#define NOFOLLOW_SYMLINKS (1<<3)
|
||||
#define SUSPEND (1<<4)
|
||||
#define NO_WRAP (1<<5)
|
||||
#define AUTOINDENT (1<<6)
|
||||
#define VIEW_MODE (1<<7)
|
||||
#define USE_MOUSE (1<<8)
|
||||
#define USE_REGEXP (1<<9)
|
||||
#define TEMP_FILE (1<<10)
|
||||
#define CUT_TO_END (1<<11)
|
||||
#define BACKWARDS_SEARCH (1<<12)
|
||||
#define MULTIBUFFER (1<<13)
|
||||
#define SMOOTH_SCROLL (1<<14)
|
||||
#define REBIND_DELETE (1<<15)
|
||||
#define REBIND_KEYPAD (1<<16)
|
||||
#define NO_CONVERT (1<<17)
|
||||
#define BACKUP_FILE (1<<18)
|
||||
#define NO_COLOR_SYNTAX (1<<19)
|
||||
#define PRESERVE (1<<20)
|
||||
#define HISTORYLOG (1<<21)
|
||||
#define RESTRICTED (1<<22)
|
||||
#define SMART_HOME (1<<23)
|
||||
#define WHITESPACE_DISPLAY (1<<24)
|
||||
#define MORE_SPACE (1<<25)
|
||||
#define TABS_TO_SPACES (1<<26)
|
||||
#define QUICK_BLANK (1<<27)
|
||||
#define WORD_BOUNDS (1<<28)
|
||||
#define NO_NEWLINES (1<<29)
|
||||
#define BOLD_TEXT (1<<30)
|
||||
|
||||
/* Control key sequences. Changing these would be very, very bad. */
|
||||
#define NANO_CONTROL_SPACE 0
|
||||
#define NANO_CONTROL_A 1
|
||||
#define NANO_CONTROL_B 2
|
||||
#define NANO_CONTROL_C 3
|
||||
#define NANO_CONTROL_D 4
|
||||
#define NANO_CONTROL_E 5
|
||||
#define NANO_CONTROL_F 6
|
||||
#define NANO_CONTROL_G 7
|
||||
#define NANO_CONTROL_H 8
|
||||
#define NANO_CONTROL_I 9
|
||||
#define NANO_CONTROL_J 10
|
||||
#define NANO_CONTROL_K 11
|
||||
#define NANO_CONTROL_L 12
|
||||
#define NANO_CONTROL_M 13
|
||||
#define NANO_CONTROL_N 14
|
||||
#define NANO_CONTROL_O 15
|
||||
#define NANO_CONTROL_P 16
|
||||
#define NANO_CONTROL_Q 17
|
||||
#define NANO_CONTROL_R 18
|
||||
#define NANO_CONTROL_S 19
|
||||
#define NANO_CONTROL_T 20
|
||||
#define NANO_CONTROL_U 21
|
||||
#define NANO_CONTROL_V 22
|
||||
#define NANO_CONTROL_W 23
|
||||
#define NANO_CONTROL_X 24
|
||||
#define NANO_CONTROL_Y 25
|
||||
#define NANO_CONTROL_Z 26
|
||||
#define NANO_CONTROL_3 27
|
||||
#define NANO_CONTROL_4 28
|
||||
#define NANO_CONTROL_5 29
|
||||
#define NANO_CONTROL_6 30
|
||||
#define NANO_CONTROL_7 31
|
||||
#define NANO_CONTROL_8 127
|
||||
|
||||
/* Meta key sequences. */
|
||||
#define NANO_META_SPACE ' '
|
||||
#define NANO_META_LPARENTHESIS '('
|
||||
#define NANO_META_RPARENTHESIS ')'
|
||||
#define NANO_META_PLUS '+'
|
||||
#define NANO_META_COMMA ','
|
||||
#define NANO_META_MINUS '-'
|
||||
#define NANO_META_PERIOD '.'
|
||||
#define NANO_META_SLASH '/'
|
||||
#define NANO_META_0 '0'
|
||||
#define NANO_META_6 '6'
|
||||
#define NANO_META_9 '9'
|
||||
#define NANO_META_LCARET '<'
|
||||
#define NANO_META_EQUALS '='
|
||||
#define NANO_META_RCARET '>'
|
||||
#define NANO_META_QUESTION '?'
|
||||
#define NANO_META_BACKSLASH '\\'
|
||||
#define NANO_META_RBRACKET ']'
|
||||
#define NANO_META_CARET '^'
|
||||
#define NANO_META_UNDERSCORE '_'
|
||||
#define NANO_META_A 'a'
|
||||
#define NANO_META_B 'b'
|
||||
#define NANO_META_C 'c'
|
||||
#define NANO_META_D 'd'
|
||||
#define NANO_META_E 'e'
|
||||
#define NANO_META_F 'f'
|
||||
#define NANO_META_G 'g'
|
||||
#define NANO_META_H 'h'
|
||||
#define NANO_META_I 'i'
|
||||
#define NANO_META_J 'j'
|
||||
#define NANO_META_K 'k'
|
||||
#define NANO_META_L 'l'
|
||||
#define NANO_META_M 'm'
|
||||
#define NANO_META_N 'n'
|
||||
#define NANO_META_O 'o'
|
||||
#define NANO_META_P 'p'
|
||||
#define NANO_META_Q 'q'
|
||||
#define NANO_META_R 'r'
|
||||
#define NANO_META_S 's'
|
||||
#define NANO_META_T 't'
|
||||
#define NANO_META_U 'u'
|
||||
#define NANO_META_V 'v'
|
||||
#define NANO_META_W 'w'
|
||||
#define NANO_META_X 'x'
|
||||
#define NANO_META_Y 'y'
|
||||
#define NANO_META_Z 'z'
|
||||
#define NANO_META_LCURLYBRACKET '{'
|
||||
#define NANO_META_PIPE '|'
|
||||
#define NANO_META_RCURLYBRACKET '}'
|
||||
|
||||
/* Some semi-changeable keybindings; don't play with these unless you're
|
||||
* sure you know what you're doing. Assume ERR is defined as -1. */
|
||||
|
||||
/* No key at all. */
|
||||
#define NANO_NO_KEY -2
|
||||
|
||||
/* Normal keys. */
|
||||
#define NANO_XON_KEY NANO_CONTROL_Q
|
||||
#define NANO_XOFF_KEY NANO_CONTROL_S
|
||||
#define NANO_CANCEL_KEY NANO_CONTROL_C
|
||||
#define NANO_EXIT_KEY NANO_CONTROL_X
|
||||
#define NANO_EXIT_FKEY KEY_F(2)
|
||||
#define NANO_INSERTFILE_KEY NANO_CONTROL_R
|
||||
#define NANO_INSERTFILE_FKEY KEY_F(5)
|
||||
#define NANO_TOOTHERINSERT_KEY NANO_CONTROL_X
|
||||
#define NANO_WRITEOUT_KEY NANO_CONTROL_O
|
||||
#define NANO_WRITEOUT_FKEY KEY_F(3)
|
||||
#define NANO_GOTOLINE_KEY NANO_CONTROL_7
|
||||
#define NANO_GOTOLINE_FKEY KEY_F(13)
|
||||
#define NANO_GOTOLINE_METAKEY NANO_META_G
|
||||
#define NANO_GOTODIR_KEY NANO_CONTROL_7
|
||||
#define NANO_GOTODIR_FKEY KEY_F(13)
|
||||
#define NANO_GOTODIR_METAKEY NANO_META_G
|
||||
#define NANO_TOGOTOLINE_KEY NANO_CONTROL_T
|
||||
#define NANO_HELP_KEY NANO_CONTROL_G
|
||||
#define NANO_HELP_FKEY KEY_F(1)
|
||||
#define NANO_WHEREIS_KEY NANO_CONTROL_W
|
||||
#define NANO_WHEREIS_FKEY KEY_F(6)
|
||||
#define NANO_WHEREIS_NEXT_KEY NANO_META_W
|
||||
#define NANO_WHEREIS_NEXT_FKEY KEY_F(16)
|
||||
#define NANO_TOOTHERWHEREIS_KEY NANO_CONTROL_T
|
||||
#define NANO_REGEXP_KEY NANO_META_R
|
||||
#define NANO_REPLACE_KEY NANO_CONTROL_4
|
||||
#define NANO_REPLACE_FKEY KEY_F(14)
|
||||
#define NANO_REPLACE_METAKEY NANO_META_R
|
||||
#define NANO_TOOTHERSEARCH_KEY NANO_CONTROL_R
|
||||
#define NANO_PREVPAGE_KEY NANO_CONTROL_Y
|
||||
#define NANO_PREVPAGE_FKEY KEY_F(7)
|
||||
#define NANO_NEXTPAGE_KEY NANO_CONTROL_V
|
||||
#define NANO_NEXTPAGE_FKEY KEY_F(8)
|
||||
#define NANO_CUT_KEY NANO_CONTROL_K
|
||||
#define NANO_CUT_FKEY KEY_F(9)
|
||||
#define NANO_COPY_KEY NANO_META_CARET
|
||||
#define NANO_COPY_METAKEY NANO_META_6
|
||||
#define NANO_UNCUT_KEY NANO_CONTROL_U
|
||||
#define NANO_UNCUT_FKEY KEY_F(10)
|
||||
#define NANO_CURSORPOS_KEY NANO_CONTROL_C
|
||||
#define NANO_CURSORPOS_FKEY KEY_F(11)
|
||||
#define NANO_SPELL_KEY NANO_CONTROL_T
|
||||
#define NANO_SPELL_FKEY KEY_F(12)
|
||||
#define NANO_FIRSTLINE_KEY NANO_PREVPAGE_KEY
|
||||
#define NANO_FIRSTLINE_FKEY NANO_PREVPAGE_FKEY
|
||||
#define NANO_FIRSTLINE_METAKEY NANO_META_BACKSLASH
|
||||
#define NANO_FIRSTLINE_METAKEY2 NANO_META_PIPE
|
||||
#define NANO_FIRSTFILE_KEY NANO_FIRSTLINE_KEY
|
||||
#define NANO_FIRSTFILE_FKEY NANO_FIRSTLINE_FKEY
|
||||
#define NANO_FIRSTFILE_METAKEY NANO_FIRSTLINE_METAKEY
|
||||
#define NANO_FIRSTFILE_METAKEY2 NANO_FIRSTLINE_METAKEY2
|
||||
#define NANO_LASTLINE_KEY NANO_NEXTPAGE_KEY
|
||||
#define NANO_LASTLINE_FKEY NANO_NEXTPAGE_FKEY
|
||||
#define NANO_LASTLINE_METAKEY NANO_META_SLASH
|
||||
#define NANO_LASTLINE_METAKEY2 NANO_META_QUESTION
|
||||
#define NANO_LASTFILE_KEY NANO_LASTLINE_KEY
|
||||
#define NANO_LASTFILE_FKEY NANO_LASTLINE_FKEY
|
||||
#define NANO_LASTFILE_METAKEY NANO_LASTLINE_METAKEY
|
||||
#define NANO_LASTFILE_METAKEY2 NANO_LASTLINE_METAKEY2
|
||||
#define NANO_REFRESH_KEY NANO_CONTROL_L
|
||||
#define NANO_JUSTIFY_KEY NANO_CONTROL_J
|
||||
#define NANO_JUSTIFY_FKEY KEY_F(4)
|
||||
#define NANO_UNJUSTIFY_KEY NANO_UNCUT_KEY
|
||||
#define NANO_UNJUSTIFY_FKEY NANO_UNCUT_FKEY
|
||||
#define NANO_PREVLINE_KEY NANO_CONTROL_P
|
||||
#define NANO_NEXTLINE_KEY NANO_CONTROL_N
|
||||
#define NANO_FORWARD_KEY NANO_CONTROL_F
|
||||
#define NANO_BACK_KEY NANO_CONTROL_B
|
||||
#define NANO_MARK_KEY NANO_CONTROL_6
|
||||
#define NANO_MARK_METAKEY NANO_META_A
|
||||
#define NANO_MARK_FKEY KEY_F(15)
|
||||
#define NANO_HOME_KEY NANO_CONTROL_A
|
||||
#define NANO_END_KEY NANO_CONTROL_E
|
||||
#define NANO_DELETE_KEY NANO_CONTROL_D
|
||||
#define NANO_BACKSPACE_KEY NANO_CONTROL_H
|
||||
#define NANO_TAB_KEY NANO_CONTROL_I
|
||||
#define NANO_INDENT_KEY NANO_META_RCURLYBRACKET
|
||||
#define NANO_UNINDENT_KEY NANO_META_LCURLYBRACKET
|
||||
#define NANO_SUSPEND_KEY NANO_CONTROL_Z
|
||||
#define NANO_ENTER_KEY NANO_CONTROL_M
|
||||
#define NANO_TOFILES_KEY NANO_CONTROL_T
|
||||
#define NANO_APPEND_KEY NANO_META_A
|
||||
#define NANO_PREPEND_KEY NANO_META_P
|
||||
#define NANO_PREVFILE_KEY NANO_META_LCARET
|
||||
#define NANO_PREVFILE_METAKEY NANO_META_COMMA
|
||||
#define NANO_NEXTFILE_KEY NANO_META_RCARET
|
||||
#define NANO_NEXTFILE_METAKEY NANO_META_PERIOD
|
||||
#define NANO_BRACKET_KEY NANO_META_RBRACKET
|
||||
#define NANO_NEXTWORD_KEY NANO_CONTROL_SPACE
|
||||
#define NANO_PREVWORD_KEY NANO_META_SPACE
|
||||
#define NANO_WORDCOUNT_KEY NANO_META_D
|
||||
#define NANO_SCROLLUP_KEY NANO_META_MINUS
|
||||
#define NANO_SCROLLDOWN_KEY NANO_META_PLUS
|
||||
#define NANO_SCROLLUP_METAKEY NANO_META_UNDERSCORE
|
||||
#define NANO_SCROLLDOWN_METAKEY NANO_META_EQUALS
|
||||
#define NANO_CUTTILLEND_METAKEY NANO_META_T
|
||||
#define NANO_PARABEGIN_KEY NANO_CONTROL_W
|
||||
#define NANO_PARABEGIN_METAKEY NANO_META_LPARENTHESIS
|
||||
#define NANO_PARABEGIN_METAKEY2 NANO_META_9
|
||||
#define NANO_PARAEND_KEY NANO_CONTROL_O
|
||||
#define NANO_PARAEND_METAKEY NANO_META_RPARENTHESIS
|
||||
#define NANO_PARAEND_METAKEY2 NANO_META_0
|
||||
#define NANO_FULLJUSTIFY_KEY NANO_CONTROL_U
|
||||
#define NANO_FULLJUSTIFY_METAKEY NANO_META_J
|
||||
#define NANO_VERBATIM_KEY NANO_META_V
|
||||
|
||||
/* Toggles do not exist if NANO_TINY is defined. */
|
||||
#ifndef NANO_TINY
|
||||
|
||||
/* No toggle at all. */
|
||||
#define TOGGLE_NO_KEY -2
|
||||
|
||||
/* Normal toggles. */
|
||||
#define TOGGLE_NOHELP_KEY NANO_META_X
|
||||
#define TOGGLE_CONST_KEY NANO_META_C
|
||||
#define TOGGLE_MORESPACE_KEY NANO_META_O
|
||||
#define TOGGLE_SMOOTH_KEY NANO_META_S
|
||||
#define TOGGLE_WHITESPACE_KEY NANO_META_P
|
||||
#define TOGGLE_SYNTAX_KEY NANO_META_Y
|
||||
#define TOGGLE_SMARTHOME_KEY NANO_META_H
|
||||
#define TOGGLE_AUTOINDENT_KEY NANO_META_I
|
||||
#define TOGGLE_CUTTOEND_KEY NANO_META_K
|
||||
#define TOGGLE_WRAP_KEY NANO_META_L
|
||||
#define TOGGLE_TABSTOSPACES_KEY NANO_META_Q
|
||||
#define TOGGLE_BACKUP_KEY NANO_META_B
|
||||
#define TOGGLE_MULTIBUFFER_KEY NANO_META_F
|
||||
#define TOGGLE_MOUSE_KEY NANO_META_M
|
||||
#define TOGGLE_NOCONVERT_KEY NANO_META_N
|
||||
#define TOGGLE_SUSPEND_KEY NANO_META_Z
|
||||
#define TOGGLE_CASE_KEY NANO_META_C
|
||||
#define TOGGLE_BACKWARDS_KEY NANO_META_B
|
||||
#define TOGGLE_DOS_KEY NANO_META_D
|
||||
#define TOGGLE_MAC_KEY NANO_META_M
|
||||
#endif /* !NANO_TINY */
|
||||
|
||||
#define VIEW TRUE
|
||||
#define NOVIEW FALSE
|
||||
|
||||
/* The maximum number of entries displayed in the main shortcut list. */
|
||||
#define MAIN_VISIBLE 12
|
||||
|
||||
/* The minimum editor window columns and rows required for nano to work
|
||||
* correctly. */
|
||||
#define MIN_EDITOR_COLS 4
|
||||
#define MIN_EDITOR_ROWS 1
|
||||
|
||||
/* The default number of characters from the end of the line where
|
||||
* wrapping occurs. */
|
||||
#define CHARS_FROM_EOL 8
|
||||
|
||||
/* The default width of a tab in spaces. */
|
||||
#define WIDTH_OF_TAB 8
|
||||
|
||||
/* The maximum number of search/replace history strings saved, not
|
||||
* counting the blank lines at their ends. */
|
||||
#define MAX_SEARCH_HISTORY 100
|
||||
|
||||
/* The maximum number of bytes buffered at one time. */
|
||||
#define MAX_BUF_SIZE 128
|
||||
|
||||
#endif /* !NANO_H */
|
1385
src/prompt.c
Normal file
1385
src/prompt.c
Normal file
File diff suppressed because it is too large
Load Diff
793
src/proto.h
Normal file
793
src/proto.h
Normal file
@ -0,0 +1,793 @@
|
||||
/* $Id: proto.h,v 1.372 2007/01/11 21:36:29 dolorous Exp $ */
|
||||
/**************************************************************************
|
||||
* proto.h *
|
||||
* *
|
||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Chris Allegretta *
|
||||
* Copyright (C) 2005, 2006, 2007 David Lawrence Ramsey *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2, or (at your option) *
|
||||
* any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
|
||||
* 02110-1301, USA. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef PROTO_H
|
||||
#define PROTO_H 1
|
||||
|
||||
#include "nano.h"
|
||||
|
||||
/* All external variables. See global.c for their descriptions. */
|
||||
#ifndef NANO_TINY
|
||||
extern sigjmp_buf jump_buf;
|
||||
extern bool jump_buf_main;
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_WRAPJUSTIFY
|
||||
extern ssize_t fill;
|
||||
extern ssize_t wrap_at;
|
||||
#endif
|
||||
|
||||
extern char *last_search;
|
||||
extern char *last_replace;
|
||||
|
||||
extern long flags;
|
||||
extern WINDOW *topwin;
|
||||
extern WINDOW *edit;
|
||||
extern WINDOW *bottomwin;
|
||||
extern int editwinrows;
|
||||
|
||||
extern filestruct *cutbuffer;
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
extern filestruct *jusbuffer;
|
||||
#endif
|
||||
extern partition *filepart;
|
||||
extern openfilestruct *openfile;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
extern char *matchbrackets;
|
||||
#endif
|
||||
|
||||
#if !defined(NANO_TINY) && defined(ENABLE_NANORC)
|
||||
extern char *whitespace;
|
||||
extern int whitespace_len[2];
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
extern char *punct;
|
||||
extern char *brackets;
|
||||
extern char *quotestr;
|
||||
#ifdef HAVE_REGEX_H
|
||||
extern regex_t quotereg;
|
||||
extern int quoterc;
|
||||
extern char *quoteerr;
|
||||
#else
|
||||
extern size_t quotelen;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern char *answer;
|
||||
|
||||
extern ssize_t tabsize;
|
||||
|
||||
#ifndef NANO_TINY
|
||||
extern char *backup_dir;
|
||||
#endif
|
||||
#ifndef DISABLE_OPERATINGDIR
|
||||
extern char *operating_dir;
|
||||
extern char *full_operating_dir;
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_SPELLER
|
||||
extern char *alt_speller;
|
||||
#endif
|
||||
|
||||
extern shortcut *main_list;
|
||||
extern shortcut *whereis_list;
|
||||
extern shortcut *replace_list;
|
||||
extern shortcut *replace_list_2;
|
||||
extern shortcut *gotoline_list;
|
||||
extern shortcut *writefile_list;
|
||||
extern shortcut *insertfile_list;
|
||||
#ifndef NANO_TINY
|
||||
extern shortcut *extcmd_list;
|
||||
#endif
|
||||
#ifndef DISABLE_HELP
|
||||
extern shortcut *help_list;
|
||||
#endif
|
||||
#ifndef DISABLE_SPELLER
|
||||
extern shortcut *spell_list;
|
||||
#endif
|
||||
#ifndef DISABLE_BROWSER
|
||||
extern shortcut *browser_list;
|
||||
extern shortcut *whereis_file_list;
|
||||
extern shortcut *gotodir_list;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
extern syntaxtype *syntaxes;
|
||||
extern char *syntaxstr;
|
||||
#endif
|
||||
|
||||
extern const shortcut *currshortcut;
|
||||
#ifndef NANO_TINY
|
||||
extern toggle *toggles;
|
||||
#endif
|
||||
|
||||
#ifndef NANO_TINY
|
||||
extern filestruct *search_history;
|
||||
extern filestruct *searchage;
|
||||
extern filestruct *searchbot;
|
||||
extern filestruct *replace_history;
|
||||
extern filestruct *replaceage;
|
||||
extern filestruct *replacebot;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_REGEX_H
|
||||
extern regex_t search_regexp;
|
||||
extern regmatch_t regmatches[10];
|
||||
#endif
|
||||
|
||||
extern int reverse_attr;
|
||||
|
||||
extern char *homedir;
|
||||
|
||||
/* All functions in browser.c. */
|
||||
#ifndef DISABLE_BROWSER
|
||||
char *do_browser(char *path, DIR *dir);
|
||||
char *do_browse_from(const char *inpath);
|
||||
void browser_init(const char *path, DIR *dir);
|
||||
void parse_browser_input(int *kbinput, bool *meta_key, bool *func_key);
|
||||
void browser_refresh(void);
|
||||
bool browser_select_filename(const char *needle);
|
||||
int filesearch_init(void);
|
||||
bool findnextfile(bool no_sameline, size_t begin, const char *needle);
|
||||
void findnextfile_wrap_reset(void);
|
||||
void filesearch_abort(void);
|
||||
void do_filesearch(void);
|
||||
void do_fileresearch(void);
|
||||
void do_first_file(void);
|
||||
void do_last_file(void);
|
||||
char *striponedir(const char *path);
|
||||
#endif
|
||||
|
||||
/* All functions in chars.c. */
|
||||
#ifdef ENABLE_UTF8
|
||||
void utf8_init(void);
|
||||
bool using_utf8(void);
|
||||
#endif
|
||||
#ifndef HAVE_ISBLANK
|
||||
bool nisblank(int c);
|
||||
#endif
|
||||
#if !defined(HAVE_ISWBLANK) && defined(ENABLE_UTF8)
|
||||
bool niswblank(wchar_t wc);
|
||||
#endif
|
||||
bool is_byte(int c);
|
||||
bool is_alnum_mbchar(const char *c);
|
||||
bool is_blank_mbchar(const char *c);
|
||||
bool is_ascii_cntrl_char(int c);
|
||||
bool is_cntrl_char(int c);
|
||||
#ifdef ENABLE_UTF8
|
||||
bool is_cntrl_wchar(wchar_t wc);
|
||||
#endif
|
||||
bool is_cntrl_mbchar(const char *c);
|
||||
bool is_punct_mbchar(const char *c);
|
||||
bool is_word_mbchar(const char *c, bool allow_punct);
|
||||
char control_rep(char c);
|
||||
#ifdef ENABLE_UTF8
|
||||
wchar_t control_wrep(wchar_t c);
|
||||
#endif
|
||||
char *control_mbrep(const char *c, char *crep, int *crep_len);
|
||||
char *mbrep(const char *c, char *crep, int *crep_len);
|
||||
int mbwidth(const char *c);
|
||||
int mb_cur_max(void);
|
||||
char *make_mbchar(long chr, int *chr_mb_len);
|
||||
int parse_mbchar(const char *buf, char *chr, size_t *col);
|
||||
size_t move_mbleft(const char *buf, size_t pos);
|
||||
size_t move_mbright(const char *buf, size_t pos);
|
||||
#ifndef HAVE_STRCASECMP
|
||||
int nstrcasecmp(const char *s1, const char *s2);
|
||||
#endif
|
||||
int mbstrcasecmp(const char *s1, const char *s2);
|
||||
#ifndef HAVE_STRNCASECMP
|
||||
int nstrncasecmp(const char *s1, const char *s2, size_t n);
|
||||
#endif
|
||||
int mbstrncasecmp(const char *s1, const char *s2, size_t n);
|
||||
#ifndef HAVE_STRCASESTR
|
||||
const char *nstrcasestr(const char *haystack, const char *needle);
|
||||
#endif
|
||||
const char *mbstrcasestr(const char *haystack, const char *needle);
|
||||
#if !defined(NANO_TINY) || !defined(DISABLE_TABCOMP)
|
||||
const char *revstrstr(const char *haystack, const char *needle, const
|
||||
char *rev_start);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
const char *revstrcasestr(const char *haystack, const char *needle,
|
||||
const char *rev_start);
|
||||
const char *mbrevstrcasestr(const char *haystack, const char *needle,
|
||||
const char *rev_start);
|
||||
#endif
|
||||
size_t mbstrlen(const char *s);
|
||||
#ifndef HAVE_STRNLEN
|
||||
size_t nstrnlen(const char *s, size_t maxlen);
|
||||
#endif
|
||||
size_t mbstrnlen(const char *s, size_t maxlen);
|
||||
#if !defined(NANO_TINY) || !defined(DISABLE_JUSTIFY)
|
||||
char *mbstrchr(const char *s, const char *c);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
char *mbstrpbrk(const char *s, const char *accept);
|
||||
char *revstrpbrk(const char *s, const char *accept, const char
|
||||
*rev_start);
|
||||
char *mbrevstrpbrk(const char *s, const char *accept, const char
|
||||
*rev_start);
|
||||
#endif
|
||||
#if defined(ENABLE_NANORC) && (!defined(NANO_TINY) || !defined(DISABLE_JUSTIFY))
|
||||
bool has_blank_chars(const char *s);
|
||||
bool has_blank_mbchars(const char *s);
|
||||
#endif
|
||||
#ifdef ENABLE_UTF8
|
||||
bool is_valid_unicode(wchar_t wc);
|
||||
#endif
|
||||
#ifdef ENABLE_NANORC
|
||||
bool is_valid_mbstring(const char *s);
|
||||
#endif
|
||||
|
||||
/* All functions in color.c. */
|
||||
#ifdef ENABLE_COLOR
|
||||
void set_colorpairs(void);
|
||||
void color_init(void);
|
||||
void color_update(void);
|
||||
#endif
|
||||
|
||||
/* All functions in cut.c. */
|
||||
void cutbuffer_reset(void);
|
||||
void cut_line(void);
|
||||
#ifndef NANO_TINY
|
||||
void cut_marked(void);
|
||||
void cut_to_eol(void);
|
||||
void cut_to_eof(void);
|
||||
#endif
|
||||
void do_cut_text(
|
||||
#ifndef NANO_TINY
|
||||
bool copy_text, bool cut_till_end
|
||||
#else
|
||||
void
|
||||
#endif
|
||||
);
|
||||
void do_cut_text_void(void);
|
||||
#ifndef NANO_TINY
|
||||
void do_copy_text(void);
|
||||
void do_cut_till_end(void);
|
||||
#endif
|
||||
void do_uncut_text(void);
|
||||
|
||||
/* All functions in files.c. */
|
||||
void make_new_buffer(void);
|
||||
void initialize_buffer(void);
|
||||
void initialize_buffer_text(void);
|
||||
void open_buffer(const char *filename);
|
||||
#ifndef DISABLE_SPELLER
|
||||
void replace_buffer(const char *filename);
|
||||
#endif
|
||||
void display_buffer(void);
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
void switch_to_prevnext_buffer(bool next);
|
||||
void switch_to_prev_buffer_void(void);
|
||||
void switch_to_next_buffer_void(void);
|
||||
bool close_buffer(void);
|
||||
#endif
|
||||
filestruct *read_line(char *buf, filestruct *prevnode, bool
|
||||
*first_line_ins, size_t buf_len);
|
||||
void read_file(FILE *f, const char *filename);
|
||||
int open_file(const char *filename, bool newfie, FILE **f);
|
||||
char *get_next_filename(const char *name, const char *suffix);
|
||||
void do_insertfile(
|
||||
#ifndef NANO_TINY
|
||||
bool execute
|
||||
#else
|
||||
void
|
||||
#endif
|
||||
);
|
||||
void do_insertfile_void(void);
|
||||
char *get_full_path(const char *origpath);
|
||||
char *check_writable_directory(const char *path);
|
||||
char *safe_tempfile(FILE **f);
|
||||
#ifndef DISABLE_OPERATINGDIR
|
||||
void init_operating_dir(void);
|
||||
bool check_operating_dir(const char *currpath, bool allow_tabcomp);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
void init_backup_dir(void);
|
||||
#endif
|
||||
int copy_file(FILE *inn, FILE *out);
|
||||
bool write_file(const char *name, FILE *f_open, bool tmp, append_type
|
||||
append, bool nonamechange);
|
||||
#ifndef NANO_TINY
|
||||
bool write_marked_file(const char *name, FILE *f_open, bool tmp,
|
||||
append_type append);
|
||||
#endif
|
||||
bool do_writeout(bool exiting);
|
||||
void do_writeout_void(void);
|
||||
char *real_dir_from_tilde(const char *buf);
|
||||
#if !defined(DISABLE_TABCOMP) || !defined(DISABLE_BROWSER)
|
||||
int diralphasort(const void *va, const void *vb);
|
||||
void free_chararray(char **array, size_t len);
|
||||
#endif
|
||||
#ifndef DISABLE_TABCOMP
|
||||
bool is_dir(const char *buf);
|
||||
char **username_tab_completion(const char *buf, size_t *num_matches,
|
||||
size_t buflen);
|
||||
char **cwd_tab_completion(const char *buf, bool allow_files, size_t
|
||||
*num_matches, size_t buflen);
|
||||
char *input_tab(char *buf, bool allow_files, size_t *place, bool
|
||||
*lastwastab, void (*refresh_func)(void), bool *list);
|
||||
#endif
|
||||
const char *tail(const char *foo);
|
||||
#if !defined(NANO_TINY) && defined(ENABLE_NANORC)
|
||||
char *histfilename(void);
|
||||
void load_history(void);
|
||||
bool writehist(FILE *hist, filestruct *histhead);
|
||||
void save_history(void);
|
||||
#endif
|
||||
|
||||
/* All functions in global.c. */
|
||||
size_t length_of_list(const shortcut *s);
|
||||
#ifndef NANO_TINY
|
||||
void toggle_init_one(int val
|
||||
#ifndef DISABLE_HELP
|
||||
, const char *desc, bool blank_after
|
||||
#endif
|
||||
, long flag);
|
||||
void toggle_init(void);
|
||||
#endif
|
||||
void sc_init_one(shortcut **shortcutage, int ctrlval, const char *desc
|
||||
#ifndef DISABLE_HELP
|
||||
, const char *help, bool blank_after
|
||||
#endif
|
||||
, int metaval, int funcval, int miscval, bool view, void
|
||||
(*func)(void));
|
||||
void shortcut_init(bool unjustify);
|
||||
void free_shortcutage(shortcut **shortcutage);
|
||||
#ifdef DEBUG
|
||||
void thanks_for_all_the_fish(void);
|
||||
#endif
|
||||
|
||||
/* All functions in help.c. */
|
||||
#ifndef DISABLE_HELP
|
||||
void do_help(void (*refresh_func)(void));
|
||||
void do_help_void(void);
|
||||
#ifndef DISABLE_BROWSER
|
||||
void do_browser_help(void);
|
||||
#endif
|
||||
void help_init(void);
|
||||
void parse_help_input(int *kbinput, bool *meta_key, bool *func_key);
|
||||
size_t help_line_len(const char *ptr);
|
||||
#endif
|
||||
|
||||
/* All functions in move.c. */
|
||||
void do_first_line(void);
|
||||
void do_last_line(void);
|
||||
void do_page_up(void);
|
||||
void do_page_down(void);
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
void do_para_begin(bool allow_update);
|
||||
void do_para_begin_void(void);
|
||||
void do_para_end(bool allow_update);
|
||||
void do_para_end_void(void);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
bool do_next_word(bool allow_punct, bool allow_update);
|
||||
void do_next_word_void(void);
|
||||
bool do_prev_word(bool allow_punct, bool allow_update);
|
||||
void do_prev_word_void(void);
|
||||
#endif
|
||||
void do_home(void);
|
||||
void do_end(void);
|
||||
void do_up(
|
||||
#ifndef NANO_TINY
|
||||
bool scroll_only
|
||||
#else
|
||||
void
|
||||
#endif
|
||||
);
|
||||
void do_up_void(void);
|
||||
#ifndef NANO_TINY
|
||||
void do_scroll_up(void);
|
||||
#endif
|
||||
void do_down(
|
||||
#ifndef NANO_TINY
|
||||
bool scroll_only
|
||||
#else
|
||||
void
|
||||
#endif
|
||||
);
|
||||
void do_down_void(void);
|
||||
#ifndef NANO_TINY
|
||||
void do_scroll_down(void);
|
||||
#endif
|
||||
void do_left(void);
|
||||
void do_right(void);
|
||||
|
||||
/* All functions in nano.c. */
|
||||
filestruct *make_new_node(filestruct *prevnode);
|
||||
filestruct *copy_node(const filestruct *src);
|
||||
void splice_node(filestruct *begin, filestruct *newnode, filestruct
|
||||
*end);
|
||||
void unlink_node(const filestruct *fileptr);
|
||||
void delete_node(filestruct *fileptr);
|
||||
filestruct *copy_filestruct(const filestruct *src);
|
||||
void free_filestruct(filestruct *src);
|
||||
void renumber(filestruct *fileptr);
|
||||
partition *partition_filestruct(filestruct *top, size_t top_x,
|
||||
filestruct *bot, size_t bot_x);
|
||||
void unpartition_filestruct(partition **p);
|
||||
void move_to_filestruct(filestruct **file_top, filestruct **file_bot,
|
||||
filestruct *top, size_t top_x, filestruct *bot, size_t bot_x);
|
||||
void copy_from_filestruct(filestruct *file_top, filestruct *file_bot);
|
||||
openfilestruct *make_new_opennode(void);
|
||||
void splice_opennode(openfilestruct *begin, openfilestruct *newnode,
|
||||
openfilestruct *end);
|
||||
void unlink_opennode(openfilestruct *fileptr);
|
||||
void delete_opennode(openfilestruct *fileptr);
|
||||
#ifdef DEBUG
|
||||
void free_openfilestruct(openfilestruct *src);
|
||||
#endif
|
||||
void print_view_warning(void);
|
||||
void finish(void);
|
||||
void die(const char *msg, ...);
|
||||
void die_save_file(const char *die_filename);
|
||||
void window_init(void);
|
||||
#ifndef DISABLE_MOUSE
|
||||
void disable_mouse_support(void);
|
||||
void enable_mouse_support(void);
|
||||
void mouse_init(void);
|
||||
#endif
|
||||
void print_opt_full(const char *shortflag
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
, const char *longflag
|
||||
#endif
|
||||
, const char *desc);
|
||||
void usage(void);
|
||||
void version(void);
|
||||
int no_more_space(void);
|
||||
int no_help(void);
|
||||
void nano_disabled_msg(void);
|
||||
void do_exit(void);
|
||||
void signal_init(void);
|
||||
RETSIGTYPE handle_hupterm(int signal);
|
||||
RETSIGTYPE do_suspend(int signal);
|
||||
RETSIGTYPE do_continue(int signal);
|
||||
#ifndef NANO_TINY
|
||||
RETSIGTYPE handle_sigwinch(int signal);
|
||||
void allow_pending_sigwinch(bool allow);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
void do_toggle(const toggle *which);
|
||||
#endif
|
||||
void disable_extended_io(void);
|
||||
void disable_signals(void);
|
||||
#ifndef NANO_TINY
|
||||
void enable_signals(void);
|
||||
#endif
|
||||
void disable_flow_control(void);
|
||||
void enable_flow_control(void);
|
||||
void terminal_init(void);
|
||||
int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
|
||||
*ran_func, bool *finished, bool allow_funcs);
|
||||
#ifndef DISABLE_MOUSE
|
||||
bool do_mouse(void);
|
||||
#endif
|
||||
void do_output(char *output, size_t output_len, bool allow_cntrls);
|
||||
|
||||
/* All functions in prompt.c. */
|
||||
int do_statusbar_input(bool *meta_key, bool *func_key, bool *s_or_t,
|
||||
bool *ran_func, bool *finished, bool allow_funcs, void
|
||||
(*refresh_func)(void));
|
||||
#ifndef DISABLE_MOUSE
|
||||
bool do_statusbar_mouse(void);
|
||||
#endif
|
||||
void do_statusbar_output(char *output, size_t output_len, bool
|
||||
*got_enter, bool allow_cntrls);
|
||||
void do_statusbar_home(void);
|
||||
void do_statusbar_end(void);
|
||||
void do_statusbar_left(void);
|
||||
void do_statusbar_right(void);
|
||||
void do_statusbar_backspace(void);
|
||||
void do_statusbar_delete(void);
|
||||
void do_statusbar_cut_text(void);
|
||||
#ifndef NANO_TINY
|
||||
bool do_statusbar_next_word(bool allow_punct);
|
||||
bool do_statusbar_prev_word(bool allow_punct);
|
||||
#endif
|
||||
void do_statusbar_verbatim_input(bool *got_enter);
|
||||
#ifndef NANO_TINY
|
||||
bool find_statusbar_bracket_match(bool reverse, const char
|
||||
*bracket_set);
|
||||
void do_statusbar_find_bracket(void);
|
||||
#endif
|
||||
size_t statusbar_xplustabs(void);
|
||||
size_t get_statusbar_page_start(size_t start_col, size_t column);
|
||||
void reset_statusbar_cursor(void);
|
||||
void update_statusbar_line(const char *curranswer, size_t index);
|
||||
bool need_statusbar_horizontal_update(size_t pww_save);
|
||||
void total_statusbar_refresh(void (*refresh_func)(void));
|
||||
int get_prompt_string(bool allow_tabs,
|
||||
#ifndef DISABLE_TABCOMP
|
||||
bool allow_files,
|
||||
#endif
|
||||
const char *curranswer,
|
||||
#ifndef NANO_TINY
|
||||
filestruct **history_list,
|
||||
#endif
|
||||
void (*refresh_func)(void), const shortcut *s
|
||||
#ifndef DISABLE_TABCOMP
|
||||
, bool *list
|
||||
#endif
|
||||
);
|
||||
int do_prompt(bool allow_tabs,
|
||||
#ifndef DISABLE_TABCOMP
|
||||
bool allow_files,
|
||||
#endif
|
||||
const shortcut *s, const char *curranswer,
|
||||
#ifndef NANO_TINY
|
||||
filestruct **history_list,
|
||||
#endif
|
||||
void (*refresh_func)(void), const char *msg, ...);
|
||||
void do_prompt_abort(void);
|
||||
int do_yesno_prompt(bool all, const char *msg);
|
||||
|
||||
/* All functions in rcfile.c. */
|
||||
#ifdef ENABLE_NANORC
|
||||
void rcfile_error(const char *msg, ...);
|
||||
char *parse_next_word(char *ptr);
|
||||
char *parse_argument(char *ptr);
|
||||
#ifdef ENABLE_COLOR
|
||||
char *parse_next_regex(char *ptr);
|
||||
bool nregcomp(const char *regex, int eflags);
|
||||
void parse_syntax(char *ptr);
|
||||
void parse_include(char *ptr);
|
||||
short color_to_short(const char *colorname, bool *bright);
|
||||
void parse_colors(char *ptr, bool icase);
|
||||
#endif
|
||||
void parse_rcfile(FILE *rcstream
|
||||
#ifdef ENABLE_COLOR
|
||||
, bool syntax_only
|
||||
#endif
|
||||
);
|
||||
void do_rcfile(void);
|
||||
#endif
|
||||
|
||||
/* All functions in search.c. */
|
||||
#ifdef HAVE_REGEX_H
|
||||
bool regexp_init(const char *regexp);
|
||||
void regexp_cleanup(void);
|
||||
#endif
|
||||
void not_found_msg(const char *str);
|
||||
void search_replace_abort(void);
|
||||
void search_init_globals(void);
|
||||
int search_init(bool replacing, bool use_answer);
|
||||
bool findnextstr(
|
||||
#ifndef DISABLE_SPELLER
|
||||
bool whole_word,
|
||||
#endif
|
||||
bool no_sameline, const filestruct *begin, size_t begin_x, const
|
||||
char *needle, size_t *needle_len);
|
||||
void findnextstr_wrap_reset(void);
|
||||
void do_search(void);
|
||||
#ifndef NANO_TINY
|
||||
void do_research(void);
|
||||
#endif
|
||||
#ifdef HAVE_REGEX_H
|
||||
int replace_regexp(char *string, bool create);
|
||||
#endif
|
||||
char *replace_line(const char *needle);
|
||||
ssize_t do_replace_loop(
|
||||
#ifndef DISABLE_SPELLER
|
||||
bool whole_word,
|
||||
#endif
|
||||
bool *canceled, const filestruct *real_current, size_t
|
||||
*real_current_x, const char *needle);
|
||||
void do_replace(void);
|
||||
void do_gotolinecolumn(ssize_t line, ssize_t column, bool use_answer,
|
||||
bool interactive, bool save_pos, bool allow_update);
|
||||
void do_gotolinecolumn_void(void);
|
||||
#ifndef DISABLE_SPELLER
|
||||
void do_gotopos(ssize_t pos_line, size_t pos_x, ssize_t pos_y, size_t
|
||||
pos_pww);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
bool find_bracket_match(bool reverse, const char *bracket_set);
|
||||
void do_find_bracket(void);
|
||||
#ifdef ENABLE_NANORC
|
||||
bool history_has_changed(void);
|
||||
#endif
|
||||
void history_init(void);
|
||||
void history_reset(const filestruct *h);
|
||||
filestruct *find_history(const filestruct *h_start, const filestruct
|
||||
*h_end, const char *s, size_t len);
|
||||
void update_history(filestruct **h, const char *s);
|
||||
char *get_history_older(filestruct **h);
|
||||
char *get_history_newer(filestruct **h);
|
||||
#ifndef DISABLE_TABCOMP
|
||||
char *get_history_completion(filestruct **h, const char *s, size_t len);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* All functions in text.c. */
|
||||
#ifndef NANO_TINY
|
||||
void do_mark(void);
|
||||
#endif
|
||||
void do_delete(void);
|
||||
void do_backspace(void);
|
||||
void do_tab(void);
|
||||
#ifndef NANO_TINY
|
||||
void do_indent(ssize_t cols);
|
||||
void do_indent_void(void);
|
||||
void do_unindent(void);
|
||||
#endif
|
||||
void do_enter(void);
|
||||
#ifndef NANO_TINY
|
||||
RETSIGTYPE cancel_command(int signal);
|
||||
bool execute_command(const char *command);
|
||||
#endif
|
||||
#ifndef DISABLE_WRAPPING
|
||||
void wrap_reset(void);
|
||||
bool do_wrap(filestruct *line);
|
||||
#endif
|
||||
#if !defined(DISABLE_HELP) || !defined(DISABLE_WRAPJUSTIFY)
|
||||
ssize_t break_line(const char *line, ssize_t goal
|
||||
#ifndef DISABLE_HELP
|
||||
, bool newline
|
||||
#endif
|
||||
);
|
||||
#endif
|
||||
#if !defined(NANO_TINY) || !defined(DISABLE_JUSTIFY)
|
||||
size_t indent_length(const char *line);
|
||||
#endif
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
void justify_format(filestruct *paragraph, size_t skip);
|
||||
size_t quote_length(const char *line);
|
||||
bool quotes_match(const char *a_line, size_t a_quote, const char
|
||||
*b_line);
|
||||
bool indents_match(const char *a_line, size_t a_indent, const char
|
||||
*b_line, size_t b_indent);
|
||||
bool begpar(const filestruct *const foo);
|
||||
bool inpar(const filestruct *const foo);
|
||||
void backup_lines(filestruct *first_line, size_t par_len);
|
||||
bool find_paragraph(size_t *const quote, size_t *const par);
|
||||
void do_justify(bool full_justify);
|
||||
void do_justify_void(void);
|
||||
void do_full_justify(void);
|
||||
#endif
|
||||
#ifndef DISABLE_SPELLER
|
||||
bool do_int_spell_fix(const char *word);
|
||||
const char *do_int_speller(const char *tempfile_name);
|
||||
const char *do_alt_speller(char *tempfile_name);
|
||||
void do_spell(void);
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
void do_wordlinechar_count(void);
|
||||
#endif
|
||||
void do_verbatim_input(void);
|
||||
|
||||
/* All functions in utils.c. */
|
||||
int digits(size_t n);
|
||||
void get_homedir(void);
|
||||
bool parse_num(const char *str, ssize_t *val);
|
||||
bool parse_line_column(const char *str, ssize_t *line, ssize_t *column);
|
||||
void align(char **str);
|
||||
void null_at(char **data, size_t index);
|
||||
void unsunder(char *str, size_t true_len);
|
||||
void sunder(char *str);
|
||||
#if !defined(NANO_TINY) && defined(ENABLE_NANORC)
|
||||
#ifndef HAVE_GETLINE
|
||||
ssize_t ngetline(char **lineptr, size_t *n, FILE *stream);
|
||||
#endif
|
||||
#ifndef HAVE_GETDELIM
|
||||
ssize_t ngetdelim(char **lineptr, size_t *n, int delim, FILE *stream);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_REGEX_H
|
||||
bool regexp_bol_or_eol(const regex_t *preg, const char *string);
|
||||
#endif
|
||||
#ifndef DISABLE_SPELLER
|
||||
bool is_whole_word(size_t pos, const char *buf, const char *word);
|
||||
#endif
|
||||
const char *strstrwrapper(const char *haystack, const char *needle,
|
||||
const char *start);
|
||||
void nperror(const char *s);
|
||||
void *nmalloc(size_t howmuch);
|
||||
void *nrealloc(void *ptr, size_t howmuch);
|
||||
char *mallocstrncpy(char *dest, const char *src, size_t n);
|
||||
char *mallocstrcpy(char *dest, const char *src);
|
||||
char *mallocstrassn(char *dest, char *src);
|
||||
size_t get_page_start(size_t column);
|
||||
size_t xplustabs(void);
|
||||
size_t actual_x(const char *s, size_t column);
|
||||
size_t strnlenpt(const char *s, size_t maxlen);
|
||||
size_t strlenpt(const char *s);
|
||||
void new_magicline(void);
|
||||
#ifndef NANO_TINY
|
||||
void remove_magicline(void);
|
||||
void mark_order(const filestruct **top, size_t *top_x, const filestruct
|
||||
**bot, size_t *bot_x, bool *right_side_up);
|
||||
#endif
|
||||
size_t get_totsize(const filestruct *begin, const filestruct *end);
|
||||
#ifdef DEBUG
|
||||
void dump_filestruct(const filestruct *inptr);
|
||||
void dump_filestruct_reverse(void);
|
||||
#endif
|
||||
|
||||
/* All functions in winio.c. */
|
||||
void get_key_buffer(WINDOW *win);
|
||||
size_t get_key_buffer_len(void);
|
||||
void unget_input(int *input, size_t input_len);
|
||||
void unget_kbinput(int kbinput, bool meta_key, bool func_key);
|
||||
int *get_input(WINDOW *win, size_t input_len);
|
||||
int get_kbinput(WINDOW *win, bool *meta_key, bool *func_key);
|
||||
int parse_kbinput(WINDOW *win, bool *meta_key, bool *func_key);
|
||||
int get_escape_seq_kbinput(const int *seq, size_t seq_len);
|
||||
int get_escape_seq_abcd(int kbinput);
|
||||
int parse_escape_seq_kbinput(WINDOW *win, int kbinput);
|
||||
int get_byte_kbinput(int kbinput);
|
||||
#ifdef ENABLE_UTF8
|
||||
long add_unicode_digit(int kbinput, long factor, long *uni);
|
||||
long get_unicode_kbinput(int kbinput);
|
||||
#endif
|
||||
int get_control_kbinput(int kbinput);
|
||||
void unparse_kbinput(char *output, size_t output_len);
|
||||
int *get_verbatim_kbinput(WINDOW *win, size_t *kbinput_len);
|
||||
int *parse_verbatim_kbinput(WINDOW *win, size_t *kbinput_len);
|
||||
#ifndef DISABLE_MOUSE
|
||||
bool get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts);
|
||||
#endif
|
||||
const shortcut *get_shortcut(const shortcut *s_list, int *kbinput, bool
|
||||
*meta_key, bool *func_key);
|
||||
#ifndef NANO_TINY
|
||||
const toggle *get_toggle(int kbinput, bool meta_key);
|
||||
#endif
|
||||
void blank_line(WINDOW *win, int y, int x, int n);
|
||||
void blank_titlebar(void);
|
||||
void blank_topbar(void);
|
||||
void blank_edit(void);
|
||||
void blank_statusbar(void);
|
||||
void blank_bottombars(void);
|
||||
void check_statusblank(void);
|
||||
char *display_string(const char *buf, size_t start_col, size_t len, bool
|
||||
dollars);
|
||||
void titlebar(const char *path);
|
||||
void set_modified(void);
|
||||
void statusbar(const char *msg, ...);
|
||||
void bottombars(const shortcut *s);
|
||||
void onekey(const char *keystroke, const char *desc, size_t len);
|
||||
void reset_cursor(void);
|
||||
void edit_draw(const filestruct *fileptr, const char *converted, int
|
||||
line, size_t start);
|
||||
void update_line(const filestruct *fileptr, size_t index);
|
||||
bool need_horizontal_update(size_t pww_save);
|
||||
bool need_vertical_update(size_t pww_save);
|
||||
void edit_scroll(scroll_dir direction, ssize_t nlines);
|
||||
void edit_redraw(const filestruct *old_current, size_t pww_save);
|
||||
void edit_refresh(void);
|
||||
void edit_update(update_type location);
|
||||
void total_redraw(void);
|
||||
void total_refresh(void);
|
||||
void display_main_list(void);
|
||||
void do_cursorpos(bool constant);
|
||||
void do_cursorpos_void(void);
|
||||
void do_replace_highlight(bool highlight, const char *word);
|
||||
#ifdef NANO_EXTRA
|
||||
void do_credits(void);
|
||||
#endif
|
||||
|
||||
#endif /* !PROTO_H */
|
932
src/rcfile.c
Normal file
932
src/rcfile.c
Normal file
@ -0,0 +1,932 @@
|
||||
/* $Id: rcfile.c,v 1.122.2.1 2007/04/18 18:22:13 dolorous Exp $ */
|
||||
/**************************************************************************
|
||||
* rcfile.c *
|
||||
* *
|
||||
* Copyright (C) 2001, 2002, 2003, 2004 Chris Allegretta *
|
||||
* Copyright (C) 2005, 2006, 2007 David Lawrence Ramsey *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2, or (at your option) *
|
||||
* any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
|
||||
* 02110-1301, USA. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#include "proto.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef ENABLE_NANORC
|
||||
|
||||
static const rcoption rcopts[] = {
|
||||
{"boldtext", BOLD_TEXT},
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
{"brackets", 0},
|
||||
#endif
|
||||
{"const", CONST_UPDATE},
|
||||
#ifndef DISABLE_WRAPJUSTIFY
|
||||
{"fill", 0},
|
||||
#endif
|
||||
#ifndef DISABLE_MOUSE
|
||||
{"mouse", USE_MOUSE},
|
||||
#endif
|
||||
#ifdef ENABLE_MULTIBUFFER
|
||||
{"multibuffer", MULTIBUFFER},
|
||||
#endif
|
||||
{"morespace", MORE_SPACE},
|
||||
{"nofollow", NOFOLLOW_SYMLINKS},
|
||||
{"nohelp", NO_HELP},
|
||||
{"nonewlines", NO_NEWLINES},
|
||||
#ifndef DISABLE_WRAPPING
|
||||
{"nowrap", NO_WRAP},
|
||||
#endif
|
||||
#ifndef DISABLE_OPERATINGDIR
|
||||
{"operatingdir", 0},
|
||||
#endif
|
||||
{"preserve", PRESERVE},
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
{"punct", 0},
|
||||
{"quotestr", 0},
|
||||
#endif
|
||||
{"rebinddelete", REBIND_DELETE},
|
||||
{"rebindkeypad", REBIND_KEYPAD},
|
||||
#ifdef HAVE_REGEX_H
|
||||
{"regexp", USE_REGEXP},
|
||||
#endif
|
||||
#ifndef DISABLE_SPELLER
|
||||
{"speller", 0},
|
||||
#endif
|
||||
{"suspend", SUSPEND},
|
||||
{"tabsize", 0},
|
||||
{"tempfile", TEMP_FILE},
|
||||
{"view", VIEW_MODE},
|
||||
#ifndef NANO_TINY
|
||||
{"autoindent", AUTOINDENT},
|
||||
{"backup", BACKUP_FILE},
|
||||
{"backupdir", 0},
|
||||
{"backwards", BACKWARDS_SEARCH},
|
||||
{"casesensitive", CASE_SENSITIVE},
|
||||
{"cut", CUT_TO_END},
|
||||
{"historylog", HISTORYLOG},
|
||||
{"matchbrackets", 0},
|
||||
{"noconvert", NO_CONVERT},
|
||||
{"quickblank", QUICK_BLANK},
|
||||
{"smarthome", SMART_HOME},
|
||||
{"smooth", SMOOTH_SCROLL},
|
||||
{"tabstospaces", TABS_TO_SPACES},
|
||||
{"whitespace", 0},
|
||||
{"wordbounds", WORD_BOUNDS},
|
||||
#endif
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
static bool errors = FALSE;
|
||||
/* Whether we got any errors while parsing an rcfile. */
|
||||
static size_t lineno = 0;
|
||||
/* If we did, the line number where the last error occurred. */
|
||||
static char *nanorc = NULL;
|
||||
/* The path to the rcfile we're parsing. */
|
||||
#ifdef ENABLE_COLOR
|
||||
static syntaxtype *endsyntax = NULL;
|
||||
/* The end of the list of syntaxes. */
|
||||
static colortype *endcolor = NULL;
|
||||
/* The end of the color list for the current syntax. */
|
||||
#endif
|
||||
|
||||
/* We have an error in some part of the rcfile. Print the error message
|
||||
* on stderr, and then make the user hit Enter to continue starting
|
||||
* nano. */
|
||||
void rcfile_error(const char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
if (lineno > 0) {
|
||||
errors = TRUE;
|
||||
fprintf(stderr, _("Error in %s on line %lu: "), nanorc, (unsigned long)lineno);
|
||||
}
|
||||
|
||||
va_start(ap, msg);
|
||||
vfprintf(stderr, _(msg), ap);
|
||||
va_end(ap);
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
/* Parse the next word from the string, null-terminate it, and return
|
||||
* a pointer to the first character after the null terminator. The
|
||||
* returned pointer will point to '\0' if we hit the end of the line. */
|
||||
char *parse_next_word(char *ptr)
|
||||
{
|
||||
while (!isblank(*ptr) && *ptr != '\0')
|
||||
ptr++;
|
||||
|
||||
if (*ptr == '\0')
|
||||
return ptr;
|
||||
|
||||
/* Null-terminate and advance ptr. */
|
||||
*ptr++ = '\0';
|
||||
|
||||
while (isblank(*ptr))
|
||||
ptr++;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Parse an argument, with optional quotes, after a keyword that takes
|
||||
* one. If the next word starts with a ", we say that it ends with the
|
||||
* last " of the line. Otherwise, we interpret it as usual, so that the
|
||||
* arguments can contain "'s too. */
|
||||
char *parse_argument(char *ptr)
|
||||
{
|
||||
const char *ptr_save = ptr;
|
||||
char *last_quote = NULL;
|
||||
|
||||
assert(ptr != NULL);
|
||||
|
||||
if (*ptr != '"')
|
||||
return parse_next_word(ptr);
|
||||
|
||||
do {
|
||||
ptr++;
|
||||
if (*ptr == '"')
|
||||
last_quote = ptr;
|
||||
} while (*ptr != '\0');
|
||||
|
||||
if (last_quote == NULL) {
|
||||
if (*ptr == '\0')
|
||||
ptr = NULL;
|
||||
else
|
||||
*ptr++ = '\0';
|
||||
rcfile_error(N_("Argument '%s' has an unterminated \""), ptr_save);
|
||||
} else {
|
||||
*last_quote = '\0';
|
||||
ptr = last_quote + 1;
|
||||
}
|
||||
if (ptr != NULL)
|
||||
while (isblank(*ptr))
|
||||
ptr++;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
/* Parse the next regex string from the line at ptr, and return it. */
|
||||
char *parse_next_regex(char *ptr)
|
||||
{
|
||||
assert(ptr != NULL);
|
||||
|
||||
/* Continue until the end of the line, or a " followed by a space, a
|
||||
* blank character, or \0. */
|
||||
while ((*ptr != '"' || (!isblank(*(ptr + 1)) &&
|
||||
*(ptr + 1) != '\0')) && *ptr != '\0')
|
||||
ptr++;
|
||||
|
||||
assert(*ptr == '"' || *ptr == '\0');
|
||||
|
||||
if (*ptr == '\0') {
|
||||
rcfile_error(
|
||||
N_("Regex strings must begin and end with a \" character"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Null-terminate and advance ptr. */
|
||||
*ptr++ = '\0';
|
||||
|
||||
while (isblank(*ptr))
|
||||
ptr++;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Compile the regular expression regex to see if it's valid. Return
|
||||
* TRUE if it is, or FALSE otherwise. */
|
||||
bool nregcomp(const char *regex, int eflags)
|
||||
{
|
||||
regex_t preg;
|
||||
int rc = regcomp(&preg, regex, REG_EXTENDED | eflags);
|
||||
|
||||
if (rc != 0) {
|
||||
size_t len = regerror(rc, &preg, NULL, 0);
|
||||
char *str = charalloc(len);
|
||||
|
||||
regerror(rc, &preg, str, len);
|
||||
rcfile_error(N_("Bad regex \"%s\": %s"), regex, str);
|
||||
free(str);
|
||||
}
|
||||
|
||||
regfree(&preg);
|
||||
|
||||
return (rc == 0);
|
||||
}
|
||||
|
||||
/* Parse the next syntax string from the line at ptr, and add it to the
|
||||
* global list of color syntaxes. */
|
||||
void parse_syntax(char *ptr)
|
||||
{
|
||||
const char *fileregptr = NULL, *nameptr = NULL;
|
||||
syntaxtype *tmpsyntax;
|
||||
exttype *endext = NULL;
|
||||
/* The end of the extensions list for this syntax. */
|
||||
|
||||
assert(ptr != NULL);
|
||||
|
||||
if (*ptr == '\0') {
|
||||
rcfile_error(N_("Missing syntax name"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (*ptr != '"') {
|
||||
rcfile_error(
|
||||
N_("Regex strings must begin and end with a \" character"));
|
||||
return;
|
||||
}
|
||||
|
||||
ptr++;
|
||||
|
||||
nameptr = ptr;
|
||||
ptr = parse_next_regex(ptr);
|
||||
|
||||
if (ptr == NULL)
|
||||
return;
|
||||
|
||||
/* Search for a duplicate syntax name. If we find one, free it, so
|
||||
* that we always use the last syntax with a given name. */
|
||||
for (tmpsyntax = syntaxes; tmpsyntax != NULL;
|
||||
tmpsyntax = tmpsyntax->next) {
|
||||
if (strcmp(nameptr, tmpsyntax->desc) == 0) {
|
||||
syntaxtype *prev_syntax = tmpsyntax;
|
||||
|
||||
tmpsyntax = tmpsyntax->next;
|
||||
free(prev_syntax);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (syntaxes == NULL) {
|
||||
syntaxes = (syntaxtype *)nmalloc(sizeof(syntaxtype));
|
||||
endsyntax = syntaxes;
|
||||
} else {
|
||||
endsyntax->next = (syntaxtype *)nmalloc(sizeof(syntaxtype));
|
||||
endsyntax = endsyntax->next;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Adding new syntax after first one\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
endsyntax->desc = mallocstrcpy(NULL, nameptr);
|
||||
endsyntax->color = NULL;
|
||||
endcolor = NULL;
|
||||
endsyntax->extensions = NULL;
|
||||
endsyntax->next = NULL;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Starting a new syntax type: \"%s\"\n", nameptr);
|
||||
#endif
|
||||
|
||||
/* The "none" syntax is the same as not having a syntax at all, so
|
||||
* we can't assign any extensions or colors to it. */
|
||||
if (strcmp(endsyntax->desc, "none") == 0) {
|
||||
rcfile_error(N_("The \"none\" syntax is reserved"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* The default syntax should have no associated extensions. */
|
||||
if (strcmp(endsyntax->desc, "default") == 0 && *ptr != '\0') {
|
||||
rcfile_error(
|
||||
N_("The \"default\" syntax must take no extensions"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now load the extensions into their part of the struct. */
|
||||
while (*ptr != '\0') {
|
||||
exttype *newext;
|
||||
/* The new extension structure. */
|
||||
|
||||
while (*ptr != '"' && *ptr != '\0')
|
||||
ptr++;
|
||||
|
||||
if (*ptr == '\0')
|
||||
return;
|
||||
|
||||
ptr++;
|
||||
|
||||
fileregptr = ptr;
|
||||
ptr = parse_next_regex(ptr);
|
||||
if (ptr == NULL)
|
||||
break;
|
||||
|
||||
newext = (exttype *)nmalloc(sizeof(exttype));
|
||||
|
||||
/* Save the extension regex if it's valid. */
|
||||
if (nregcomp(fileregptr, REG_NOSUB)) {
|
||||
newext->ext_regex = mallocstrcpy(NULL, fileregptr);
|
||||
newext->ext = NULL;
|
||||
|
||||
if (endext == NULL)
|
||||
endsyntax->extensions = newext;
|
||||
else
|
||||
endext->next = newext;
|
||||
endext = newext;
|
||||
endext->next = NULL;
|
||||
} else
|
||||
free(newext);
|
||||
}
|
||||
}
|
||||
|
||||
/* Read and parse additional syntax files. */
|
||||
void parse_include(char *ptr)
|
||||
{
|
||||
struct stat rcinfo;
|
||||
FILE *rcstream;
|
||||
char *option, *full_option, *nanorc_save = nanorc;
|
||||
size_t lineno_save = lineno;
|
||||
|
||||
option = ptr;
|
||||
if (*option == '"')
|
||||
option++;
|
||||
ptr = parse_argument(ptr);
|
||||
|
||||
/* Get the specified file's full path. */
|
||||
full_option = get_full_path(option);
|
||||
|
||||
if (full_option == NULL)
|
||||
full_option = mallocstrcpy(NULL, option);
|
||||
|
||||
/* Don't open directories, character files, or block files. */
|
||||
if (stat(full_option, &rcinfo) != -1) {
|
||||
if (S_ISDIR(rcinfo.st_mode) || S_ISCHR(rcinfo.st_mode) ||
|
||||
S_ISBLK(rcinfo.st_mode)) {
|
||||
rcfile_error(S_ISDIR(rcinfo.st_mode) ?
|
||||
_("\"%s\" is a directory") :
|
||||
_("\"%s\" is a device file"), option);
|
||||
goto cleanup_include;
|
||||
}
|
||||
}
|
||||
|
||||
/* Open the new syntax file. */
|
||||
if ((rcstream = fopen(full_option, "rb")) == NULL) {
|
||||
rcfile_error(_("Error reading %s: %s"), option,
|
||||
strerror(errno));
|
||||
goto cleanup_include;
|
||||
}
|
||||
|
||||
/* Use the name and line number position of the new syntax file
|
||||
* while parsing it, so we can know where any errors in it are. */
|
||||
nanorc = full_option;
|
||||
lineno = 0;
|
||||
|
||||
parse_rcfile(rcstream
|
||||
#ifdef ENABLE_COLOR
|
||||
, TRUE
|
||||
#endif
|
||||
);
|
||||
|
||||
/* We're done with the new syntax file. Restore the original
|
||||
* filename and line number position. */
|
||||
nanorc = nanorc_save;
|
||||
lineno = lineno_save;
|
||||
|
||||
cleanup_include:
|
||||
free(full_option);
|
||||
}
|
||||
|
||||
/* Return the short value corresponding to the color named in colorname,
|
||||
* and set bright to TRUE if that color is bright. */
|
||||
short color_to_short(const char *colorname, bool *bright)
|
||||
{
|
||||
short mcolor = -1;
|
||||
|
||||
assert(colorname != NULL && bright != NULL);
|
||||
|
||||
if (strncasecmp(colorname, "bright", 6) == 0) {
|
||||
*bright = TRUE;
|
||||
colorname += 6;
|
||||
}
|
||||
|
||||
if (strcasecmp(colorname, "green") == 0)
|
||||
mcolor = COLOR_GREEN;
|
||||
else if (strcasecmp(colorname, "red") == 0)
|
||||
mcolor = COLOR_RED;
|
||||
else if (strcasecmp(colorname, "blue") == 0)
|
||||
mcolor = COLOR_BLUE;
|
||||
else if (strcasecmp(colorname, "white") == 0)
|
||||
mcolor = COLOR_WHITE;
|
||||
else if (strcasecmp(colorname, "yellow") == 0)
|
||||
mcolor = COLOR_YELLOW;
|
||||
else if (strcasecmp(colorname, "cyan") == 0)
|
||||
mcolor = COLOR_CYAN;
|
||||
else if (strcasecmp(colorname, "magenta") == 0)
|
||||
mcolor = COLOR_MAGENTA;
|
||||
else if (strcasecmp(colorname, "black") == 0)
|
||||
mcolor = COLOR_BLACK;
|
||||
else
|
||||
rcfile_error(N_("Color \"%s\" not understood.\n"
|
||||
"Valid colors are \"green\", \"red\", \"blue\",\n"
|
||||
"\"white\", \"yellow\", \"cyan\", \"magenta\" and\n"
|
||||
"\"black\", with the optional prefix \"bright\"\n"
|
||||
"for foreground colors."), colorname);
|
||||
|
||||
return mcolor;
|
||||
}
|
||||
|
||||
/* Parse the color string in the line at ptr, and add it to the current
|
||||
* file's associated colors. If icase is TRUE, treat the color string
|
||||
* as case insensitive. */
|
||||
void parse_colors(char *ptr, bool icase)
|
||||
{
|
||||
short fg, bg;
|
||||
bool bright = FALSE, no_fgcolor = FALSE;
|
||||
char *fgstr;
|
||||
|
||||
assert(ptr != NULL);
|
||||
|
||||
if (syntaxes == NULL) {
|
||||
rcfile_error(
|
||||
N_("Cannot add a color command without a syntax command"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (*ptr == '\0') {
|
||||
rcfile_error(N_("Missing color name"));
|
||||
return;
|
||||
}
|
||||
|
||||
fgstr = ptr;
|
||||
ptr = parse_next_word(ptr);
|
||||
|
||||
if (strchr(fgstr, ',') != NULL) {
|
||||
char *bgcolorname;
|
||||
|
||||
strtok(fgstr, ",");
|
||||
bgcolorname = strtok(NULL, ",");
|
||||
if (bgcolorname == NULL) {
|
||||
/* If we have a background color without a foreground color,
|
||||
* parse it properly. */
|
||||
bgcolorname = fgstr + 1;
|
||||
no_fgcolor = TRUE;
|
||||
}
|
||||
if (strncasecmp(bgcolorname, "bright", 6) == 0) {
|
||||
rcfile_error(
|
||||
N_("Background color \"%s\" cannot be bright"),
|
||||
bgcolorname);
|
||||
return;
|
||||
}
|
||||
bg = color_to_short(bgcolorname, &bright);
|
||||
} else
|
||||
bg = -1;
|
||||
|
||||
if (!no_fgcolor) {
|
||||
fg = color_to_short(fgstr, &bright);
|
||||
|
||||
/* Don't try to parse screwed-up foreground colors. */
|
||||
if (fg == -1)
|
||||
return;
|
||||
} else
|
||||
fg = -1;
|
||||
|
||||
if (*ptr == '\0') {
|
||||
rcfile_error(N_("Missing regex string"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now for the fun part. Start adding regexes to individual strings
|
||||
* in the colorstrings array, woo! */
|
||||
while (ptr != NULL && *ptr != '\0') {
|
||||
colortype *newcolor;
|
||||
/* The new color structure. */
|
||||
bool cancelled = FALSE;
|
||||
/* The start expression was bad. */
|
||||
bool expectend = FALSE;
|
||||
/* Do we expect an end= line? */
|
||||
|
||||
if (strncasecmp(ptr, "start=", 6) == 0) {
|
||||
ptr += 6;
|
||||
expectend = TRUE;
|
||||
}
|
||||
|
||||
if (*ptr != '"') {
|
||||
rcfile_error(
|
||||
N_("Regex strings must begin and end with a \" character"));
|
||||
ptr = parse_next_regex(ptr);
|
||||
continue;
|
||||
}
|
||||
|
||||
ptr++;
|
||||
|
||||
fgstr = ptr;
|
||||
ptr = parse_next_regex(ptr);
|
||||
if (ptr == NULL)
|
||||
break;
|
||||
|
||||
newcolor = (colortype *)nmalloc(sizeof(colortype));
|
||||
|
||||
/* Save the starting regex string if it's valid, and set up the
|
||||
* color information. */
|
||||
if (nregcomp(fgstr, icase ? REG_ICASE : 0)) {
|
||||
newcolor->fg = fg;
|
||||
newcolor->bg = bg;
|
||||
newcolor->bright = bright;
|
||||
newcolor->icase = icase;
|
||||
|
||||
newcolor->start_regex = mallocstrcpy(NULL, fgstr);
|
||||
newcolor->start = NULL;
|
||||
|
||||
newcolor->end_regex = NULL;
|
||||
newcolor->end = NULL;
|
||||
|
||||
newcolor->next = NULL;
|
||||
|
||||
if (endcolor == NULL) {
|
||||
endsyntax->color = newcolor;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Starting a new colorstring for fg %hd, bg %hd\n", fg, bg);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Adding new entry for fg %hd, bg %hd\n", fg, bg);
|
||||
#endif
|
||||
endcolor->next = newcolor;
|
||||
}
|
||||
|
||||
endcolor = newcolor;
|
||||
} else {
|
||||
free(newcolor);
|
||||
cancelled = TRUE;
|
||||
}
|
||||
|
||||
if (expectend) {
|
||||
if (ptr == NULL || strncasecmp(ptr, "end=", 4) != 0) {
|
||||
rcfile_error(
|
||||
N_("\"start=\" requires a corresponding \"end=\""));
|
||||
return;
|
||||
}
|
||||
ptr += 4;
|
||||
if (*ptr != '"') {
|
||||
rcfile_error(
|
||||
N_("Regex strings must begin and end with a \" character"));
|
||||
continue;
|
||||
}
|
||||
|
||||
ptr++;
|
||||
|
||||
fgstr = ptr;
|
||||
ptr = parse_next_regex(ptr);
|
||||
if (ptr == NULL)
|
||||
break;
|
||||
|
||||
/* If the start regex was invalid, skip past the end regex to
|
||||
* stay in sync. */
|
||||
if (cancelled)
|
||||
continue;
|
||||
|
||||
/* Save the ending regex string if it's valid. */
|
||||
newcolor->end_regex = (nregcomp(fgstr, icase ? REG_ICASE :
|
||||
0)) ? mallocstrcpy(NULL, fgstr) : NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_COLOR */
|
||||
|
||||
/* Parse the rcfile, once it has been opened successfully at rcstream,
|
||||
* and close it afterwards. If syntax_only is TRUE, only allow the file
|
||||
* to contain color syntax commands: syntax, color, and icolor. */
|
||||
void parse_rcfile(FILE *rcstream
|
||||
#ifdef ENABLE_COLOR
|
||||
, bool syntax_only
|
||||
#endif
|
||||
)
|
||||
{
|
||||
char *buf = NULL;
|
||||
ssize_t len;
|
||||
size_t n;
|
||||
|
||||
while ((len = getline(&buf, &n, rcstream)) > 0) {
|
||||
char *ptr, *keyword, *option;
|
||||
int set = 0;
|
||||
size_t i;
|
||||
|
||||
/* Ignore the newline. */
|
||||
if (buf[len - 1] == '\n')
|
||||
buf[len - 1] = '\0';
|
||||
|
||||
lineno++;
|
||||
ptr = buf;
|
||||
while (isblank(*ptr))
|
||||
ptr++;
|
||||
|
||||
/* If we have a blank line or a comment, skip to the next
|
||||
* line. */
|
||||
if (*ptr == '\0' || *ptr == '#')
|
||||
continue;
|
||||
|
||||
/* Otherwise, skip to the next space. */
|
||||
keyword = ptr;
|
||||
ptr = parse_next_word(ptr);
|
||||
|
||||
/* Try to parse the keyword. */
|
||||
if (strcasecmp(keyword, "set") == 0) {
|
||||
#ifdef ENABLE_COLOR
|
||||
if (syntax_only)
|
||||
rcfile_error(
|
||||
N_("Command \"%s\" not allowed in included file"),
|
||||
keyword);
|
||||
else
|
||||
#endif
|
||||
set = 1;
|
||||
} else if (strcasecmp(keyword, "unset") == 0) {
|
||||
#ifdef ENABLE_COLOR
|
||||
if (syntax_only)
|
||||
rcfile_error(
|
||||
N_("Command \"%s\" not allowed in included file"),
|
||||
keyword);
|
||||
else
|
||||
#endif
|
||||
set = -1;
|
||||
}
|
||||
#ifdef ENABLE_COLOR
|
||||
else if (strcasecmp(keyword, "include") == 0) {
|
||||
if (syntax_only)
|
||||
rcfile_error(
|
||||
N_("Command \"%s\" not allowed in included file"),
|
||||
keyword);
|
||||
else
|
||||
parse_include(ptr);
|
||||
} else if (strcasecmp(keyword, "syntax") == 0) {
|
||||
if (endsyntax != NULL && endcolor == NULL)
|
||||
rcfile_error(N_("Syntax \"%s\" has no color commands"),
|
||||
endsyntax->desc);
|
||||
parse_syntax(ptr);
|
||||
} else if (strcasecmp(keyword, "color") == 0)
|
||||
parse_colors(ptr, FALSE);
|
||||
else if (strcasecmp(keyword, "icolor") == 0)
|
||||
parse_colors(ptr, TRUE);
|
||||
#endif /* ENABLE_COLOR */
|
||||
else
|
||||
rcfile_error(N_("Command \"%s\" not understood"), keyword);
|
||||
|
||||
if (set == 0)
|
||||
continue;
|
||||
|
||||
if (*ptr == '\0') {
|
||||
rcfile_error(N_("Missing flag"));
|
||||
continue;
|
||||
}
|
||||
|
||||
option = ptr;
|
||||
ptr = parse_next_word(ptr);
|
||||
|
||||
for (i = 0; rcopts[i].name != NULL; i++) {
|
||||
if (strcasecmp(option, rcopts[i].name) == 0) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "parse_rcfile(): name = \"%s\"\n", rcopts[i].name);
|
||||
#endif
|
||||
if (set == 1) {
|
||||
if (rcopts[i].flag != 0)
|
||||
/* This option has a flag, so it doesn't take an
|
||||
* argument. */
|
||||
SET(rcopts[i].flag);
|
||||
else {
|
||||
/* This option doesn't have a flag, so it takes
|
||||
* an argument. */
|
||||
if (*ptr == '\0') {
|
||||
rcfile_error(
|
||||
N_("Option \"%s\" requires an argument"),
|
||||
rcopts[i].name);
|
||||
break;
|
||||
}
|
||||
option = ptr;
|
||||
if (*option == '"')
|
||||
option++;
|
||||
ptr = parse_argument(ptr);
|
||||
|
||||
option = mallocstrcpy(NULL, option);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "option = \"%s\"\n", option);
|
||||
#endif
|
||||
|
||||
/* Make sure option is a valid multibyte
|
||||
* string. */
|
||||
if (!is_valid_mbstring(option)) {
|
||||
rcfile_error(
|
||||
N_("Option is not a valid multibyte string"));
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef DISABLE_OPERATINGDIR
|
||||
if (strcasecmp(rcopts[i].name, "operatingdir") == 0)
|
||||
operating_dir = option;
|
||||
else
|
||||
#endif
|
||||
#ifndef DISABLE_WRAPJUSTIFY
|
||||
if (strcasecmp(rcopts[i].name, "fill") == 0) {
|
||||
if (!parse_num(option, &wrap_at)) {
|
||||
rcfile_error(
|
||||
N_("Requested fill size \"%s\" is invalid"),
|
||||
option);
|
||||
wrap_at = -CHARS_FROM_EOL;
|
||||
} else
|
||||
free(option);
|
||||
} else
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
if (strcasecmp(rcopts[i].name,
|
||||
"matchbrackets") == 0) {
|
||||
matchbrackets = option;
|
||||
if (has_blank_mbchars(matchbrackets)) {
|
||||
rcfile_error(
|
||||
N_("Non-blank characters required"));
|
||||
free(matchbrackets);
|
||||
matchbrackets = NULL;
|
||||
}
|
||||
} else if (strcasecmp(rcopts[i].name,
|
||||
"whitespace") == 0) {
|
||||
whitespace = option;
|
||||
if (mbstrlen(whitespace) != 2 ||
|
||||
strlenpt(whitespace) != 2) {
|
||||
rcfile_error(
|
||||
N_("Two single-column characters required"));
|
||||
free(whitespace);
|
||||
whitespace = NULL;
|
||||
} else {
|
||||
whitespace_len[0] =
|
||||
parse_mbchar(whitespace, NULL,
|
||||
NULL);
|
||||
whitespace_len[1] =
|
||||
parse_mbchar(whitespace +
|
||||
whitespace_len[0], NULL, NULL);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
#ifndef DISABLE_JUSTIFY
|
||||
if (strcasecmp(rcopts[i].name, "punct") == 0) {
|
||||
punct = option;
|
||||
if (has_blank_mbchars(punct)) {
|
||||
rcfile_error(
|
||||
N_("Non-blank characters required"));
|
||||
free(punct);
|
||||
punct = NULL;
|
||||
}
|
||||
} else if (strcasecmp(rcopts[i].name,
|
||||
"brackets") == 0) {
|
||||
brackets = option;
|
||||
if (has_blank_mbchars(brackets)) {
|
||||
rcfile_error(
|
||||
N_("Non-blank characters required"));
|
||||
free(brackets);
|
||||
brackets = NULL;
|
||||
}
|
||||
} else if (strcasecmp(rcopts[i].name,
|
||||
"quotestr") == 0)
|
||||
quotestr = option;
|
||||
else
|
||||
#endif
|
||||
#ifndef NANO_TINY
|
||||
if (strcasecmp(rcopts[i].name,
|
||||
"backupdir") == 0)
|
||||
backup_dir = option;
|
||||
else
|
||||
#endif
|
||||
#ifndef DISABLE_SPELLER
|
||||
if (strcasecmp(rcopts[i].name, "speller") == 0)
|
||||
alt_speller = option;
|
||||
else
|
||||
#endif
|
||||
if (strcasecmp(rcopts[i].name,
|
||||
"tabsize") == 0) {
|
||||
if (!parse_num(option, &tabsize) ||
|
||||
tabsize <= 0) {
|
||||
rcfile_error(
|
||||
N_("Requested tab size \"%s\" is invalid"),
|
||||
option);
|
||||
tabsize = -1;
|
||||
} else
|
||||
free(option);
|
||||
} else
|
||||
assert(FALSE);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "flag = %ld\n", rcopts[i].flag);
|
||||
#endif
|
||||
} else if (rcopts[i].flag != 0)
|
||||
UNSET(rcopts[i].flag);
|
||||
else
|
||||
rcfile_error(N_("Cannot unset flag \"%s\""),
|
||||
rcopts[i].name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rcopts[i].name == NULL)
|
||||
rcfile_error(N_("Unknown flag \"%s\""), option);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
if (endsyntax != NULL && endcolor == NULL)
|
||||
rcfile_error(N_("Syntax \"%s\" has no color commands"),
|
||||
endsyntax->desc);
|
||||
#endif
|
||||
|
||||
free(buf);
|
||||
fclose(rcstream);
|
||||
lineno = 0;
|
||||
|
||||
if (errors) {
|
||||
errors = FALSE;
|
||||
fprintf(stderr,
|
||||
_("\nPress Enter to continue starting nano.\n"));
|
||||
while (getchar() != '\n')
|
||||
;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* The main rcfile function. It tries to open the system-wide rcfile,
|
||||
* followed by the current user's rcfile. */
|
||||
void do_rcfile(void)
|
||||
{
|
||||
struct stat rcinfo;
|
||||
FILE *rcstream;
|
||||
|
||||
nanorc = mallocstrcpy(nanorc, SYSCONFDIR "/nanorc");
|
||||
|
||||
/* Don't open directories, character files, or block files. */
|
||||
if (stat(nanorc, &rcinfo) != -1) {
|
||||
if (S_ISDIR(rcinfo.st_mode) || S_ISCHR(rcinfo.st_mode) ||
|
||||
S_ISBLK(rcinfo.st_mode))
|
||||
rcfile_error(S_ISDIR(rcinfo.st_mode) ?
|
||||
_("\"%s\" is a directory") :
|
||||
_("\"%s\" is a device file"), nanorc);
|
||||
}
|
||||
|
||||
/* Try to open the system-wide nanorc. */
|
||||
rcstream = fopen(nanorc, "rb");
|
||||
if (rcstream != NULL)
|
||||
parse_rcfile(rcstream
|
||||
#ifdef ENABLE_COLOR
|
||||
, FALSE
|
||||
#endif
|
||||
);
|
||||
|
||||
#ifdef DISABLE_ROOTWRAPPING
|
||||
/* We've already read SYSCONFDIR/nanorc, if it's there. If we're
|
||||
* root, and --disable-wrapping-as-root is used, turn wrapping off
|
||||
* now. */
|
||||
if (geteuid() == NANO_ROOT_UID)
|
||||
SET(NO_WRAP);
|
||||
#endif
|
||||
|
||||
get_homedir();
|
||||
|
||||
if (homedir == NULL)
|
||||
rcfile_error(N_("I can't find my home directory! Wah!"));
|
||||
else {
|
||||
nanorc = charealloc(nanorc, strlen(homedir) + 9);
|
||||
sprintf(nanorc, "%s/.nanorc", homedir);
|
||||
|
||||
/* Don't open directories, character files, or block files. */
|
||||
if (stat(nanorc, &rcinfo) != -1) {
|
||||
if (S_ISDIR(rcinfo.st_mode) || S_ISCHR(rcinfo.st_mode) ||
|
||||
S_ISBLK(rcinfo.st_mode))
|
||||
rcfile_error(S_ISDIR(rcinfo.st_mode) ?
|
||||
_("\"%s\" is a directory") :
|
||||
_("\"%s\" is a device file"), nanorc);
|
||||
}
|
||||
|
||||
/* Try to open the current user's nanorc. */
|
||||
rcstream = fopen(nanorc, "rb");
|
||||
if (rcstream == NULL) {
|
||||
/* Don't complain about the file's not existing. */
|
||||
if (errno != ENOENT)
|
||||
rcfile_error(N_("Error reading %s: %s"), nanorc,
|
||||
strerror(errno));
|
||||
} else
|
||||
parse_rcfile(rcstream
|
||||
#ifdef ENABLE_COLOR
|
||||
, FALSE
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
free(nanorc);
|
||||
nanorc = NULL;
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
set_colorpairs();
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* ENABLE_NANORC */
|
1442
src/search.c
Normal file
1442
src/search.c
Normal file
File diff suppressed because it is too large
Load Diff
2461
src/text.c
Normal file
2461
src/text.c
Normal file
File diff suppressed because it is too large
Load Diff
616
src/utils.c
Normal file
616
src/utils.c
Normal file
@ -0,0 +1,616 @@
|
||||
/* $Id: utils.c,v 1.124 2007/01/01 05:15:32 dolorous Exp $ */
|
||||
/**************************************************************************
|
||||
* utils.c *
|
||||
* *
|
||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Chris Allegretta *
|
||||
* Copyright (C) 2005, 2006, 2007 David Lawrence Ramsey *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2, or (at your option) *
|
||||
* any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
|
||||
* 02110-1301, USA. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#include "proto.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* Return the number of decimal digits in n. */
|
||||
int digits(size_t n)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (n == 0)
|
||||
i = 1;
|
||||
else {
|
||||
for (i = 0; n != 0; n /= 10, i++)
|
||||
;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/* Return the user's home directory. We use $HOME, and if that fails,
|
||||
* we fall back on the home directory of the effective user ID. */
|
||||
void get_homedir(void)
|
||||
{
|
||||
if (homedir == NULL) {
|
||||
const char *homenv = getenv("HOME");
|
||||
|
||||
if (homenv == NULL) {
|
||||
const struct passwd *userage = getpwuid(geteuid());
|
||||
|
||||
if (userage != NULL)
|
||||
homenv = userage->pw_dir;
|
||||
}
|
||||
homedir = mallocstrcpy(NULL, homenv);
|
||||
}
|
||||
}
|
||||
|
||||
/* Read a ssize_t from str, and store it in *val (if val is not NULL).
|
||||
* On error, we return FALSE and don't change *val. Otherwise, we
|
||||
* return TRUE. */
|
||||
bool parse_num(const char *str, ssize_t *val)
|
||||
{
|
||||
char *first_error;
|
||||
ssize_t j;
|
||||
|
||||
assert(str != NULL);
|
||||
|
||||
j = (ssize_t)strtol(str, &first_error, 10);
|
||||
|
||||
if (errno == ERANGE || *str == '\0' || *first_error != '\0')
|
||||
return FALSE;
|
||||
|
||||
if (val != NULL)
|
||||
*val = j;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Read two ssize_t's, separated by a comma, from str, and store them in
|
||||
* *line and *column (if they're not both NULL). Return FALSE on error,
|
||||
* or TRUE otherwise. */
|
||||
bool parse_line_column(const char *str, ssize_t *line, ssize_t *column)
|
||||
{
|
||||
bool retval = TRUE;
|
||||
const char *comma;
|
||||
|
||||
assert(str != NULL);
|
||||
|
||||
comma = strchr(str, ',');
|
||||
|
||||
if (comma != NULL && column != NULL) {
|
||||
if (!parse_num(comma + 1, column))
|
||||
retval = FALSE;
|
||||
}
|
||||
|
||||
if (line != NULL) {
|
||||
if (comma != NULL) {
|
||||
char *str_line = mallocstrncpy(NULL, str, comma - str + 1);
|
||||
str_line[comma - str] = '\0';
|
||||
|
||||
if (str_line[0] != '\0' && !parse_num(str_line, line))
|
||||
retval = FALSE;
|
||||
|
||||
free(str_line);
|
||||
} else if (!parse_num(str, line))
|
||||
retval = FALSE;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Fix the memory allocation for a string. */
|
||||
void align(char **str)
|
||||
{
|
||||
assert(str != NULL);
|
||||
|
||||
if (*str != NULL)
|
||||
*str = charealloc(*str, strlen(*str) + 1);
|
||||
}
|
||||
|
||||
/* Null a string at a certain index and align it. */
|
||||
void null_at(char **data, size_t index)
|
||||
{
|
||||
assert(data != NULL);
|
||||
|
||||
*data = charealloc(*data, index + 1);
|
||||
(*data)[index] = '\0';
|
||||
}
|
||||
|
||||
/* For non-null-terminated lines. A line, by definition, shouldn't
|
||||
* normally have newlines in it, so encode its nulls as newlines. */
|
||||
void unsunder(char *str, size_t true_len)
|
||||
{
|
||||
assert(str != NULL);
|
||||
|
||||
for (; true_len > 0; true_len--, str++) {
|
||||
if (*str == '\0')
|
||||
*str = '\n';
|
||||
}
|
||||
}
|
||||
|
||||
/* For non-null-terminated lines. A line, by definition, shouldn't
|
||||
* normally have newlines in it, so decode its newlines as nulls. */
|
||||
void sunder(char *str)
|
||||
{
|
||||
assert(str != NULL);
|
||||
|
||||
for (; *str != '\0'; str++) {
|
||||
if (*str == '\n')
|
||||
*str = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/* These functions, ngetline() (originally getline()) and ngetdelim()
|
||||
* (originally getdelim()), were adapted from GNU mailutils 0.5
|
||||
* (mailbox/getline.c). Here is the notice from that file, after
|
||||
* converting to the GPL via LGPL clause 3, and with the Free Software
|
||||
* Foundation's address updated:
|
||||
*
|
||||
* GNU Mailutils -- a suite of utilities for electronic mail
|
||||
* Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA. */
|
||||
|
||||
#if !defined(NANO_TINY) && defined(ENABLE_NANORC)
|
||||
#ifndef HAVE_GETLINE
|
||||
/* This function is equivalent to getline(). */
|
||||
ssize_t ngetline(char **lineptr, size_t *n, FILE *stream)
|
||||
{
|
||||
return getdelim(lineptr, n, '\n', stream);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GETDELIM
|
||||
/* This function is equivalent to getdelim(). */
|
||||
ssize_t ngetdelim(char **lineptr, size_t *n, int delim, FILE *stream)
|
||||
{
|
||||
size_t indx = 0;
|
||||
int c;
|
||||
|
||||
/* Sanity checks. */
|
||||
if (lineptr == NULL || n == NULL || stream == NULL ||
|
||||
fileno(stream) == -1) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Allocate the line the first time. */
|
||||
if (*lineptr == NULL) {
|
||||
*lineptr = charalloc(MAX_BUF_SIZE);
|
||||
*n = MAX_BUF_SIZE;
|
||||
}
|
||||
|
||||
while ((c = getc(stream)) != EOF) {
|
||||
/* Check if more memory is needed. */
|
||||
if (indx >= *n) {
|
||||
*lineptr = charealloc(*lineptr, *n + MAX_BUF_SIZE);
|
||||
*n += MAX_BUF_SIZE;
|
||||
}
|
||||
|
||||
/* Put the result in the line. */
|
||||
(*lineptr)[indx++] = (char)c;
|
||||
|
||||
/* Bail out. */
|
||||
if (c == delim)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Make room for the null character. */
|
||||
if (indx >= *n) {
|
||||
*lineptr = charealloc(*lineptr, *n + MAX_BUF_SIZE);
|
||||
*n += MAX_BUF_SIZE;
|
||||
}
|
||||
|
||||
/* Null-terminate the buffer. */
|
||||
null_at(lineptr, indx++);
|
||||
*n = indx;
|
||||
|
||||
/* The last line may not have the delimiter. We have to return what
|
||||
* we got, and the error will be seen on the next iteration. */
|
||||
return (c == EOF && (indx - 1) == 0) ? -1 : indx - 1;
|
||||
}
|
||||
#endif
|
||||
#endif /* !NANO_TINY && ENABLE_NANORC */
|
||||
|
||||
#ifdef HAVE_REGEX_H
|
||||
/* Do the compiled regex in preg and the regex in string match the
|
||||
* beginning or end of a line? */
|
||||
bool regexp_bol_or_eol(const regex_t *preg, const char *string)
|
||||
{
|
||||
return (regexec(preg, string, 0, NULL, 0) == 0 &&
|
||||
regexec(preg, string, 0, NULL, REG_NOTBOL | REG_NOTEOL) ==
|
||||
REG_NOMATCH);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_SPELLER
|
||||
/* Is the word starting at position pos in buf a whole word? */
|
||||
bool is_whole_word(size_t pos, const char *buf, const char *word)
|
||||
{
|
||||
char *p = charalloc(mb_cur_max()), *r = charalloc(mb_cur_max());
|
||||
size_t word_end = pos + strlen(word);
|
||||
bool retval;
|
||||
|
||||
assert(buf != NULL && pos <= strlen(buf) && word != NULL);
|
||||
|
||||
parse_mbchar(buf + move_mbleft(buf, pos), p, NULL);
|
||||
parse_mbchar(buf + word_end, r, NULL);
|
||||
|
||||
/* If we're at the beginning of the line or the character before the
|
||||
* word isn't a non-punctuation "word" character, and if we're at
|
||||
* the end of the line or the character after the word isn't a
|
||||
* non-punctuation "word" character, we have a whole word. */
|
||||
retval = (pos == 0 || !is_word_mbchar(p, FALSE)) &&
|
||||
(word_end == strlen(buf) || !is_word_mbchar(r, FALSE));
|
||||
|
||||
free(p);
|
||||
free(r);
|
||||
|
||||
return retval;
|
||||
}
|
||||
#endif /* !DISABLE_SPELLER */
|
||||
|
||||
/* If we are searching backwards, we will find the last match that
|
||||
* starts no later than start. Otherwise we find the first match
|
||||
* starting no earlier than start. If we are doing a regexp search, we
|
||||
* fill in the global variable regmatches with at most 9 subexpression
|
||||
* matches. Also, all .rm_so elements are relative to the start of the
|
||||
* whole match, so regmatches[0].rm_so == 0. */
|
||||
const char *strstrwrapper(const char *haystack, const char *needle,
|
||||
const char *start)
|
||||
{
|
||||
/* start can be 1 character before the start or after the end of the
|
||||
* line. In either case, we just say no match was found. */
|
||||
if ((start > haystack && *(start - 1) == '\0') || start < haystack)
|
||||
return NULL;
|
||||
|
||||
assert(haystack != NULL && needle != NULL && start != NULL);
|
||||
|
||||
#ifdef HAVE_REGEX_H
|
||||
if (ISSET(USE_REGEXP)) {
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(BACKWARDS_SEARCH)) {
|
||||
if (regexec(&search_regexp, haystack, 1, regmatches,
|
||||
0) == 0 && haystack + regmatches[0].rm_so <= start) {
|
||||
const char *retval = haystack + regmatches[0].rm_so;
|
||||
|
||||
/* Search forward until there are no more matches. */
|
||||
while (regexec(&search_regexp, retval + 1, 1,
|
||||
regmatches, REG_NOTBOL) == 0 &&
|
||||
retval + regmatches[0].rm_so + 1 <= start)
|
||||
retval += regmatches[0].rm_so + 1;
|
||||
/* Finally, put the subexpression matches in global
|
||||
* variable regmatches. The REG_NOTBOL flag doesn't
|
||||
* matter now. */
|
||||
regexec(&search_regexp, retval, 10, regmatches, 0);
|
||||
return retval;
|
||||
}
|
||||
} else
|
||||
#endif /* !NANO_TINY */
|
||||
if (regexec(&search_regexp, start, 10, regmatches,
|
||||
(start > haystack) ? REG_NOTBOL : 0) == 0) {
|
||||
const char *retval = start + regmatches[0].rm_so;
|
||||
|
||||
regexec(&search_regexp, retval, 10, regmatches, 0);
|
||||
return retval;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif /* HAVE_REGEX_H */
|
||||
#if !defined(NANO_TINY) || !defined(DISABLE_SPELLER)
|
||||
if (ISSET(CASE_SENSITIVE)) {
|
||||
#ifndef NANO_TINY
|
||||
if (ISSET(BACKWARDS_SEARCH))
|
||||
return revstrstr(haystack, needle, start);
|
||||
else
|
||||
#endif
|
||||
return strstr(start, needle);
|
||||
}
|
||||
#endif /* !DISABLE_SPELLER || !NANO_TINY */
|
||||
#ifndef NANO_TINY
|
||||
else if (ISSET(BACKWARDS_SEARCH))
|
||||
return mbrevstrcasestr(haystack, needle, start);
|
||||
#endif
|
||||
return mbstrcasestr(start, needle);
|
||||
}
|
||||
|
||||
/* This is a wrapper for the perror() function. The wrapper temporarily
|
||||
* leaves curses mode, calls perror() (which writes to stderr), and then
|
||||
* reenters curses mode, updating the screen in the process. Note that
|
||||
* nperror() causes the window to flicker once. */
|
||||
void nperror(const char *s)
|
||||
{
|
||||
endwin();
|
||||
perror(s);
|
||||
doupdate();
|
||||
}
|
||||
|
||||
/* This is a wrapper for the malloc() function that properly handles
|
||||
* things when we run out of memory. Thanks, BG, many people have been
|
||||
* asking for this... */
|
||||
void *nmalloc(size_t howmuch)
|
||||
{
|
||||
void *r = malloc(howmuch);
|
||||
|
||||
if (r == NULL && howmuch != 0)
|
||||
die(_("nano is out of memory!"));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* This is a wrapper for the realloc() function that properly handles
|
||||
* things when we run out of memory. */
|
||||
void *nrealloc(void *ptr, size_t howmuch)
|
||||
{
|
||||
void *r = realloc(ptr, howmuch);
|
||||
|
||||
if (r == NULL && howmuch != 0)
|
||||
die(_("nano is out of memory!"));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Copy the first n characters of one malloc()ed string to another
|
||||
* pointer. Should be used as: "dest = mallocstrncpy(dest, src,
|
||||
* n);". */
|
||||
char *mallocstrncpy(char *dest, const char *src, size_t n)
|
||||
{
|
||||
if (src == NULL)
|
||||
src = "";
|
||||
|
||||
if (src != dest)
|
||||
free(dest);
|
||||
|
||||
dest = charalloc(n);
|
||||
strncpy(dest, src, n);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
/* Copy one malloc()ed string to another pointer. Should be used as:
|
||||
* "dest = mallocstrcpy(dest, src);". */
|
||||
char *mallocstrcpy(char *dest, const char *src)
|
||||
{
|
||||
return mallocstrncpy(dest, src, (src == NULL) ? 1 :
|
||||
strlen(src) + 1);
|
||||
}
|
||||
|
||||
/* Free the malloc()ed string at dest and return the malloc()ed string
|
||||
* at src. Should be used as: "answer = mallocstrassn(answer,
|
||||
* real_dir_from_tilde(answer));". */
|
||||
char *mallocstrassn(char *dest, char *src)
|
||||
{
|
||||
free(dest);
|
||||
return src;
|
||||
}
|
||||
|
||||
/* nano scrolls horizontally within a line in chunks. Return the column
|
||||
* number of the first character displayed in the edit window when the
|
||||
* cursor is at the given column. Note that (0 <= column -
|
||||
* get_page_start(column) < COLS). */
|
||||
size_t get_page_start(size_t column)
|
||||
{
|
||||
if (column == 0 || column < COLS - 1)
|
||||
return 0;
|
||||
else if (COLS > 8)
|
||||
return column - 7 - (column - 7) % (COLS - 8);
|
||||
else
|
||||
return column - (COLS - 2);
|
||||
}
|
||||
|
||||
/* Return the placewewant associated with current_x, i.e. the zero-based
|
||||
* column position of the cursor. The value will be no smaller than
|
||||
* current_x. */
|
||||
size_t xplustabs(void)
|
||||
{
|
||||
return strnlenpt(openfile->current->data, openfile->current_x);
|
||||
}
|
||||
|
||||
/* Return the index in s of the character displayed at the given column,
|
||||
* i.e. the largest value such that strnlenpt(s, actual_x(s, column)) <=
|
||||
* column. */
|
||||
size_t actual_x(const char *s, size_t column)
|
||||
{
|
||||
size_t i = 0;
|
||||
/* The position in s, returned. */
|
||||
size_t len = 0;
|
||||
/* The screen display width to s[i]. */
|
||||
|
||||
assert(s != NULL);
|
||||
|
||||
while (*s != '\0') {
|
||||
int s_len = parse_mbchar(s, NULL, &len);
|
||||
|
||||
if (len > column)
|
||||
break;
|
||||
|
||||
i += s_len;
|
||||
s += s_len;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/* A strnlen() with tabs and multicolumn characters factored in, similar
|
||||
* to xplustabs(). How many columns wide are the first maxlen characters
|
||||
* of s? */
|
||||
size_t strnlenpt(const char *s, size_t maxlen)
|
||||
{
|
||||
size_t len = 0;
|
||||
/* The screen display width to s[i]. */
|
||||
|
||||
if (maxlen == 0)
|
||||
return 0;
|
||||
|
||||
assert(s != NULL);
|
||||
|
||||
while (*s != '\0') {
|
||||
int s_len = parse_mbchar(s, NULL, &len);
|
||||
|
||||
s += s_len;
|
||||
|
||||
if (maxlen <= s_len)
|
||||
break;
|
||||
|
||||
maxlen -= s_len;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/* A strlen() with tabs and multicolumn characters factored in, similar
|
||||
* to xplustabs(). How many columns wide is s? */
|
||||
size_t strlenpt(const char *s)
|
||||
{
|
||||
return strnlenpt(s, (size_t)-1);
|
||||
}
|
||||
|
||||
/* Append a new magicline to filebot. */
|
||||
void new_magicline(void)
|
||||
{
|
||||
openfile->filebot->next = (filestruct *)nmalloc(sizeof(filestruct));
|
||||
openfile->filebot->next->data = mallocstrcpy(NULL, "");
|
||||
openfile->filebot->next->prev = openfile->filebot;
|
||||
openfile->filebot->next->next = NULL;
|
||||
openfile->filebot->next->lineno = openfile->filebot->lineno + 1;
|
||||
openfile->filebot = openfile->filebot->next;
|
||||
openfile->totsize++;
|
||||
}
|
||||
|
||||
#ifndef NANO_TINY
|
||||
/* Remove the magicline from filebot, if there is one and it isn't the
|
||||
* only line in the file. Assume that edittop and current are not at
|
||||
* filebot. */
|
||||
void remove_magicline(void)
|
||||
{
|
||||
if (openfile->filebot->data[0] == '\0' &&
|
||||
openfile->filebot != openfile->fileage) {
|
||||
assert(openfile->filebot != openfile->edittop && openfile->filebot != openfile->current);
|
||||
|
||||
openfile->filebot = openfile->filebot->prev;
|
||||
free_filestruct(openfile->filebot->next);
|
||||
openfile->filebot->next = NULL;
|
||||
openfile->totsize--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set top_x and bot_x to the top and bottom x-coordinates of the mark,
|
||||
* respectively, based on the locations of top and bot. If
|
||||
* right_side_up isn't NULL, set it to TRUE If the mark begins with
|
||||
* (mark_begin, mark_begin_x) and ends with (current, current_x), or
|
||||
* FALSE otherwise. */
|
||||
void mark_order(const filestruct **top, size_t *top_x, const filestruct
|
||||
**bot, size_t *bot_x, bool *right_side_up)
|
||||
{
|
||||
assert(top != NULL && top_x != NULL && bot != NULL && bot_x != NULL);
|
||||
|
||||
if ((openfile->current->lineno == openfile->mark_begin->lineno &&
|
||||
openfile->current_x > openfile->mark_begin_x) ||
|
||||
openfile->current->lineno > openfile->mark_begin->lineno) {
|
||||
*top = openfile->mark_begin;
|
||||
*top_x = openfile->mark_begin_x;
|
||||
*bot = openfile->current;
|
||||
*bot_x = openfile->current_x;
|
||||
if (right_side_up != NULL)
|
||||
*right_side_up = TRUE;
|
||||
} else {
|
||||
*bot = openfile->mark_begin;
|
||||
*bot_x = openfile->mark_begin_x;
|
||||
*top = openfile->current;
|
||||
*top_x = openfile->current_x;
|
||||
if (right_side_up != NULL)
|
||||
*right_side_up = FALSE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Calculate the number of characters between begin and end, and return
|
||||
* it. */
|
||||
size_t get_totsize(const filestruct *begin, const filestruct *end)
|
||||
{
|
||||
size_t totsize = 0;
|
||||
const filestruct *f;
|
||||
|
||||
/* Go through the lines from begin to end->prev, if we can. */
|
||||
for (f = begin; f != end && f != NULL; f = f->next) {
|
||||
/* Count the number of characters on this line. */
|
||||
totsize += mbstrlen(f->data);
|
||||
|
||||
/* Count the newline if we have one. */
|
||||
if (f->next != NULL)
|
||||
totsize++;
|
||||
}
|
||||
|
||||
/* Go through the line at end, if we can. */
|
||||
if (f != NULL) {
|
||||
/* Count the number of characters on this line. */
|
||||
totsize += mbstrlen(f->data);
|
||||
|
||||
/* Count the newline if we have one. */
|
||||
if (f->next != NULL)
|
||||
totsize++;
|
||||
}
|
||||
|
||||
return totsize;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Dump the filestruct inptr to stderr. */
|
||||
void dump_filestruct(const filestruct *inptr)
|
||||
{
|
||||
if (inptr == openfile->fileage)
|
||||
fprintf(stderr, "Dumping file buffer to stderr...\n");
|
||||
else if (inptr == cutbuffer)
|
||||
fprintf(stderr, "Dumping cutbuffer to stderr...\n");
|
||||
else
|
||||
fprintf(stderr, "Dumping a buffer to stderr...\n");
|
||||
|
||||
while (inptr != NULL) {
|
||||
fprintf(stderr, "(%ld) %s\n", (long)inptr->lineno, inptr->data);
|
||||
inptr = inptr->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dump the current buffer's filestruct to stderr in reverse. */
|
||||
void dump_filestruct_reverse(void)
|
||||
{
|
||||
const filestruct *fileptr = openfile->filebot;
|
||||
|
||||
while (fileptr != NULL) {
|
||||
fprintf(stderr, "(%ld) %s\n", (long)fileptr->lineno,
|
||||
fileptr->data);
|
||||
fileptr = fileptr->prev;
|
||||
}
|
||||
}
|
||||
#endif /* DEBUG */
|
3399
src/winio.c
Normal file
3399
src/winio.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user