I'm looking for a way to write content of a quickfix window to a file with a specific formatting, preferably in a way that is easily scriptable.
What I'm trying to achieve is a very light integration of Vim and ipdb:
I set 'breakpoints' as items on a quickfix list with mapping:
nmap <leader>s :call setqflist([], 'a', {'items': [{'filename': #%, 'lnum':line('.'), 'text':'break'}]})
Write content of the quickfix to .pdbrc file with break file_path:line_number formatting
Run ipdb on specified script
You have two problems:
Turning items into a list of properly formatted lines.
You will need to:
get the quickfix list with :help getqflist(),
format each item of the list with :help map(),
derive file_path from the bufnr field with :help bufname() and possibly :help fnamemodify().
Writing that list to a given file.
You will need :help writefile().
Related
I want to show all buffers' names on statusline(I use powerline). And I hope current buffer can be highlighted, while others are not. When I use :bn or :bp it highlights the changed buffer. How can I make it?
I don't know how to do such a thing with powerline, however I have come across vim-buftabline which does what you ask but with the tabline instead of the statusline.
Personally, I would forget doing this in the statusline or tabline, because it is very easy to run out of space on either line. I would also stop using :bn/:bp and just use :b instead to jump directly to the buffer in question.
Behold the power of :b:
Uses <tab> completion
Use <c-d> to list out completion
Use partial file name. e.g. :b foo. Works great with <tab>.
Globbing. e.g. :b foo*bar or :b foo/**/bar
Might want to use 'hidden' via set hidden
Split variant of :b is :sb.
Also accepts a buffer number
A common mapping:
nnoremap <leader>b :ls<cr>:b<space>
For more help see:
:h :b
:h :ls
:h 'switchbuf'
:h 'hidden'
:h 'tabline'
In powerline, the list of open buffers can be displayed by adding the following line to your .vimrc configuration file:
set showtabline=2
This will add an additional status line at the top of your vim session and also highlight the active buffer.
Source: Powerline documentation
Does anyone know how to highlight the entire line if there is or if there are matches after doing a search.
p.e. I do a search for /user
Now I want to highlight the entire line if there are matches.
EDIT
I want to use the highlighting as in the search highlighting.
I don't want to use the highlighting groups.
An alternative to highlighting the the lines might be using the quickfix list. For example doing following will put all lines matching the pattern /user/ into the quickfix list for the current file (%).
:vimgrep /user/ %
You can display in a separate window the contents of the quickfix list by doing :copen. You can move between matching lines by :cnext, :cprev, and friends. I personally recommend Tim Pope's excellent unimpaired.vim plugin to provide some rather nice and natural feeling mappings like [q and ]q to move through the quickfix list. You can also add a g flag to find multiple matches per line and add them to the quickfix list as well.
You may want to mapping to this vimgrep command to make it a bit faster. I personally use the following in my ~/.vimrc
nnoremap <leader>/ :vimgrep/<c-r>//g %<cr>:copen<cr>
A disadvantage to using :vimgrep command is that it needs a saved file, so unsaved buffers must be saved first. You can overcome this with using a combination of :global and :cgetexpr as shown below.
:cexpr []
:g//caddexpr expand("%").":".line(".").":".getline(".")
However maybe you really do just want to highlight the lines with a match instead of using the quickfix list. The I would suggest using :match like so
:match Search /.*user.*/
You can use whatever highlight group you want. I choose Search as it seemed appropriate. To turn off the highlighting just execute :match with out any arguments.
I personally prefer using :vimgrep and the quickfix list, but your needs may vary from mine.
For more help see:
:h quickfix
:h :vimgrep
:h :cnext
:h :cexpr
:h :caddexpr
:h :match
If you use
:let #/ = '.*\%(' . #/ . '\m\).*'
that should work for most regexp patterns (e.g. the bracketing takes care of \| branches). You could refine that to recognize ^ and $, and magic modifiers like \V.
I don't know if this is acceptable for you:
first you need to define a highlight group: e.g. userline
:highlight userline ctermbg=darkred guibg=darkred
then you could:
:match userline /.*user.*/
all lines containing "user" would be highlighted.
What is the highlight group for the currently selected line in the quickfix window?
The selected line in the quickfix window uses Search for highlighting. I'd like to continue using yellow for Search highlighting, but use blue for quickfix selected line.
Ingo Karkat's answer is right. It's indeed hard-coded in vim code.
I have created a patch - QuickFixCurrentLine.patch for vim8.
Patch is long enough to be posted here. Plus, it has mix of tabs and spaces. So, providing a link-only-answer.
EDIT:
The patch has got upstreamed in the latest vim code.
The name of the highlight has been changed to quickfixline instead of quickfixcurrentline.
The currently selected quickfix item is hard-coded to Search. You'd have to change the Vim source code and recompile to change this.
I see only limited ways to work around this with Vimscript. You could try to override the highlighting for the current line via :match / matchadd() (it has higher priority), but it would only cover the length of the text, not the entire line the original highlighting. Also, I think the currently selected item cannot be easily queried from Vim, so you'd have to hook into the quickfix-local <CR> mapping to update it, and stop using :cnext etc. to move to different errors.
:highlight BlueLine guibg=Blue
:autocmd BufReadPost quickfix match BlueLine /\%1l/
:autocmd BufReadPost quickfix nnoremap <buffer> <CR> :execute 'match BlueLine /\%' . line('.') . 'l/'<CR><CR>
From the command line, if you type "vim some_directory/", vim will open a sort of file browser, where you can navigate through your directory structure by moving up or down with "j" and "k", and selecting with "enter" until you get to and open a file.
I'd like to write a function for vim in VimL that generates a (for now) arbitrary list of file names in your sub-directories and lists them in that file browser-like form mentioned above, where you can navigate to a file in the list by pressing "j" or "k" and selecting it (opening it, to edit) by pressing "enter".
Is that possible with VimL? If so, how? Bear in mind I'm interested in implementing the file-browser functionality, I've already figured out getting a list of file names.
Thanks in advance!
In Vim, this is implemented by scratch buffers; i.e. you open a new buffer with :new, populate it with Vimscript (:normal i... or :call setline(1, "foo")), and :setlocal nomodifiable.
Usually, the following settings are also applied:
:setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile
To implement actions, use :map <buffer> to define special mappings just for that scratch buffer, e.g.
:nnoremap <buffer> <CR> :echo "you selected: " getline('.')
Voila!
I'm reading through a large C++ code base in Vim.
Within a single file, I can do
/foo
n
n
n
Now, if I want to search through more than one file, I have to do:
:vimgrep /foo/
:cn
:cn
:cn
Now, typing :cn is so much less convenient than n. Is there a way to search through vimgrep results with n (like searches with /) instead of :cn?
Use the Quickfix List. It will automatically be filled with found matches (no matter if you use :grep or :vimgrep). It can be navigated with the usual keys (so the key for "next" is j instead of n).
To open it use :copen.
This is what I have in my .vimrc exactly for this purpose:
nmap <F7> :cp^M
nmap <F8> :cn^M
Just another option: the vim-unimpaired plugin binds ]q to :cnext and [q to :cNext among many other useful keymappings.