Skip to content

Commit

Permalink
bundle/QFEnter: Pulled new 'master' from 'git@github.com:yssl/QFEnter'
Browse files Browse the repository at this point in the history
  • Loading branch information
dlitz committed Mar 23, 2014
2 parents 845ca04 + cbfe86f commit 0407b61
Show file tree
Hide file tree
Showing 5 changed files with 537 additions and 0 deletions.
2 changes: 2 additions & 0 deletions bundle/QFEnter/.gitignore
@@ -0,0 +1,2 @@
tags
video/*
60 changes: 60 additions & 0 deletions bundle/QFEnter/README.md
@@ -0,0 +1,60 @@
# QFEnter

QFEnter allows you to open a Quickfix item in a window you choose.
You can choose the window by giving it a focus just before jumping to Quickfix window.
You can also open multiple items at once by including them in the visual block.

A normal mode example:
![qfenter](https://f.cloud.github.com/assets/5915359/1632228/bb76dc72-5774-11e3-83d1-2933b95d5b81.gif)

A visual mode example:
![qfentervisualopt](https://f.cloud.github.com/assets/5915359/2006385/61c6f720-8717-11e3-806b-d0f276af3ef9.gif)

## Usage

In Quickfix window,

**\<Enter\>**, **\<2-LeftMouse\>**
*Normal mode* : Open an item under cursor in a previously focused window.
*Visual mode* : Open items in visual block in a previously focused window. As a result, the last item appears in the window.

**\<Leader\>\<Enter\>**
*Normal mode* : Open an item under cursor in a new vertical split from a previously focused window.
*Visual mode* : Open items in visual block in a sequence of new vertical splits from a previously focused window.

**\<Leader\>\<Space\>**
*Normal mode* : Open an item under cursor in a new horizontal split from a previously focused window.
*Visual mode* : Open items in visual block in a sequence of new horizontal splits from a previously focused window.

**\<Leader\>\<Tab\>**
*Normal mode* : Open an item under cursor in a new tab.
*Visual mode* : Open items in visual block in a sequence of new tabs.
Quickfix window is automatically opened in the new tab to help you open other Quickfix items.

You can change the key mappings in your .vimrc. The default setting is,
```
let g:qfenter_open_map = ['<CR>', '<2-LeftMouse>']
let g:qfenter_vopen_map = ['<Leader><CR>']
let g:qfenter_hopen_map = ['<Leader><Space>']
let g:qfenter_topen_map = ['<Leader><Tab>']
```

## Motivation

Default opening methods for QuickFix items are quite inconvenient,

- You cannot select a window in which a file is opened when you press `<Enter>` in Quickfix.

> Hitting the \<Enter\> key or double-clicking the mouse on a line has the same effect. The
file containing the error is opened **in the window above the quickfix window**.
*`:help quickfix`*

It is inconsistent with other Quickfix commands like `:cnext` and `:cprev` which open a file in a previously focused window.

- You also cannot specify the window when you use `Ctrl-W <Enter>`,
because Vim always create a new horizontal split window above Quickfix window and open a file in it.
There is even no command for 'open in new vertical split window'.

They are confusing and bother me every time, so I wrote a simple plugin to make up for these weak points.
It's name comes from the most basic way to open a file from Quickfix window - the `<Enter>` key.

165 changes: 165 additions & 0 deletions bundle/QFEnter/autoload/QFEnter.vim
@@ -0,0 +1,165 @@
" File: autoload/QFEnter.vim
" Description: Open a Quickfix item in a window you choose.
" Author: yssl <http://github.com/yssl>
" License: MIT License

" functions
function! s:ExecuteCC(lnumqf)
let cc_cmd = substitute(g:qfenter_cc_cmd, '##', a:lnumqf, "")
execute cc_cmd
endfunction

function! s:ExecuteCN(count)
let cn_cmd = g:qfenter_cn_cmd
execute cn_cmd
endfunction

function! s:ExecuteCP(count)
let cp_cmd = g:qfenter_cp_cmd
execute cp_cmd
endfunction

function! QFEnter#OpenQFItem(wintype, opencmd, isvisual)
let qfbufnr = bufnr('%')
let qflnum = line('.')

if a:isvisual
let vblnum2 = getpos("'>")[1]
endif

call s:OpenQFItem(a:wintype, a:opencmd, qflnum)

if a:isvisual
if qflnum==vblnum2
if g:qfenter_keep_quickfixfocus[a:opencmd]==1
redraw
let qfwinnr = bufwinnr(qfbufnr)
exec qfwinnr.'wincmd w'
endif
else
let qfwinnr = bufwinnr(qfbufnr)
exec qfwinnr.'wincmd w'
endif
else
if g:qfenter_keep_quickfixfocus[a:opencmd]==1
redraw
let qfwinnr = bufwinnr(qfbufnr)
exec qfwinnr.'wincmd w'
endif
endif
endfunction

"wintype: 'open', 'vert', 'horz', 'tab'
"opencmd: 'cc', 'cn', 'cp'
function! s:OpenQFItem(wintype, opencmd, qflnum)
let lnumqf = a:qflnum

" arrange a window or tab in which quickfix item to be opened
if a:wintype==#'open'
wincmd p
elseif a:wintype==#'vert'
wincmd p
vnew
elseif a:wintype==#'horz'
wincmd p
new
elseif a:wintype==#'tab'
let qfview = winsaveview()

let modifier = ''
let widthratio = winwidth(0)*&lines
let heightratio = winheight(0)*&columns
if widthratio > heightratio
let modifier = modifier.''
let qfresize = 'resize '.winheight(0)
else
let modifier = modifier.'vert'
let qfresize = 'vert resize '.winwidth(0)
endif

if winnr() <= winnr('$')/2
let modifier = modifier.' topleft'
else
let modifier = modifier.' botright'
endif

tabnew
endif

" save current tab or window to check after switchbuf applied when executing cc, cn, cp commands
let before_tabnr = tabpagenr()
let before_winnr = winnr()

" execute vim quickfix open commands
if a:opencmd==#'open'
call s:ExecuteCC(lnumqf)
elseif a:opencmd==#'cnext'
call s:ExecuteCN(lnumqf)
elseif a:opencmd==#'cprev'
call s:ExecuteCP(lnumqf)
endif

" check if switchbuf applied.
" if useopen or usetab are applied with new window or tab command, close the newly opened tab or window.
let after_tabnr = tabpagenr()
let after_winnr = winnr()
if (match(&switchbuf,'useopen')>-1 || match(&switchbuf,'usetab')>-1)
if a:wintype==#'tab'
if before_tabnr!=after_tabnr
call s:JumpToTab(before_tabnr)
call s:CloseTab(after_tabnr)
endif
elseif a:wintype==#'vert'|| a:wintype==#'horz'
if before_tabnr!=after_tabnr |"when 'usetab' applied
call s:JumpToTab(before_tabnr)
call s:CloseWin(after_winnr)
call s:JumpToTab(after_tabnr)
elseif before_winnr!=after_winnr
call s:JumpToWin(before_winnr)
call s:CloseWin(after_winnr)
endif
endif
endif
"echo before_tabnr after_tabnr
"echo before_winnr after_winnr

" restore quickfix window when tab mode
if a:wintype==#'tab'
if g:qfenter_enable_autoquickfix
exec modifier 'copen'
exec qfresize
call winrestview(qfview)
wincmd p
endif
endif
endfunction

fun! s:CloseWin(return_winnr)
let prevwinnr = a:return_winnr
if prevwinnr > winnr()
let prevwinnr = prevwinnr - 1
endif

quit

call s:JumpToWin(prevwinnr)
endfun

fun! s:JumpToWin(winnum)
exec a:winnum.'wincmd w'
endfun

fun! s:CloseTab(return_tabnr)
let prevtabnr = a:return_tabnr
if prevtabnr > tabpagenr()
let prevtabnr = prevtabnr - 1
endif

tabclose

call s:JumpToTab(prevtabnr)
endfun

fun! s:JumpToTab(tabnum)
exec 'tabnext' a:tabnum
endfun

0 comments on commit 0407b61

Please sign in to comment.