shell: use msg_outtrans_len_attr for :!cmd

fixes #7830 and #7788
This commit is contained in:
Björn Linse
2018-01-12 08:32:28 +01:00
parent 0851057a8d
commit 2d99b81ab5
4 changed files with 32 additions and 50 deletions

View File

@@ -123,6 +123,9 @@ int os_call_shell(char_u *cmd, ShellOpts opts, char_u *extra_args)
if (opts & kShellOptRead) {
output_ptr = &output;
forward_output = false;
} else if (opts & kShellOptDoOut) {
// Caller has already redirected output
forward_output = false;
}
}
@@ -257,11 +260,25 @@ static int do_os_system(char **argv,
// busy state.
ui_busy_start();
ui_flush();
if (forward_output) {
msg_sb_eol();
msg_start();
msg_no_more = true;
lines_left = -1;
}
int exitcode = process_wait(proc, -1, NULL);
if (!got_int && out_data_decide_throttle(0)) {
// Last chunk of output was skipped; display it now.
out_data_ring(NULL, SIZE_MAX);
}
if (forward_output) {
// caller should decide if wait_return is invoked
no_wait_return++;
msg_end();
no_wait_return--;
msg_no_more = false;
}
ui_busy_stop();
// prepare the out parameters if requested
@@ -436,47 +453,17 @@ static void out_data_ring(char *output, size_t size)
static void out_data_append_to_screen(char *output, size_t remaining,
bool new_line)
{
static colnr_T last_col = 0; // Column of last row to append to.
char *p = output, *end = output + remaining;
while (p < end) {
if (*p == '\n' || *p == '\r' || *p == TAB) {
msg_putchar_attr((uint8_t)(*p), 0);
p++;
} else {
int i = *p ? mb_ptr2len_len((char_u *)p, (int)(end-p)) : 1;
size_t off = 0;
int last_row = (int)Rows - 1;
while (output != NULL && off < remaining) {
// Found end of line?
if (output[off] == NL) {
// Can we start a new line or do we need to continue the last one?
if (last_col == 0) {
screen_del_lines(0, 0, 1, (int)Rows, NULL);
}
screen_puts_len((char_u *)output, (int)off, last_row, last_col, 0);
last_col = 0;
size_t skip = off + 1;
output += skip;
remaining -= skip;
off = 0;
continue;
(void)msg_outtrans_len_attr((char_u *)p, i, 0);
p += i;
}
// TODO(bfredl): using msg_puts would be better until
// terminal emulation is implemented.
if (output[off] < 0x20) {
output[off] = ' ';
}
off++;
}
if (output != NULL && remaining) {
if (last_col == 0) {
screen_del_lines(0, 0, 1, (int)Rows, NULL);
}
screen_puts_len((char_u *)output, (int)remaining, last_row, last_col, 0);
last_col += (colnr_T)remaining;
}
if (new_line) {
last_col = 0;
}
ui_flush();