ansi-select 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dbdb0d626907ead9edbe0c70ece388639bfd60b2
4
+ data.tar.gz: f6c5d41601a0ba70f4c5c14ba6b30992968fd6d6
5
+ SHA512:
6
+ metadata.gz: 93fd756748db4238b3fd331c947ae32973596909b04c349d40469688a1dcda566695c5109c1200514c4511f15d56c3e355d44fc3bd528abdd7e6df21a942a573
7
+ data.tar.gz: beebfe8259573a84716765cbd55d0ac64e394bbb0f8a1aedb3c470972a5665b62070dbe4f3b377f5010fe6fc8756b3fe5d7111a601db708421bf5aa17d66de6b
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1 @@
1
+ ansi-select
@@ -0,0 +1 @@
1
+ 2.2.2
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ansi-select.gemspec
4
+ gemspec
@@ -0,0 +1,41 @@
1
+ ![](https://dl.dropboxusercontent.com/spa/dlqheu39w0arg9q/yaano147.png)
2
+
3
+ ## Installation
4
+
5
+ $ gem install ansi-select
6
+
7
+
8
+ ## Usage
9
+
10
+ There are two options:
11
+
12
+ * A standalone executable. Lines passed to STDIN will form your options. The result will be printed to STDOUT.
13
+
14
+ ```bash
15
+ echo some words to choose from | tr ' ' '\n' | ansi-select
16
+ cd $(ls -d */ | ansi-select) # Go to a visually selected subdirectory.
17
+ git checkout $(git branch | ansi-select) # The same, but with git branches.
18
+ ```
19
+
20
+ * A Ruby library.
21
+
22
+ ```ruby
23
+ require "ansi/select"
24
+
25
+ answer = Ansi::Select.new(["some", "words", "to", "choose", "from"]).select
26
+ print "You chose #{answer}."
27
+ ```
28
+
29
+ The Ruby interface has an additional benefit of accepting any objects that respond
30
+ to `#to_s` and returning one of them instead of a string.
31
+
32
+
33
+ ## Keyboard
34
+
35
+ You can use up and down keys or `j`/`k` for navigation, and space or return key for choosing an option.
36
+ If you've changed your mind, you can quit with Ctrl+C or `q`.
37
+
38
+
39
+ ## TODO
40
+
41
+ * Support multi-select.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ansi/select/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ansi-select"
8
+ spec.version = Ansi::Select::VERSION
9
+ spec.authors = ["Volodymyr Shatskyi"]
10
+ spec.email = ["shockone89@gmail.com"]
11
+
12
+ spec.summary = %q{Simple, not full-screen, ncurses-like TUI select}
13
+ spec.description = %q{This gem allows you to select an array element (where an array is arbitrary input) with a pretty text user interface.}
14
+ spec.homepage = "https://github.com/shockone/ansi-select"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "bin"
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.9"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ end
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'ansi/select'
3
+
4
+ puts Ansi::Select.new(STDIN.readlines.map(&:chomp)).select
@@ -0,0 +1,121 @@
1
+ # coding: utf-8
2
+
3
+ require "io/console"
4
+
5
+ module Ansi
6
+ class Select
7
+ CODES = {
8
+ standout_mode: `tput rev`,
9
+ exit_standout_mode: `tput rmso`,
10
+ cursor_up: `tput cuu1`,
11
+ cursor_down: `tput cud1`,
12
+ carriage_return_key: `tput cr`
13
+ }
14
+
15
+ # @param [Array<#to_s>] options
16
+ def initialize(options)
17
+ @options = options
18
+
19
+ @highlighted_line_index = 0
20
+ @cursor_line_index = 0
21
+ end
22
+
23
+ # @return [#to_s] option
24
+ def select
25
+ print_options
26
+ answer = ask_to_choose
27
+ go_to_line(@options.size)
28
+
29
+ answer
30
+ ensure
31
+ tty.close
32
+ end
33
+
34
+ private
35
+
36
+ # @return [File]
37
+ def tty
38
+ @tty ||= File.open('/dev/tty', 'w+')
39
+ end
40
+
41
+ def print_options
42
+ @options.each.with_index do |_, index|
43
+ print_line(index, index == @highlighted_line_index)
44
+
45
+ unless index == @options.size - 1
46
+ tty.print $/ # This strange thing is a cross-platform new line.
47
+ @cursor_line_index += 1
48
+ end
49
+ end
50
+
51
+ go_to_line(0)
52
+ end
53
+
54
+ # @return [String]
55
+ def listen_carefully_to_keyboard
56
+ tty.noecho do
57
+ tty.raw do
58
+ input = tty.getc.chr
59
+ if input == "\e"
60
+ input << tty.read_nonblock(3) rescue nil
61
+ input << tty.read_nonblock(2) rescue nil
62
+ end
63
+
64
+ input
65
+ end
66
+ end
67
+ end
68
+
69
+ # @return [#to_s]
70
+ def ask_to_choose
71
+ loop do
72
+ input = listen_carefully_to_keyboard
73
+
74
+ case input
75
+ when "\u0003", "q"
76
+ exit(0)
77
+ when CODES[:carriage_return_key], " "
78
+ break @options[@highlighted_line_index]
79
+ when "\e[A", "k", CODES[:cursor_up]
80
+ highlight_line(@highlighted_line_index - 1) unless @highlighted_line_index == 0
81
+ when "\e[B", "j", CODES[:cursor_down]
82
+ highlight_line(@highlighted_line_index + 1) unless @highlighted_line_index == @options.size - 1
83
+ end
84
+ end
85
+ end
86
+
87
+ # @param [Fixnum] index
88
+ # @param [Boolean] highlight
89
+ def print_line(index, highlight)
90
+ go_to_line(index)
91
+
92
+ if highlight
93
+ tty.print "#{CODES[:standout_mode]}#{@options[index]}#{CODES[:exit_standout_mode]}"
94
+ else
95
+ tty.print @options[index]
96
+ end
97
+ end
98
+
99
+ # @param [Fixnum] index
100
+ def highlight_line(index)
101
+ print_line(@highlighted_line_index, false)
102
+ print_line(index, true)
103
+
104
+ @highlighted_line_index = index
105
+ end
106
+
107
+ # @param [Fixnum] index
108
+ def go_to_line(index)
109
+ if index == @cursor_line_index
110
+ # do nothing
111
+ elsif index > @cursor_line_index
112
+ (index - @cursor_line_index).times { tty.print CODES[:cursor_down] }
113
+ else
114
+ (@cursor_line_index - index).times { tty.print CODES[:cursor_up] }
115
+ end
116
+
117
+ @cursor_line_index = index
118
+ tty.print CODES[:carriage_return_key]
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,5 @@
1
+ module Ansi
2
+ class Select
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ansi-select
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Volodymyr Shatskyi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-09-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.9'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.9'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: This gem allows you to select an array element (where an array is arbitrary
42
+ input) with a pretty text user interface.
43
+ email:
44
+ - shockone89@gmail.com
45
+ executables:
46
+ - ansi-select
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - ".gitignore"
51
+ - ".rspec"
52
+ - ".ruby-gemset"
53
+ - ".ruby-version"
54
+ - ".travis.yml"
55
+ - Gemfile
56
+ - README.md
57
+ - Rakefile
58
+ - ansi-select.gemspec
59
+ - bin/ansi-select
60
+ - lib/ansi/select.rb
61
+ - lib/ansi/select/version.rb
62
+ homepage: https://github.com/shockone/ansi-select
63
+ licenses: []
64
+ metadata: {}
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 2.4.8
82
+ signing_key:
83
+ specification_version: 4
84
+ summary: Simple, not full-screen, ncurses-like TUI select
85
+ test_files: []