summaryrefslogtreecommitdiff
path: root/editors/vi.c
diff options
context:
space:
mode:
Diffstat (limited to 'editors/vi.c')
-rw-r--r--editors/vi.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/editors/vi.c b/editors/vi.c
index c4360f8d3..a8b4dc5a4 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -349,7 +349,9 @@ struct globals {
349#if ENABLE_FEATURE_VI_USE_SIGNALS 349#if ENABLE_FEATURE_VI_USE_SIGNALS
350 sigjmp_buf restart; // int_handler() jumps to location remembered here 350 sigjmp_buf restart; // int_handler() jumps to location remembered here
351#endif 351#endif
352#if !ENABLE_PLATFORM_MINGW32
352 struct termios term_orig; // remember what the cooked mode was 353 struct termios term_orig; // remember what the cooked mode was
354#endif
353#if ENABLE_FEATURE_VI_COLON 355#if ENABLE_FEATURE_VI_COLON
354 char *initial_cmds[3]; // currently 2 entries, NULL terminated 356 char *initial_cmds[3]; // currently 2 entries, NULL terminated
355#endif 357#endif
@@ -545,6 +547,23 @@ static ALWAYS_INLINE int query_screen_dimensions(void)
545// sleep for 'h' 1/100 seconds, return 1/0 if stdin is (ready for read)/(not ready) 547// sleep for 'h' 1/100 seconds, return 1/0 if stdin is (ready for read)/(not ready)
546static int mysleep(int hund) 548static int mysleep(int hund)
547{ 549{
550#if ENABLE_PLATFORM_MINGW32
551 HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
552 DWORD ret;
553
554 if (hund == 0) {
555 // Allow two events in the queue. Otherwise pasted test isn't
556 // displayed because there's still a key release event waiting
557 // after the last character is processed.
558 DWORD nevent_out;
559
560 ret = GetNumberOfConsoleInputEvents(h, &nevent_out);
561 return ret != 0 ? (nevent_out > 2) : 0;
562 }
563 fflush_all();
564 ret = WaitForSingleObject(h, hund*10);
565 return ret != WAIT_TIMEOUT;
566#else
548 struct pollfd pfd[1]; 567 struct pollfd pfd[1];
549 568
550 if (hund != 0) 569 if (hund != 0)
@@ -553,9 +572,11 @@ static int mysleep(int hund)
553 pfd[0].fd = STDIN_FILENO; 572 pfd[0].fd = STDIN_FILENO;
554 pfd[0].events = POLLIN; 573 pfd[0].events = POLLIN;
555 return safe_poll(pfd, 1, hund*10) > 0; 574 return safe_poll(pfd, 1, hund*10) > 0;
575#endif
556} 576}
557 577
558//----- Set terminal attributes -------------------------------- 578//----- Set terminal attributes --------------------------------
579#if !ENABLE_PLATFORM_MINGW32
559static void rawmode(void) 580static void rawmode(void)
560{ 581{
561 // no TERMIOS_CLEAR_ISIG: leave ISIG on - allow signals 582 // no TERMIOS_CLEAR_ISIG: leave ISIG on - allow signals
@@ -567,6 +588,10 @@ static void cookmode(void)
567 fflush_all(); 588 fflush_all();
568 tcsetattr_stdin_TCSANOW(&term_orig); 589 tcsetattr_stdin_TCSANOW(&term_orig);
569} 590}
591#else
592#define rawmode() ((void)0)
593#define cookmode fflush_all
594#endif
570 595
571//----- Terminal Drawing --------------------------------------- 596//----- Terminal Drawing ---------------------------------------
572// The terminal is made up of 'rows' line of 'columns' columns. 597// The terminal is made up of 'rows' line of 'columns' columns.
@@ -1105,7 +1130,11 @@ static char *get_input_line(const char *prompt)
1105 c = get_one_char(); 1130 c = get_one_char();
1106 if (c == '\n' || c == '\r' || c == 27) 1131 if (c == '\n' || c == '\r' || c == 27)
1107 break; // this is end of input 1132 break; // this is end of input
1133#if !ENABLE_PLATFORM_MINGW32
1108 if (c == term_orig.c_cc[VERASE] || c == 8 || c == 127) { 1134 if (c == term_orig.c_cc[VERASE] || c == 8 || c == 127) {
1135#else
1136 if (c == 8 || c == 127) {
1137#endif
1109 // user wants to erase prev char 1138 // user wants to erase prev char
1110 buf[--i] = '\0'; 1139 buf[--i] = '\0';
1111 write1("\b \b"); // erase char on screen 1140 write1("\b \b"); // erase char on screen
@@ -1858,6 +1887,18 @@ static char *yank_delete(char *start, char *stop, int dist, int yf, int undo)
1858 return p; 1887 return p;
1859} 1888}
1860 1889
1890#if ENABLE_PLATFORM_MINGW32
1891static int count_cr(char *p, int len)
1892{
1893 int i, cnt;
1894
1895 for (i = cnt = 0; i < len; ++i)
1896 if (p[i] == '\n')
1897 ++cnt;
1898 return cnt;
1899}
1900#endif
1901
1861// might reallocate text[]! 1902// might reallocate text[]!
1862static int file_insert(const char *fn, char *p, int initial) 1903static int file_insert(const char *fn, char *p, int initial)
1863{ 1904{
@@ -1870,7 +1911,11 @@ static int file_insert(const char *fn, char *p, int initial)
1870 if (p > end) 1911 if (p > end)
1871 p = end; 1912 p = end;
1872 1913
1914#if !ENABLE_PLATFORM_MINGW32
1873 fd = open(fn, O_RDONLY); 1915 fd = open(fn, O_RDONLY);
1916#else
1917 fd = open(fn, O_RDONLY | _O_TEXT);
1918#endif
1874 if (fd < 0) { 1919 if (fd < 0) {
1875 if (!initial) 1920 if (!initial)
1876 status_line_bold_errno(fn); 1921 status_line_bold_errno(fn);
@@ -1893,8 +1938,15 @@ static int file_insert(const char *fn, char *p, int initial)
1893 status_line_bold_errno(fn); 1938 status_line_bold_errno(fn);
1894 p = text_hole_delete(p, p + size - 1, NO_UNDO); // un-do buffer insert 1939 p = text_hole_delete(p, p + size - 1, NO_UNDO); // un-do buffer insert
1895 } else if (cnt < size) { 1940 } else if (cnt < size) {
1941#if ENABLE_PLATFORM_MINGW32
1942 // On WIN32 a partial read might just mean CRs have been removed
1943 int cnt_cr = cnt + count_cr(p, cnt);
1944#endif
1896 // There was a partial read, shrink unused space 1945 // There was a partial read, shrink unused space
1897 p = text_hole_delete(p + cnt, p + size - 1, NO_UNDO); 1946 p = text_hole_delete(p + cnt, p + size - 1, NO_UNDO);
1947#if ENABLE_PLATFORM_MINGW32
1948 if (cnt_cr < size)
1949#endif
1898 status_line_bold("can't read '%s'", fn); 1950 status_line_bold("can't read '%s'", fn);
1899 } 1951 }
1900 fi: 1952 fi:
@@ -2001,7 +2053,11 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p'
2001 if ((p[-1] != '\n') && (dot > text)) { 2053 if ((p[-1] != '\n') && (dot > text)) {
2002 p--; 2054 p--;
2003 } 2055 }
2056#if !ENABLE_PLATFORM_MINGW32
2004 } else if (c == term_orig.c_cc[VERASE] || c == 8 || c == 127) { // Is this a BS 2057 } else if (c == term_orig.c_cc[VERASE] || c == 8 || c == 127) { // Is this a BS
2058#else
2059 } else if (c == 8 || c == 127) { // Is this a BS
2060#endif
2005 if (p > text) { 2061 if (p > text) {
2006 p--; 2062 p--;
2007 p = text_hole_delete(p, p, ALLOW_UNDO_QUEUED); // shrink buffer 1 char 2063 p = text_hole_delete(p, p, ALLOW_UNDO_QUEUED); // shrink buffer 1 char
@@ -2122,12 +2178,22 @@ static int file_write(char *fn, char *first, char *last)
2122 // By popular request we do not open file with O_TRUNC, 2178 // By popular request we do not open file with O_TRUNC,
2123 // but instead ftruncate() it _after_ successful write. 2179 // but instead ftruncate() it _after_ successful write.
2124 // Might reduce amount of data lost on power fail etc. 2180 // Might reduce amount of data lost on power fail etc.
2181#if !ENABLE_PLATFORM_MINGW32
2125 fd = open(fn, (O_WRONLY | O_CREAT), 0666); 2182 fd = open(fn, (O_WRONLY | O_CREAT), 0666);
2183#else
2184 fd = open(fn, (O_WRONLY | O_CREAT | _O_TEXT), 0666);
2185#endif
2126 if (fd < 0) 2186 if (fd < 0)
2127 return -1; 2187 return -1;
2128 cnt = last - first + 1; 2188 cnt = last - first + 1;
2129 charcnt = full_write(fd, first, cnt); 2189 charcnt = full_write(fd, first, cnt);
2190#if !ENABLE_PLATFORM_MINGW32
2130 ftruncate(fd, charcnt); 2191 ftruncate(fd, charcnt);
2192#else
2193 // File was written in text mode; this makes it bigger so adjust
2194 // the truncation to match.
2195 ftruncate(fd, charcnt + count_cr(first, cnt));
2196#endif
2131 if (charcnt == cnt) { 2197 if (charcnt == cnt) {
2132 // good write 2198 // good write
2133 //modified_count = FALSE; 2199 //modified_count = FALSE;