1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
Post- dos2unix, Tabify, and Trim.
--- a/qname.1.2.vim 2025-08-03 20:12:24.629096223 -0400
+++ b/qname.1.2.vim 2025-11-04 11:19:39.070454407 -0500
@@ -7,7 +7,30 @@
" License: Vim License
" =============================================================================
+" https://www.vim.org/scripts/script.php?script_id=2317
+"
" Change Log
+" EDIT:
+" 2025-06-24:
+" Remove redraw on update
+" Don't wrap around in the list
+" ls! -> ls
+" <Tab> -> <C-j/k>
+" Take out built-in hotkey
+" 2025-08-05:
+" Use path relative to current dir
+" Match against file path
+" 2025-08-13:
+" Sort buffers by most recently used
+" Add bind to "flatten" the list
+" Replace fmatch() with built-in matchfuzzy() (speedup)
+" Fix logic to not include buffers with modifiable off
+" 2025-10-30:
+" Treat <S-BS> the same as <BS>
+" 2025-11-04:
+" Open selected buffer in the current window, even if the same buffer is
+" already open in another window.
+"
" 1.2 2013-01-03
" ADD: <Tab> and <S-Tab> moves selection like <Up> and <Down>
" ADD: Use <silent> mapping to keep cmdline clear
@@ -30,12 +53,6 @@
finish
endif
-if !exists("g:qname_hotkey") || g:qname_hotkey == ""
- let g:qname_hotkey = "<F3>"
-endif
-exe "nmap" g:qname_hotkey ":cal QNameInit(1)<cr>:~"
-let s:qname_hotkey = eval('"\'.g:qname_hotkey.'"')
-
if exists("g:qname_loaded") && g:qname_loaded
finish
endif
@@ -53,7 +70,7 @@
" use case-sensitive equality operator, otherwise <BS> looks like
" <S-Tab> if 'ignorecase' is set
- if _key ==# "\<BS>"
+ if _key ==# "\<BS>" || _key ==# "\<S-BS>"
let s:inp = s:inp[:-2]
elseif _key ==# "\<C-U>"
let s:inp = ""
@@ -70,16 +87,19 @@
call s:swb(str2nr(matchstr(s:s[_sel], '<\zs\d\+\ze>')))
endif
call QNameInit(0)
- elseif _key ==# "\<Up>" || _key ==# "\<S-Tab>"
+ elseif _key ==# "\<Up>" || _key ==# "\<C-k>"
call s:colPrinter.vert(-1)
- elseif _key ==# "\<Down>" || _key ==# "\<Tab>"
+ elseif _key ==# "\<Down>" || _key ==# "\<C-j>"
call s:colPrinter.vert(1)
elseif _key ==# "\<Left>"
call s:colPrinter.horz(-1)
elseif _key ==# "\<Right>"
call s:colPrinter.horz(1)
- elseif _key ==# s:qname_hotkey
- call QNameInit(0)
+ elseif _key ==# "\<C-f>"
+ let s:flat = 1 - s:flat
+ let prev_sel = s:colPrinter.sel
+ call s:build()
+ let s:colPrinter.sel = prev_sel
else
call s:build()
endif
@@ -88,7 +108,6 @@
cal QNameInit(0)
finally
" clean up screen after dismissing search window
- redraw!
call inputrestore()
endtry
endfunc
@@ -99,6 +118,7 @@
let s:cmdh = &cmdheight
if a:start != -1
let s:inp = ""
+ let s:flat = 0
endif
call s:baselist()
call s:build()
@@ -112,16 +132,27 @@
function! s:build()
let s:s = []
let s:n = []
+ let s:sp = []
+ let s:np = []
let s:blen = 0
let _cmp = tolower(tr(s:inp, '\', '/'))
for _line in s:ls
- let _name = matchstr(_line, '^.\{-}\ze \+<')
- if s:fmatch(tolower(_name), _cmp)
+ " Match everthing before |<xx>| Match everthing after space.
+ let _match = matchlist(_line, '^.\{-}\ze \+<.*> \+\(.*\)')
+ let _name = _match[0]
+ let _path = _match[1]
+ if strlen(_cmp) == 0 || s:fmatch(tolower(_name), _cmp)
cal add(s:s, _line)
cal add(s:n, _name)
+ elseif s:fmatch(tolower(_path), _cmp)
+ cal add(s:sp, _line)
+ cal add(s:np, _name)
endif
endfor
- if len(s:n) > s:colPrinter.trow
+ " Put filename matches before path matches.
+ let s:n = s:n + s:np
+ let s:s = s:s + s:sp
+ if !s:flat && len(s:n) > s:colPrinter.trow
cal s:colPrinter.put(s:n)
else
cal s:colPrinter.put(s:s)
@@ -129,45 +160,32 @@
endfunc
function! s:swb(bno)
- if bufwinnr(a:bno) == -1
- exe "hid b" a:bno
- else
- exe bufwinnr(a:bno) . "winc w"
- endif
+ exe "hid b" a:bno
endfunc
function! s:fmatch(src,pat)
- let _si = strlen(a:src)-1
- let _pi = strlen(a:pat)-1
- while _si>=0 && _pi>=0
- if a:src[_si] == a:pat[_pi]
- let _pi -= 1
- endif
- let _si -= 1
- endwhile
- return _pi < 0
+ return len(matchfuzzy([a:src], a:pat)) > 0
endfunc
function! s:baselist()
let s:ls = []
- redir => l:bufs | silent ls! | redir END
+ redir => l:bufs | silent ls t | redir END
for _line in split(l:bufs, "\n")
- if _line[3]!='u' || _line[6]!='-'
+ if _line[6] != '-'
let _bno = matchstr(_line, '^ *\zs\d*')+0
let _fname = substitute(expand("#"._bno.":p"), '\', '/', 'g')
if _fname == ""
let _fname = "|".matchstr(_line, '"\[\zs[^\]]*')."|"
endif
let _name = fnamemodify(_fname,":t")
- cal add(s:ls, _name." <"._bno."> ".fnamemodify(_fname,":h"))
+ cal add(s:ls, _name." <"._bno."> ".fnamemodify(_fname,":."))
endif
endfor
let _align = max(map(copy(s:ls),'stridx(v:val,">")'))
call map(s:ls, 'substitute(v:val, " <", repeat(" ",_align-stridx(v:val,">"))." <", "")')
- cal sort(s:ls, 1)
endfunc
-let s:colPrinter = {"trow": 4}
+let s:colPrinter = {"trow": 5}
function! s:colPrinter.put(its) dict
let _cols = []
let _trow = self.trow
@@ -224,11 +242,7 @@
function! s:colPrinter.vert(mv) dict
let _t = self.sel + a:mv
let _len = self.len
- if _t < 0 && _len > 0
- let self.sel = _len-1
- elseif _t >= _len
- let self.sel = 0
- else
+ if _t >= 0 && _t < _len
let self.sel = _t
endif
endfunc
@@ -244,7 +258,7 @@
let _t = _sel/_trow
let _cpos = self.cpos
let _lcol = self.lcol
- let _tcol = &columns
+ let _tcol = s:flat ? 1 : &columns
if _cpos[_lcol]+_tcol < _cpos[_t+1]
let _rcol = _t
let _pos = _cpos[_t+1]-_tcol-2
|