diff options
author | Junegunn Choi <junegunn.c@gmail.com> | 2014-03-06 12:21:09 +0900 |
---|---|---|
committer | Junegunn Choi <junegunn.c@gmail.com> | 2014-03-06 12:21:09 +0900 |
commit | 2fb8ae010f1481d05a9eab0dd6facdf01aadd11e (patch) | |
tree | 71e3b6623e041054d95c35084989bfb2e2737afb | |
parent | 65ae6cabb594b474d4cec4452939d0659711f9c4 (diff) |
Completely remove mouse support
Since the version 0.7.0, fzf internally used Curses.getch() call to take user
input, which allowed it to support mouse input as well. However it has turned
out that Curses.getch() has introduced glitches that cannot be easily handled
(e.g. Try resize the terminal). So I finally decided that it's not worth the
trouble and drop the mouse support.
-rw-r--r-- | README.md | 4 | ||||
-rwxr-xr-x | fzf | 196 | ||||
-rw-r--r-- | test/test_fzf.rb | 8 |
3 files changed, 72 insertions, 136 deletions
@@ -58,7 +58,6 @@ usage: fzf [options] -i Case-insensitive match (default: smart-case match) +i Case-sensitive match +c, --no-color Disable colors - --no-mouse Disable mouse Environment variables FZF_DEFAULT_COMMAND Default command to use when input is tty @@ -102,9 +101,6 @@ The following readline key bindings should also work as expected. If you enable multi-select mode with `-m` option, you can select multiple items with TAB or Shift-TAB key. -You can also use mouse. Click on an item to select it or shift-click to select -multiple items. Use mouse wheel to move the cursor up and down. - ### Extended-search mode With `-x` or `--extended` option, fzf will start in "extended-search mode". @@ -7,7 +7,7 @@ # / __/ / /_/ __/ # /_/ /___/_/ Fuzzy finder for your shell # -# Version: 0.7.3 (March 5, 2014) +# Version: 0.8.0 (March 6, 2014) # # Author: Junegunn Choi # URL: https://github.com/junegunn/fzf @@ -50,7 +50,7 @@ end class FZF C = Curses - attr_reader :rxflag, :sort, :color, :mouse, :multi, :query, :filter, :extended + attr_reader :rxflag, :sort, :color, :multi, :query, :filter, :extended class AtomicVar def initialize value @@ -79,9 +79,7 @@ class FZF @color = true @multi = false @extended = nil - @mouse = true @filter = nil - @pending = nil argv = if opts = ENV['FZF_DEFAULT_OPTS'] @@ -102,7 +100,6 @@ class FZF when '+i' then @rxflag = 0 when '-c', '--color' then @color = true when '+c', '--no-color' then @color = false - when '--no-mouse' then @mouse = false when '+s', '--no-sort' then @sort = nil when '-q', '--query' usage 1, 'query string required' unless query = argv.shift @@ -129,11 +126,11 @@ class FZF @source = source.clone @mtx = Mutex.new - @rmtx = Mutex.new @cv = ConditionVariable.new @events = {} @new = [] @queue = Queue.new + @pending = nil unless @filter @query ||= AtomicVar.new('') @@ -207,7 +204,6 @@ class FZF -i Case-insensitive match (default: smart-case match) +i Case-sensitive match +c, --no-color Disable colors - --no-mouse Disable mouse Environment variables FZF_DEFAULT_COMMAND Default command to use when input is tty @@ -510,11 +506,6 @@ class FZF def init_screen C.init_screen - if @mouse - C.mouseinterval 0 - C.mousemask C::ALL_MOUSE_EVENTS - end - C.stdscr.keypad(true) C.start_color dbg = if C.respond_to?(:use_default_colors) @@ -524,7 +515,6 @@ class FZF C::COLOR_BLACK end C.raw - C.nonl C.noecho if @color @@ -582,7 +572,6 @@ class FZF exit 1 end else - $stdin.reopen IO.open(IO.sysopen('/dev/tty'), 'r') if curses @source end @@ -722,10 +711,8 @@ class FZF Thread.new do begin while blk = @queue.shift - @rmtx.synchronize do - blk.call - refresh - end + blk.call + refresh end rescue Exception => e @main.raise e @@ -757,54 +744,67 @@ class FZF end end - def test_mouse st, *states - states.any? { |s| s & st > 0 } - end - - def to_printable ch - if ch.is_a?(Fixnum) - # Ruby 1.8 - if (ch.chr rescue '') =~ /[[:print:]]/ - ch = ch.chr - elsif (nch = num_unicode_bytes(ch)) > 1 - chs = [ch] - (nch - 1).times do |i| - chs << getch_nb - end - # UTF-8 TODO Ruby 1.8 - ch = chs.pack('C*').force_encoding('UTF-8') - end - end + def get_input actions + @tty ||= IO.open(IO.sysopen('/dev/tty'), 'r') - ch.is_a?(String) && ch =~ /[[:print:]]/ && ch - end - - def getch_nb - @rmtx.synchronize { C.getch } - end - - def getch if pending = @pending @pending = nil return pending end - C.stdscr.timeout = -1 - c = C.getch - C.stdscr.timeout = 0 - if ch = to_printable(c) - chs = [ch] - while AFTER_1_9 && c = getch_nb - if ch = to_printable(c) - chs << ch + str = '' + while true + ord = + if str.empty? + @tty.getc.ord else - @pending = c - break + begin + ord = @tty.read_nonblock(1).ord + if (nb = num_unicode_bytes(ord)) > 1 + ords = [ord] + (nb - 1).times do |_| + ords << @tty.read_nonblock(1).ord + end + # UTF-8 TODO Ruby 1.8 + ords.pack('C*').force_encoding('UTF-8') + else + ord + end + rescue Exception + return str + end end + + ord = + case ord = (@tty.read_nonblock(1).ord rescue :esc) + when 91 + case (@tty.read_nonblock(1).ord rescue nil) + when 68 then ctrl(:b) + when 67 then ctrl(:f) + when 66 then ctrl(:j) + when 65 then ctrl(:k) + when 90 then :stab + else next + end + when 'b', 98 then :alt_b + when 'f', 102 then :alt_f + when :esc then :esc + else next + end if ord == 27 + + if actions.has_key?(ord) + if str.empty? + return ord + else + @pending = ord + return str + end + else + unless ord.is_a? String + ord = [ord].pack('U*') + end + str << ord if ord =~ /[[:print:]]/ end - chs - else - c end end @@ -841,13 +841,7 @@ class FZF else @selects[sel] = 1 end - vselect { |v| - v + case o - when :select then 0 - when C::KEY_BTAB then 1 - else -1 - end - } + vselect { |v| v + (o == :stab ? 1 : -1) } end }, ctrl(:b) => proc { cursor = [0, cursor - 1].max; nil }, @@ -859,76 +853,26 @@ class FZF nil }, } - actions[C::KEY_UP] = actions[ctrl(:p)] = actions[ctrl(:k)] - actions[C::KEY_DOWN] = actions[ctrl(:n)] = actions[ctrl(:j)] - actions[C::KEY_LEFT] = actions[ctrl(:b)] - actions[C::KEY_RIGHT] = actions[ctrl(:f)] - actions[C::KEY_BTAB] = actions[:select] = actions[ctrl(:i)] - actions[C::KEY_BACKSPACE] = actions[127] = actions[ctrl(:h)] + actions[ctrl(:p)] = actions[ctrl(:k)] + actions[ctrl(:n)] = actions[ctrl(:j)] + actions[:stab] = actions[ctrl(:i)] + actions[127] = actions[ctrl(:h)] actions[ctrl(:q)] = actions[ctrl(:g)] = actions[ctrl(:c)] = actions[:esc] emit(:key) { [@query.get, cursor] } unless @query.empty? - pmv = nil while true @cursor_x.set cursor render { print_input } - case ch = getch - when C::KEY_MOUSE - if m = C.getmouse - st = m.bstate - if test_mouse(st, C::BUTTON1_PRESSED, C::BUTTON1_RELEASED) - if m.y == cursor_y - # TODO Wide-characters - cursor = [0, [input.length, m.x - 2].min].max - elsif m.x > 1 && m.y <= max_items - vselect { |v| - tv = max_items - m.y - 1 - if test_mouse(st, C::BUTTON1_RELEASED) - if test_mouse(st, C::BUTTON_SHIFT) - ch = :select - elsif pmv == tv - ch = ctrl(:m) - end - pmv = tv - end - tv - } - end - elsif test_mouse(st, 0x8000000, C::BUTTON2_PRESSED) - ch = C::KEY_DOWN - elsif test_mouse(st, C::BUTTON4_PRESSED) - ch = C::KEY_UP - end - end - when 27 - C.stdscr.timeout = 0 - ch = # Typeahead arrow keys - case ch2 = getch_nb - when '[', 91 - case ch3 = getch_nb - when 'D', 68 then ctrl(:b) - when 'C', 67 then ctrl(:f) - when 'B', 66 then ctrl(:j) - when 'A', 65 then ctrl(:k) - else ch3 - end - when 'b', 98 then :alt_b - when 'f', 102 then :alt_f - when nil then :esc - else ch2 - end - end - - upd = actions.fetch(ch, proc { |ch| - if ch.is_a? Array - input.insert cursor, ch.join - cursor += ch.length - end - }).call(ch) + if key = get_input(actions) + upd = actions.fetch(key, proc { |str| + input.insert cursor, str + cursor += str.length + }).call(key) - # Dispatch key event - emit(:key) { [@query.set(input.dup), cursor] } if upd + # Dispatch key event + emit(:key) { [@query.set(input.dup), cursor] } if upd + end end ensure C.close_screen diff --git a/test/test_fzf.rb b/test/test_fzf.rb index d1006659..65b105ae 100644 --- a/test/test_fzf.rb +++ b/test/test_fzf.rb @@ -20,7 +20,6 @@ class TestFZF < MiniTest::Unit::TestCase assert_equal false, fzf.multi assert_equal true, fzf.color assert_equal nil, fzf.rxflag - assert_equal true, fzf.mouse end def test_environment_variables @@ -29,7 +28,7 @@ class TestFZF < MiniTest::Unit::TestCase fzf = FZF.new [] assert_equal 20000, fzf.sort - ENV['FZF_DEFAULT_OPTS'] = '-x -m -s 10000 -q " hello world " +c --no-mouse -f "goodbye world"' + ENV['FZF_DEFAULT_OPTS'] = '-x -m -s 10000 -q " hello world " +c -f "goodbye world"' fzf = FZF.new [] assert_equal 10000, fzf.sort assert_equal ' hello world ', @@ -39,17 +38,15 @@ class TestFZF < MiniTest::Unit::TestCase assert_equal :fuzzy, fzf.extended assert_equal true, fzf.multi assert_equal false, fzf.color - assert_equal false, fzf.mouse end def test_option_parser # Long opts fzf = FZF.new %w[--sort=2000 --no-color --multi +i --query hello - --filter=howdy --extended-exact --no-mouse] + --filter=howdy --extended-exact] assert_equal 2000, fzf.sort assert_equal true, fzf.multi assert_equal false, fzf.color - assert_equal false, fzf.mouse assert_equal 0, fzf.rxflag assert_equal 'hello', fzf.query.get assert_equal 'howdy', fzf.filter @@ -61,7 +58,6 @@ class TestFZF < MiniTest::Unit::TestCase assert_equal nil, fzf.sort assert_equal false, fzf.multi assert_equal true, fzf.color - assert_equal true, fzf.mouse assert_equal 1, fzf.rxflag assert_equal 'b', fzf.filter assert_equal 'hello', fzf.query.get |