Skip to content

Commit 192a288

Browse files
committed
Improve linenoise.c compatability.
+ Don't flush characters when switching into and out of raw mode. This avoids eating characters that follow '\n'. (Such characters can occur when pasting multiple line input, or when scripts are driving input.) + Try to be slightly cleverer about calculating the length of the prompt, so that prompts with embedded '\n' characters are handled OK. This is an area that really needs to be replaced with a query of the cursor position from the terminal. + As a hack, just assume the screen is very wide if we don't know how wide it is. This allows dexpropt to work correctly. (It was getting confused by the editing commands emitted when the end-of-line was reached.) Change-Id: I988dd0f0bceb22b298e915be0dde085c9358ef66
1 parent ad5431d commit 192a288

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

liblinenoise/linenoise.c

+20-6
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,8 @@ static int enableRawMode(int fd) {
138138
* We want read to return every single byte, without timeout. */
139139
raw.c_cc[VMIN] = 1; raw.c_cc[VTIME] = 0; /* 1 byte, no timer */
140140

141-
/* put terminal in raw mode after flushing */
142-
if (tcsetattr(fd,TCSAFLUSH,&raw) < 0) goto fatal;
141+
/* put terminal in raw mode */
142+
if (tcsetattr(fd,TCSADRAIN,&raw) < 0) goto fatal;
143143
rawmode = 1;
144144
return 0;
145145

@@ -150,7 +150,7 @@ static int enableRawMode(int fd) {
150150

151151
static void disableRawMode(int fd) {
152152
/* Don't even check the return value as it's too late. */
153-
if (rawmode && tcsetattr(fd,TCSAFLUSH,&orig_termios) != -1)
153+
if (rawmode && tcsetattr(fd,TCSADRAIN,&orig_termios) != -1)
154154
rawmode = 0;
155155
}
156156

@@ -163,16 +163,30 @@ static void linenoiseAtExit(void) {
163163
static int getColumns(void) {
164164
struct winsize ws;
165165

166-
if (ioctl(1, TIOCGWINSZ, &ws) == -1) return 80;
166+
if (ioctl(1, TIOCGWINSZ, &ws) == -1) return 4096;
167167
if (ws.ws_col == 0) {
168-
return 80;
168+
return 4096;
169169
}
170170
return ws.ws_col;
171171
}
172172

173+
static int effectiveLen(const char* prompt) {
174+
int col = 0;
175+
char c;
176+
// TODO: Handle escape sequences.
177+
while ( (c = *prompt++) != 0 ) {
178+
if (c == '\n') {
179+
col = 0;
180+
} else {
181+
col++;
182+
}
183+
}
184+
return col;
185+
}
186+
173187
static void refreshLine(int fd, const char *prompt, char *buf, size_t len, size_t pos, size_t cols) {
174188
char seq[64];
175-
size_t plen = strlen(prompt);
189+
size_t plen = effectiveLen(prompt);
176190

177191
while((plen+pos) >= cols) {
178192
buf++;

0 commit comments

Comments
 (0)