aboutsummaryrefslogtreecommitdiff
path: root/editors/vi.c
diff options
context:
space:
mode:
Diffstat (limited to 'editors/vi.c')
-rw-r--r--editors/vi.c221
1 files changed, 181 insertions, 40 deletions
diff --git a/editors/vi.c b/editors/vi.c
index 3656fee95..3f4ccdcdd 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -21,6 +21,134 @@
21 * An "ex" line oriented mode- maybe using "cmdedit" 21 * An "ex" line oriented mode- maybe using "cmdedit"
22 */ 22 */
23 23
24//config:config VI
25//config: bool "vi"
26//config: default y
27//config: help
28//config: 'vi' is a text editor. More specifically, it is the One True
29//config: text editor <grin>. It does, however, have a rather steep
30//config: learning curve. If you are not already comfortable with 'vi'
31//config: you may wish to use something else.
32//config:
33//config:config FEATURE_VI_MAX_LEN
34//config: int "Maximum screen width in vi"
35//config: range 256 16384
36//config: default 4096
37//config: depends on VI
38//config: help
39//config: Contrary to what you may think, this is not eating much.
40//config: Make it smaller than 4k only if you are very limited on memory.
41//config:
42//config:config FEATURE_VI_8BIT
43//config: bool "Allow vi to display 8-bit chars (otherwise shows dots)"
44//config: default n
45//config: depends on VI
46//config: help
47//config: If your terminal can display characters with high bit set,
48//config: you may want to enable this. Note: vi is not Unicode-capable.
49//config: If your terminal combines several 8-bit bytes into one character
50//config: (as in Unicode mode), this will not work properly.
51//config:
52//config:config FEATURE_VI_COLON
53//config: bool "Enable \":\" colon commands (no \"ex\" mode)"
54//config: default y
55//config: depends on VI
56//config: help
57//config: Enable a limited set of colon commands for vi. This does not
58//config: provide an "ex" mode.
59//config:
60//config:config FEATURE_VI_YANKMARK
61//config: bool "Enable yank/put commands and mark cmds"
62//config: default y
63//config: depends on VI
64//config: help
65//config: This will enable you to use yank and put, as well as mark in
66//config: busybox vi.
67//config:
68//config:config FEATURE_VI_SEARCH
69//config: bool "Enable search and replace cmds"
70//config: default y
71//config: depends on VI
72//config: help
73//config: Select this if you wish to be able to do search and replace in
74//config: busybox vi.
75//config:
76//config:config FEATURE_VI_REGEX_SEARCH
77//config: bool "Enable regex in search and replace"
78//config: default n # Uses GNU regex, which may be unavailable. FIXME
79//config: depends on FEATURE_VI_SEARCH
80//config: help
81//config: Use extended regex search.
82//config:
83//config:config FEATURE_VI_USE_SIGNALS
84//config: bool "Catch signals"
85//config: default y
86//config: depends on VI
87//config: help
88//config: Selecting this option will make busybox vi signal aware. This will
89//config: make busybox vi support SIGWINCH to deal with Window Changes, catch
90//config: Ctrl-Z and Ctrl-C and alarms.
91//config:
92//config:config FEATURE_VI_DOT_CMD
93//config: bool "Remember previous cmd and \".\" cmd"
94//config: default y
95//config: depends on VI
96//config: help
97//config: Make busybox vi remember the last command and be able to repeat it.
98//config:
99//config:config FEATURE_VI_READONLY
100//config: bool "Enable -R option and \"view\" mode"
101//config: default y
102//config: depends on VI
103//config: help
104//config: Enable the read-only command line option, which allows the user to
105//config: open a file in read-only mode.
106//config:
107//config:config FEATURE_VI_SETOPTS
108//config: bool "Enable set-able options, ai ic showmatch"
109//config: default y
110//config: depends on VI
111//config: help
112//config: Enable the editor to set some (ai, ic, showmatch) options.
113//config:
114//config:config FEATURE_VI_SET
115//config: bool "Support for :set"
116//config: default y
117//config: depends on VI
118//config: help
119//config: Support for ":set".
120//config:
121//config:config FEATURE_VI_WIN_RESIZE
122//config: bool "Handle window resize"
123//config: default y
124//config: depends on VI
125//config: help
126//config: Make busybox vi behave nicely with terminals that get resized.
127//config:
128//config:config FEATURE_VI_ASK_TERMINAL
129//config: bool "Use 'tell me cursor position' ESC sequence to measure window"
130//config: default y
131//config: depends on VI
132//config: help
133//config: If terminal size can't be retrieved and $LINES/$COLUMNS are not set,
134//config: this option makes vi perform a last-ditch effort to find it:
135//config: vi positions cursor to 999,999 and asks terminal to report real
136//config: cursor position using "ESC [ 6 n" escape sequence, then reads stdin.
137//config:
138//config: This is not clean but helps a lot on serial lines and such.
139//config:
140//config:config FEATURE_VI_OPTIMIZE_CURSOR
141//config: bool "Optimize cursor movement"
142//config: default y
143//config: depends on VI
144//config: help
145//config: This will make the cursor movement faster, but requires more memory
146//config: and it makes the applet a tiny bit larger.
147
148//applet:IF_VI(APPLET(vi, BB_DIR_BIN, BB_SUID_DROP))
149
150//kbuild:lib-$(CONFIG_VI) += vi.o
151
24//usage:#define vi_trivial_usage 152//usage:#define vi_trivial_usage
25//usage: "[OPTIONS] [FILE]..." 153//usage: "[OPTIONS] [FILE]..."
26//usage:#define vi_full_usage "\n\n" 154//usage:#define vi_full_usage "\n\n"
@@ -33,6 +161,7 @@
33//usage: ) 161//usage: )
34//usage: "\n -H Short help regarding available features" 162//usage: "\n -H Short help regarding available features"
35 163
164#include <regex.h>
36#include "libbb.h" 165#include "libbb.h"
37 166
38/* the CRASHME code is unmaintained, and doesn't currently build */ 167/* the CRASHME code is unmaintained, and doesn't currently build */
@@ -366,7 +495,6 @@ static void Hit_Return(void);
366 495
367#if ENABLE_FEATURE_VI_SEARCH 496#if ENABLE_FEATURE_VI_SEARCH
368static char *char_search(char *, const char *, int, int); // search for pattern starting at p 497static char *char_search(char *, const char *, int, int); // search for pattern starting at p
369static int mycmp(const char *, const char *, int); // string cmp based in "ignorecase"
370#endif 498#endif
371#if ENABLE_FEATURE_VI_COLON 499#if ENABLE_FEATURE_VI_COLON
372static char *get_one_address(char *, int *); // get colon addr, if present 500static char *get_one_address(char *, int *); // get colon addr, if present
@@ -1561,48 +1689,16 @@ static char *new_screen(int ro, int co)
1561} 1689}
1562 1690
1563#if ENABLE_FEATURE_VI_SEARCH 1691#if ENABLE_FEATURE_VI_SEARCH
1564static int mycmp(const char *s1, const char *s2, int len) 1692
1565{ 1693# if ENABLE_FEATURE_VI_REGEX_SEARCH
1566 if (ENABLE_FEATURE_VI_SETOPTS && ignorecase) {
1567 return strncasecmp(s1, s2, len);
1568 }
1569 return strncmp(s1, s2, len);
1570}
1571 1694
1572// search for pattern starting at p 1695// search for pattern starting at p
1573static char *char_search(char *p, const char *pat, int dir, int range) 1696static char *char_search(char *p, const char *pat, int dir, int range)
1574{ 1697{
1575#ifndef REGEX_SEARCH
1576 char *start, *stop;
1577 int len;
1578
1579 len = strlen(pat);
1580 if (dir == FORWARD) {
1581 stop = end - 1; // assume range is p - end-1
1582 if (range == LIMITED)
1583 stop = next_line(p); // range is to next line
1584 for (start = p; start < stop; start++) {
1585 if (mycmp(start, pat, len) == 0) {
1586 return start;
1587 }
1588 }
1589 } else if (dir == BACK) {
1590 stop = text; // assume range is text - p
1591 if (range == LIMITED)
1592 stop = prev_line(p); // range is to prev line
1593 for (start = p - len; start >= stop; start--) {
1594 if (mycmp(start, pat, len) == 0) {
1595 return start;
1596 }
1597 }
1598 }
1599 // pattern not found
1600 return NULL;
1601#else /* REGEX_SEARCH */
1602 char *q; 1698 char *q;
1603 struct re_pattern_buffer preg; 1699 struct re_pattern_buffer preg;
1604 int i; 1700 int i;
1605 int size, range; 1701 int size;
1606 1702
1607 re_syntax_options = RE_SYNTAX_POSIX_EXTENDED; 1703 re_syntax_options = RE_SYNTAX_POSIX_EXTENDED;
1608 preg.translate = 0; 1704 preg.translate = 0;
@@ -1625,7 +1721,7 @@ static char *char_search(char *p, const char *pat, int dir, int range)
1625 // RANGE could be negative if we are searching backwards 1721 // RANGE could be negative if we are searching backwards
1626 range = q - p; 1722 range = q - p;
1627 1723
1628 q = re_compile_pattern(pat, strlen(pat), &preg); 1724 q = (char *)re_compile_pattern(pat, strlen(pat), (struct re_pattern_buffer *)&preg);
1629 if (q != 0) { 1725 if (q != 0) {
1630 // The pattern was not compiled 1726 // The pattern was not compiled
1631 status_line_bold("bad search pattern: \"%s\": %s", pat, q); 1727 status_line_bold("bad search pattern: \"%s\": %s", pat, q);
@@ -1659,8 +1755,53 @@ static char *char_search(char *p, const char *pat, int dir, int range)
1659 p = p - i; 1755 p = p - i;
1660 } 1756 }
1661 return p; 1757 return p;
1662#endif /* REGEX_SEARCH */
1663} 1758}
1759
1760# else
1761
1762# if ENABLE_FEATURE_VI_SETOPTS
1763static int mycmp(const char *s1, const char *s2, int len)
1764{
1765 if (ignorecase) {
1766 return strncasecmp(s1, s2, len);
1767 }
1768 return strncmp(s1, s2, len);
1769}
1770# else
1771# define mycmp strncmp
1772# endif
1773
1774static char *char_search(char *p, const char *pat, int dir, int range)
1775{
1776 char *start, *stop;
1777 int len;
1778
1779 len = strlen(pat);
1780 if (dir == FORWARD) {
1781 stop = end - 1; // assume range is p - end-1
1782 if (range == LIMITED)
1783 stop = next_line(p); // range is to next line
1784 for (start = p; start < stop; start++) {
1785 if (mycmp(start, pat, len) == 0) {
1786 return start;
1787 }
1788 }
1789 } else if (dir == BACK) {
1790 stop = text; // assume range is text - p
1791 if (range == LIMITED)
1792 stop = prev_line(p); // range is to prev line
1793 for (start = p - len; start >= stop; start--) {
1794 if (mycmp(start, pat, len) == 0) {
1795 return start;
1796 }
1797 }
1798 }
1799 // pattern not found
1800 return NULL;
1801}
1802
1803# endif
1804
1664#endif /* FEATURE_VI_SEARCH */ 1805#endif /* FEATURE_VI_SEARCH */
1665 1806
1666static char *char_insert(char *p, char c) // insert the char c at 'p' 1807static char *char_insert(char *p, char c) // insert the char c at 'p'
@@ -2022,8 +2163,8 @@ static void show_help(void)
2022 "\n\tNamed buffers with \"x" 2163 "\n\tNamed buffers with \"x"
2023#endif 2164#endif
2024#if ENABLE_FEATURE_VI_READONLY 2165#if ENABLE_FEATURE_VI_READONLY
2025 "\n\tReadonly if vi is called as \"view\"" 2166 //not implemented: "\n\tReadonly if vi is called as \"view\""
2026 "\n\tReadonly with -R command line arg" 2167 //redundant: usage text says this too: "\n\tReadonly with -R command line arg"
2027#endif 2168#endif
2028#if ENABLE_FEATURE_VI_SET 2169#if ENABLE_FEATURE_VI_SET
2029 "\n\tSome colon mode commands with \':\'" 2170 "\n\tSome colon mode commands with \':\'"