Skip to content

Vim terminal does not properly handle emojis if output was delayed #16559

@ychin

Description

@ychin

Steps to reproduce

  1. Compile the following C program:

    #include <stdio.h>
    #include <unistd.h>
    int main()
    {
        setbuf(stdout, NULL);
        printf("abc%c%c", 0xf0, 0x9f); // first half of 😅
        sleep(1);
        fflush(stdout);
        printf("%c%c", 0x98, 0x85); // second half
        printf("\n");
        return 0;
    }
    clang -o prog test.c
  2. Run Vim, open terminal by typing :terminal

  3. Run the compiled prog program.

  4. Observe that Vim shows a broken emoji because the time delay of printing the emoji "😅" caused the terminal emulator to improperly split it into two half:

     ➜ ychin ~/testbed/vim/broken_terminal_output% ./prog
     abc��
     �%                                                                                                                                                                                                       
    

Expected behaviour

It should look like this:

➜ ychin ~/testbed/vim/broken_terminal_output% ./prog
abc😅

Note that I tried this in Apple Terminal / Ghostty / iTerm2 / Kitty, and also Neovim's own terminal and they all work correctly.

I did notice that an old version of Neovim that I had lying around (0.9.5) would render this incorrectly. So they probably fixed it after then.

Version of Vim

9.1.1061

Environment

OS: macOS 15.2
Terminal: Tested on different ones, doesn't matter (since the bug happens in Vim's own libvterm terminal emulator)

Logs and stack traces

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions