diff options
Diffstat (limited to 'editors')
-rw-r--r-- | editors/vi.c | 100 |
1 files changed, 97 insertions, 3 deletions
diff --git a/editors/vi.c b/editors/vi.c index 2c1048a4c..b973cc056 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -112,6 +112,15 @@ | |||
112 | //config: help | 112 | //config: help |
113 | //config: Enable the editor to set some (ai, ic, showmatch) options. | 113 | //config: Enable the editor to set some (ai, ic, showmatch) options. |
114 | //config: | 114 | //config: |
115 | //config:config FEATURE_VI_FILE_FORMAT | ||
116 | //config: bool "Enable detection of file format" | ||
117 | //config: default y | ||
118 | //config: depends on VI && FEATURE_VI_SETOPTS && PLATFORM_MINGW32 | ||
119 | //config: help | ||
120 | //config: Enable the editor to detect the format of files it reads | ||
121 | //config: so they can be written out with the appropriate line | ||
122 | //config: endings. Enable the 'fileformats' option. | ||
123 | //config: | ||
115 | //config:config FEATURE_VI_SET | 124 | //config:config FEATURE_VI_SET |
116 | //config: bool "Support :set" | 125 | //config: bool "Support :set" |
117 | //config: default y | 126 | //config: default y |
@@ -297,6 +306,7 @@ struct globals { | |||
297 | 306 | ||
298 | // the rest | 307 | // the rest |
299 | #if ENABLE_FEATURE_VI_SETOPTS | 308 | #if ENABLE_FEATURE_VI_SETOPTS |
309 | #if !ENABLE_FEATURE_VI_FILE_FORMAT | ||
300 | smallint vi_setops; // set by setops() | 310 | smallint vi_setops; // set by setops() |
301 | #define VI_AUTOINDENT (1 << 0) | 311 | #define VI_AUTOINDENT (1 << 0) |
302 | #define VI_EXPANDTAB (1 << 1) | 312 | #define VI_EXPANDTAB (1 << 1) |
@@ -304,6 +314,17 @@ struct globals { | |||
304 | #define VI_IGNORECASE (1 << 3) | 314 | #define VI_IGNORECASE (1 << 3) |
305 | #define VI_SHOWMATCH (1 << 4) | 315 | #define VI_SHOWMATCH (1 << 4) |
306 | #define VI_TABSTOP (1 << 5) | 316 | #define VI_TABSTOP (1 << 5) |
317 | #else | ||
318 | smalluint vi_setops; // set by setops() | ||
319 | #define VI_AUTOINDENT (1 << 0) | ||
320 | #define VI_EXPANDTAB (1 << 1) | ||
321 | #define VI_FILEFORMAT (1 << 2) | ||
322 | #define VI_FILEFORMATS (1 << 3) | ||
323 | #define VI_ERR_METHOD (1 << 4) | ||
324 | #define VI_IGNORECASE (1 << 5) | ||
325 | #define VI_SHOWMATCH (1 << 6) | ||
326 | #define VI_TABSTOP (1 << 7) | ||
327 | #endif | ||
307 | #define autoindent (vi_setops & VI_AUTOINDENT) | 328 | #define autoindent (vi_setops & VI_AUTOINDENT) |
308 | #define expandtab (vi_setops & VI_EXPANDTAB ) | 329 | #define expandtab (vi_setops & VI_EXPANDTAB ) |
309 | #define err_method (vi_setops & VI_ERR_METHOD) // indicate error with beep or flash | 330 | #define err_method (vi_setops & VI_ERR_METHOD) // indicate error with beep or flash |
@@ -313,10 +334,18 @@ struct globals { | |||
313 | #define OPTS_STR \ | 334 | #define OPTS_STR \ |
314 | "ai\0""autoindent\0" \ | 335 | "ai\0""autoindent\0" \ |
315 | "et\0""expandtab\0" \ | 336 | "et\0""expandtab\0" \ |
337 | IF_FEATURE_VI_FILE_FORMAT("ff\0""fileformat\0") \ | ||
338 | IF_FEATURE_VI_FILE_FORMAT("ffs\0""fileformats\0") \ | ||
316 | "fl\0""flash\0" \ | 339 | "fl\0""flash\0" \ |
317 | "ic\0""ignorecase\0" \ | 340 | "ic\0""ignorecase\0" \ |
318 | "sm\0""showmatch\0" \ | 341 | "sm\0""showmatch\0" \ |
319 | "ts\0""tabstop\0" | 342 | "ts\0""tabstop\0" |
343 | |||
344 | #define FF_DOS_UNIX 0 | ||
345 | #define FF_UNIX_DOS 1 | ||
346 | #define FORMATS_STR \ | ||
347 | "dos,unix\0" \ | ||
348 | "unix,dos\0" | ||
320 | #else | 349 | #else |
321 | #define autoindent (0) | 350 | #define autoindent (0) |
322 | #define expandtab (0) | 351 | #define expandtab (0) |
@@ -380,6 +409,10 @@ struct globals { | |||
380 | #if ENABLE_FEATURE_VI_SETOPTS | 409 | #if ENABLE_FEATURE_VI_SETOPTS |
381 | int indentcol; // column of recently autoindent, 0 or -1 | 410 | int indentcol; // column of recently autoindent, 0 or -1 |
382 | #endif | 411 | #endif |
412 | #if ENABLE_FEATURE_VI_FILE_FORMAT | ||
413 | smallint fileformat; | ||
414 | smallint fileformats; | ||
415 | #endif | ||
383 | smallint cmd_error; | 416 | smallint cmd_error; |
384 | 417 | ||
385 | // former statics | 418 | // former statics |
@@ -507,6 +540,8 @@ struct globals { | |||
507 | #define dotcnt (G.dotcnt ) | 540 | #define dotcnt (G.dotcnt ) |
508 | #define last_search_pattern (G.last_search_pattern) | 541 | #define last_search_pattern (G.last_search_pattern) |
509 | #define indentcol (G.indentcol ) | 542 | #define indentcol (G.indentcol ) |
543 | #define fileformat (G.fileformat ) | ||
544 | #define fileformats (G.fileformats ) | ||
510 | #define cmd_error (G.cmd_error ) | 545 | #define cmd_error (G.cmd_error ) |
511 | 546 | ||
512 | #define edit_file__cur_line (G.edit_file__cur_line) | 547 | #define edit_file__cur_line (G.edit_file__cur_line) |
@@ -2066,6 +2101,10 @@ static int file_insert(const char *fn, char *p, int initial) | |||
2066 | undo_push_insert(p, size, ALLOW_UNDO); | 2101 | undo_push_insert(p, size, ALLOW_UNDO); |
2067 | } | 2102 | } |
2068 | # endif | 2103 | # endif |
2104 | #if ENABLE_FEATURE_VI_FILE_FORMAT | ||
2105 | if (initial && cnt > 0) | ||
2106 | fileformat = cnt == size ? FF_UNIX_DOS : FF_DOS_UNIX; | ||
2107 | #endif | ||
2069 | fi: | 2108 | fi: |
2070 | close(fd); | 2109 | close(fd); |
2071 | 2110 | ||
@@ -2342,6 +2381,9 @@ static int init_text_buffer(char *fn) | |||
2342 | free(text); | 2381 | free(text); |
2343 | text_size = 10240; | 2382 | text_size = 10240; |
2344 | screenbegin = dot = end = text = xzalloc(text_size); | 2383 | screenbegin = dot = end = text = xzalloc(text_size); |
2384 | #if ENABLE_FEATURE_VI_FILE_FORMAT | ||
2385 | fileformat = fileformats; | ||
2386 | #endif | ||
2345 | 2387 | ||
2346 | update_filename(fn); | 2388 | update_filename(fn); |
2347 | rc = file_insert(fn, text, 1); | 2389 | rc = file_insert(fn, text, 1); |
@@ -2387,6 +2429,13 @@ static uintptr_t string_insert(char *p, const char *s, int undo) // insert the s | |||
2387 | static int file_write(char *fn, char *first, char *last) | 2429 | static int file_write(char *fn, char *first, char *last) |
2388 | { | 2430 | { |
2389 | int fd, cnt, charcnt; | 2431 | int fd, cnt, charcnt; |
2432 | #if ENABLE_PLATFORM_MINGW32 | ||
2433 | # if ENABLE_FEATURE_VI_FILE_FORMAT | ||
2434 | # define dos (fileformat == FF_DOS_UNIX) | ||
2435 | # else | ||
2436 | # define dos (1) | ||
2437 | # endif | ||
2438 | #endif | ||
2390 | 2439 | ||
2391 | if (fn == 0) { | 2440 | if (fn == 0) { |
2392 | status_line_bold("No current filename"); | 2441 | status_line_bold("No current filename"); |
@@ -2398,7 +2447,7 @@ static int file_write(char *fn, char *first, char *last) | |||
2398 | #if !ENABLE_PLATFORM_MINGW32 | 2447 | #if !ENABLE_PLATFORM_MINGW32 |
2399 | fd = open(fn, (O_WRONLY | O_CREAT), 0666); | 2448 | fd = open(fn, (O_WRONLY | O_CREAT), 0666); |
2400 | #else | 2449 | #else |
2401 | fd = open(fn, (O_WRONLY | O_CREAT | _O_TEXT), 0666); | 2450 | fd = open(fn, (O_WRONLY | O_CREAT | (dos ? _O_TEXT : 0)), 0666); |
2402 | #endif | 2451 | #endif |
2403 | if (fd < 0) | 2452 | if (fd < 0) |
2404 | return -1; | 2453 | return -1; |
@@ -2407,9 +2456,9 @@ static int file_write(char *fn, char *first, char *last) | |||
2407 | #if !ENABLE_PLATFORM_MINGW32 | 2456 | #if !ENABLE_PLATFORM_MINGW32 |
2408 | ftruncate(fd, charcnt); | 2457 | ftruncate(fd, charcnt); |
2409 | #else | 2458 | #else |
2410 | // File was written in text mode; this makes it bigger so adjust | 2459 | // If file was written in text mode it will be bigger so adjust |
2411 | // the truncation to match. | 2460 | // the truncation to match. |
2412 | ftruncate(fd, charcnt + count_cr(first, cnt)); | 2461 | ftruncate(fd, charcnt + (dos ? count_cr(first, cnt) : 0)); |
2413 | #endif | 2462 | #endif |
2414 | if (charcnt == cnt) { | 2463 | if (charcnt == cnt) { |
2415 | // good write | 2464 | // good write |
@@ -2699,6 +2748,7 @@ static void setops(char *args, int flg_no) | |||
2699 | 2748 | ||
2700 | index = 1 << (index >> 1); // convert to VI_bit | 2749 | index = 1 << (index >> 1); // convert to VI_bit |
2701 | 2750 | ||
2751 | #if !ENABLE_FEATURE_VI_FILE_FORMAT | ||
2702 | if (index & VI_TABSTOP) { | 2752 | if (index & VI_TABSTOP) { |
2703 | int t; | 2753 | int t; |
2704 | if (!eq || flg_no) // no "=NNN" or it is "notabstop"? | 2754 | if (!eq || flg_no) // no "=NNN" or it is "notabstop"? |
@@ -2709,6 +2759,27 @@ static void setops(char *args, int flg_no) | |||
2709 | tabstop = t; | 2759 | tabstop = t; |
2710 | return; | 2760 | return; |
2711 | } | 2761 | } |
2762 | #else | ||
2763 | if (index & VI_FILEFORMAT) | ||
2764 | goto bad; | ||
2765 | if (index & (VI_TABSTOP | VI_FILEFORMATS)) { | ||
2766 | if (!eq || flg_no) // no "=NNN" or it is "notabstop"? | ||
2767 | goto bad; | ||
2768 | if (index & VI_TABSTOP) { | ||
2769 | int t = bb_strtou(eq + 1, NULL, 10); | ||
2770 | if (t <= 0 || t > MAX_TABSTOP) | ||
2771 | goto bad; | ||
2772 | tabstop = t; | ||
2773 | return; | ||
2774 | } else { // VI_FILEFORMATS | ||
2775 | int t = index_in_strings(FORMATS_STR, eq + 1); | ||
2776 | if (t < 0) | ||
2777 | goto bad; | ||
2778 | fileformats = t; | ||
2779 | return; | ||
2780 | } | ||
2781 | } | ||
2782 | #endif | ||
2712 | if (eq) goto bad; // boolean option has "="? | 2783 | if (eq) goto bad; // boolean option has "="? |
2713 | if (flg_no) { | 2784 | if (flg_no) { |
2714 | vi_setops &= ~index; | 2785 | vi_setops &= ~index; |
@@ -3205,6 +3276,7 @@ static void colon(char *buf) | |||
3205 | if (!args[0] || strcmp(args, "all") == 0) { | 3276 | if (!args[0] || strcmp(args, "all") == 0) { |
3206 | // print out values of all options | 3277 | // print out values of all options |
3207 | # if ENABLE_FEATURE_VI_SETOPTS | 3278 | # if ENABLE_FEATURE_VI_SETOPTS |
3279 | # if !ENABLE_FEATURE_VI_FILE_FORMAT | ||
3208 | status_line_bold( | 3280 | status_line_bold( |
3209 | "%sautoindent " | 3281 | "%sautoindent " |
3210 | "%sexpandtab " | 3282 | "%sexpandtab " |
@@ -3219,6 +3291,28 @@ static void colon(char *buf) | |||
3219 | showmatch ? "" : "no", | 3291 | showmatch ? "" : "no", |
3220 | tabstop | 3292 | tabstop |
3221 | ); | 3293 | ); |
3294 | # else // ENABLE_FEATURE_VI_FILE_FORMAT | ||
3295 | unsigned int mask = 1, j = 0; | ||
3296 | go_bottom_and_clear_to_eol(); | ||
3297 | for (;;) { | ||
3298 | const char *name = nth_string(OPTS_STR, 2 * j + 1); | ||
3299 | if (!name[0]) | ||
3300 | break; | ||
3301 | if (mask == VI_FILEFORMAT) | ||
3302 | printf("%s=%s ", name, nth_string("dos\0unix\0", fileformat)); | ||
3303 | else if (mask == VI_FILEFORMATS) | ||
3304 | printf("%s=%s ", name, nth_string(FORMATS_STR, fileformats)); | ||
3305 | else if (mask == VI_TABSTOP) | ||
3306 | printf("%s=%u ", name, tabstop); | ||
3307 | else | ||
3308 | printf("%s%s ", vi_setops & mask ? "" : "no", name); | ||
3309 | if (j++ == 4) | ||
3310 | bb_putchar('\n'); | ||
3311 | mask <<= 1; | ||
3312 | } | ||
3313 | bb_putchar('\n'); | ||
3314 | Hit_Return(); | ||
3315 | # endif | ||
3222 | # endif | 3316 | # endif |
3223 | goto ret; | 3317 | goto ret; |
3224 | } | 3318 | } |