neovim

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

treesitter_spec.lua (7539B)


      1 local n = require('test.functional.testnvim')()
      2 local Screen = require('test.functional.ui.screen')
      3 
      4 local clear = n.clear
      5 local exec_lua = n.exec_lua
      6 
      7 describe('treesitter perf', function()
      8  before_each(function()
      9    clear()
     10  end)
     11 
     12  it('can handle large folds', function()
     13    n.command 'edit ./src/nvim/eval.c'
     14    exec_lua [[
     15      local parser = vim.treesitter.get_parser(0, "c", {})
     16      vim.treesitter.highlighter.new(parser)
     17 
     18      local function keys(k)
     19        vim.api.nvim_feedkeys(k, 't', true)
     20      end
     21 
     22      vim.opt.foldmethod = "manual"
     23      vim.opt.lazyredraw = false
     24 
     25      vim.cmd '1000,7000fold'
     26      vim.cmd '999'
     27 
     28      local function mk_keys(n)
     29        local acc = ""
     30        for _ = 1, n do
     31          acc = acc .. "j"
     32        end
     33        for _ = 1, n do
     34          acc = acc .. "k"
     35        end
     36 
     37        return "qq" .. acc .. "q"
     38      end
     39 
     40      local start = vim.uv.hrtime()
     41      keys(mk_keys(10))
     42 
     43      for _ = 1, 100 do
     44        keys "@q"
     45        vim.cmd'redraw!'
     46      end
     47 
     48      return vim.uv.hrtime() - start
     49    ]]
     50  end)
     51 
     52  local function test_long_line(_pos, _wrap, _line, grid)
     53    local screen = Screen.new(20, 11)
     54 
     55    local result = exec_lua(function(...)
     56      local pos, wrap, line = ...
     57 
     58      vim.api.nvim_buf_set_lines(0, 0, 0, false, { line })
     59      vim.api.nvim_win_set_cursor(0, pos)
     60      vim.api.nvim_set_option_value('wrap', wrap, { win = 0 })
     61 
     62      vim.treesitter.start(0, 'lua')
     63 
     64      local total = {}
     65      for _ = 1, 100 do
     66        local tic = vim.uv.hrtime()
     67        vim.cmd 'redraw!'
     68        local toc = vim.uv.hrtime()
     69        table.insert(total, toc - tic)
     70      end
     71 
     72      return { total }
     73    end, _pos, _wrap, _line)
     74 
     75    screen:expect({ grid = grid or '' })
     76 
     77    local total = unpack(result)
     78    table.sort(total)
     79 
     80    local ms = 1 / 1000000
     81    local res = string.format(
     82      'min, 25%%, median, 75%%, max:\n\t%0.2fms,\t%0.2fms,\t%0.2fms,\t%0.2fms,\t%0.2fms',
     83      total[1] * ms,
     84      total[1 + math.floor(#total * 0.25)] * ms,
     85      total[1 + math.floor(#total * 0.5)] * ms,
     86      total[1 + math.floor(#total * 0.75)] * ms,
     87      total[#total] * ms
     88    )
     89    print('\nTotal ' .. res)
     90  end
     91 
     92  local long_line = 'local a = { ' .. ('a = 5, '):rep(500) .. '}'
     93  it('can redraw the beginning of a long line with wrapping', function()
     94    local grid = [[
     95      {15:^local} {25:a} {15:=} {16:{} {25:a} {15:=} {26:5}{16:,} {25:a}|
     96       {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} |
     97      {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,}|
     98       {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}|
     99      {16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} |
    100      {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=}|
    101       {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} |
    102      {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a}|
    103       {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} |
    104      {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,}|
    105                          |
    106    ]]
    107    test_long_line({ 1, 0 }, true, long_line, grid)
    108  end)
    109 
    110  it('can redraw the middle of a long line with wrapping', function()
    111    local grid = [[
    112      {1:<<<}{26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} |
    113      {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,}|
    114       {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}|
    115      {16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} |
    116      {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=}|
    117       {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} |
    118      {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a}|
    119       {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} |
    120      {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,}|
    121       {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a}^ {15:=} {26:5}|
    122                          |
    123    ]]
    124    test_long_line({ 1, math.floor(#long_line / 2) }, true, long_line, grid)
    125  end)
    126 
    127  it('can redraw the end of a long line with wrapping', function()
    128    local grid = [[
    129      {1:<<<}{25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=}|
    130       {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} |
    131      {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a}|
    132       {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} |
    133      {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,}|
    134       {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}|
    135      {16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} |
    136      {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=}|
    137       {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {25:a} |
    138      {15:=} {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {16:^}}       |
    139                          |
    140    ]]
    141    test_long_line({ 1, #long_line - 1 }, true, long_line, grid)
    142  end)
    143 
    144  it('can redraw the beginning of a long line without wrapping', function()
    145    local grid = [[
    146      {15:^local} {25:a} {15:=} {16:{} {25:a} {15:=} {26:5}{16:,} {25:a}|
    147                          |
    148      {1:~                   }|*8
    149                          |
    150    ]]
    151    test_long_line({ 1, 0 }, false, long_line, grid)
    152  end)
    153 
    154  it('can redraw the middle of a long line without wrapping', function()
    155    local grid = [[
    156      {16:,} {25:a} {15:=} {26:5}{16:,} {25:a}^ {15:=} {26:5}{16:,} {25:a} {15:=} |
    157                          |
    158      {1:~                   }|*8
    159                          |
    160    ]]
    161    test_long_line({ 1, math.floor(#long_line / 2) }, false, long_line, grid)
    162  end)
    163 
    164  it('can redraw the end of a long line without wrapping', function()
    165    local grid = [[
    166      {26:5}{16:,} {25:a} {15:=} {26:5}{16:,} {16:^}}         |
    167                          |
    168      {1:~                   }|*8
    169                          |
    170    ]]
    171    test_long_line({ 1, #long_line - 1 }, false, long_line, grid)
    172  end)
    173 
    174  local long_line_mb = 'local a = { ' .. ('À = 5, '):rep(500) .. '}'
    175  it('can redraw the middle of a long line with multibyte characters', function()
    176    local grid = [[
    177      {1:<<<}{26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} |
    178      {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,}|
    179       {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}|
    180      {16:,} {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} |
    181      {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À} {15:=}|
    182       {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À} |
    183      {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À}|
    184       {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} |
    185      {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,}|
    186       {25:À} {15:=} {26:5}{16:,} {25:À} {15:=} {26:5}{16:,} {25:À}^ {15:=} {26:5}|
    187                          |
    188    ]]
    189    test_long_line({ 1, math.floor(#long_line_mb / 2) }, true, long_line_mb, grid)
    190  end)
    191 end)