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