neovim

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

searchhl_spec.lua (25839B)


      1 local t = require('test.testutil')
      2 local n = require('test.functional.testnvim')()
      3 local Screen = require('test.functional.ui.screen')
      4 
      5 local clear, feed, insert = n.clear, n.feed, n.insert
      6 local command = n.command
      7 local feed_command = n.feed_command
      8 local eq = t.eq
      9 local eval = n.eval
     10 local fn = n.fn
     11 local testprg = n.testprg
     12 
     13 describe('search highlighting', function()
     14  local screen
     15 
     16  before_each(function()
     17    clear()
     18    screen = Screen.new(40, 7)
     19    screen:add_extra_attr_ids({
     20      [100] = { foreground = Screen.colors.Gray100, background = Screen.colors.Grey0 },
     21      [101] = { foreground = Screen.colors.White, background = Screen.colors.DarkGreen },
     22      [102] = { background = Screen.colors.WebGreen, bold = true },
     23      [103] = { background = Screen.colors.Magenta1, italic = true },
     24      [104] = { background = Screen.colors.Yellow1, bold = true },
     25    })
     26  end)
     27 
     28  it('is disabled by ":set nohlsearch"', function()
     29    feed_command('set nohlsearch')
     30    insert('some text\nmore text')
     31    feed('gg/text<cr>')
     32    screen:expect([[
     33      some ^text                               |
     34      more text                               |
     35      {1:~                                       }|*4
     36      /text                                   |
     37    ]])
     38  end)
     39 
     40  it('is disabled in folded text', function()
     41    insert('some text\nmore text')
     42    feed_command('1,2fold')
     43    feed('gg/text')
     44    screen:expect {
     45      grid = [[
     46      {13:+--  2 lines: some text·················}|
     47      {1:~                                       }|*5
     48      /text^                                   |
     49    ]],
     50      win_viewport = {
     51        [2] = {
     52          win = 1000,
     53          topline = 0,
     54          botline = 3,
     55          curline = 0,
     56          curcol = 9,
     57          linecount = 2,
     58          sum_scroll_delta = 0,
     59        },
     60      },
     61    }
     62  end)
     63 
     64  local function test_search_hl()
     65    insert([[
     66      some text
     67      more textstuff
     68      stupidtexttextstuff
     69      a text word
     70    ]])
     71 
     72    -- 'hlsearch' is enabled by default. #2859
     73    feed('gg/text<cr>')
     74    screen:expect([[
     75      some {100:^text}                               |
     76      more {100:text}stuff                          |
     77      stupid{100:texttext}stuff                     |
     78      a {100:text} word                             |
     79                                              |
     80      {101:~                                       }|
     81      /text                                   |
     82    ]])
     83 
     84    -- overlapping matches not allowed
     85    feed('3nx')
     86    screen:expect([[
     87      some {100:text}                               |
     88      more {100:text}stuff                          |
     89      stupid{100:text}^extstuff                      |
     90      a {100:text} word                             |
     91                                              |
     92      {101:~                                       }|
     93      /text                                   |
     94    ]])
     95 
     96    feed('ggn*') -- search for entire word
     97    screen:expect([[
     98      some {100:text}                               |
     99      more textstuff                          |
    100      stupidtextextstuff                      |
    101      a {100:^text} word                             |
    102                                              |
    103      {101:~                                       }|
    104      /\<text\>                               |
    105    ]])
    106 
    107    feed_command('nohlsearch')
    108    screen:expect([[
    109      some text                               |
    110      more textstuff                          |
    111      stupidtextextstuff                      |
    112      a ^text word                             |
    113                                              |
    114      {101:~                                       }|
    115      :nohlsearch                             |
    116    ]])
    117  end
    118 
    119  it("works when 'winhighlight' is not set", function()
    120    screen:add_extra_attr_ids({
    121      [100] = { background = Screen.colors.Yellow1 },
    122      [101] = { foreground = Screen.colors.Blue1, bold = true },
    123    })
    124    test_search_hl()
    125  end)
    126 
    127  it("works when 'winhighlight' doesn't change Search highlight", function()
    128    command('setlocal winhl=NonText:Underlined')
    129    screen:add_extra_attr_ids({
    130      [100] = { background = Screen.colors.Yellow },
    131      [101] = { foreground = Screen.colors.SlateBlue, underline = true },
    132    })
    133    test_search_hl()
    134  end)
    135 
    136  it("works when 'winhighlight' changes Search highlight", function()
    137    command('setlocal winhl=Search:Underlined')
    138    screen:add_extra_attr_ids({
    139      [100] = { foreground = Screen.colors.SlateBlue, underline = true },
    140      [101] = { foreground = Screen.colors.Blue1, bold = true },
    141    })
    142    test_search_hl()
    143  end)
    144 
    145  describe('CurSearch highlight', function()
    146    before_each(function()
    147      command('highlight CurSearch guibg=Black guifg=White')
    148    end)
    149 
    150    it('works for match under cursor', function()
    151      insert([[
    152        There is no way that a bee should be
    153        able to fly. Its wings are too small
    154        to get its fat little body off the
    155        ground. The bee, of course, flies
    156        anyway because bees don't care what
    157        humans think is impossible.]])
    158 
    159      feed('/bee<CR>')
    160      screen:expect([[
    161        There is no way that a {100:^bee} should be    |
    162        able to fly. Its wings are too small    |
    163        to get its fat little body off the      |
    164        ground. The {10:bee}, of course, flies       |
    165        anyway because {10:bee}s don't care what     |
    166        humans think is impossible.             |
    167        {19:search hit BOTTOM, continuing at TOP}    |
    168      ]])
    169 
    170      feed('nn')
    171      screen:expect([[
    172        There is no way that a {10:bee} should be    |
    173        able to fly. Its wings are too small    |
    174        to get its fat little body off the      |
    175        ground. The {10:bee}, of course, flies       |
    176        anyway because {100:^bee}s don't care what     |
    177        humans think is impossible.             |
    178        /bee                                    |
    179      ]])
    180 
    181      feed('N')
    182      screen:expect([[
    183        There is no way that a {10:bee} should be    |
    184        able to fly. Its wings are too small    |
    185        to get its fat little body off the      |
    186        ground. The {100:^bee}, of course, flies       |
    187        anyway because {10:bee}s don't care what     |
    188        humans think is impossible.             |
    189        ?bee                                    |
    190      ]])
    191    end)
    192 
    193    -- oldtest: Test_hlsearch_cursearch()
    194    it('works for multiline match, no duplicate highlight', function()
    195      command([[call setline(1, ['one', 'foo', 'bar', 'baz', 'foo the foo and foo', 'bar'])]])
    196      feed('gg/foo<CR>')
    197      screen:expect([[
    198        one                                     |
    199        {100:^foo}                                     |
    200        bar                                     |
    201        baz                                     |
    202        {10:foo} the {10:foo} and {10:foo}                     |
    203        bar                                     |
    204        /foo                                    |
    205      ]])
    206      feed('n')
    207      screen:expect([[
    208        one                                     |
    209        {10:foo}                                     |
    210        bar                                     |
    211        baz                                     |
    212        {100:^foo} the {10:foo} and {10:foo}                     |
    213        bar                                     |
    214        /foo                                    |
    215      ]])
    216      feed('n')
    217      screen:expect([[
    218        one                                     |
    219        {10:foo}                                     |
    220        bar                                     |
    221        baz                                     |
    222        {10:foo} the {100:^foo} and {10:foo}                     |
    223        bar                                     |
    224        /foo                                    |
    225      ]])
    226      feed('n')
    227      screen:expect([[
    228        one                                     |
    229        {10:foo}                                     |
    230        bar                                     |
    231        baz                                     |
    232        {10:foo} the {10:foo} and {100:^foo}                     |
    233        bar                                     |
    234        /foo                                    |
    235      ]])
    236      command([[call setline(5, 'foo')]])
    237      feed('0?<CR>')
    238      screen:expect([[
    239        one                                     |
    240        {100:^foo}                                     |
    241        bar                                     |
    242        baz                                     |
    243        {10:foo}                                     |
    244        bar                                     |
    245        ?foo                                    |
    246      ]])
    247      feed('gg/foo\\nbar<CR>')
    248      screen:expect([[
    249        one                                     |
    250        {100:^foo }                                    |
    251        {100:bar}                                     |
    252        baz                                     |
    253        {10:foo }                                    |
    254        {10:bar}                                     |
    255        /foo\nbar                               |
    256      ]])
    257      command([[call setline(1, ['---', 'abcdefg', 'hijkl', '---', 'abcdefg', 'hijkl'])]])
    258      feed('gg/efg\\nhij<CR>')
    259      screen:expect([[
    260        ---                                     |
    261        abcd{100:^efg }                                |
    262        {100:hij}kl                                   |
    263        ---                                     |
    264        abcd{10:efg }                                |
    265        {10:hij}kl                                   |
    266        /efg\nhij                               |
    267      ]])
    268      feed('n')
    269      screen:expect([[
    270        ---                                     |
    271        abcd{10:efg }                                |
    272        {10:hij}kl                                   |
    273        ---                                     |
    274        abcd{100:^efg }                                |
    275        {100:hij}kl                                   |
    276        /efg\nhij                               |
    277      ]])
    278 
    279      -- check clearing CurSearch when using it for another match
    280      feed('G?^abcd<CR>Y')
    281      screen:expect([[
    282        ---                                     |
    283        {10:abcd}efg                                 |
    284        hijkl                                   |
    285        ---                                     |
    286        {100:^abcd}efg                                 |
    287        hijkl                                   |
    288        ?^abcd                                  |
    289      ]])
    290      feed('kkP')
    291      screen:expect([[
    292        ---                                     |
    293        {10:abcd}efg                                 |
    294        {100:^abcd}efg                                 |
    295        hijkl                                   |
    296        ---                                     |
    297        {10:abcd}efg                                 |
    298        ?^abcd                                  |
    299      ]])
    300    end)
    301  end)
    302 
    303  it('highlights after EOL', function()
    304    insert('\n\n\n\n\n\n')
    305 
    306    feed('gg/^<cr>')
    307    screen:expect([[
    308      {10: }                                       |
    309      {10:^ }                                       |
    310      {10: }                                       |*4
    311      /^                                      |
    312    ]])
    313 
    314    -- Test that highlights are preserved after moving the cursor.
    315    feed('j')
    316    screen:expect([[
    317      {10: }                                       |*2
    318      {10:^ }                                       |
    319      {10: }                                       |*3
    320      /^                                      |
    321    ]])
    322 
    323    -- Repeat the test in rightleft mode.
    324    command('nohlsearch')
    325    command('set rightleft')
    326    feed('gg/^<cr>')
    327 
    328    screen:expect([[
    329                                             {10: }|
    330                                             {10:^ }|
    331                                             {10: }|*4
    332      ^/                                      |
    333    ]])
    334 
    335    feed('j')
    336    screen:expect([[
    337                                             {10: }|*2
    338                                             {10:^ }|
    339                                             {10: }|*3
    340      ^/                                      |
    341    ]])
    342  end)
    343 
    344  it('is preserved during :terminal activity', function()
    345    feed((':terminal "%s" REP 5000 foo<cr>'):format(testprg('shell-test')))
    346    feed(':file term<CR>')
    347    screen:expect([[
    348      ^0: foo                                  |
    349      1: foo                                  |
    350      2: foo                                  |
    351      3: foo                                  |
    352      4: foo                                  |
    353      5: foo                                  |
    354      :file term                              |
    355    ]])
    356 
    357    feed('G') -- Follow :terminal output.
    358    feed(':vnew<CR>')
    359    insert([[
    360      foo bar baz
    361      bar baz foo
    362      bar foo baz]])
    363    feed('/foo')
    364    screen:expect([[
    365      {2:foo} bar baz         {MATCH:%d+}: {10:foo}{MATCH:%s+}|
    366      bar baz {10:foo}         {MATCH:%d+}: {10:foo}{MATCH:%s+}|
    367      bar {10:foo} baz         {MATCH:%d+}: {10:foo}{MATCH:%s+}|
    368      {1:~                   }{MATCH:.*}|*2
    369      {3:[No Name] [+]        }{101:term [-]           }|
    370      /foo^                                    |
    371    ]])
    372  end)
    373 
    374  it('works with incsearch', function()
    375    command('set hlsearch')
    376    command('set incsearch')
    377    command('set laststatus=0')
    378    insert([[
    379      the first line
    380      in a little file]])
    381    command('vsplit')
    382    feed('gg/li')
    383    screen:expect([[
    384      the first {2:li}ne      the first {10:li}ne     |
    385      in a {10:li}ttle file    in a {10:li}ttle file   |
    386      {1:~                   }{1:~                  }|*4
    387      /li^                                     |
    388    ]])
    389 
    390    -- check that consecutive matches are caught by C-g/C-t
    391    feed('<C-g>')
    392    screen:expect([[
    393      the first {10:li}ne      the first {10:li}ne     |
    394      in a {2:li}ttle file    in a {10:li}ttle file   |
    395      {1:~                   }{1:~                  }|*4
    396      /li^                                     |
    397    ]])
    398 
    399    feed('<C-t>')
    400    screen:expect([[
    401      the first {2:li}ne      the first {10:li}ne     |
    402      in a {10:li}ttle file    in a {10:li}ttle file   |
    403      {1:~                   }{1:~                  }|*4
    404      /li^                                     |
    405    ]])
    406 
    407    feed('t')
    408    screen:expect([[
    409      the first line      the first line     |
    410      in a {2:lit}tle file    in a {10:lit}tle file   |
    411      {1:~                   }{1:~                  }|*4
    412      /lit^                                    |
    413    ]])
    414 
    415    feed('<cr>')
    416    screen:expect([[
    417      the first line      the first line     |
    418      in a {10:^lit}tle file    in a {10:lit}tle file   |
    419      {1:~                   }{1:~                  }|*4
    420      /lit                                    |
    421    ]])
    422 
    423    feed('/fir')
    424    screen:expect([[
    425      the {2:fir}st line      the {10:fir}st line     |
    426      in a little file    in a little file   |
    427      {1:~                   }{1:~                  }|*4
    428      /fir^                                    |
    429    ]])
    430 
    431    -- incsearch have priority over hlsearch
    432    feed('<esc>/ttle')
    433    screen:expect([[
    434      the first line      the first line     |
    435      in a li{2:ttle} file    in a li{10:ttle} file   |
    436      {1:~                   }{1:~                  }|*4
    437      /ttle^                                   |
    438    ]])
    439 
    440    -- cancelling search resets to the old search term
    441    feed('<esc>')
    442    screen:expect([[
    443      the first line      the first line     |
    444      in a {10:^lit}tle file    in a {10:lit}tle file   |
    445      {1:~                   }{1:~                  }|*4
    446                                              |
    447    ]])
    448    eq('lit', eval('@/'))
    449 
    450    -- cancelling inc search restores the hl state
    451    feed(':noh<cr>')
    452    screen:expect([[
    453      the first line      the first line     |
    454      in a ^little file    in a little file   |
    455      {1:~                   }{1:~                  }|*4
    456      :noh                                    |
    457    ]])
    458 
    459    feed('/first')
    460    screen:expect([[
    461      the {2:first} line      the {10:first} line     |
    462      in a little file    in a little file   |
    463      {1:~                   }{1:~                  }|*4
    464      /first^                                  |
    465    ]])
    466    feed('<esc>')
    467    screen:expect([[
    468      the first line      the first line     |
    469      in a ^little file    in a little file   |
    470      {1:~                   }{1:~                  }|*4
    471                                              |
    472    ]])
    473 
    474    -- test that pressing C-g in an empty command line does not move the cursor
    475    feed('gg0')
    476    command([[let @/ = 'i']])
    477    -- moves to next match of previous search pattern, just like /<cr>
    478    feed('/<c-g><cr>')
    479    eq({ 0, 1, 6, 0 }, fn.getpos('.'))
    480    -- moves to next match of previous search pattern, just like /<cr>
    481    feed('/<cr>')
    482    eq({ 0, 1, 12, 0 }, fn.getpos('.'))
    483    -- moves to next match of previous search pattern, just like /<cr>
    484    feed('/<c-t><cr>')
    485    eq({ 0, 2, 1, 0 }, fn.getpos('.'))
    486 
    487    -- 8.0.1304, test that C-g and C-t works with incsearch and empty pattern
    488    feed('<esc>/fi<CR>')
    489    screen:expect([[
    490      the {10:fi}rst line      the {10:fi}rst line     |
    491      in a little {10:^fi}le    in a little {10:fi}le   |
    492      {1:~                   }{1:~                  }|*4
    493      /fi                                     |
    494    ]])
    495    feed('//')
    496    screen:expect([[
    497      the {2:fi}rst line      the {10:fi}rst line     |
    498      in a little {10:fi}le    in a little {10:fi}le   |
    499      {1:~                   }{1:~                  }|*4
    500      //^                                      |
    501    ]])
    502    feed('<C-g>')
    503    screen:expect([[
    504      the {10:fi}rst line      the {10:fi}rst line     |
    505      in a little {2:fi}le    in a little {10:fi}le   |
    506      {1:~                   }{1:~                  }|*4
    507      //^                                      |
    508    ]])
    509    feed('<Esc>')
    510 
    511    -- incsearch works after c_CTRL-R_CTRL-R
    512    command('let @" = "file"')
    513    feed('/<C-R><C-R>"')
    514    screen:expect([[
    515      the first line      the first line     |
    516      in a little {2:file}    in a little {10:file}   |
    517      {1:~                   }{1:~                  }|*4
    518      /file^                                   |
    519    ]])
    520    feed('<Esc>')
    521 
    522    command('set rtp^=test/functional/fixtures')
    523    -- incsearch works after c_CTRL-R inserts clipboard register
    524 
    525    command('let @* = "first"')
    526    feed('/<C-R>*')
    527    screen:expect([[
    528      the {2:first} line      the {10:first} line     |
    529      in a little file    in a little file   |
    530      {1:~                   }{1:~                  }|*4
    531      /first^                                  |
    532    ]])
    533    feed('<Esc>')
    534 
    535    command('let @+ = "little"')
    536    feed('/<C-R>+')
    537    screen:expect([[
    538      the first line      the first line     |
    539      in a {2:little} file    in a {10:little} file   |
    540      {1:~                   }{1:~                  }|*4
    541      /little^                                 |
    542    ]])
    543    feed('<Esc>')
    544  end)
    545 
    546  it('works with incsearch and offset', function()
    547    feed_command('set hlsearch')
    548    feed_command('set incsearch')
    549    insert([[
    550      not the match you're looking for
    551      the match is here]])
    552 
    553    feed('gg/mat/e')
    554    screen:expect([[
    555      not the {2:mat}ch you're looking for        |
    556      the {10:mat}ch is here                       |
    557      {1:~                                       }|*4
    558      /mat/e^                                  |
    559    ]])
    560 
    561    -- Search with count and /e offset fixed in Vim patch 7.4.532.
    562    feed('<esc>2/mat/e')
    563    screen:expect([[
    564      not the {10:mat}ch you're looking for        |
    565      the {2:mat}ch is here                       |
    566      {1:~                                       }|*4
    567      /mat/e^                                  |
    568    ]])
    569 
    570    feed('<cr>')
    571    screen:expect([[
    572      not the {10:mat}ch you're looking for        |
    573      the {10:ma^t}ch is here                       |
    574      {1:~                                       }|*4
    575      /mat/e                                  |
    576    ]])
    577  end)
    578 
    579  it('works with multiline regexps', function()
    580    feed_command('set hlsearch')
    581    feed('4oa  repeated line<esc>')
    582    feed('/line\\na<cr>')
    583    screen:expect([[
    584                                              |
    585      a  repeated {10:^line }                       |
    586      {10:a}  repeated {10:line }                       |*2
    587      {10:a}  repeated line                        |
    588      {1:~                                       }|
    589      {19:search hit BOTTOM, continuing at TOP}    |
    590    ]])
    591 
    592    -- it redraws rows above the changed one
    593    feed('4Grb')
    594    screen:expect([[
    595                                              |
    596      a  repeated {10:line }                       |
    597      {10:a}  repeated line                        |
    598      ^b  repeated {10:line }                       |
    599      {10:a}  repeated line                        |
    600      {1:~                                       }|
    601      {19:search hit BOTTOM, continuing at TOP}    |
    602    ]])
    603  end)
    604 
    605  it('works with matchadd and syntax', function()
    606    feed_command('set hlsearch')
    607    insert [[
    608      very special text
    609    ]]
    610    feed_command('syntax on')
    611    feed_command('highlight MyGroup guibg=Green gui=bold')
    612    feed_command('highlight MyGroup2 guibg=Magenta gui=italic')
    613    feed_command("call matchadd('MyGroup', 'special')")
    614    feed_command("call matchadd('MyGroup2', 'text', 0)")
    615 
    616    -- searchhl and matchadd matches are exclusive, only the highest priority
    617    -- is used (and matches with lower priorities are not combined)
    618    feed_command('/ial te')
    619    screen:expect([[
    620      very {102:spec^ial}{10: te}{103:xt}                       |
    621                                              |
    622      {1:~                                       }|*4
    623      {19:search hit BOTTOM, continuing at TOP}    |
    624    ]])
    625 
    626    -- check highlights work also in folds
    627    feed('zf4j')
    628    screen:expect([[
    629      {13:^+--  2 lines: very special text·········}|
    630      {1:~                                       }|*5
    631      {19:search hit BOTTOM, continuing at TOP}    |
    632    ]])
    633    command('%foldopen')
    634    screen:expect([[
    635      very {102:spec^ial}{10: te}{103:xt}                       |
    636                                              |
    637      {1:~                                       }|*4
    638      {19:search hit BOTTOM, continuing at TOP}    |
    639    ]])
    640 
    641    feed_command('call clearmatches()')
    642    screen:expect([[
    643      very spec{10:^ial te}xt                       |
    644                                              |
    645      {1:~                                       }|*4
    646      :call clearmatches()                    |
    647    ]])
    648 
    649    -- searchhl has priority over syntax, but in this case
    650    -- nonconflicting attributes are combined
    651    feed_command('syntax keyword MyGroup special')
    652    screen:expect([[
    653      very {102:spec}{104:^ial}{10: te}xt                       |
    654                                              |
    655      {1:~                                       }|*4
    656      :syntax keyword MyGroup special         |
    657    ]])
    658  end)
    659 
    660  it('highlights entire pattern on :%g@a/b', function()
    661    command('set inccommand=nosplit')
    662    feed('ia/b/c<Esc>')
    663    feed(':%g@a/b')
    664    screen:expect([[
    665      {2:a/b}/c                                   |
    666      {1:~                                       }|*5
    667      :%g@a/b^                                 |
    668    ]])
    669  end)
    670 
    671  it('incsearch is still visible after :redraw from K_EVENT', function()
    672    fn.setline(1, { 'foo', 'bar' })
    673    feed('/foo<CR>/bar')
    674    screen:expect([[
    675      foo                                     |
    676      {2:bar}                                     |
    677      {1:~                                       }|*4
    678      /bar^                                    |
    679    ]])
    680    command('redraw!')
    681    -- There is an intermediate state where :redraw! removes 'incsearch' highlight.
    682    screen:expect_unchanged(true)
    683  end)
    684 
    685  it('no ml_get error with incsearch and <Cmd> mapping that opens window', function()
    686    command('cnoremap <F3> <Cmd>vnew<Bar>redraw!<CR>')
    687    fn.setline(1, { 'foo', 'bar', 'baz' })
    688    feed('G/z')
    689    screen:expect([[
    690      foo                                     |
    691      bar                                     |
    692      ba{2:z}                                     |
    693      {1:~                                       }|*3
    694      /z^                                      |
    695    ]])
    696    feed('<F3>')
    697    screen:expect([[
    698                          foo                |
    699      {1:~                   }bar                |
    700      {1:~                   }baz                |
    701      {1:~                   }{1:~                  }|*2
    702      {3:[No Name]            }{2:[No Name] [+]      }|
    703      /z^                                      |
    704    ]])
    705    eq('', n.api.nvim_get_vvar('errmsg'))
    706    feed('<C-G>')
    707    screen:expect_unchanged(true)
    708    eq('', n.api.nvim_get_vvar('errmsg'))
    709  end)
    710 
    711  it('highlight is not after redraw during substitute confirm prompt', function()
    712    fn.setline(1, { 'foo', 'bar' })
    713    command('set nohlsearch')
    714    feed(':%s/bar/baz/c<CR>')
    715    screen:try_resize(screen._width, screen._height - 1)
    716    screen:expect([[
    717      foo                                     |
    718      {2:bar}                                     |
    719      {1:~                                       }|
    720      {3:                                        }|
    721      {6:replace with baz? (y)es/(n)o/(a)ll/(q)ui}|
    722      {6:t/(l)ast/scroll up(^E)/down(^Y)}^         |
    723    ]])
    724  end)
    725 end)