neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

window_spec.lua (38814B)


      1 local t = require('test.testutil')
      2 local n = require('test.functional.testnvim')()
      3 local Screen = require('test.functional.ui.screen')
      4 
      5 local tt = require('test.functional.testterm')
      6 local feed_data = tt.feed_data
      7 local feed_csi = tt.feed_csi
      8 local feed, clear = n.feed, n.clear
      9 local poke_eventloop = n.poke_eventloop
     10 local exec_lua = n.exec_lua
     11 local command = n.command
     12 local retry = t.retry
     13 local eq = t.eq
     14 local eval = n.eval
     15 local skip = t.skip
     16 local is_os = t.is_os
     17 local testprg = n.testprg
     18 
     19 describe(':terminal window', function()
     20  before_each(clear)
     21 
     22  it('sets local values of window options #29325', function()
     23    command('setglobal wrap list')
     24    command('terminal')
     25    eq({ 0, 0, 1 }, eval('[&l:wrap, &wrap, &g:wrap]'))
     26    eq({ 0, 0, 1 }, eval('[&l:list, &list, &g:list]'))
     27    command('enew')
     28    eq({ 1, 1, 1 }, eval('[&l:wrap, &wrap, &g:wrap]'))
     29    eq({ 1, 1, 1 }, eval('[&l:list, &list, &g:list]'))
     30    command('buffer #')
     31    eq({ 0, 0, 1 }, eval('[&l:wrap, &wrap, &g:wrap]'))
     32    eq({ 0, 0, 1 }, eval('[&l:list, &list, &g:list]'))
     33    command('new')
     34    eq({ 1, 1, 1 }, eval('[&l:wrap, &wrap, &g:wrap]'))
     35    eq({ 1, 1, 1 }, eval('[&l:list, &list, &g:list]'))
     36  end)
     37 
     38  it('resets horizontal scroll on resize #35331', function()
     39    skip(is_os('win'), 'Too flaky on Windows')
     40    local screen = tt.setup_screen(0, { testprg('shell-test'), 'INTERACT' })
     41    command('set statusline=%{win_getid()} splitright')
     42    screen:expect([[
     43      interact $ ^                                       |
     44                                                        |*5
     45      {5:-- TERMINAL --}                                    |
     46    ]])
     47    feed_data(('A'):rep(30))
     48    screen:expect([[
     49      interact $ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA^         |
     50                                                        |*5
     51      {5:-- TERMINAL --}                                    |
     52    ]])
     53    command('vnew | wincmd p')
     54    screen:expect([[
     55      interact $ AAAAAAAAAAAAA                         |
     56      AAAAAAAAAAAAAAAAA^       {100:~                        }|
     57                              {100:~                        }|*3
     58      {120:1000                     }{2:1001                     }|
     59      {5:-- TERMINAL --}                                    |
     60    ]])
     61 
     62    feed([[<C-\><C-N><C-W>o]])
     63    screen:expect([[
     64      interact $ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA         |
     65      ^                                                  |
     66                                                        |*5
     67    ]])
     68    -- Window with less room scrolls anyway to keep its cursor in-view.
     69    feed('gg$20<C-W>v')
     70    screen:expect([[
     71      interact $ AAAAAAAAAAAAAAAAAA│$ AAAAAAAAAAAAAAAAA^A|
     72      AAAAAAAAAAAA                 AAA                 |
     73                                                       |*3
     74      {119:1000                          }{120:1002                }|
     75                                                        |
     76    ]])
     77  end)
     78 end)
     79 
     80 describe(':terminal window', function()
     81  local screen
     82 
     83  before_each(function()
     84    clear()
     85    screen = tt.setup_screen()
     86  end)
     87 
     88  it('sets topline correctly #8556', function()
     89    skip(is_os('win'))
     90    -- Test has hardcoded assumptions of dimensions.
     91    eq(7, eval('&lines'))
     92    feed_data('\n\n\n') -- Add blank lines.
     93    -- Terminal/shell contents must exceed the height of this window.
     94    command('topleft 1split')
     95    eq('terminal', eval('&buftype'))
     96    feed([[i<cr>]])
     97    -- Check topline _while_ in terminal-mode.
     98    retry(nil, nil, function()
     99      eq(6, eval('winsaveview()["topline"]'))
    100    end)
    101  end)
    102 
    103  describe("with 'number'", function()
    104    it('wraps text', function()
    105      feed([[<C-\><C-N>]])
    106      feed([[:set numberwidth=1 number<CR>i]])
    107      screen:expect([[
    108        {121:1 }tty ready                                       |
    109        {121:2 }rows: 6, cols: 48                               |
    110        {121:3 }^                                                |
    111        {121:4 }                                                |
    112        {121:5 }                                                |
    113        {121:6 }                                                |
    114        {5:-- TERMINAL --}                                    |
    115      ]])
    116      feed_data('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
    117      screen:expect([[
    118        {121:1 }tty ready                                       |
    119        {121:2 }rows: 6, cols: 48                               |
    120        {121:3 }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV|
    121        {121:4 }WXYZ^                                            |
    122        {121:5 }                                                |
    123        {121:6 }                                                |
    124        {5:-- TERMINAL --}                                    |
    125      ]])
    126 
    127      -- numberwidth=9
    128      feed([[<C-\><C-N>]])
    129      feed([[:set numberwidth=9 number<CR>i]])
    130      screen:expect([[
    131        {121:       1 }tty ready                                |
    132        {121:       2 }rows: 6, cols: 48                        |
    133        {121:       3 }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO|
    134        {121:       4 }PQRSTUVWXYZrows: 6, cols: 41             |
    135        {121:       5 }^                                         |
    136        {121:       6 }                                         |
    137        {5:-- TERMINAL --}                                    |
    138      ]])
    139      feed_data(' abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
    140      screen:expect([[
    141        {121:       1 }tty ready                                |
    142        {121:       2 }rows: 6, cols: 48                        |
    143        {121:       3 }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO|
    144        {121:       4 }PQRSTUVWXYZrows: 6, cols: 41             |
    145        {121:       5 } abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN|
    146        {121:       6 }OPQRSTUVWXYZ^                             |
    147        {5:-- TERMINAL --}                                    |
    148      ]])
    149    end)
    150  end)
    151 
    152  describe("with 'statuscolumn'", function()
    153    it('wraps text', function()
    154      command([[set number statuscolumn=++%l\ \ ]])
    155      screen:expect([[
    156        {121:++1  }tty ready                                    |
    157        {121:++2  }rows: 6, cols: 45                            |
    158        {121:++3  }^                                             |
    159        {121:++4  }                                             |
    160        {121:++5  }                                             |
    161        {121:++6  }                                             |
    162        {5:-- TERMINAL --}                                    |
    163      ]])
    164      feed_data('\n\n\n\n\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
    165      screen:expect([[
    166        {121:++4  }                                             |
    167        {121:++5  }                                             |
    168        {121:++6  }                                             |
    169        {121:++7  }                                             |
    170        {121:++8  }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS|
    171        {121:++9  }TUVWXYZ^                                      |
    172        {5:-- TERMINAL --}                                    |
    173      ]])
    174      feed_data('\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
    175      screen:expect([[
    176        {121:++ 7  }                                            |
    177        {121:++ 8  }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR|
    178        {121:++ 9  }STUVWXYZ                                    |
    179        {121:++10  }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR|
    180        {121:++11  }STUVWXYZrows: 6, cols: 44                   |
    181        {121:++12  }^                                            |
    182        {5:-- TERMINAL --}                                    |
    183      ]])
    184    end)
    185  end)
    186 
    187  describe("with 'colorcolumn'", function()
    188    before_each(function()
    189      feed([[<C-\><C-N>]])
    190      screen:expect([[
    191        tty ready                                         |
    192        ^                                                  |
    193                                                          |*5
    194      ]])
    195      feed(':set colorcolumn=20<CR>i')
    196    end)
    197 
    198    it('wont show the color column', function()
    199      screen:expect([[
    200        tty ready                                         |
    201        ^                                                  |
    202                                                          |*4
    203        {5:-- TERMINAL --}                                    |
    204      ]])
    205    end)
    206  end)
    207 
    208  describe('with fold set', function()
    209    before_each(function()
    210      feed([[<C-\><C-N>:set foldenable foldmethod=manual<CR>i]])
    211      feed_data({ 'line1', 'line2', 'line3', 'line4', '' })
    212      screen:expect([[
    213        tty ready                                         |
    214        line1                                             |
    215        line2                                             |
    216        line3                                             |
    217        line4                                             |
    218        ^                                                  |
    219        {5:-- TERMINAL --}                                    |
    220      ]])
    221    end)
    222 
    223    it('wont show any folds', function()
    224      feed([[<C-\><C-N>ggvGzf]])
    225      poke_eventloop()
    226      screen:expect([[
    227        ^tty ready                                         |
    228        line1                                             |
    229        line2                                             |
    230        line3                                             |
    231        line4                                             |
    232                                                          |*2
    233      ]])
    234    end)
    235  end)
    236 
    237  it('redrawn when restoring cursorline/column', function()
    238    screen:set_default_attr_ids({
    239      [1] = { bold = true },
    240      [2] = { foreground = 130 },
    241      [3] = { foreground = 130, underline = true },
    242      [12] = { underline = true },
    243      [19] = { background = 7 },
    244    })
    245 
    246    feed([[<C-\><C-N>]])
    247    command('setlocal cursorline')
    248    screen:expect([[
    249      tty ready                                         |
    250      {12:^                                                  }|
    251                                                        |*5
    252    ]])
    253    feed('i')
    254    screen:expect([[
    255      tty ready                                         |
    256      ^                                                  |
    257                                                        |*4
    258      {1:-- TERMINAL --}                                    |
    259    ]])
    260    feed([[<C-\><C-N>]])
    261    screen:expect([[
    262      tty ready                                         |
    263      {12:^                                                  }|
    264                                                        |*5
    265    ]])
    266 
    267    command('setlocal number')
    268    screen:expect([[
    269      {2:  1 }tty ready                                     |
    270      {3:  2 }{12:^rows: 6, cols: 46                             }|
    271      {2:  3 }                                              |
    272      {2:  4 }                                              |
    273      {2:  5 }                                              |
    274      {2:  6 }                                              |
    275                                                        |
    276    ]])
    277    feed('i')
    278    screen:expect([[
    279      {2:  1 }tty ready                                     |
    280      {2:  2 }rows: 6, cols: 46                             |
    281      {3:  3 }^                                              |
    282      {2:  4 }                                              |
    283      {2:  5 }                                              |
    284      {2:  6 }                                              |
    285      {1:-- TERMINAL --}                                    |
    286    ]])
    287    feed([[<C-\><C-N>]])
    288    screen:expect([[
    289      {2:  1 }tty ready                                     |
    290      {2:  2 }rows: 6, cols: 46                             |
    291      {3:  3 }{12:^                                              }|
    292      {2:  4 }                                              |
    293      {2:  5 }                                              |
    294      {2:  6 }                                              |
    295                                                        |
    296    ]])
    297 
    298    command('setlocal nonumber nocursorline cursorcolumn')
    299    screen:expect([[
    300      {19:t}ty ready                                         |
    301      {19:r}ows: 6, cols: 46                                 |
    302      ^rows: 6, cols: 50                                 |
    303      {19: }                                                 |*3
    304                                                        |
    305    ]])
    306    feed('i')
    307    screen:expect([[
    308      tty ready                                         |
    309      rows: 6, cols: 46                                 |
    310      rows: 6, cols: 50                                 |
    311      ^                                                  |
    312                                                        |*2
    313      {1:-- TERMINAL --}                                    |
    314    ]])
    315    feed([[<C-\><C-N>]])
    316    screen:expect([[
    317      {19:t}ty ready                                         |
    318      {19:r}ows: 6, cols: 46                                 |
    319      {19:r}ows: 6, cols: 50                                 |
    320      ^                                                  |
    321      {19: }                                                 |*2
    322                                                        |
    323    ]])
    324  end)
    325 
    326  it('redraws cursor info in terminal mode', function()
    327    command('file AMOGUS | set laststatus=2 ruler')
    328    screen:expect([[
    329      tty ready                                         |
    330      rows: 5, cols: 50                                 |
    331      ^                                                  |
    332                                                        |*2
    333      {120:AMOGUS [-]                      3,0-1          All}|
    334      {5:-- TERMINAL --}                                    |
    335    ]])
    336    feed_data('you are the imposter')
    337    screen:expect([[
    338      tty ready                                         |
    339      rows: 5, cols: 50                                 |
    340      you are the imposter^                              |
    341                                                        |*2
    342      {120:AMOGUS [-]                      3,21           All}|
    343      {5:-- TERMINAL --}                                    |
    344    ]])
    345    feed([[<C-\><C-N>]])
    346    screen:expect([[
    347      tty ready                                         |
    348      rows: 5, cols: 50                                 |
    349      you are the imposte^r                              |
    350                                                        |*2
    351      {120:AMOGUS [-]                      3,20           All}|
    352                                                        |
    353    ]])
    354  end)
    355 
    356  it('redraws stale statuslines and mode when not updating screen', function()
    357    command('file foo | set ruler | vsplit')
    358    screen:expect([[
    359      tty ready                tty ready               |
    360      rows: 5, cols: 25        rows: 5, cols: 25       |
    361      ^                                                 |
    362                                                       |*2
    363      {120:<o [-] 3,0-1          All }{119:< [-] 2,0-1          Top}|
    364      {5:-- TERMINAL --}                                    |
    365    ]])
    366    command("call win_execute(win_getid(winnr('#')), 'call cursor(1, 1)')")
    367    screen:expect([[
    368      tty ready                tty ready               |
    369      rows: 5, cols: 25        rows: 5, cols: 25       |
    370      ^                                                 |
    371                                                       |*2
    372      {120:<o [-] 3,0-1          All }{119:< [-] 1,1            All}|
    373      {5:-- TERMINAL --}                                    |
    374    ]])
    375    command('echo ""')
    376    screen:expect_unchanged()
    377  end)
    378 
    379  it('has correct topline if scrolled by events', function()
    380    local lines = {}
    381    for i = 1, 10 do
    382      table.insert(lines, 'cool line ' .. i)
    383    end
    384    feed_data(lines)
    385    feed_csi('1;1H') -- Cursor to 1,1 (after any scrollback)
    386 
    387    -- :sleep (with leeway) until the refresh_terminal uv timer event triggers before we move the
    388    -- cursor. Check that the next terminal_check tails topline correctly.
    389    command('set ruler | sleep 20m | call nvim_win_set_cursor(0, [1, 0])')
    390    screen:expect([[
    391      ^cool line 5                                       |
    392      cool line 6                                       |
    393      cool line 7                                       |
    394      cool line 8                                       |
    395      cool line 9                                       |
    396      cool line 10                                      |
    397      {5:-- TERMINAL --}                  6,1           Bot |
    398    ]])
    399    command('call nvim_win_set_cursor(0, [1, 0])')
    400    screen:expect_unchanged()
    401 
    402    feed_csi('2;5H') -- Cursor to 2,5 (after any scrollback)
    403    screen:expect([[
    404      cool line 5                                       |
    405      cool^ line 6                                       |
    406      cool line 7                                       |
    407      cool line 8                                       |
    408      cool line 9                                       |
    409      cool line 10                                      |
    410      {5:-- TERMINAL --}                  7,5           Bot |
    411    ]])
    412    -- Check topline correct after leaving terminal mode.
    413    -- The new cursor position is one column left of the terminal's actual cursor position.
    414    command('stopinsert | call nvim_win_set_cursor(0, [1, 0])')
    415    screen:expect([[
    416      cool line 5                                       |
    417      coo^l line 6                                       |
    418      cool line 7                                       |
    419      cool line 8                                       |
    420      cool line 9                                       |
    421      cool line 10                                      |
    422                                      7,4           Bot |
    423    ]])
    424  end)
    425 
    426  it('updates terminal size', function()
    427    skip(is_os('win'), "Windows doesn't show all lines?")
    428    screen:set_default_attr_ids({
    429      [1] = { reverse = true },
    430      [2] = { background = 225, foreground = Screen.colors.Gray0 },
    431      [3] = { bold = true },
    432      [4] = { foreground = 12 },
    433      [5] = { reverse = true, bold = true },
    434      [17] = { background = 2, foreground = Screen.colors.Grey0 },
    435      [18] = { background = 2, foreground = 8 },
    436      [19] = { underline = true, foreground = Screen.colors.Grey0, background = 7 },
    437      [20] = { underline = true, foreground = 5, background = 7 },
    438    })
    439 
    440    command('file foo | vsplit')
    441    screen:expect([[
    442      tty ready                tty ready               |
    443      rows: 5, cols: 25        rows: 5, cols: 25       |
    444      ^                                                 |
    445                                                       |*2
    446      {17:foo [-]                   }{18:foo [-]                 }|
    447      {3:-- TERMINAL --}                                    |
    448    ]])
    449    command('tab split')
    450    screen:expect([[
    451      {19: }{20:2}{19: foo }{3: foo }{1:                                     }{19:X}|
    452      tty ready                                         |
    453      rows: 5, cols: 25                                 |
    454      rows: 5, cols: 50                                 |
    455      ^                                                  |
    456                                                        |
    457      {3:-- TERMINAL --}                                    |
    458    ]])
    459 
    460    command('quit | botright split')
    461    -- NOTE: right window's cursor not on the last line, so it's not tailing.
    462    screen:expect([[
    463      rows: 5, cols: 50        rows: 5, cols: 25       |
    464      rows: 2, cols: 50        rows: 5, cols: 50       |
    465      {18:foo [-]                   foo [-]                 }|
    466      rows: 2, cols: 50                                 |
    467      ^                                                  |
    468      {17:foo [-]                                           }|
    469      {3:-- TERMINAL --}                                    |
    470    ]])
    471    command('quit')
    472    screen:expect([[
    473      rows: 5, cols: 25        tty ready               |
    474      rows: 5, cols: 50        rows: 5, cols: 25       |
    475      rows: 2, cols: 50        rows: 5, cols: 50       |
    476      rows: 5, cols: 25        rows: 2, cols: 50       |
    477      ^                         rows: 5, cols: 25       |
    478      {17:foo [-]                   }{18:foo [-]                 }|
    479      {3:-- TERMINAL --}                                    |
    480    ]])
    481    command('call nvim_open_win(0, 0, #{relative: "editor", row: 0, col: 0, width: 40, height: 3})')
    482    screen:expect([[
    483      {2:rows: 5, cols: 25                       }          |
    484      {2:rows: 5, cols: 40                       } 25       |
    485      {2:                                        } 50       |
    486      rows: 5, cols: 40        rows: 2, cols: 50       |
    487      ^                         rows: 5, cols: 25       |
    488      {17:foo [-]                   }{18:foo [-]                 }|
    489      {3:-- TERMINAL --}                                    |
    490    ]])
    491    command('fclose!')
    492    screen:expect([[
    493      rows: 2, cols: 50        tty ready               |
    494      rows: 5, cols: 25        rows: 5, cols: 25       |
    495      rows: 5, cols: 40        rows: 5, cols: 50       |
    496      rows: 5, cols: 25        rows: 2, cols: 50       |
    497      ^                         rows: 5, cols: 25       |
    498      {17:foo [-]                   }{18:foo [-]                 }|
    499      {3:-- TERMINAL --}                                    |
    500    ]])
    501    command('tab split')
    502    screen:expect([[
    503      {19: }{20:2}{19: foo }{3: foo }{1:                                     }{19:X}|
    504      rows: 5, cols: 25                                 |
    505      rows: 5, cols: 40                                 |
    506      rows: 5, cols: 25                                 |
    507      rows: 5, cols: 50                                 |
    508      ^                                                  |
    509      {3:-- TERMINAL --}                                    |
    510    ]])
    511    command('tabfirst | tabonly')
    512    screen:expect([[
    513      rows: 5, cols: 40        tty ready               |
    514      rows: 5, cols: 25        rows: 5, cols: 25       |
    515      rows: 5, cols: 50        rows: 5, cols: 50       |
    516      rows: 5, cols: 25        rows: 2, cols: 50       |
    517      ^                         rows: 5, cols: 25       |
    518      {17:foo [-]                   }{18:foo [-]                 }|
    519      {3:-- TERMINAL --}                                    |
    520    ]])
    521 
    522    -- Sizing logic should only consider the final buffer shown in a window, even if autocommands
    523    -- changed it at the last moment.
    524    exec_lua(function()
    525      vim.g.fired = 0
    526      vim.api.nvim_create_autocmd('BufHidden', {
    527        callback = function(ev)
    528          vim.api.nvim_win_set_buf(vim.fn.win_findbuf(ev.buf)[1], vim.fn.bufnr('foo'))
    529          vim.g.fired = vim.g.fired + 1
    530          return vim.g.fired == 2
    531        end,
    532      })
    533    end)
    534    command('botright new')
    535    screen:expect([[
    536      rows: 2, cols: 25        rows: 5, cols: 25       |
    537                               rows: 5, cols: 50       |
    538      {18:foo [-]                   foo [-]                 }|
    539      ^                                                  |
    540      {4:~                                                 }|
    541      {5:[No Name]                                         }|
    542                                                        |
    543    ]])
    544    command('quit')
    545    eq(1, eval('g:fired'))
    546    screen:expect([[
    547      rows: 5, cols: 50        tty ready               |
    548      rows: 5, cols: 25        rows: 5, cols: 25       |
    549      rows: 2, cols: 25        rows: 5, cols: 50       |
    550      rows: 5, cols: 25        rows: 2, cols: 50       |
    551      ^                         rows: 5, cols: 25       |
    552      {17:foo [-]                   }{18:foo [-]                 }|
    553                                                        |
    554    ]])
    555    -- Check it doesn't use the size of the closed window in the other tab page; size should only
    556    -- change via the :wincmd below. Hide tabline so it doesn't affect sizes.
    557    command('set showtabline=0 | tabnew | tabprevious | wincmd > | tabonly')
    558    eq(2, eval('g:fired'))
    559    screen:expect([[
    560      rows: 5, cols: 25         tty ready              |
    561      rows: 2, cols: 25         rows: 5, cols: 25      |
    562      rows: 5, cols: 25         rows: 5, cols: 50      |
    563      rows: 5, cols: 26         rows: 2, cols: 50      |
    564      ^                          rows: 5, cols: 25      |
    565      {17:foo [-]                    }{18:foo [-]                }|
    566                                                        |
    567    ]])
    568    n.expect([[
    569      tty ready
    570      rows: 5, cols: 25
    571      rows: 5, cols: 50
    572      rows: 2, cols: 50
    573      rows: 5, cols: 25
    574      rows: 5, cols: 40
    575      rows: 5, cols: 25
    576      rows: 5, cols: 50
    577      rows: 5, cols: 25
    578      rows: 2, cols: 25
    579      rows: 5, cols: 25
    580      rows: 5, cols: 26
    581      ]])
    582  end)
    583 
    584  it('restores window options when switching terminals', function()
    585    -- Make this a screen test to also check for proper redrawing.
    586    screen:set_default_attr_ids({
    587      [1] = { bold = true },
    588      [2] = { foreground = Screen.colors.Gray0, background = 7, underline = true },
    589      [3] = { foreground = 5, background = 7, underline = true },
    590      [4] = { reverse = true },
    591      [5] = { bold = true, foreground = 5 },
    592      [6] = { foreground = 12 },
    593      [7] = { reverse = true, bold = true },
    594      [12] = { underline = true },
    595      [17] = { foreground = Screen.colors.Gray0, background = 2 },
    596      [18] = { foreground = 8, background = 2 },
    597      [19] = { background = 7 },
    598    })
    599 
    600    feed([[<C-\><C-N>]])
    601    command([[
    602      file foo
    603      setlocal cursorline
    604      vsplit
    605      setlocal nocursorline cursorcolumn cursorlineopt=number
    606    ]])
    607    screen:expect([[
    608      {19:t}ty ready                tty ready               |
    609      ^rows: 5, cols: 25        │{12:rows: 5, cols: 25       }|
    610      {19: }                                                |*3
    611      {17:foo [-]                   }{18:foo [-]                 }|
    612                                                        |
    613    ]])
    614 
    615    feed('i')
    616    screen:expect([[
    617      tty ready                tty ready               |
    618      rows: 5, cols: 25        │{12:rows: 5, cols: 25       }|
    619      ^                                                 |
    620                                                       |*2
    621      {17:foo [-]                   }{18:foo [-]                 }|
    622      {1:-- TERMINAL --}                                    |
    623    ]])
    624    command('wincmd p')
    625    screen:expect([[
    626      {19:t}ty ready                tty ready               |
    627      {19:r}ows: 5, cols: 25        rows: 5, cols: 25       |
    628                               │^                        |
    629      {19: }                                                |*2
    630      {18:foo [-]                   }{17:foo [-]                 }|
    631      {1:-- TERMINAL --}                                    |
    632    ]])
    633    feed([[<C-\><C-N>]])
    634    screen:expect([[
    635      {19:t}ty ready                tty ready               |
    636      {19:r}ows: 5, cols: 25        rows: 5, cols: 25       |
    637                               │{12:^                        }|
    638      {19: }                                                |*2
    639      {18:foo [-]                   }{17:foo [-]                 }|
    640                                                        |
    641    ]])
    642 
    643    -- Ensure things work when switching tabpages.
    644    command('tab split | setlocal cursorline cursorcolumn')
    645    screen:expect([[
    646      {2: }{3:2}{2: foo }{1: foo }{4:                                     }{2:X}|
    647      {19:t}ty ready                                         |
    648      {19:r}ows: 5, cols: 25                                 |
    649      {12:^rows: 5, cols: 50                                 }|
    650      {19: }                                                 |*2
    651                                                        |
    652    ]])
    653    feed('i')
    654    screen:expect([[
    655      {2: }{3:2}{2: foo }{1: foo }{4:                                     }{2:X}|
    656      tty ready                                         |
    657      rows: 5, cols: 25                                 |
    658      rows: 5, cols: 50                                 |
    659      ^                                                  |
    660                                                        |
    661      {1:-- TERMINAL --}                                    |
    662    ]])
    663    command('tabprevious')
    664    screen:expect([[
    665      {1: }{5:2}{1: foo }{2: foo }{4:                                     }{2:X}|
    666      {19:r}ows: 5, cols: 25        rows: 5, cols: 25       |
    667      rows: 5, cols: 50        rows: 5, cols: 50       |
    668      {19: }                        │^                        |
    669      {19: }                                                |
    670      {18:foo [-]                   }{17:foo [-]                 }|
    671      {1:-- TERMINAL --}                                    |
    672    ]])
    673    feed([[<C-\><C-N>]])
    674    screen:expect([[
    675      {1: }{5:2}{1: foo }{2: foo }{4:                                     }{2:X}|
    676      {19:r}ows: 5, cols: 25        rows: 5, cols: 25       |
    677      rows: 5, cols: 50        rows: 5, cols: 50       |
    678      {19: }                        │{12:^                        }|
    679      {19: }                                                |
    680      {18:foo [-]                   }{17:foo [-]                 }|
    681                                                        |
    682    ]])
    683    command('tabnext')
    684    screen:expect([[
    685      {2: }{3:2}{2: foo }{1: foo }{4:                                     }{2:X}|
    686      {19:t}ty ready                                         |
    687      {19:r}ows: 5, cols: 25                                 |
    688      {19:r}ows: 5, cols: 50                                 |
    689      {12:^                                                  }|
    690      {19: }                                                 |
    691                                                        |
    692    ]])
    693 
    694    -- Closing windows shouldn't break things.
    695    command('tabprevious')
    696    feed('i')
    697    screen:expect([[
    698      {1: }{5:2}{1: foo }{2: foo }{4:                                     }{2:X}|
    699      {19:r}ows: 5, cols: 25        rows: 5, cols: 25       |
    700      rows: 5, cols: 50        rows: 5, cols: 50       |
    701      {19: }                        │^                        |
    702      {19: }                                                |
    703      {18:foo [-]                   }{17:foo [-]                 }|
    704      {1:-- TERMINAL --}                                    |
    705    ]])
    706    command('quit')
    707    screen:expect([[
    708      {1: foo }{2: foo }{4:                                       }{2:X}|
    709      tty ready                                         |
    710      rows: 5, cols: 25                                 |
    711      rows: 5, cols: 50                                 |
    712      ^                                                  |
    713                                                        |
    714      {1:-- TERMINAL --}                                    |
    715    ]])
    716    feed([[<C-\><C-N>]])
    717    screen:expect([[
    718      {1: foo }{2: foo }{4:                                       }{2:X}|
    719      {19:t}ty ready                                         |
    720      {19:r}ows: 5, cols: 25                                 |
    721      {19:r}ows: 5, cols: 50                                 |
    722      ^                                                  |
    723      {19: }                                                 |
    724                                                        |
    725    ]])
    726 
    727    -- Switching to a non-terminal.
    728    command('vnew')
    729    feed([[<C-W>pi]])
    730    screen:expect([[
    731      {1: }{5:2}{1: foo }{2: foo }{4:                                     }{2:X}|
    732                               rows: 5, cols: 25       |
    733      {6:~                        }│rows: 5, cols: 50       |
    734      {6:~                        }│^                        |
    735      {6:~                        }│                        |
    736      {4:[No Name]                 }{17:foo [-]                 }|
    737      {1:-- TERMINAL --}                                    |
    738    ]])
    739    command('wincmd p')
    740    screen:expect([[
    741      {1: }{5:2}{1: [No Name] }{2: foo }{4:                               }{2:X}|
    742      ^                         {19:r}ows: 5, cols: 25       |
    743      {6:~                        }│{19:r}ows: 5, cols: 50       |
    744      {6:~                        }│                        |
    745      {6:~                        }│{19: }                       |
    746      {7:[No Name]                 }{18:foo [-]                 }|
    747                                                        |
    748    ]])
    749 
    750    command('wincmd l | enew | setlocal cursorline nocursorcolumn')
    751    screen:expect([[
    752      {1: }{5:2}{1: [No Name] }{2: foo }{4:                               }{2:X}|
    753                               {12:^                        }|
    754      {6:~                        }{6:~                       }|*3
    755      {4:[No Name]                 }{7:[No Name]               }|
    756                                                        |
    757    ]])
    758    command('buffer # | startinsert')
    759    screen:expect([[
    760      {1: }{5:2}{1: foo }{2: foo }{4:                                     }{2:X}|
    761                               rows: 5, cols: 25       |
    762      {6:~                        }│rows: 5, cols: 50       |
    763      {6:~                        }│^                        |
    764      {6:~                        }│                        |
    765      {4:[No Name]                 }{17:foo [-]                 }|
    766      {1:-- TERMINAL --}                                    |
    767    ]])
    768    -- Switching to another buffer shouldn't change window options there. #37484
    769    command('buffer # | call setline(1, ["aaa", "bbb", "ccc"]) | normal! jl')
    770    screen:expect([[
    771      {1: }{5:2}{1:+ [No Name] }{2: foo }{4:                              }{2:X}|
    772                               aaa                     |
    773      {6:~                        }{12:b^bb                     }|
    774      {6:~                        }ccc                     |
    775      {6:~                        }{6:~                       }|
    776      {4:[No Name]                 }{7:[No Name] [+]           }|
    777                                                        |
    778    ]])
    779    -- Window options are restored when switching back to the terminal buffer.
    780    command('buffer #')
    781    screen:expect([[
    782      {1: }{5:2}{1: foo }{2: foo }{4:                                     }{2:X}|
    783                               {19:r}ows: 5, cols: 25       |
    784      {6:~                        }│{19:r}ows: 5, cols: 50       |
    785      {6:~                        }│^                        |
    786      {6:~                        }│{19: }                       |
    787      {4:[No Name]                 }{17:foo [-]                 }|
    788                                                        |
    789    ]])
    790    -- 'cursorlineopt' should still be "number".
    791    eq('number', eval('&l:cursorlineopt'))
    792  end)
    793 
    794  it('not unnecessarily redrawn by events', function()
    795    eq('t', eval('mode()'))
    796    exec_lua(function()
    797      _G.redraws = {}
    798      local ns = vim.api.nvim_create_namespace('test')
    799      vim.api.nvim_set_decoration_provider(ns, {
    800        on_start = function()
    801          table.insert(_G.redraws, 'start')
    802        end,
    803        on_win = function(_, win)
    804          table.insert(_G.redraws, 'win ' .. win)
    805        end,
    806        on_end = function()
    807          table.insert(_G.redraws, 'end')
    808        end,
    809      })
    810      -- Setting a decoration provider typically causes an initial redraw.
    811      vim.cmd.redraw()
    812      _G.redraws = {}
    813    end)
    814 
    815    -- The event we sent above to set up the test shouldn't have caused a redraw.
    816    -- For good measure, also poke the event loop.
    817    poke_eventloop()
    818    eq({}, exec_lua('return _G.redraws'))
    819 
    820    -- Redraws if we do something useful, of course.
    821    feed_data('foo')
    822    screen:expect { any = 'foo' }
    823    eq({ 'start', 'win 1000', 'end' }, exec_lua('return _G.redraws'))
    824  end)
    825 end)
    826 
    827 describe(':terminal with multigrid', function()
    828  local screen
    829 
    830  before_each(function()
    831    clear()
    832    screen = tt.setup_screen(0, nil, 50, nil, { ext_multigrid = true })
    833  end)
    834 
    835  it('resizes to requested size', function()
    836    screen:expect([[
    837    ## grid 1
    838      [2:--------------------------------------------------]|*6
    839      [3:--------------------------------------------------]|
    840    ## grid 2
    841      tty ready                                         |
    842      ^                                                  |
    843                                                        |*4
    844    ## grid 3
    845      {5:-- TERMINAL --}                                    |
    846    ]])
    847 
    848    screen:try_resize_grid(2, 20, 10)
    849    if is_os('win') then
    850      screen:expect { any = 'rows: 10, cols: 20' }
    851    else
    852      screen:expect([[
    853      ## grid 1
    854        [2:--------------------------------------------------]|*6
    855        [3:--------------------------------------------------]|
    856      ## grid 2
    857        tty ready           |
    858        rows: 10, cols: 20  |
    859        ^                    |
    860                            |*7
    861      ## grid 3
    862        {5:-- TERMINAL --}                                    |
    863      ]])
    864    end
    865 
    866    screen:try_resize_grid(2, 70, 3)
    867    if is_os('win') then
    868      screen:expect { any = 'rows: 3, cols: 70' }
    869    else
    870      screen:expect([[
    871      ## grid 1
    872        [2:--------------------------------------------------]|*6
    873        [3:--------------------------------------------------]|
    874      ## grid 2
    875        rows: 10, cols: 20                                                    |
    876        rows: 3, cols: 70                                                     |
    877        ^                                                                      |
    878      ## grid 3
    879        {5:-- TERMINAL --}                                    |
    880      ]])
    881    end
    882 
    883    screen:try_resize_grid(2, 0, 0)
    884    if is_os('win') then
    885      screen:expect { any = 'rows: 6, cols: 50' }
    886    else
    887      screen:expect([[
    888      ## grid 1
    889        [2:--------------------------------------------------]|*6
    890        [3:--------------------------------------------------]|
    891      ## grid 2
    892        tty ready                                         |
    893        rows: 10, cols: 20                                |
    894        rows: 3, cols: 70                                 |
    895        rows: 6, cols: 50                                 |
    896        ^                                                  |
    897                                                          |
    898      ## grid 3
    899        {5:-- TERMINAL --}                                    |
    900      ]])
    901    end
    902  end)
    903 end)