remedy 0.2.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 346c9d17734819cc9516ee578ae4b647e70c13c876c7a84e3ffe74e9cb956e27
4
- data.tar.gz: 4add78044a3161d6eae52452a6a0bd3f3ba46a18b238af7b533f996ac6599ac6
3
+ metadata.gz: 2efe0ed0180c60202b73b0cf9f0fce46b51bcfeefe2a83171f4915c9d2b022ad
4
+ data.tar.gz: 2b11a6544dec2796c6bdf5ce96691be0c7b232f132174d0b79496098252fe5ab
5
5
  SHA512:
6
- metadata.gz: e3a676f7b7df84dc9732aad2518a4bf2d53625736f0928ed3c2dea7f613d727d3fb6539b724939fa83c427cff098d39fcc7ee09412b195d44dca05d3e28dbbbd
7
- data.tar.gz: a6f5a5cc4a4523b6220b426b4016b6370c814f38a2effc993c729a1456e22f3dd9765c43d62bb1f5a8e0ee351a4e14530a87286b58e87409ba9b5c2968cf46ff
6
+ metadata.gz: c76c67debc47dd95b9b614a6681923cb5e47f53c4135335c39170243bcb9a007630af5bc364894f33489cde79c5692e9a28d97ed0f5caf0bfbe83e229ad394eb
7
+ data.tar.gz: a001aa18bd36640ebe267c8d6ae4bf68e7e73d60df0017e31875b222ff30b87169c4c36d06130c27096def9e4ccfa26c50ad350ea1d2cf2adbb42228af5dcf8d
@@ -0,0 +1,6 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "github-actions"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
@@ -0,0 +1,23 @@
1
+ name: CI
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ test:
7
+
8
+ runs-on: ubuntu-latest
9
+
10
+ strategy:
11
+ fail-fast: false
12
+ matrix:
13
+ ruby: ["2.3", "2.4", "2.5", "2.6", "2.7", "3.0", "3.1", "3.2", ruby-head, jruby-9.2, jruby-9.3, jruby-head]
14
+
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - name: Set up Ruby
18
+ uses: ruby/setup-ruby@v1
19
+ with:
20
+ bundler-cache: true # 'bundle install' and cache gems
21
+ ruby-version: ${{ matrix.ruby }}
22
+ - name: Run tests
23
+ run: bundle exec rspec
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.3.7
1
+ 3.1.2
data/README.markdown CHANGED
@@ -1,10 +1,13 @@
1
1
  Remedy
2
2
  ======
3
3
 
4
- Remedy is a console interaction framework along the lines of Curses written in pure Ruby with an Object-Oriented approach and well-seperated concerns making it easy to use what you need and ignore the rest.
4
+ Remedy is a console interaction framework along the lines of Curses written in pure Ruby. It is modular, making it easy to use what you need and ignore the rest.
5
+
6
+ [![Gem Version](https://img.shields.io/gem/v/remedy.svg?style=for-the-badge)](https://rubygems.org/gems/remedy)
7
+ [![Gem Downloads](https://img.shields.io/gem/dt/remedy.svg?style=for-the-badge)](https://rubygems.org/gems/remedy)
8
+ [![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/acook/remedy/ci.yml?style=for-the-badge)](https://github.com/acook/remedy/actions/workflows/ci.yml)
9
+ [![Code Climate maintainability](https://img.shields.io/codeclimate/maintainability/acook/remedy?style=for-the-badge)](https://codeclimate.com/github/acook/remedy/maintainability)
5
10
 
6
- [![TravisCI](http://img.shields.io/travis/acook/remedy.svg?style=flat)](https://travis-ci.org/acook/remedy)
7
- [![Code Climate](https://codeclimate.com/github/acook/remedy/badges/gpa.svg)](https://codeclimate.com/github/acook/remedy)
8
11
 
9
12
  If you have any suggestions or find any bugs, drop them in GitHub/issues so I can keep track of them. Thanks!
10
13
 
@@ -42,6 +45,8 @@ There are objects for input as well as output, including low level console keyst
42
45
 
43
46
  The `Interaction` object wraps raw keyboard reads and streamlines some aspects of accepting keyboard input.
44
47
 
48
+ For instance to get a keypress from the terminal and display it:
49
+
45
50
  ```ruby
46
51
  include Remedy
47
52
  user_input = Interaction.new
@@ -65,20 +70,18 @@ The `Interaction` object wraps raw keyboard reads and streamlines some aspects o
65
70
  screen.draw joke
66
71
  ```
67
72
 
68
- `Remedy::Partial` has the subclasses `Header`, `Footer`, and `Content`.
69
-
70
- You can use the above classes to divide your Views into 3 seperate pieces. Content will be truncated as needed to accomodate the header and footer and the dimensions of the console. You can also specify the cursor/scroll position of the content being drawn, and when specifying headers or footers, you must.
73
+ Content in `Remedy::Partial`s will be truncated as needed to accommodate the header and footer and the dimensions of the console. You can also specify the cursor/scroll position of the content being drawn, and when specifying headers or footers, you must.
71
74
 
72
75
  ```ruby
73
76
  include Remedy
74
- title = Header.new
77
+ title = Partial.new
75
78
  title << "Someone Said These Were Good"
76
79
 
77
80
  jokes = Content.new
78
81
  jokes << %q{1. A woman gets on a bus with her baby. The bus driver says: 'Ugh, that's the ugliest baby I've ever seen!' The woman walks to the rear of the bus and sits down, fuming. She says to a man next to her: 'The driver just insulted me!' The man says: 'You go up there and tell him off. Go on, I'll hold your monkey for you.'}
79
82
  jokes << %q{2. I went to the zoo the other day, there was only one dog in it, it was a shitzu.}
80
83
 
81
- disclaimer = Footer.new
84
+ disclaimer = Partial.new
82
85
  disclaimer << "According to a survey they were funny. I didn't make them."
83
86
 
84
87
  screen = Viewport.new
@@ -95,14 +98,34 @@ The most interesting function in my opinion is the callback that gets triggered
95
98
  include Remedy
96
99
 
97
100
  screen = Viewport.new
98
- notice = Content.new
99
- notice << "You just resized your screen!\n\nBrilliant!"
100
101
 
101
- Console.set_console_resized_hook! do
102
+ Console.set_console_resized_hook! do |size|
103
+ notice = Partial.new
104
+ notice << "You just resized your screen!\n\nNew size:"
105
+ notice << size
102
106
  screen.draw notice
103
107
  end
104
108
  ```
105
109
 
110
+ Remedy in the Wild
111
+ ------------------
112
+
113
+ Remedy was originally written for my own console-based game which was sort of like Dwarf Fortress. Most of the project files were lost, but since Remedy was extracted from it and open-sourced it has lived on.
114
+
115
+ Here are some projects that use Remedy:
116
+
117
+ - A screenreader-friendly code editor for blind and visually impaired programmers: [Viper](https://github.com/edhowland/viper)
118
+ - [The Official ElasticSearch Ruby Connector](https://github.com/elastic/connectors-ruby)
119
+ - A multiplayer Yahtzee for web and console: [YahtzeeGame](https://github.com/ProgrammingPractice/YahtzeeGame)
120
+ - Twitter/RSS/Facebook reader: [noizee](https://github.com/acook/noizee)
121
+
122
+ Check them out!
123
+
124
+ Examples
125
+ --------
126
+
127
+ The `examples` directory has a couple of running implementations to get you started!
128
+
106
129
  Contributing
107
130
  ------------
108
131
 
@@ -111,4 +134,3 @@ Contributing
111
134
  3. Commit your changes (`git commit -am 'Add some feature'`)
112
135
  4. Push to the branch (`git push origin my-new-feature`)
113
136
  5. Create new Pull Request
114
-
@@ -1,19 +1,22 @@
1
+ require 'bundler'
2
+ Bundler.require
1
3
  require 'remedy'
2
4
 
3
5
  include Remedy
4
6
 
5
7
  screen = Viewport.new
6
8
 
7
- notice = Content.new
8
- notice << "You just resized your screen!\n\nBrilliant!"
9
+ Console.set_console_resized_hook! do |size|
10
+ notice = Partial.new
11
+ notice << "You just resized your screen!\n\nNew size:"
12
+ notice << size
9
13
 
10
- Console.set_console_resized_hook! do
11
14
  screen.draw notice
12
15
  end
13
16
 
14
17
  user_input = Interaction.new "press any key to continue"
15
18
 
16
- joke = Content.new
19
+ joke = Partial.new
17
20
  joke << "Q: What's the difference between a duck?"
18
21
  joke << "A: Purple, because ice cream has no bones!"
19
22
 
@@ -21,14 +24,14 @@ screen.draw joke
21
24
 
22
25
  user_input.get_key
23
26
 
24
- title = Header.new
27
+ title = Partial.new
25
28
  title << "Someone Said These Were Good"
26
29
 
27
- jokes = Content.new
30
+ jokes = Partial.new
28
31
  jokes << %q{1. A woman gets on a bus with her baby. The bus driver says: 'Ugh, that's the ugliest baby I've ever seen!' The woman walks to the rear of the bus and sits down, fuming. She says to a man next to her: 'The driver just insulted me!' The man says: 'You go up there and tell him off. Go on, I'll hold your monkey for you.'}
29
32
  jokes << %q{2. I went to the zoo the other day, there was only one dog in it, it was a shitzu.}
30
33
 
31
- disclaimer = Footer.new
34
+ disclaimer = Partial.new
32
35
  disclaimer << "According to a survey they were funny. I didn't make them."
33
36
 
34
37
  screen.draw jokes, Size.new(0,0), title, disclaimer
@@ -36,11 +39,12 @@ screen.draw jokes, Size.new(0,0), title, disclaimer
36
39
  user_input.get_key
37
40
 
38
41
  ANSI.cursor.next_line!
39
- loop_demo = Interaction.new "press q to exit, or any other key to display it\n"
42
+ keys = Partial.new
43
+ loop_demo = Interaction.new "press q to exit, or any other key to display that key's name\n"
40
44
  loop_demo.loop do |key|
41
- ANSI.cursor.beginning_of_line!
42
- ANSI.command.clear_line!
43
- puts key
45
+ keys << key
46
+
47
+ screen.draw keys
44
48
  break if key == ?q
45
49
  end
46
50
 
@@ -1,12 +1,23 @@
1
+ require 'bundler'
2
+ Bundler.require
1
3
  require 'remedy'
2
4
 
3
5
  class Menu
4
6
  include Remedy
5
7
 
8
+ def initialize
9
+ @viewport = Viewport.new
10
+ end
11
+
6
12
  # will do basic setup and then loop over user input
7
13
  def listen
14
+ # get the screen in a reliable state and clear it
15
+ ANSI.screen.safe_reset!
16
+ ANSI.cursor.home!
17
+ ANSI.command.clear_screen!
18
+
8
19
  # if the user resizes the screen we redraw it to fit the new dimensions
9
- Console.set_console_resized_hook! do
20
+ Console.set_console_resized_hook! do |size|
10
21
  draw
11
22
  end
12
23
 
@@ -28,11 +39,14 @@ class Menu
28
39
 
29
40
  # this tells the Viewport to draw to the screen
30
41
  def draw
31
- Viewport.new.draw content, Size([0,0]), header, footer
42
+ @viewport.draw content, Size([0,0]), header, footer
32
43
  end
33
44
 
34
45
  # this is the body of our menu, it will be squished if the terminal is too small
35
46
  def content
47
+ # this creates a new content every time we draw
48
+ # you may want to only create a new content/header/footer when they change
49
+ # or create your own Partial subclass
36
50
  c = Partial.new
37
51
  c << <<-CONTENT
38
52
 
@@ -47,12 +61,12 @@ class Menu
47
61
 
48
62
  # headers are displayed the top of the viewport
49
63
  def header
50
- Header.new << "The time is: #{Time.now}"
64
+ Partial.new << "The time is: #{Time.now}"
51
65
  end
52
66
 
53
67
  # footers are displayed the bottom of the viewport
54
68
  def footer
55
- Footer.new << "You pressed: #{@last_key}"
69
+ Partial.new << "Screen size: #{Console.size} You pressed: #{@last_key}"
56
70
  end
57
71
  end
58
72
 
@@ -42,19 +42,19 @@ module Remedy
42
42
  end
43
43
 
44
44
  def columns
45
- size.last
45
+ size.cols
46
46
  end
47
47
  alias_method :width, :columns
48
48
 
49
49
  def rows
50
- size.first
50
+ size.rows
51
51
  end
52
52
  alias_method :height, :rows
53
53
 
54
54
  def size
55
55
  str = [0, 0, 0, 0].pack('SSSS')
56
56
  if input.ioctl(TIOCGWINSZ, str) >= 0 then
57
- str.unpack('SSSS').first 2
57
+ Size.new str.unpack('SSSS').first 2
58
58
  else
59
59
  raise UnknownConsoleSize, "Unable to get console size"
60
60
  end
@@ -65,8 +65,8 @@ module Remedy
65
65
  end
66
66
 
67
67
  def set_console_resized_hook!
68
- Console::Resize.set_console_resized_hook! do
69
- yield
68
+ Console::Resize.set_console_resized_hook! do |*args|
69
+ yield *args
70
70
  end
71
71
  end
72
72
 
@@ -24,18 +24,21 @@ module Remedy; module Console; module Resize
24
24
  def set_console_resized_hook!
25
25
  @resize_count = 0
26
26
 
27
- command = lambda { |x|
27
+ Signal.trap 'SIGWINCH' do
28
28
  resizing!
29
- sleep 0.25
30
29
 
31
30
  if resized? then
32
- yield
31
+ begin
32
+ yield Console.size
33
+ rescue Exception => ex
34
+ # Ruby will eat *any* errors inside a trap,
35
+ # so we need to expose them for debuggability
36
+ p ex
37
+ end
33
38
  end
34
39
 
35
40
  resized!
36
- }
37
-
38
- Signal.trap 'SIGWINCH', command
41
+ end
39
42
  end
40
43
 
41
44
  def default_console_resized_hook!
data/lib/remedy/key.rb CHANGED
@@ -15,6 +15,10 @@ module Remedy
15
15
  seq
16
16
  end
17
17
 
18
+ def enc
19
+ seq.dump[1..-2]
20
+ end
21
+
18
22
  def name
19
23
  @name ||= Characters[seq] || :unknown
20
24
  end
@@ -51,6 +55,10 @@ module Remedy
51
55
  @recognized ||= name != :unknown
52
56
  end
53
57
 
58
+ def known?
59
+ !!Characters[seq]
60
+ end
61
+
54
62
  def single?
55
63
  @single ||= raw.length == 1
56
64
  end
@@ -60,7 +68,7 @@ module Remedy
60
68
  end
61
69
 
62
70
  def to_s
63
- @to_s ||= name.to_s
71
+ @to_s ||= known? ? name.to_s : enc
64
72
  end
65
73
 
66
74
  def value
@@ -14,6 +14,7 @@ module Remedy
14
14
 
15
15
  def << line
16
16
  reset_width!
17
+ line = "#{line}" # opportunistically convert any object into a string
17
18
  @lines += clean line unless line.nil? || line.empty?
18
19
  end
19
20
 
@@ -64,7 +65,7 @@ module Remedy
64
65
  end
65
66
 
66
67
  def split line
67
- line.split /\r\n|\n\r|\n|\r/
68
+ line.split(/\r\n|\n\r|\n|\r/)
68
69
  end
69
70
  end
70
71
  end
data/lib/remedy/size.rb CHANGED
@@ -39,12 +39,13 @@ module Remedy
39
39
  end
40
40
 
41
41
  def rows
42
- dimensions.first
42
+ dimensions[0]
43
43
  end
44
44
 
45
45
  def cols
46
46
  dimensions[1]
47
47
  end
48
+ alias :columns :cols
48
49
 
49
50
  def [] index
50
51
  dimensions[index]
@@ -1,3 +1,3 @@
1
1
  module Remedy
2
- VERSION = '0.2.0'
2
+ VERSION = '0.3.1'
3
3
  end
@@ -1,6 +1,5 @@
1
1
  require 'remedy/view'
2
2
  require 'remedy/size'
3
- require 'remedy/content'
4
3
  require 'remedy/console'
5
4
  require 'remedy/ansi'
6
5
 
data/lib/remedy.rb CHANGED
@@ -3,7 +3,7 @@ module Remedy
3
3
 
4
4
  def libs
5
5
  %w{
6
- version ansi characters console console_resize content header footer
6
+ version ansi characters console console_resize
7
7
  interaction key keyboard partial view viewport
8
8
  }
9
9
  end
@@ -3,7 +3,7 @@ require 'remedy/viewport'
3
3
 
4
4
  describe Remedy::Viewport do
5
5
  it 'should be able to execute the example code from the readme' do
6
- joke = ::Remedy::Content.new
6
+ joke = ::Remedy::Partial.new
7
7
  joke << "Q: What's the difference between a duck?"
8
8
  joke << "A: Purple, because ice cream has no bones!"
9
9
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: remedy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anthony M. Cook
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-16 00:00:00.000000000 Z
11
+ date: 2023-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -32,6 +32,8 @@ executables: []
32
32
  extensions: []
33
33
  extra_rdoc_files: []
34
34
  files:
35
+ - ".github/dependabot.yml"
36
+ - ".github/workflows/ci.yml"
35
37
  - ".gitignore"
36
38
  - ".ruby-gemset"
37
39
  - ".ruby-version"
@@ -47,9 +49,6 @@ files:
47
49
  - lib/remedy/characters.rb
48
50
  - lib/remedy/console.rb
49
51
  - lib/remedy/console_resize.rb
50
- - lib/remedy/content.rb
51
- - lib/remedy/footer.rb
52
- - lib/remedy/header.rb
53
52
  - lib/remedy/interaction.rb
54
53
  - lib/remedy/key.rb
55
54
  - lib/remedy/keyboard.rb
@@ -68,7 +67,7 @@ homepage: http://github.com/acook/remedy
68
67
  licenses:
69
68
  - MIT
70
69
  metadata: {}
71
- post_install_message:
70
+ post_install_message:
72
71
  rdoc_options: []
73
72
  require_paths:
74
73
  - lib
@@ -83,8 +82,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
82
  - !ruby/object:Gem::Version
84
83
  version: '0'
85
84
  requirements: []
86
- rubygems_version: 3.0.4
87
- signing_key:
85
+ rubygems_version: 3.3.7
86
+ signing_key:
88
87
  specification_version: 4
89
88
  summary: Pure Ruby Console Interaction Library
90
89
  test_files:
@@ -1,4 +0,0 @@
1
- require 'remedy/partial'
2
-
3
- class Remedy::Content < Remedy::Partial
4
- end
data/lib/remedy/footer.rb DELETED
@@ -1,4 +0,0 @@
1
- require 'remedy/partial'
2
-
3
- class Remedy::Footer < Remedy::Partial
4
- end
data/lib/remedy/header.rb DELETED
@@ -1,4 +0,0 @@
1
- require 'remedy/partial'
2
-
3
- class Remedy::Header < Remedy::Partial
4
- end