Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

More flexible 'mixed' mode #310

Open
teranex opened this Issue · 2 comments

3 participants

@teranex

I would really like to be able to search for files and tags (and lines, ...) at the same time, using some advanced 'mixed' mode. I know there is currently a 'mixed' mode but this only supports files, MRU and buffers and as you said in #101 (comment) it can not be extended to also include tags.

Now I'm wondering if it would be possible to modify CtrlP to support a more advanced 'mixed' mode which can work with all available extensions. In that case the user would be able to configure which modes should be active in mixed mode. (where the default would be 'files', 'mru' and 'buffers' to mimic the current mixed mode).
I'm wondering if it would to possible to work somehow like this:

  • when mixed mode is started, it invokes the #init() method for each enable mode
  • it merges the results and appends an identifier at the beginning of each line to indicate the source (file: ctrl.vim; tag: s:highlight|function; line: this is a line; and so on)
  • When a selection is made, it can parse the correct mode from the beginning of the line (file:; tag:; etc), remove that part again and invoke the #accept() function for the correct mode.

In fact, I already created a small (and dirty) 'proof of concept' which seems to work without any problems (combining 'line' + 'tag').
Do you see any possible problems with this approach? Maybe the syntax patterns might give troubles? If you think this can work I can try to modify the existing mixed extension to use this approach, work with any available extensions and make the enabled extensions configurable. I am however not very well known with how exactly CtrlP caches the file listing etc.

Here is my proof of concept extension:

" command:
" com! -bar CtrlPGTA      cal ctrlp#init(ctrlp#gotoanything#id())

if exists('g:loaded_ctrlp_gotany') && g:loaded_ctrlp_gotany
    finish
end

let g:loaded_ctrlp_gotany = 1


call add(g:ctrlp_ext_vars, {
    \ 'init': 'ctrlp#gotoanything#init()',
    \ 'accept': 'ctrlp#gotoanything#accept',
    \ 'lname': 'gotoanything',
    \ 'sname': 'gta',
    \ })

function! s:syntax()
    if !ctrlp#nosy()
        call ctrlp#hicheck('CtrlPGTAType', 'Type')
        syntax match CtrlPGTAType /\v\w+: /
    endif
endfunction

function! ctrlp#gotoanything#init()
    let g:ctrlp_gta_mixed = []

    let entries = ctrlp#tag#init()
    for entry in entries
        call add(g:ctrlp_gta_mixed, 'tag: '.entry)
    endfor

    let entries = ctrlp#line#init()
    for entry in entries
        call add(g:ctrlp_gta_mixed, 'line: '.entry)
    endfor

    call s:syntax()

    return g:ctrlp_gta_mixed
endfunction

function! ctrlp#gotoanything#accept(mode, str)
    call ctrlp#exit()

    if strpart(a:str, 0, 5) ==# "line:"
        let l:str = strpart(a:str, 6)
        return ctrlp#line#accept(a:mode, l:str)
    endif

    if strpart(a:str, 0, 4) ==# "tag:"
        let l:str = strpart(a:str, 5)
        return ctrlp#tag#accept(a:mode, l:str)
    endif
endfunction

" Give the extension an ID
let s:id = g:ctrlp_builtins + len(g:ctrlp_ext_vars)
" Allow it to be called later
function! ctrlp#gotoanything#id()
  return s:id
endfunction
@kien
Owner

Good idea, but aside from the highlighting, there's still the problem with the matching. Matching a filename including path is different from matching a tag or a line entry.

Your proof works because coincidently the tag's and the line's lines have very similar formats. But if you throw files or buffers into the mix then filename-only mode won't work, and the entire tag line (the tagname and the extra infos) will be included when matching.

Originally, I also wanted the mixed mode to work with a command like this:

CtrlPMixed --mode=files,buffers,tags,...

But I didn't and still don't think it's worth making, at least until I can figure out how to solve all the major problems.

@danemacmillan

Being able to define what mixed mode means would be awesome. I currently would like to specify "files" and "buffers" as a custom mixed mode, but it's not possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.