command-t icon indicating copy to clipboard operation
command-t copied to clipboard

Allow disabling g:CommandTGitIncludeUntracked when writing query

Open jlebon opened this issue 7 years ago • 7 comments

I really like the git backend and definitely like the default of IncludeUntracked being false, especially when srcdir == builddir. However, sometimes I do want CommandT to match untracked files, e.g. when working on new files I haven't added to git yet, or to verify an auto-generated file. I can write a hotkey to toggle the IncludeUntracked setting, though it would be nice if there were an easy way to toggle it from the query window and have the results update immediately.

jlebon avatar Jun 12 '17 15:06 jlebon

This is a pretty specific ask, which I figure only a few people share. I think the right way to make this possible will be to add the ability for the user to define custom arbitrary mappings to be set-up when the match listing is active and specify a callback that will be invoked when they are triggered.

So in your example, you could do something like map <C-r> (mnemonic: "t[r]acked") to run a function like this:

function! CommandTControlRCallback()
  let g:CommandTGitIncludeUntracked=!get(g:, 'CommandTGitIncludeUntracked', 0)
  call commandt#Flush()
endfunction

wincent avatar Jun 13 '17 00:06 wincent

I think the right way to make this possible will be to add the ability for the user to define custom arbitrary mappings to be set-up when the match listing is active and specify a callback that will be invoked when they are triggered.

Yeah, that sounds much better!

jlebon avatar Jun 13 '17 02:06 jlebon

I'm feeling pretty sick, so I am not confident in this code, but here's a quick demo showing something that would work given configuration like:

function! CommandTControlRCallback()
  let g:CommandTMatchWindowReverse=!get(g:, 'CommandTMatchWindowReverse', 1)
  call commandt#Flush()
  call commandt#Refresh()
endfunction

let g:CommandTCustomMappings={
      \   '<C-r>': ':call CommandTControlRCallback()<cr>'
      \ }

Here it is:

diff --git a/autoload/commandt.vim b/autoload/commandt.vim
index 8f2988d..6a13799 100644
--- a/autoload/commandt.vim
+++ b/autoload/commandt.vim
@@ -139,6 +139,12 @@ function! commandt#CheckBuffer(buffer_number) abort
   endif
 endfunction
 
+function! commandt#Refresh() abort
+  if has('ruby')
+    ruby $command_t.refresh
+  endif
+endfunction
+
 function! s:BufHidden(buffer)
   let bufno = bufnr(a:buffer)
   let listed_buffers = ''
diff --git a/ruby/command-t/lib/command-t/controller.rb b/ruby/command-t/lib/command-t/controller.rb
index 9d966bf..181b213 100644
--- a/ruby/command-t/lib/command-t/controller.rb
+++ b/ruby/command-t/lib/command-t/controller.rb
@@ -62,64 +62,64 @@ def return_is_own_buffer(buffer_number)
     end
 
     def show_buffer_finder
-      @path          = VIM::pwd
-      @active_finder = buffer_finder
+      @path = VIM::pwd
+      @get_finder = self.method(:buffer_finder)
       show
     end
     guard :show_buffer_finder
 
     def show_command_finder
-      @path          = VIM::pwd
-      @active_finder = command_finder
+      @path = VIM::pwd
+      @get_finder = self.method(:command_finder)
       show
     end
     guard :show_command_finder
 
     def show_help_finder
-      @path          = VIM::pwd
-      @active_finder = help_finder
+      @path = VIM::pwd
+      @get_finder = self.method(:help_finder)
       show
     end
     guard :show_help_finder
 
     def show_history_finder
-      @path          = VIM::pwd
-      @active_finder = history_finder
+      @path = VIM::pwd
+      @get_finder = self.method(:history_finder)
       show
     end
     guard :show_history_finder
 
     def show_jump_finder
-      @path          = VIM::pwd
-      @active_finder = jump_finder
+      @path = VIM::pwd
+      @get_finder = self.method(:jump_finder)
       show
     end
     guard :show_jump_finder
 
     def show_line_finder
-      @path          = VIM::pwd
-      @active_finder = line_finder
+      @path = VIM::pwd
+      @get_finder = self.method(:line_finder)
       show
     end
     guard :show_line_finder
 
     def show_mru_finder
-      @path          = VIM::pwd
-      @active_finder = mru_finder
+      @path = VIM::pwd
+      @get_finder = self.method(:mru_finder)
       show
     end
     guard :show_mru_finder
 
     def show_search_finder
-      @path          = VIM::pwd
-      @active_finder = search_finder
+      @path = VIM::pwd
+      @get_finder = self.method(:search_finder)
       show
     end
     guard :show_search_finder
 
     def show_tag_finder
-      @path          = VIM::pwd
-      @active_finder = tag_finder
+      @path = VIM::pwd
+      @get_finder = self.method(:tag_finder)
       show
     end
     guard :show_tag_finder
@@ -142,8 +142,7 @@ def show_file_finder
         end
       end
 
-      @active_finder    = file_finder
-      file_finder.path  = @path
+      @get_finder = self.method(:file_finder)
       show
     rescue Errno::ENOENT
       # probably a problem with the optional parameter
@@ -178,9 +177,11 @@ def quickfix
     guard :quickfix
 
     def refresh
-      return unless @active_finder && @active_finder.respond_to?(:flush)
-      @active_finder.flush
-      list_matches!
+      return unless @get_finder
+      flush
+      @active_finder = @get_finder.call
+      hide
+      show
     end
     guard :refresh
 
@@ -360,6 +361,7 @@ def list_matches!
     end
 
     def show
+      @active_finder = @get_finder.call
       @initial_window = $curwin
       @initial_buffer = $curbuf
       @debounce_interval = VIM::get_number('g:CommandTInputDebounce') || 0
@@ -523,6 +525,13 @@ def register_for_key_presses
           end
         end
       end
+
+      custom_mappings = VIM::get_dictionary('g:CommandTCustomMappings')
+      if custom_mappings
+        custom_mappings.each do |mapping, value|
+          ::VIM::command "noremap <silent> <buffer> #{@nowait} #{mapping} #{value}"
+        end
+      end
     end
 
     def set_up_autocmds
@@ -567,7 +576,7 @@ def wildignore
     end
 
     def file_finder
-      @file_finder ||= CommandT::Finder::FileFinder.new nil,
+      @file_finder ||= CommandT::Finder::FileFinder.new @path,
         :max_depth              => VIM::get_number('g:CommandTMaxDepth'),
         :max_files              => VIM::get_number('g:CommandTMaxFiles'),
         :max_caches             => VIM::get_number('g:CommandTMaxCachedDirectories'),
diff --git a/ruby/command-t/lib/command-t/vim.rb b/ruby/command-t/lib/command-t/vim.rb
index 2a1c92f..1bc1493 100644
--- a/ruby/command-t/lib/command-t/vim.rb
+++ b/ruby/command-t/lib/command-t/vim.rb
@@ -23,21 +23,21 @@ def exists?(str)
       end
 
       def get_number(name)
-        exists?(name) ? ::VIM::evaluate("#{name}").to_i : nil
+        exists?(name) ? ::VIM::evaluate(name).to_i : nil
       end
 
       def get_bool(name, default = nil)
-        exists?(name) ? ::VIM::evaluate("#{name}").to_i != 0 : default
+        exists?(name) ? ::VIM::evaluate(name).to_i != 0 : default
       end
 
       def get_string(name)
-        exists?(name) ? ::VIM::evaluate("#{name}").to_s : nil
+        exists?(name) ? ::VIM::evaluate(name).to_s : nil
       end
 
       # expect a string or a list of strings
       def get_list_or_string(name)
         return nil unless exists?(name)
-        list_or_string = ::VIM::evaluate("#{name}")
+        list_or_string = ::VIM::evaluate(name)
         if list_or_string.kind_of?(Array)
           list_or_string.map { |item| item.to_s }
         else
@@ -45,6 +45,11 @@ def get_list_or_string(name)
         end
       end
 
+      def get_dictionary(name)
+        hash = exists?(name) && ::VIM::evaluate(name)
+        Hash === hash ? hash : nil
+      end
+
       def pwd
         ::VIM::evaluate 'getcwd()'
       end

wincent avatar Jun 13 '17 06:06 wincent

FWIW, this works great here. Thanks for the patch, and hope you feel better! 🤒

jlebon avatar Jun 13 '17 15:06 jlebon

Thanks for confirming it works. I will merge something like this with a bit more clean-up in place. The part for defining the custom mappings is fine, but the controller code is a ghastly mess of statefulness.

wincent avatar Jun 13 '17 15:06 wincent

At the risk of pushing my luck here, is there a function CommandT exports to allow scripts to fetch the currently typed query and insert it back? Basically so that I can do:

function! CommandTControlRCallback()
  let g:CommandTGitIncludeUntracked=!get(g:, 'CommandTGitIncludeUntracked', 0)
  let l:typed_command = commandt#CurrentQuery()
  call commandt#Flush()
  call commandt#Refresh()
  call commandt#Query(l:typed_command)
endfunction

?

Or alternatively teach this to Refresh() directly?

jlebon avatar Jun 13 '17 16:06 jlebon

Yeah, for your use case there needs to be something like that if there isn't already. (I don't think there is, but it would be pretty easy to add.)

wincent avatar Jun 13 '17 16:06 wincent

Given the big rewrite for v6.0.x, I'm closing all older issues as there is unlikely to be anything significant happening on the 5-x-devel branch from here on[^patches]. Feedback issue for 6.0.x is here:

  • https://github.com/wincent/command-t/issues/393

[^patches]: Patches and PRs would be welcome, but my personal efforts are going to be directed towards main.

wincent avatar Aug 26 '22 21:08 wincent