blob: 2470a5bce5ee4b287700605c889bb9796808299c [file] [log] [blame]
Bram Moolenaar119d4692016-03-05 21:21:24 +01001" Tests for the history functions
2
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02003CheckFeature cmdline_hist
Bram Moolenaar119d4692016-03-05 21:21:24 +01004
5set history=7
6
7function History_Tests(hist)
8 " First clear the history
9 call histadd(a:hist, 'dummy')
10 call assert_true(histdel(a:hist))
11 call assert_equal(-1, histnr(a:hist))
12 call assert_equal('', histget(a:hist))
13
Bram Moolenaarf9f24ce2019-08-31 21:17:39 +020014 call assert_true('ls'->histadd(a:hist))
Bram Moolenaar119d4692016-03-05 21:21:24 +010015 call assert_true(histadd(a:hist, 'buffers'))
16 call assert_equal('buffers', histget(a:hist))
17 call assert_equal('ls', histget(a:hist, -2))
18 call assert_equal('ls', histget(a:hist, 1))
19 call assert_equal('', histget(a:hist, 5))
20 call assert_equal('', histget(a:hist, -5))
21 call assert_equal(2, histnr(a:hist))
22 call assert_true(histdel(a:hist, 2))
Bram Moolenaarf9f24ce2019-08-31 21:17:39 +020023 call assert_false(a:hist->histdel(7))
Bram Moolenaar119d4692016-03-05 21:21:24 +010024 call assert_equal(1, histnr(a:hist))
25 call assert_equal('ls', histget(a:hist, -1))
26
27 call assert_true(histadd(a:hist, 'buffers'))
28 call assert_true(histadd(a:hist, 'ls'))
Bram Moolenaarf9f24ce2019-08-31 21:17:39 +020029 call assert_equal('ls', a:hist->histget(-1))
30 call assert_equal(4, a:hist->histnr())
Bram Moolenaar119d4692016-03-05 21:21:24 +010031
Bram Moolenaareebd84e2016-12-01 17:57:44 +010032 let a=execute('history ' . a:hist)
33 call assert_match("^\n # \\S* history\n 3 buffers\n> 4 ls$", a)
34 let a=execute('history all')
35 call assert_match("^\n # .* history\n 3 buffers\n> 4 ls", a)
36
37 if len(a:hist) > 0
38 let a=execute('history ' . a:hist . ' 2')
39 call assert_match("^\n # \\S* history$", a)
40 let a=execute('history ' . a:hist . ' 3')
41 call assert_match("^\n # \\S* history\n 3 buffers$", a)
42 let a=execute('history ' . a:hist . ' 4')
43 call assert_match("^\n # \\S* history\n> 4 ls$", a)
44 let a=execute('history ' . a:hist . ' 3,4')
45 call assert_match("^\n # \\S* history\n 3 buffers\n> 4 ls$", a)
46 let a=execute('history ' . a:hist . ' -1')
47 call assert_match("^\n # \\S* history\n> 4 ls$", a)
48 let a=execute('history ' . a:hist . ' -2')
49 call assert_match("^\n # \\S* history\n 3 buffers$", a)
50 let a=execute('history ' . a:hist . ' -2,')
51 call assert_match("^\n # \\S* history\n 3 buffers\n> 4 ls$", a)
52 let a=execute('history ' . a:hist . ' -3')
53 call assert_match("^\n # \\S* history$", a)
54 endif
55
Bram Moolenaar119d4692016-03-05 21:21:24 +010056 " Test for removing entries matching a pattern
57 for i in range(1, 3)
58 call histadd(a:hist, 'text_' . i)
59 endfor
60 call assert_true(histdel(a:hist, 'text_\d\+'))
61 call assert_equal('ls', histget(a:hist, -1))
62
63 " Test for freeing the entire history list
64 for i in range(1, 7)
65 call histadd(a:hist, 'text_' . i)
66 endfor
67 call histdel(a:hist)
68 for i in range(1, 7)
69 call assert_equal('', histget(a:hist, i))
70 call assert_equal('', histget(a:hist, i - 7 - 1))
71 endfor
Bram Moolenaar578fe942020-02-27 21:32:51 +010072
73 " Test for freeing an entry at the beginning of the history list
74 for i in range(1, 4)
75 call histadd(a:hist, 'text_' . i)
76 endfor
77 call histdel(a:hist, 1)
78 call assert_equal('', histget(a:hist, 1))
79 call assert_equal('text_4', histget(a:hist, 4))
Bram Moolenaar119d4692016-03-05 21:21:24 +010080endfunction
81
82function Test_History()
83 for h in ['cmd', ':', '', 'search', '/', '?', 'expr', '=', 'input', '@', 'debug', '>']
84 call History_Tests(h)
85 endfor
86
87 " Negative tests
88 call assert_false(histdel('abc'))
89 call assert_equal('', histget('abc'))
90 call assert_fails('call histdel([])', 'E730:')
91 call assert_equal('', histget(10))
92 call assert_fails('call histget([])', 'E730:')
93 call assert_equal(-1, histnr('abc'))
94 call assert_fails('call histnr([])', 'E730:')
Bram Moolenaar8d588cc2020-02-25 21:47:45 +010095 call assert_fails('history xyz', 'E488:')
96 call assert_fails('history ,abc', 'E488:')
Bram Moolenaar531be472020-09-23 22:38:05 +020097 call assert_fails('call histdel(":", "\\%(")', 'E53:')
Christian Brabandt42a5b5a2024-05-24 07:39:34 +020098
99 " Test for filtering the history list
100 let hist_filter = execute(':filter /_\d/ :history all')->split('\n')
101 call assert_equal(20, len(hist_filter))
102 let expected = [' # cmd history',
103 \ ' 2 text_2',
104 \ ' 3 text_3',
105 \ '> 4 text_4',
106 \ ' # search history',
107 \ ' 2 text_2',
108 \ ' 3 text_3',
109 \ '> 4 text_4',
110 \ ' # expr history',
111 \ ' 2 text_2',
112 \ ' 3 text_3',
113 \ '> 4 text_4',
114 \ ' # input history',
115 \ ' 2 text_2',
116 \ ' 3 text_3',
117 \ '> 4 text_4',
118 \ ' # debug history',
119 \ ' 2 text_2',
120 \ ' 3 text_3',
121 \ '> 4 text_4']
122 call assert_equal(expected, hist_filter)
123
124 let cmds = {'c': 'cmd', 's': 'search', 'e': 'expr', 'i': 'input', 'd': 'debug'}
125 for h in sort(keys(cmds))
126 " find some items
127 let hist_filter = execute(':filter /_\d/ :history ' .. h)->split('\n')
128 call assert_equal(4, len(hist_filter))
129
130 let expected = [' # ' .. cmds[h] .. ' history',
131 \ ' 2 text_2',
132 \ ' 3 text_3',
133 \ '> 4 text_4']
134 call assert_equal(expected, hist_filter)
135
136 " Search for an item that is not there
137 let hist_filter = execute(':filter /XXXX/ :history ' .. h)->split('\n')
138 call assert_equal(1, len(hist_filter))
139
140 let expected = [' # ' .. cmds[h] .. ' history']
141 call assert_equal(expected, hist_filter)
142
143 " Invert the filter condition, find non-matches
144 let hist_filter = execute(':filter! /_3$/ :history ' .. h)->split('\n')
145 call assert_equal(3, len(hist_filter))
146
147 let expected = [' # ' .. cmds[h] .. ' history',
148 \ ' 2 text_2',
149 \ '> 4 text_4']
150 call assert_equal(expected, hist_filter)
151 endfor
Bram Moolenaar119d4692016-03-05 21:21:24 +0100152endfunction
Bram Moolenaar1d669c22017-01-11 22:40:19 +0100153
Dominique Pelled176ca32021-09-09 20:45:34 +0200154function Test_history_truncates_long_entry()
155 " History entry short enough to fit on the screen should not be truncated.
156 call histadd(':', 'echo x' .. repeat('y', &columns - 17) .. 'z')
157 let a = execute('history : -1')
158
159 call assert_match("^\n # cmd history\n"
160 \ .. "> *\\d\\+ echo x" .. repeat('y', &columns - 17) .. 'z$', a)
161
162 " Long history entry should be truncated to fit on the screen, with, '...'
163 " inserted in the string to indicate the that there is truncation.
164 call histadd(':', 'echo x' .. repeat('y', &columns - 16) .. 'z')
165 let a = execute('history : -1')
166 call assert_match("^\n # cmd history\n"
167 \ .. "> *\\d\\+ echo xy\\+\.\.\.y\\+z$", a)
168endfunction
169
Bram Moolenaar1d669c22017-01-11 22:40:19 +0100170function Test_Search_history_window()
171 new
172 call setline(1, ['a', 'b', 'a', 'b'])
173 1
174 call feedkeys("/a\<CR>", 'xt')
175 call assert_equal('a', getline('.'))
176 1
177 call feedkeys("/b\<CR>", 'xt')
178 call assert_equal('b', getline('.'))
179 1
180 " select the previous /a command
181 call feedkeys("q/kk\<CR>", 'x!')
182 call assert_equal('a', getline('.'))
183 call assert_equal('a', @/)
184 bwipe!
185endfunc
Bram Moolenaarb513d302018-12-02 14:55:08 +0100186
Bram Moolenaar0546d7d2020-03-01 16:53:09 +0100187" Test for :history command option completion
Bram Moolenaarb513d302018-12-02 14:55:08 +0100188function Test_history_completion()
189 call feedkeys(":history \<C-A>\<C-B>\"\<CR>", 'tx')
190 call assert_equal('"history / : = > ? @ all cmd debug expr input search', @:)
191endfunc
Bram Moolenaar8d588cc2020-02-25 21:47:45 +0100192
193" Test for increasing the 'history' option value
194func Test_history_size()
195 let save_histsz = &history
Bram Moolenaar578fe942020-02-27 21:32:51 +0100196 set history=10
Bram Moolenaar0546d7d2020-03-01 16:53:09 +0100197 call histadd(':', 'ls')
198 call histdel(':')
Bram Moolenaar8d588cc2020-02-25 21:47:45 +0100199 for i in range(1, 5)
200 call histadd(':', 'cmd' .. i)
201 endfor
202 call assert_equal(5, histnr(':'))
203 call assert_equal('cmd5', histget(':', -1))
204
Bram Moolenaar578fe942020-02-27 21:32:51 +0100205 set history=15
Bram Moolenaar8d588cc2020-02-25 21:47:45 +0100206 for i in range(6, 10)
207 call histadd(':', 'cmd' .. i)
208 endfor
209 call assert_equal(10, histnr(':'))
210 call assert_equal('cmd1', histget(':', 1))
211 call assert_equal('cmd10', histget(':', -1))
212
213 set history=5
214 call histadd(':', 'abc')
215 call assert_equal('', histget(':', 6))
216 call assert_equal('', histget(':', 12))
217 call assert_equal('cmd7', histget(':', 7))
218 call assert_equal('abc', histget(':', -1))
219
Bram Moolenaar578fe942020-02-27 21:32:51 +0100220 " This test works only when the language is English
221 if v:lang == "C" || v:lang =~ '^[Ee]n'
222 set history=0
223 redir => v
224 call feedkeys(":history\<CR>", 'xt')
225 redir END
226 call assert_equal(["'history' option is zero"], split(v, "\n"))
227 endif
228
Bram Moolenaar8d588cc2020-02-25 21:47:45 +0100229 let &history=save_histsz
230endfunc
231
232" Test for recalling old search patterns in /
233func Test_history_search()
234 call histdel('/')
235 let g:pat = []
236 func SavePat()
237 call add(g:pat, getcmdline())
238 return ''
239 endfunc
240 cnoremap <F2> <C-\>eSavePat()<CR>
241 call histadd('/', 'pat1')
242 call histadd('/', 'pat2')
243 let @/ = ''
244 call feedkeys("/\<Up>\<F2>\<Up>\<F2>\<Down>\<Down>\<F2>\<Esc>", 'xt')
245 call assert_equal(['pat2', 'pat1', ''], g:pat)
246 cunmap <F2>
247 delfunc SavePat
Bram Moolenaar0546d7d2020-03-01 16:53:09 +0100248
Bram Moolenaar91ffc8a2020-03-02 20:54:22 +0100249 " Search for a pattern that is not present in the history
250 call assert_beeps('call feedkeys("/a1b2\<Up>\<CR>", "xt")')
251
Bram Moolenaar0546d7d2020-03-01 16:53:09 +0100252 " Recall patterns with 'history' set to 0
253 set history=0
254 let @/ = 'abc'
255 let cmd = 'call feedkeys("/\<Up>\<Down>\<S-Up>\<S-Down>\<CR>", "xt")'
256 call assert_fails(cmd, 'E486:')
257 set history&
Bram Moolenaar91ffc8a2020-03-02 20:54:22 +0100258
259 " Recall patterns till the end of history
260 set history=4
261 call histadd('/', 'pat')
262 call histdel('/')
263 call histadd('/', 'pat1')
264 call histadd('/', 'pat2')
265 call assert_beeps('call feedkeys("/\<Up>\<Up>\<Up>\<C-U>\<cr>", "xt")')
266 call assert_beeps('call feedkeys("/\<Down><cr>", "xt")')
267
268 " Test for wrapping around the history list
269 for i in range(3, 7)
270 call histadd('/', 'pat' .. i)
271 endfor
272 let upcmd = "\<up>\<up>\<up>\<up>\<up>"
273 let downcmd = "\<down>\<down>\<down>\<down>\<down>"
274 try
275 call feedkeys("/" .. upcmd .. "\<cr>", 'xt')
276 catch /E486:/
277 endtry
278 call assert_equal('pat4', @/)
279 try
280 call feedkeys("/" .. upcmd .. downcmd .. "\<cr>", 'xt')
281 catch /E486:/
282 endtry
283 call assert_equal('pat4', @/)
284
285 " Test for changing the search command separator in the history
286 call assert_fails('call feedkeys("/def/\<cr>", "xt")', 'E486:')
287 call assert_fails('call feedkeys("?\<up>\<cr>", "xt")', 'E486:')
288 call assert_equal('def?', histget('/', -1))
289
290 call assert_fails('call feedkeys("/ghi?\<cr>", "xt")', 'E486:')
291 call assert_fails('call feedkeys("?\<up>\<cr>", "xt")', 'E486:')
292 call assert_equal('ghi\?', histget('/', -1))
293
294 set history&
Bram Moolenaar8d588cc2020-02-25 21:47:45 +0100295endfunc
296
Bram Moolenaar578fe942020-02-27 21:32:51 +0100297" Test for making sure the key value is not stored in history
298func Test_history_crypt_key()
299 CheckFeature cryptv
Yee Cheng Chin6ee7b522023-10-01 09:13:22 +0200300
Bram Moolenaar578fe942020-02-27 21:32:51 +0100301 call feedkeys(":set bs=2 key=abc ts=8\<CR>", 'xt')
302 call assert_equal('set bs=2 key= ts=8', histget(':'))
Yee Cheng Chin6ee7b522023-10-01 09:13:22 +0200303
304 call assert_fails("call feedkeys(':set bs=2 key-=abc ts=8\<CR>', 'xt')")
305 call assert_equal('set bs=2 key-= ts=8', histget(':'))
306
Bram Moolenaar578fe942020-02-27 21:32:51 +0100307 set key& bs& ts&
308endfunc
309
zeertzjqc029c132024-03-28 11:37:26 +0100310" The following used to overflow and causing a use-after-free
Christian Brabandt9198c1f2023-10-26 21:29:32 +0200311func Test_history_max_val()
312
313 set history=10
314 call assert_fails(':history 2147483648', 'E1510:')
315 set history&
316endfunc
317
Bram Moolenaar8d588cc2020-02-25 21:47:45 +0100318" vim: shiftwidth=2 sts=2 expandtab