Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accept/cancel input programmatically in extensions #28

Closed
bkudria opened this issue Sep 17, 2014 · 13 comments
Closed

Accept/cancel input programmatically in extensions #28

bkudria opened this issue Sep 17, 2014 · 13 comments

Comments

@bkudria
Copy link

bkudria commented Sep 17, 2014

(This is a duplicate of kien#524)

https://github.com/phalkunz/ctrlp-related is a very useful plugin that lists related files relative to the current file. However, often times there are no related files, or only one - in that case, it would be useful to cancel ctrlp or accept the one result respectively, programmatically from the extension.

Currently, there isn't a good way to do that. I've succeed in almost possibly getting this working using feedkeys, but it requires managing the global g:ctrlp_buffer_func in an incredibly error-prone way.

An official supported option to enable this behavior would be very welcome.

@mattn
Copy link
Member

mattn commented Sep 18, 2014

let str = ctrlp#getcline()
if !empty(str)
  call ctrlp#exit()
  call ctrlp#myctrlpextension#accept('m', str)
endif

This should be work. Or you mean that more generic way to accept current line?

@bkudria
Copy link
Author

bkudria commented Sep 18, 2014

I don't think this will work - where would you call it from? See @kien's comments in kien#524.

A way to support this and other functionality would be to provide a per-extension equivalent of g:crlp_buffer_func. (From the docs: "Specify the functions that will be called after entering and before exiting the CtrlP buffer".) s:ext_vars['enter'] and 'exit are inverse advice, that is, they are called before entering and after exiting, making them useless to detect the amount of results returned by s:ext_vars['init']. (Further complicating things is that each extensions s:ext_vars['enter'] is called every time, not just the extension triggered.)

Does this make sense? I don't have the time in the near future, but perhaps I can work up a PR at some point. However my vimscript is nascent and the ctrlp codebase is ... abbreviated. It seems like you have more experience with the codebase.

@mattn
Copy link
Member

mattn commented Sep 18, 2014

I don't think this will work - where would you call it from?

Where do you want to call accept() ?

@bkudria
Copy link
Author

bkudria commented Sep 24, 2014

I want to call it after init - so that I can check that there was only one result. But there is currently no way to execute extension code after init, but before accept.

@mattn
Copy link
Member

mattn commented Sep 25, 2014

Most easy way to do it is set filetype for the buffer.

@d11wtq How do you think?

@bkudria
Copy link
Author

bkudria commented Sep 25, 2014

@mattn not sure what you mean - how would setting the filetype be relevant?

@mattn
Copy link
Member

mattn commented Sep 25, 2014

If ctrlp have filetype (ex. ControlP), we can use BufEnter or FileType autocmd to handle event instead of init.

@bkudria
Copy link
Author

bkudria commented Sep 25, 2014

Ah, certainly. You could also define a new extvar and call it from ctrlp (ideally, only for the triggered extension, instead of for all as is the current behavior.) Maybe called something like afterInit.

@tacahiroy
Copy link
Member

IMHO, setting filetype, ControlP, is useful in some cases.
Also it affects nothing against current behaviour, so it's really worth, isn't it?

@mattn
Copy link
Member

mattn commented Sep 26, 2014

Hmm, It seems setting FileType occur some problems because ControlP buffer is not created always. And FileType event is not an event to fire sometimes. So how about User autocmd?

diff --git a/autoload/ctrlp.vim b/autoload/ctrlp.vim
index 1e31ca5..2a17758 100644
--- a/autoload/ctrlp.vim
+++ b/autoload/ctrlp.vim
@@ -306,7 +306,7 @@ fu! s:Close()
        exe s:winres[0].s:winres[0]
    en
    unl! s:focus s:hisidx s:hstgot s:marked s:statypes s:cline s:init s:savestr
-       \ s:mrbs s:did_exp
+       \ s:mrbs s:did_exp s:doenter
    cal ctrlp#recordhist()
    cal s:execextvar('exit')
    cal s:log(0)
@@ -567,6 +567,12 @@ fu! s:Render(lines, pat)
    en
 endf

+fu! s:doenter()
+   if !has('autocmd') || !exists('#User#CtrlPEnter') || get(s:, 'doenter') | retu | en
+   doau User CtrlPEnter
+   let s:doenter = 1
+endf
+
 fu! s:Update(str)
    " Get the previous string if existed
    let oldstr = exists('s:savestr') ? s:savestr : ''
@@ -579,6 +585,7 @@ fu! s:Update(str)
    let lines = s:nolim == 1 && empty(str) ? copy(g:ctrlp_lines)
        \ : s:MatchedItems(g:ctrlp_lines, pat, s:mw_res)
    cal s:Render(lines, pat)
+   call s:doenter()
 endf

 fu! s:ForceUpdate()

You can handle this event like below.

function! s:autoclose()
  let nr = len(filter(getline(1, "$"), 'v:val =~ "^>"'))
  if nr == 0
    call feedkeys("\<esc>", "m")
  elseif nr == 1
    call feedkeys("\<cr>", "m")
  endif
endfunction

autocmd User CtrlPEnter call <SID>autoclose()

@bkudria
Copy link
Author

bkudria commented Oct 22, 2014

Sorry for the late reply, but this works great! I'd love to see the ctrlp changes make it in!

@ggVGc
Copy link

ggVGc commented Feb 27, 2015

I just made a PR adding an option exactly for this(although I use it for ctrlp-funky), #80

@bkudria
Copy link
Author

bkudria commented Mar 24, 2015

Closed by #80

@bkudria bkudria closed this as completed Mar 24, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants