neovim

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

output_spec.lua (10508B)


      1 local t = require('test.testutil')
      2 local n = require('test.functional.testnvim')()
      3 local Screen = require('test.functional.ui.screen')
      4 local tt = require('test.functional.testterm')
      5 
      6 local assert_alive = n.assert_alive
      7 local mkdir, write_file, rmdir = t.mkdir, t.write_file, n.rmdir
      8 local eq = t.eq
      9 local feed = n.feed
     10 local feed_command = n.feed_command
     11 local clear = n.clear
     12 local command = n.command
     13 local testprg = n.testprg
     14 local nvim_dir = n.nvim_dir
     15 local has_powershell = n.has_powershell
     16 local set_shell_powershell = n.set_shell_powershell
     17 local skip = t.skip
     18 local is_os = t.is_os
     19 
     20 clear() -- for has_powershell()
     21 
     22 describe('shell command :!', function()
     23  local screen
     24  before_each(function()
     25    clear()
     26    screen = tt.setup_child_nvim({
     27      '-u',
     28      'NONE',
     29      '-i',
     30      'NONE',
     31      '--cmd',
     32      'colorscheme vim',
     33      '--cmd',
     34      n.nvim_set .. ' notermguicolors',
     35    })
     36    screen:expect([[
     37      ^                                                  |
     38      {100:~                                                 }|*4
     39                                                        |
     40      {5:-- TERMINAL --}                                    |
     41    ]])
     42  end)
     43 
     44  it('displays output without LF/EOF. #4646 #4569 #3772', function()
     45    skip(is_os('win'))
     46    -- NOTE: We use a child nvim (within a :term buffer)
     47    --       to avoid triggering a UI flush.
     48    tt.feed_data(':!printf foo; sleep 200\n')
     49    screen:expect([[
     50                                                        |
     51      {100:~                                                 }|*2
     52      {3:                                                  }|
     53      :!printf foo; sleep 200                           |
     54      foo                                               |
     55      {5:-- TERMINAL --}                                    |
     56    ]])
     57    tt.feed_data('\3') -- Ctrl-C
     58    screen:expect([[
     59      ^                                                  |
     60      {100:~                                                 }|*4
     61                                                        |
     62      {5:-- TERMINAL --}                                    |
     63    ]])
     64  end)
     65 
     66  it('throttles shell-command output greater than ~10KB', function()
     67    skip(is_os('openbsd'), 'FIXME #10804')
     68    skip(is_os('win'))
     69    tt.feed_data((':!%s REP 30001 foo\n'):format(testprg('shell-test')))
     70 
     71    -- If we observe any line starting with a dot, then throttling occurred.
     72    -- Avoid false failure on slow systems.
     73    screen:expect { any = '\n%.', timeout = 20000 }
     74 
     75    -- Final chunk of output should always be displayed, never skipped.
     76    -- (Throttling is non-deterministic, this test is merely a sanity check.)
     77    screen:expect([[
     78      29997: foo                                        |
     79      29998: foo                                        |
     80      29999: foo                                        |
     81      30000: foo                                        |
     82                                                        |
     83      {123:Press ENTER or type command to continue}^           |
     84      {5:-- TERMINAL --}                                    |
     85    ]])
     86  end)
     87 end)
     88 
     89 describe('shell command :!', function()
     90  before_each(function()
     91    clear()
     92  end)
     93 
     94  it('cat a binary file #4142', function()
     95    feed(":exe 'silent !cat '.shellescape(v:progpath)<CR>")
     96    assert_alive()
     97  end)
     98 
     99  it([[display \x08 char #4142]], function()
    100    feed(':silent !echo \08<CR>')
    101    assert_alive()
    102  end)
    103 
    104  it('handles control codes', function()
    105    skip(is_os('win'), 'missing printf')
    106    local screen = Screen.new(50, 4)
    107    -- Print TAB chars. #2958
    108    feed([[:!printf '1\t2\t3'<CR>]])
    109    screen:expect([[
    110      {3:                                                  }|
    111      :!printf '1\t2\t3'                                |
    112      1       2       3                                 |
    113      {6:Press ENTER or type command to continue}^           |
    114    ]])
    115    feed([[<CR>]])
    116 
    117    -- Print BELL control code. #4338
    118    screen.bell = false
    119    feed([[:!printf '\007\007\007\007text'<CR>]])
    120    screen:expect {
    121      grid = [[
    122        {3:                                                  }|
    123        :!printf '\007\007\007\007text'                   |
    124        text                                              |
    125        {6:Press ENTER or type command to continue}^           |
    126      ]],
    127      condition = function()
    128        eq(true, screen.bell)
    129      end,
    130    }
    131    feed([[<CR>]])
    132 
    133    -- Print BS control code.
    134    feed([[:echo system('printf ''\010\n''')<CR>]])
    135    screen:expect([[
    136      {3:                                                  }|
    137      {18:^H}                                                |
    138                                                        |
    139      {6:Press ENTER or type command to continue}^           |
    140    ]])
    141    feed([[<CR>]])
    142 
    143    -- Print LF control code.
    144    feed([[:!printf '\n'<CR>]])
    145    screen:expect([[
    146      :!printf '\n'                                     |
    147                                                        |*2
    148      {6:Press ENTER or type command to continue}^           |
    149    ]])
    150    feed([[<CR>]])
    151  end)
    152 
    153  describe('', function()
    154    local screen
    155    before_each(function()
    156      rmdir('bang_filter_spec')
    157      mkdir('bang_filter_spec')
    158      write_file('bang_filter_spec/f1', 'f1')
    159      write_file('bang_filter_spec/f2', 'f2')
    160      write_file('bang_filter_spec/f3', 'f3')
    161      screen = Screen.new(53, 10)
    162    end)
    163 
    164    after_each(function()
    165      rmdir('bang_filter_spec')
    166    end)
    167 
    168    it("doesn't truncate Last line of shell output #3269", function()
    169      command(
    170        is_os('win') and [[nnoremap <silent>\l :!dir /b bang_filter_spec<cr>]]
    171          or [[nnoremap <silent>\l :!ls bang_filter_spec<cr>]]
    172      )
    173      local result = (
    174        is_os('win') and [[:!dir /b bang_filter_spec]] or [[:!ls bang_filter_spec    ]]
    175      )
    176      feed([[\l]])
    177      screen:expect([[
    178                                                             |
    179        {1:~                                                    }|*2
    180        {3:                                                     }|
    181        ]] .. result .. [[                            |
    182        f1                                                   |
    183        f2                                                   |
    184        f3                                                   |
    185                                                             |
    186        {6:Press ENTER or type command to continue}^              |
    187      ]])
    188    end)
    189 
    190    it('handles binary and multibyte data', function()
    191      feed_command('!cat test/functional/fixtures/shell_data.txt')
    192      screen.bell = false
    193      screen:expect {
    194        grid = [[
    195                                                               |
    196          {1:~                                                    }|
    197          {3:                                                     }|
    198          :!cat test/functional/fixtures/shell_data.txt        |
    199          ^@^A^B^C^D^E^F^H                                     |
    200          ^N^O^P^Q^R^S^T^U^V^W^X^Y^Z^[^\^]^^^_                 |
    201          ö 한글 <a5><c3>                                      |
    202          t       <ff>                                         |
    203                                                               |
    204          {6:Press ENTER or type command to continue}^              |
    205        ]],
    206        condition = function()
    207          eq(true, screen.bell)
    208        end,
    209      }
    210    end)
    211 
    212    it('handles multibyte sequences split over buffer boundaries', function()
    213      command('cd ' .. nvim_dir)
    214      local cmd = is_os('win') and '!shell-test UTF-8  ' or '!./shell-test UTF-8'
    215      feed_command(cmd)
    216      -- Note: only the first example of split composed char works
    217      screen:expect([[
    218                                                             |
    219        {3:                                                     }|
    220        :]] .. cmd .. [[                                 |
    221        å                                                    |
    222        ref: å̲                                               |
    223        1: å̲                                                 |
    224        2: å ̲                                                |
    225        3: å ̲                                                |
    226                                                             |
    227        {6:Press ENTER or type command to continue}^              |
    228      ]])
    229    end)
    230  end)
    231  if has_powershell() then
    232    it('powershell supports literal strings', function()
    233      set_shell_powershell()
    234      local screen = Screen.new(45, 4)
    235      feed_command([[!'Write-Output $a']])
    236      screen:expect([[
    237        :!'Write-Output $a'                          |
    238        Write-Output $a                              |
    239                                                     |
    240        {6:Press ENTER or type command to continue}^      |
    241      ]])
    242      feed_command([[!$a = 1; Write-Output '$a']])
    243      screen:expect([[
    244        :!$a = 1; Write-Output '$a'                  |
    245        $a                                           |
    246                                                     |
    247        {6:Press ENTER or type command to continue}^      |
    248      ]])
    249      feed_command([[!"Write-Output $a"]])
    250      screen:expect([[
    251        :!"Write-Output $a"                          |
    252        Write-Output                                 |
    253                                                     |
    254        {6:Press ENTER or type command to continue}^      |
    255      ]])
    256      feed_command([[!$a = 1; Write-Output "$a"]])
    257      screen:expect([[
    258        :!$a = 1; Write-Output "$a"                  |
    259        1                                            |
    260                                                     |
    261        {6:Press ENTER or type command to continue}^      |
    262      ]])
    263      if is_os('win') then
    264        feed_command([[!& 'cmd.exe' /c 'echo $a']])
    265        screen:expect([[
    266          :!& 'cmd.exe' /c 'echo $a'                   |
    267          $a                                           |
    268                                                       |
    269          {6:Press ENTER or type command to continue}^      |
    270        ]])
    271      else
    272        feed_command([[!& '/bin/sh' -c 'echo ''$a''']])
    273        screen:expect([[
    274          :!& '/bin/sh' -c 'echo ''$a'''               |
    275          $a                                           |
    276                                                       |
    277          {6:Press ENTER or type command to continue}^      |
    278        ]])
    279      end
    280    end)
    281  end
    282 end)