remedy 0.3.0 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b308f7cf135ba7a8f6ab69ef9c56ff7d640a189c9f44056e14f49b987948ec1f
4
- data.tar.gz: 9f1969fea60358a6585974f948f572bdeeeb55afd0f176d6dd220bdd4b29c094
3
+ metadata.gz: af17b629f35cdae5c8a15c47a6e23f5aa51bce006afa7f7e129a8640c9d191b1
4
+ data.tar.gz: 36568e55906c286e97666183f9e6eb704535b6155830bc93acda7c59299a2ab6
5
5
  SHA512:
6
- metadata.gz: 0d664d1b61638b139bd2aef66ed2facd0d25e4dbaa65a39014892bcb3f967895cbf78304a8b4235cce1a5210384e7cadaa6672fa41a2d2e102c22a80c0cd40ef
7
- data.tar.gz: ea8a3d1aeaeb8a0e474bf2a69f6837ab300810dfaf3bd014200e284f6e45058875fa5363e73948228806e35e24957ded1d342d07a8622f089726e94da2e93a3b
6
+ metadata.gz: 447afaf7d518eb6b8ddeb80dc9d7b4cae579a978ec6af952749dafe52b2d95b930ef6e6bbc24378ebab81ec48807102453d07e0f8196b251d62ffd84662f80a9
7
+ data.tar.gz: 7d800899e64c41e9acd31215df9b66fd1dd96f9da52a735e3393c855bf91f8d75f1fc224dc559f9560fedaa89a4c88468cce94b9713bd3bb1ef3e2b428d52e61
@@ -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.6.3
1
+ 3.1.2
data/README.markdown CHANGED
@@ -5,7 +5,7 @@ Remedy is a console interaction framework along the lines of Curses written in p
5
5
 
6
6
  [![Gem Version](https://img.shields.io/gem/v/remedy.svg?style=for-the-badge)](https://rubygems.org/gems/remedy)
7
7
  [![Gem Downloads](https://img.shields.io/gem/dt/remedy.svg?style=for-the-badge)](https://rubygems.org/gems/remedy)
8
- [![Build Status](https://img.shields.io/travis/acook/remedy.svg?style=for-the-badge)](https://travis-ci.org/acook/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
9
  [![Code Climate maintainability](https://img.shields.io/codeclimate/maintainability/acook/remedy?style=for-the-badge)](https://codeclimate.com/github/acook/remedy/maintainability)
10
10
 
11
11
 
@@ -70,20 +70,18 @@ For instance to get a keypress from the terminal and display it:
70
70
  screen.draw joke
71
71
  ```
72
72
 
73
- `Remedy::Partial` has the subclasses `Header`, `Footer`, and `Content`.
74
-
75
- You can use the above classes to divide your Views into 3 separate pieces. Content 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.
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.
76
74
 
77
75
  ```ruby
78
76
  include Remedy
79
- title = Header.new
77
+ title = Partial.new
80
78
  title << "Someone Said These Were Good"
81
79
 
82
80
  jokes = Content.new
83
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.'}
84
82
  jokes << %q{2. I went to the zoo the other day, there was only one dog in it, it was a shitzu.}
85
83
 
86
- disclaimer = Footer.new
84
+ disclaimer = Partial.new
87
85
  disclaimer << "According to a survey they were funny. I didn't make them."
88
86
 
89
87
  screen = Viewport.new
@@ -102,7 +100,7 @@ The most interesting function in my opinion is the callback that gets triggered
102
100
  screen = Viewport.new
103
101
 
104
102
  Console.set_console_resized_hook! do |size|
105
- notice = Content.new
103
+ notice = Partial.new
106
104
  notice << "You just resized your screen!\n\nNew size:"
107
105
  notice << size
108
106
  screen.draw notice
@@ -114,7 +112,10 @@ Remedy in the Wild
114
112
 
115
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.
116
114
 
117
- Here are a couple of projects that use many of Remedy's features:
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)
118
119
  - A multiplayer Yahtzee for web and console: [YahtzeeGame](https://github.com/ProgrammingPractice/YahtzeeGame)
119
120
  - Twitter/RSS/Facebook reader: [noizee](https://github.com/acook/noizee)
120
121
 
@@ -133,4 +134,3 @@ Contributing
133
134
  3. Commit your changes (`git commit -am 'Add some feature'`)
134
135
  4. Push to the branch (`git push origin my-new-feature`)
135
136
  5. Create new Pull Request
136
-
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "remedy", path: "../.."
@@ -7,7 +7,7 @@ include Remedy
7
7
  screen = Viewport.new
8
8
 
9
9
  Console.set_console_resized_hook! do |size|
10
- notice = Content.new
10
+ notice = Partial.new
11
11
  notice << "You just resized your screen!\n\nNew size:"
12
12
  notice << size
13
13
 
@@ -16,7 +16,7 @@ end
16
16
 
17
17
  user_input = Interaction.new "press any key to continue"
18
18
 
19
- joke = Content.new
19
+ joke = Partial.new
20
20
  joke << "Q: What's the difference between a duck?"
21
21
  joke << "A: Purple, because ice cream has no bones!"
22
22
 
@@ -24,14 +24,14 @@ screen.draw joke
24
24
 
25
25
  user_input.get_key
26
26
 
27
- title = Header.new
27
+ title = Partial.new
28
28
  title << "Someone Said These Were Good"
29
29
 
30
- jokes = Content.new
30
+ jokes = Partial.new
31
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.'}
32
32
  jokes << %q{2. I went to the zoo the other day, there was only one dog in it, it was a shitzu.}
33
33
 
34
- disclaimer = Footer.new
34
+ disclaimer = Partial.new
35
35
  disclaimer << "According to a survey they were funny. I didn't make them."
36
36
 
37
37
  screen.draw jokes, Size.new(0,0), title, disclaimer
@@ -39,7 +39,7 @@ screen.draw jokes, Size.new(0,0), title, disclaimer
39
39
  user_input.get_key
40
40
 
41
41
  ANSI.cursor.next_line!
42
- keys = Content.new
42
+ keys = Partial.new
43
43
  loop_demo = Interaction.new "press q to exit, or any other key to display that key's name\n"
44
44
  loop_demo.loop do |key|
45
45
  keys << key
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "remedy", path: "../.."
@@ -11,11 +11,6 @@ class Menu
11
11
 
12
12
  # will do basic setup and then loop over user input
13
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
-
19
14
  # if the user resizes the screen we redraw it to fit the new dimensions
20
15
  Console.set_console_resized_hook! do |size|
21
16
  draw
@@ -24,10 +19,10 @@ class Menu
24
19
  # create an interaction object to handle user input
25
20
  interaction = Interaction.new
26
21
 
27
- # call draw here because interaction blocks until it gets input
22
+ # call draw here because the interaction loop blocks until it gets input
28
23
  draw
29
24
 
30
- # loop over user input (individual keypresses)
25
+ # loop over individual keypresses or ANSI codes from the terminal
31
26
  interaction.loop do |key|
32
27
  @last_key = key
33
28
  if key == "q" then
@@ -39,7 +34,7 @@ class Menu
39
34
 
40
35
  # this tells the Viewport to draw to the screen
41
36
  def draw
42
- @viewport.draw content, Size([0,0]), header, footer
37
+ @viewport.draw content, Size.zero, header, footer
43
38
  end
44
39
 
45
40
  # this is the body of our menu, it will be squished if the terminal is too small
@@ -47,7 +42,7 @@ class Menu
47
42
  # this creates a new content every time we draw
48
43
  # you may want to only create a new content/header/footer when they change
49
44
  # or create your own Partial subclass
50
- c = Content.new
45
+ c = Partial.new
51
46
  c << <<-CONTENT
52
47
 
53
48
  1. Do the thing
@@ -61,12 +56,12 @@ class Menu
61
56
 
62
57
  # headers are displayed the top of the viewport
63
58
  def header
64
- Header.new << "The time is: #{Time.now}"
59
+ Partial.new << "The time is: #{Time.now}"
65
60
  end
66
61
 
67
62
  # footers are displayed the bottom of the viewport
68
63
  def footer
69
- Footer.new << "Screen size: #{Console.size} You pressed: #{@last_key}"
64
+ Partial.new << "Screen size: #{Console.size} You pressed: #{@last_key}"
70
65
  end
71
66
  end
72
67
 
@@ -16,6 +16,7 @@ module Remedy
16
16
  reset_width!
17
17
  line = "#{line}" # opportunistically convert any object into a string
18
18
  @lines += clean line unless line.nil? || line.empty?
19
+ self
19
20
  end
20
21
 
21
22
  def first
@@ -26,16 +27,17 @@ module Remedy
26
27
  lines.last
27
28
  end
28
29
 
29
- def length
30
+ def height
30
31
  lines.length
31
32
  end
33
+ alias_method :length, :height
32
34
 
33
35
  def width
34
- @width ||= lines.max{|line| line.length }.length
36
+ lines.map{|line| line.length }.max
35
37
  end
36
38
 
37
39
  def size
38
- Size.new length, width
40
+ Size.new height, width
39
41
  end
40
42
 
41
43
  def to_a
data/lib/remedy/size.rb CHANGED
@@ -11,6 +11,10 @@ module Remedy
11
11
  end
12
12
  attr_accessor :dimensions
13
13
 
14
+ def self.zero
15
+ self.new([0,0])
16
+ end
17
+
14
18
  def - other_size
15
19
  if other_size.respond_to? :length then
16
20
  self.class.new subtract(other_size)
@@ -41,11 +45,13 @@ module Remedy
41
45
  def rows
42
46
  dimensions[0]
43
47
  end
48
+ alias_method :height, :rows
44
49
 
45
50
  def cols
46
51
  dimensions[1]
47
52
  end
48
- alias :columns :cols
53
+ alias_method :columns, :cols
54
+ alias_method :width, :cols
49
55
 
50
56
  def [] index
51
57
  dimensions[index]
@@ -1,3 +1,3 @@
1
1
  module Remedy
2
- VERSION = '0.3.0'
2
+ VERSION = '0.4.0'
3
3
  end
@@ -1,19 +1,14 @@
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
 
7
6
  module Remedy
8
7
  class Viewport
9
- def draw content, center = Size.new(0,0), header = [], footer = []
10
- range = range_find content, center, content_size(header,footer)
8
+ def draw content, scroll = Size.zero, header = Partial.new, footer = Partial.new
9
+ range = range_find content, scroll, available_space(header,footer)
11
10
 
12
- if content.size.fits_into? range then
13
- viewable_content = content
14
- else
15
- viewable_content = content.excerpt *range
16
- end
11
+ viewable_content = content.excerpt *range
17
12
 
18
13
  view = View.new viewable_content, header, footer
19
14
 
@@ -21,19 +16,22 @@ module Remedy
21
16
  Console.output << view
22
17
  end
23
18
 
24
- def range_find partial, center, heightwidth
25
- row_size, col_size = heightwidth
26
- row_limit, col_limit = partial.size
19
+ def range_find partial, scroll, available_heightwidth
20
+ avail_height, avail_width = available_heightwidth
21
+ partial_height, partial_width = partial.size
22
+
23
+ center_row, center_col = scroll
27
24
 
28
- center_row, center_col = center
25
+ row_range = get_range center_row, partial_height, avail_height
26
+ col_range = get_range center_col, partial_width, avail_width
29
27
 
30
- row_range = center_range center_row, row_size, row_limit
31
- col_range = center_range center_col, col_size, col_limit
32
28
  [row_range, col_range]
33
29
  end
34
30
 
35
- def content_size header, footer
36
- trim = Size [header.length + footer.length, 0]
31
+ # This determines the maximum amount of room left available for Content
32
+ # after taking into consideration the height of the Header and Footer
33
+ def available_space header, footer
34
+ trim = Size [header.height + footer.height, 0]
37
35
  size - trim
38
36
  end
39
37
 
@@ -41,20 +39,26 @@ module Remedy
41
39
  Size Console.size
42
40
  end
43
41
 
44
- def center_range center, width, limit
45
- range_start = center - (width / 2)
42
+ def get_range offset, actual, available
43
+ # if the actual content can fit into the available space, then we're done
44
+ return (0...actual) if actual <= available
46
45
 
47
- if range_start + width > limit then
48
- range_start = limit - width
49
- end
46
+ # otherwise start looking at the scrolling offset, if any
50
47
 
51
- if range_start < 0 then
48
+ # clamp the offset within the possible range of the actual content
49
+ if offset < 0 then
52
50
  range_start = 0
51
+ elsif offset > actual then
52
+ range_start = actual
53
+ else
54
+ range_start = offset
53
55
  end
54
56
 
55
- range_end = range_start + width
57
+ # determine the subset of content that can be displayed
58
+ range_end = range_start + (available - offset)
56
59
 
57
60
  (range_start...range_end)
58
61
  end
62
+
59
63
  end
60
64
  end
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,11 +3,17 @@ 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
+ @stdout = $stdout
7
+ joke = ::Remedy::Partial.new
7
8
  joke << "Q: What's the difference between a duck?"
8
9
  joke << "A: Purple, because ice cream has no bones!"
9
10
 
10
11
  screen = ::Remedy::Viewport.new
12
+ sio = StringIO.new
13
+ $stdout = sio
11
14
  screen.draw joke unless ENV['CI']
15
+ expect(sio.string).to include("ice cream")
16
+ ensure
17
+ $stdout = @stdout
12
18
  end
13
19
  end
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.3.0
4
+ version: 0.4.0
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: 2021-03-22 00:00:00.000000000 Z
11
+ date: 2023-10-05 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"
@@ -40,16 +42,15 @@ files:
40
42
  - LICENSE.txt
41
43
  - README.markdown
42
44
  - Rakefile
45
+ - examples/from_readme/Gemfile
43
46
  - examples/from_readme/readme.rb
47
+ - examples/menu/Gemfile
44
48
  - examples/menu/menu.rb
45
49
  - lib/remedy.rb
46
50
  - lib/remedy/ansi.rb
47
51
  - lib/remedy/characters.rb
48
52
  - lib/remedy/console.rb
49
53
  - lib/remedy/console_resize.rb
50
- - lib/remedy/content.rb
51
- - lib/remedy/footer.rb
52
- - lib/remedy/header.rb
53
54
  - lib/remedy/interaction.rb
54
55
  - lib/remedy/key.rb
55
56
  - lib/remedy/keyboard.rb
@@ -68,7 +69,7 @@ homepage: http://github.com/acook/remedy
68
69
  licenses:
69
70
  - MIT
70
71
  metadata: {}
71
- post_install_message:
72
+ post_install_message:
72
73
  rdoc_options: []
73
74
  require_paths:
74
75
  - lib
@@ -83,8 +84,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
84
  - !ruby/object:Gem::Version
84
85
  version: '0'
85
86
  requirements: []
86
- rubygems_version: 3.1.2
87
- signing_key:
87
+ rubygems_version: 3.3.7
88
+ signing_key:
88
89
  specification_version: 4
89
90
  summary: Pure Ruby Console Interaction Library
90
91
  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