Просмотр исходного кода

Tighten the logic for getting just one buffer's information.

- Adjust the regular expression used for limiting `:buffers` output to a
  single buffer:

  - Use `\D` instead of `\>` to detect the end of the buffer number.
    Unlisted buffers use a `u` character adjacent to the buffer number
    (e.g,. `1u`), and `\>` doesn't match before the `u`.  This allows
    narrowing to a specific unlisted buffer's information.

  - Use `matchstr()` to extract the line containing the desired single
    buffer (or the empty string if not found).  Using `substitute()` to
    search for the pattern `(pre-lines)(desired line)(post-lines)` and
    replacing with `(desired line)` works when the desired line is
    found, but leaves the string unmodified (with all undesired buffers
    present) when the desired line is not present.

- Use `:silent buffers` (without `!`) to return only listed buffers when
  we know we are looking for a single listed buffer.
Michael Henry 9 месяцев назад
Родитель
Сommit
1c6329bbd5
1 измененных файлов с 32 добавлено и 6 удалено
  1. 32 6
      plugin/bufexplorer.vim

+ 32 - 6
plugin/bufexplorer.vim

@@ -855,6 +855,10 @@ endfunction
 
 " CalculateBufferDetails {{{2
 " Calculate `buf`-related details.
+" Only these fields of `buf` must be defined on entry:
+" - `._bufnr`
+" - `.attributes`
+" - `.line`
 function! s:CalculateBufferDetails(buf)
     let buf = a:buf
     let name = bufname(buf._bufnr)
@@ -897,19 +901,41 @@ function! s:CalculateBufferDetails(buf)
 endfunction
 
 " GetBufferInfo {{{2
-function! s:GetBufferInfo(bufnr)
+" Return dictionary `{ bufNbr : buf }`.
+" - If `onlyBufNbr > 0`, dictionary will contain at most that buffer.
+" On return, only these fields are set for each `buf`:
+" - `._bufnr`
+" - `.attributes`
+" - `.line`
+" Other fields will be populated by `s:CalculateBufferDetails()`.
+function! s:GetBufferInfo(onlyBufNbr)
     redir => bufoutput
 
-    " Show all buffers including the unlisted ones. [!] tells Vim to show the
-    " unlisted ones.  `:silent` allows capturing the output via `:redir`, but
+    " Below, `:silent buffers` allows capturing the output via `:redir` but
     " prevents display to the user.
-    silent buffers!
+
+    if a:onlyBufNbr > 0 && buflisted(a:onlyBufNbr)
+        " We care only about the listed buffer `a:onlyBufNbr`, so no need to
+        " enumerate unlisted buffers.
+        silent buffers
+    else
+        " Use `!` to show all buffers including the unlisted ones.
+        silent buffers!
+    endif
     redir END
 
-    if a:bufnr > 0
+    if a:onlyBufNbr > 0
         " Since we are only interested in this specified buffer remove the
         " other buffers listed.
-        let bufoutput = substitute(bufoutput."\n", '^.*\n\(\s*'.a:bufnr.'\>.\{-}\)\n.*', '\1', '')
+        " Use a very-magic pattern starting with a newline and a run of zero or
+        " more spaces/tabs:
+        let onlyLinePattern = '\v\n\s*'
+        " Continue with the buffer number followed by a non-digit character
+        " (which will be a buffer attribute character such as `u` or ` `).
+        let onlyLinePattern .= a:onlyBufNbr . '\D'
+        " Finish with a run of zero or more non-newline characters plus newline:
+        let onlyLinePattern .= '[^\n]*\n'
+        let bufoutput = matchstr("\n" . bufoutput . "\n", onlyLinePattern)
     endif
 
     let all = {}