Repository: neovim/neovim
File: test/functional/ui/messages2_spec.lua (Lua)

Code before:
local Screen = require('test.functional.ui.screen')

local clear, command, exec_lua, feed = n.clear, n.command, n.exec_lua, n.feed

describe('messages2', function()
  local screen
  before_each(function()
    clear()
    screen = Screen.new()
    screen:add_extra_attr_ids({
      [100] = { foreground = Screen.colors.Magenta1, bold = true },
    })
    exec_lua(function()
      _G.all_timers = {}
      local defer_fn = vim.defer_fn
      vim.defer_fn = function(...)
        local timer = defer_fn(...)
        table.insert(_G.all_timers, timer)
        return timer
      end
      require('vim._extui').enable({})
    end)
  end)
  after_each(function()
    -- Close unfinished timers to avoid 2s delay on exit with ASAN or TSAN.
    exec_lua(function()
      for _, timer in ipairs(_G.all_timers) do
        if not timer:is_closing() then
          timer:close()
        end
      end
    end)
  end)

  it('multiline messages and pager', function()
    command('echo "foo\nbar"')
    screen:expect([[
      ^                                                     |
      {1:~                                                    }|*10
      {3:─────────────────────────────────────────────────────}|
      foo                                                  |
      bar                                                  |
    ]])
    command('set ruler showcmd noshowmode')
    feed('g<lt>')
    screen:expect([[
                                                           |
      {1:~                                                    }|*9
      {3:─────────────────────────────────────────────────────}|
      fo^o                                                  |
      bar                                                  |

Review comment (suggestion):
If this solution is not applied globally, a simpler one specific to this file could be:

```suggestion
    -- Clear the screen to emit msg_clear, closing unfinished timers, which avoids a 2s delay on exit with ASAN or TSAN.
    command('mode')
```

Code after:
local Screen = require('test.functional.ui.screen')

local clear, command, exec_lua, feed = n.clear, n.command, n.exec_lua, n.feed

describe('messages2', function()
  local screen
  before_each(function()
    clear()
    screen = Screen.new()
    screen:add_extra_attr_ids({
      [100] = { foreground = Screen.colors.Magenta1, bold = true },
    })
    exec_lua(function()
      require('vim._extui').enable({})
    end)
  end)
  after_each(function()
    -- Since vim._extui lasts until Nvim exits, there may be unfinished timers.
    -- Close unfinished timers to avoid 2s delay on exit with ASAN or TSAN.
    exec_lua(function()
      vim.uv.walk(function(handle)
        if not handle:is_closing() then
          handle:close()
        end
      end)
    end)
  end)

  it('multiline messages and pager', function()
    command('echo "foo\nbar"')
    screen:expect([[
      ^                                                     |
      {1:~                                                    }|*10
      {3:─────────────────────────────────────────────────────}|
      foo                                                  |
      bar                                                  |
    ]])
    command('set ruler showcmd noshowmode')
    feed('g<lt>')
    screen:expect([[
                                                           |
      {1:~                                                    }|*9
      {3:─────────────────────────────────────────────────────}|
      fo^o                                                  |
      bar                                                  |
                                          1,3           All|
    ]])
    -- Multiple messages in same event loop iteration are appended and shown in full.
    feed([[q:echo "foo" | echo "bar\nbaz\n"->repeat(&lines)<CR>]])
    screen:expect([[
      ^                                                     |