dynamic_curses_input 1.0.0 → 1.2.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 +4 -4
- data/CHANGELOG.md +35 -2
- data/Gemfile +2 -0
- data/Gemfile.lock +17 -23
- data/README.md +62 -17
- data/Rakefile +3 -3
- data/buildgem.sh +23 -0
- data/dynamic_curses_input.gemspec +27 -22
- data/lib/dynamic_curses_input/color_window.rb +77 -0
- data/lib/dynamic_curses_input/input_handler.rb +30 -3
- data/lib/dynamic_curses_input/version.rb +1 -1
- data/lib/dynamic_curses_input.rb +70 -6
- data/tester.rb +20 -0
- metadata +29 -12
- data/.github/workflows/main.yml +0 -27
- data/.gitignore +0 -11
- data/.rubocop.yml +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 94be33a37c50fb5c028854b16e18ec655ee6a9b20c0caa0007f3939b2f4d73a8
|
4
|
+
data.tar.gz: a5f98c86a14da07791b4cc3c5950a08bb5635d5f55bbb7beef7ef873bd07d07e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 492b393474c5e309a2003cadba1049fd7bed476ba39f7c5e6592f78fcc89345000e5c70eb7e02c143d3c3362b7ffabcd5d8e3953627ec46f3771b33bdbc44d19
|
7
|
+
data.tar.gz: c9a3249fd853c5b22e457274c61f80da3c80391d0bdec16b05328196fc6db60c5d8a6657c7221af15aa6cbef2a2cdb916382e64a121f2086be4ee6d56fb565f8
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,38 @@
|
|
1
|
-
## [
|
1
|
+
## [Release]
|
2
2
|
|
3
|
-
## [
|
3
|
+
## [1.0.0] - 2023-06-07
|
4
4
|
|
5
5
|
- Initial release
|
6
|
+
|
7
|
+
## [1.1.0] - 2023-07-26
|
8
|
+
|
9
|
+
- Features and Enhancements:
|
10
|
+
|
11
|
+
- Added support for printing colored windows with customized positions and color schemes.
|
12
|
+
- Introduced the DynamicCursesInput::ColorWindow class, which allows creating colored text windows within the terminal.
|
13
|
+
- The ColorWindow class provides methods to add colored text to the window and handle user input.
|
14
|
+
- Implemented automatic centering of text within the window when x is set to 'center'.
|
15
|
+
- Adjusted the centered position to shift back by 12 cells for better visual layout when necessary.
|
16
|
+
- Removed reliance on Fibers and replaced it with instance methods to resolve issues with positioning.
|
17
|
+
- Handled compatibility issues with different terminal environments to ensure consistent behavior.
|
18
|
+
- Refactored the code to eliminate unnecessary checks for IRB, enabling smooth execution in various contexts.
|
19
|
+
- Improved the debug log functionality for easier debugging and troubleshooting.
|
20
|
+
|
21
|
+
- Bug Fixes:
|
22
|
+
|
23
|
+
- Fixed the issue causing text to be misaligned or misplaced in certain terminal environments.
|
24
|
+
- Resolved a bug where the window position was not being updated correctly in some cases.
|
25
|
+
|
26
|
+
- Other Changes:
|
27
|
+
|
28
|
+
- Removed redundant and unused code snippets to improve code cleanliness and maintainability.
|
29
|
+
|
30
|
+
## [1.2.0] - 2023-07-31
|
31
|
+
|
32
|
+
- Features Added
|
33
|
+
|
34
|
+
- Added automatic handling for the up and down arrow keys to behave more like the user would expect.
|
35
|
+
|
36
|
+
- The Up arrow will bring the cursor to the beginning of the line by setting the cursor position to 0 after checking if the cursor is already there
|
37
|
+
|
38
|
+
- The Down arrow will bring the cursor to the end of the line by setting the cursor to the position equal to the length of the input line plus 1
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,44 +1,38 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
dynamic_curses_input (1.
|
4
|
+
dynamic_curses_input (1.1.0)
|
5
5
|
curses
|
6
|
+
reline
|
6
7
|
|
7
8
|
GEM
|
8
9
|
remote: https://rubygems.org/
|
9
10
|
specs:
|
10
11
|
ast (2.4.2)
|
11
12
|
curses (1.4.4)
|
12
|
-
|
13
|
+
io-console (0.6.0)
|
13
14
|
json (2.6.3)
|
15
|
+
language_server-protocol (3.17.0.3)
|
14
16
|
parallel (1.23.0)
|
15
|
-
parser (3.2.2.
|
17
|
+
parser (3.2.2.3)
|
16
18
|
ast (~> 2.4.1)
|
19
|
+
racc
|
20
|
+
racc (1.7.1)
|
17
21
|
rainbow (3.1.1)
|
18
22
|
rake (13.0.6)
|
19
|
-
regexp_parser (2.8.
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
rspec-mocks (~> 3.12.0)
|
25
|
-
rspec-core (3.12.2)
|
26
|
-
rspec-support (~> 3.12.0)
|
27
|
-
rspec-expectations (3.12.3)
|
28
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
29
|
-
rspec-support (~> 3.12.0)
|
30
|
-
rspec-mocks (3.12.5)
|
31
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
32
|
-
rspec-support (~> 3.12.0)
|
33
|
-
rspec-support (3.12.0)
|
34
|
-
rubocop (1.52.0)
|
23
|
+
regexp_parser (2.8.1)
|
24
|
+
reline (0.3.7)
|
25
|
+
io-console (~> 0.5)
|
26
|
+
rexml (3.2.6)
|
27
|
+
rubocop (1.55.0)
|
35
28
|
json (~> 2.3)
|
29
|
+
language_server-protocol (>= 3.17.0)
|
36
30
|
parallel (~> 1.10)
|
37
|
-
parser (>= 3.2.
|
31
|
+
parser (>= 3.2.2.3)
|
38
32
|
rainbow (>= 2.2.2, < 4.0)
|
39
33
|
regexp_parser (>= 1.8, < 3.0)
|
40
34
|
rexml (>= 3.2.5, < 4.0)
|
41
|
-
rubocop-ast (>= 1.28.
|
35
|
+
rubocop-ast (>= 1.28.1, < 2.0)
|
42
36
|
ruby-progressbar (~> 1.7)
|
43
37
|
unicode-display_width (>= 2.4.0, < 3.0)
|
44
38
|
rubocop-ast (1.29.0)
|
@@ -53,8 +47,8 @@ DEPENDENCIES
|
|
53
47
|
curses
|
54
48
|
dynamic_curses_input!
|
55
49
|
rake
|
56
|
-
|
50
|
+
reline
|
57
51
|
rubocop
|
58
52
|
|
59
53
|
BUNDLED WITH
|
60
|
-
2.4.
|
54
|
+
2.4.16
|
data/README.md
CHANGED
@@ -1,39 +1,84 @@
|
|
1
|
-
#
|
1
|
+
# Dynamic Curses Input
|
2
2
|
|
3
|
-
|
3
|
+
Dynamic Curses Input is a Ruby gem that provides a simple and intuitive way to handle user input in a Curses-based terminal user interface (TUI). It allows for dynamic input handling, including cursor movement and inline character addition and deletion.
|
4
4
|
|
5
|
-
|
5
|
+
- [Installation](#installation)
|
6
|
+
- [Usage](#usage)
|
7
|
+
- [Documentation](#documentation)
|
8
|
+
- [Dependencies](#dependencies)
|
9
|
+
- [FAQs](#faqs)
|
10
|
+
- [Troubleshooting](#troubleshooting)
|
11
|
+
- [Contribution Guidelines](#contribution-guidelines)
|
12
|
+
- [License](#license)
|
6
13
|
|
7
14
|
## Installation
|
8
15
|
|
9
|
-
|
16
|
+
To install Dynamic Curses Input, add the following line to your application's Gemfile:
|
10
17
|
|
11
|
-
|
18
|
+
```ruby
|
19
|
+
gem 'dynamic_curses_input'
|
20
|
+
```
|
12
21
|
|
13
|
-
|
22
|
+
Then execute:
|
14
23
|
|
15
|
-
|
24
|
+
```bash
|
25
|
+
$ bundle install
|
26
|
+
```
|
16
27
|
|
17
|
-
|
28
|
+
Or install it yourself as:
|
29
|
+
|
30
|
+
```bash
|
31
|
+
$ gem install dynamic_curses_input
|
32
|
+
```
|
18
33
|
|
19
34
|
## Usage
|
20
35
|
|
21
|
-
|
36
|
+
Here's a simple example of how to use Dynamic Curses Input:
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
require "curses"
|
40
|
+
require "dynamic_curses_input"
|
41
|
+
|
42
|
+
begin
|
43
|
+
Curses.init_screen
|
44
|
+
Curses.start_color
|
45
|
+
Curses.addstr("You should be able to use the left and right arrow keys to switch between characters in the line, and selectively edit them.\n")
|
46
|
+
Curses.addstr("Enter your name: ")
|
47
|
+
name = DCI.catch_input(true)
|
48
|
+
Curses.addstr("\nYou entered: #{name}")
|
49
|
+
Curses.getch
|
50
|
+
|
51
|
+
# Log the output
|
52
|
+
logger.info("Name entered: #{name}")
|
53
|
+
ensure
|
54
|
+
Curses.close_screen
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
58
|
+
In this example, `DCI.catch_input(true)` will capture user input until the Enter key is pressed, echoing the input to the screen.
|
22
59
|
|
23
|
-
##
|
60
|
+
## Documentation
|
24
61
|
|
25
|
-
|
62
|
+
Detailed documentation for each function is available in the [wiki](https://git.pixelridgesoftworks.com/PixelRidge-Softworks/dynamic_curses_input/wiki).
|
26
63
|
|
27
|
-
|
64
|
+
## Dependencies
|
28
65
|
|
29
|
-
|
66
|
+
DynamicCursesInput depends on the [Curses](https://github.com/ruby/curses) gem.
|
30
67
|
|
31
|
-
|
68
|
+
## Troubleshooting
|
69
|
+
|
70
|
+
If you encounter any issues while using DynamicCursesInput, please check the [issues](https://git.pixelridgesoftworks.com/PixelRidge-Softworks/dynamic_curses_input/issues) page. If your issue isn't listed, feel free to open a new issue.
|
71
|
+
|
72
|
+
## Contribution Guidelines
|
73
|
+
|
74
|
+
We welcome contributions from the community! Please read our [contribution guidelines](CONTRIBUTING.md) before submitting a pull request.
|
32
75
|
|
33
76
|
## License
|
34
77
|
|
35
|
-
|
78
|
+
DynamicCursesInput is available under the [MIT License](LICENSE.txt).
|
79
|
+
|
80
|
+
---
|
36
81
|
|
37
|
-
|
82
|
+
### Note from the Developer:
|
38
83
|
|
39
|
-
|
84
|
+
There is a function in this gem that is not finished yet, it's for making asking questions in a Curses TUI easier from within the gem. This method shouldn't be used yet.
|
data/Rakefile
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rspec/core/rake_task'
|
5
5
|
|
6
6
|
RSpec::Core::RakeTask.new(:spec)
|
7
7
|
|
8
|
-
require
|
8
|
+
require 'rubocop/rake_task'
|
9
9
|
|
10
10
|
RuboCop::RakeTask.new
|
11
11
|
|
data/buildgem.sh
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#/bin/bash
|
2
|
+
echo "rebuilding dynamic_curses_input..."
|
3
|
+
sleep 1
|
4
|
+
echo "Uninstalling existing version..."
|
5
|
+
sleep 1
|
6
|
+
gem uninstall dynamic_curses_input
|
7
|
+
sleep 1
|
8
|
+
echo "Cleaning up old files..."
|
9
|
+
sleep 1
|
10
|
+
gem cleanup dynamic_curses_input
|
11
|
+
rm -f dynamic_curses_input-1.2.0.gem
|
12
|
+
sleep 1
|
13
|
+
echo "Building DCI..."
|
14
|
+
sleep 1
|
15
|
+
gem build dynamic_curses_input.gemspec
|
16
|
+
echo "built!"
|
17
|
+
sleep 1
|
18
|
+
echo "Installing new version of DCI..."
|
19
|
+
sleep 1
|
20
|
+
gem install dynamic_curses_input-1.2.0.gem
|
21
|
+
echo "Installed!"
|
22
|
+
echo "press any key to exit..."
|
23
|
+
read ""
|
@@ -1,14 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative 'lib/dynamic_curses_input/version'
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
|
-
spec.name =
|
6
|
+
spec.name = 'dynamic_curses_input'
|
7
7
|
spec.version = DynamicCursesInput::VERSION
|
8
|
-
spec.authors = [
|
9
|
-
spec.email = [
|
8
|
+
spec.authors = ['PixelRidge-Softworks']
|
9
|
+
spec.email = ['connorc@pixelridgesoftworks.com']
|
10
10
|
|
11
|
-
spec.summary =
|
11
|
+
spec.summary = 'A simple library for making Curses TUI input more dynamic and user-friendly'
|
12
12
|
spec.description = "Dynamic Curses Input is a highly simple, yet powerful gem that allows simple implementation of
|
13
13
|
dynamic typing in curses TUI menus built in Ruby. For example, one can't simply use their arrow
|
14
14
|
keys to navigate and edit inputs in Cursese TUI menus without adding a bunch of extra code to your
|
@@ -16,24 +16,29 @@ Gem::Specification.new do |spec|
|
|
16
16
|
that code, by providing simple to use methods that allow developers to capture user input, while
|
17
17
|
allowing the special keys to work as the average user would expect.
|
18
18
|
IE: When you press the left arrow key, the cursor moves to the left and allows you to delete a
|
19
|
-
character you entered that isn't the last character you entered.
|
20
|
-
spec.homepage = "https://github.com/Pixelated-Studios/dynamic_curses_input"
|
21
|
-
spec.license = "MIT"
|
22
|
-
spec.required_ruby_version = "3.2.2"
|
19
|
+
character you entered that isn't the last character you entered.
|
23
20
|
|
24
|
-
|
25
|
-
|
26
|
-
spec.
|
21
|
+
KNOWN BUG: X & Y coords for placing windows appear to be broken right now. Will fix with
|
22
|
+
next update"
|
23
|
+
spec.homepage = 'https://git.pixelridgesoftworks.com/PixelRidge-Softworks/dynamic_curses_input'
|
24
|
+
spec.license = 'MIT'
|
25
|
+
spec.required_ruby_version = '3.2.2'
|
26
|
+
|
27
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
28
|
+
spec.metadata['source_code_uri'] = 'https://git.pixelridgesoftworks.com/PixelRidge-Softworks/dynamic_curses_input'
|
29
|
+
spec.metadata['changelog_uri'] = 'https://git.pixelridgesoftworks.com/PixelRidge-Softworks/dynamic_curses_input/src/branch/main/CHANGELOG.md'
|
27
30
|
|
28
31
|
# Specify which files should be added to the gem when it is released.
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
spec.
|
32
|
+
spec.files = Dir.glob('{bin,lib,sig}/**/*') + Dir.glob('*').reject do |f|
|
33
|
+
f.start_with?('spec', '.rspec', 'dynamic_curses_input.gemspec')
|
34
|
+
end
|
35
|
+
spec.files << 'LICENSE.txt'
|
36
|
+
spec.files << 'README.md'
|
37
|
+
spec.files << 'dynamic_curses_input.gemspec'
|
38
|
+
|
39
|
+
spec.require_paths = ['lib']
|
40
|
+
|
41
|
+
spec.add_dependency 'curses'
|
42
|
+
spec.add_dependency 'reline'
|
43
|
+
spec.add_development_dependency 'rubocop'
|
39
44
|
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# lib/dynamic_curses_input/color_window.rb
|
4
|
+
|
5
|
+
require 'curses'
|
6
|
+
require_relative 'input_handler'
|
7
|
+
|
8
|
+
module DynamicCursesInput
|
9
|
+
# Class for creating a colored window
|
10
|
+
class ColorWindow
|
11
|
+
# Initialize instance variables and setup curses
|
12
|
+
def initialize(echo, x, y) # rubocop:disable Metrics/MethodLength, Naming/MethodParameterName
|
13
|
+
@echo = echo # Determines whether input should be echoed to the screen
|
14
|
+
setup_curses_color # Setup curses
|
15
|
+
@x = x
|
16
|
+
@y = y
|
17
|
+
# Define color pairs
|
18
|
+
Curses.init_pair(1, Curses::COLOR_BLACK, Curses::COLOR_BLACK)
|
19
|
+
Curses.init_pair(2, Curses::COLOR_BLUE, Curses::COLOR_BLACK)
|
20
|
+
Curses.init_pair(3, Curses::COLOR_GREEN, Curses::COLOR_BLACK)
|
21
|
+
Curses.init_pair(4, Curses::COLOR_CYAN, Curses::COLOR_BLACK)
|
22
|
+
Curses.init_pair(5, Curses::COLOR_RED, Curses::COLOR_BLACK)
|
23
|
+
Curses.init_pair(6, Curses::COLOR_MAGENTA, Curses::COLOR_BLACK)
|
24
|
+
Curses.init_pair(7, Curses::COLOR_YELLOW, Curses::COLOR_BLACK) # Brown is usually represented as yellow
|
25
|
+
Curses.init_pair(8, Curses::COLOR_WHITE, Curses::COLOR_BLACK)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Method that adds colored text to the window
|
29
|
+
def add_color_window(color, text, x, y, input: nil, echo: true) # rubocop:disable Metrics/MethodLength, Metrics/ParameterLists, Naming/MethodParameterName
|
30
|
+
# Map color names to color pair numbers
|
31
|
+
color_map = {
|
32
|
+
'black' => 1,
|
33
|
+
'blue' => 2,
|
34
|
+
'green' => 3,
|
35
|
+
'cyan' => 4,
|
36
|
+
'red' => 5,
|
37
|
+
'magenta' => 6,
|
38
|
+
'brown' => 7, # Brown is usually represented as yellow in terminal colors
|
39
|
+
'white' => 8
|
40
|
+
}
|
41
|
+
|
42
|
+
# Get the color pair number for the specified color
|
43
|
+
color_pair = color_map[color.downcase]
|
44
|
+
|
45
|
+
# Set the cursor position if both x and y are specified
|
46
|
+
if x && y
|
47
|
+
set_position(y, x)
|
48
|
+
elsif x.nil? && y.nil?
|
49
|
+
# If both x and y are not specified, raise an ArgumentError
|
50
|
+
raise ArgumentError, 'Both x and y coordinates must be specified for printing the color window.'
|
51
|
+
end
|
52
|
+
|
53
|
+
# Print the text in the specified color
|
54
|
+
Curses.attron(Curses.color_pair(color_pair))
|
55
|
+
Curses.addstr(text)
|
56
|
+
Curses.attroff(Curses.color_pair(color_pair))
|
57
|
+
|
58
|
+
# If an input is specified, take input from the user
|
59
|
+
InputHandler.catch_input(echo) if input
|
60
|
+
|
61
|
+
Curses.refresh
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
# Setup curses
|
67
|
+
def setup_curses_color
|
68
|
+
Curses.init_screen
|
69
|
+
Curses.start_color
|
70
|
+
end
|
71
|
+
|
72
|
+
# Set cursor position manually on the X and Y axis
|
73
|
+
def set_position(y, x) # rubocop:disable Naming/MethodParameterName
|
74
|
+
Curses.setpos(y, x)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# lib/dynamic_curses_input/input_handler.rb
|
4
4
|
|
5
|
-
require
|
5
|
+
require 'curses'
|
6
6
|
|
7
7
|
module DynamicCursesInput
|
8
8
|
# our main class for handling input
|
@@ -15,7 +15,7 @@ module DynamicCursesInput
|
|
15
15
|
# Initialize instance variables and setup curses
|
16
16
|
def initialize(echo)
|
17
17
|
@echo = echo # Determines whether input should be echoed to the screen
|
18
|
-
@input =
|
18
|
+
@input = '' # Stores the input string
|
19
19
|
@cursor_pos = 0 # Stores the current cursor position
|
20
20
|
@initial_y = Curses.stdscr.cury # Stores the initial y-coordinate of the cursor
|
21
21
|
@initial_x = Curses.stdscr.curx # Stores the initial x-coordinate of the cursor
|
@@ -47,6 +47,8 @@ module DynamicCursesInput
|
|
47
47
|
case chk
|
48
48
|
when Curses::KEY_LEFT then handle_left_key # Move cursor left
|
49
49
|
when Curses::KEY_RIGHT then handle_right_key # Move cursor right
|
50
|
+
when Curses::KEY_UP then handle_up_key
|
51
|
+
when Curses::KEY_DOWN then handle_down_key
|
50
52
|
when Curses::KEY_BACKSPACE, 127 then handle_backspace_key # Delete character
|
51
53
|
when 10, 13 then handle_enter_key # Break loop if enter key is pressed
|
52
54
|
else handle_default_key(chk) # Add character to input string
|
@@ -63,6 +65,16 @@ module DynamicCursesInput
|
|
63
65
|
@cursor_pos = CursorMover.right(@cursor_pos, @input.length)
|
64
66
|
end
|
65
67
|
|
68
|
+
# Move cursor down
|
69
|
+
def handle_down_key
|
70
|
+
@cursor_pos = CursorMover.down(@cursor_pos, @input.length)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Move cursor up
|
74
|
+
def handle_up_key
|
75
|
+
@cursor_pos = CursorMover.up(@cursor_pos, @input.length)
|
76
|
+
end
|
77
|
+
|
66
78
|
# Delete character
|
67
79
|
def handle_backspace_key
|
68
80
|
@input, @cursor_pos = CharacterDeleter.delete(@input, @cursor_pos)
|
@@ -84,7 +96,7 @@ module DynamicCursesInput
|
|
84
96
|
# Redraw the input string
|
85
97
|
def redraw_input
|
86
98
|
Curses.setpos(@initial_y, @initial_x) # Move cursor to initial position
|
87
|
-
Curses.addstr(
|
99
|
+
Curses.addstr(' ' * (Curses.cols - @initial_x)) # Clear line
|
88
100
|
Curses.setpos(@initial_y, @initial_x) # Move cursor to initial position
|
89
101
|
Curses.addstr(@input) if @echo # Draw input string if @echo is true
|
90
102
|
Curses.setpos(@initial_y, @initial_x + @cursor_pos) # Move cursor to current position
|
@@ -102,6 +114,21 @@ module DynamicCursesInput
|
|
102
114
|
def self.right(cursor_pos, length)
|
103
115
|
cursor_pos == length ? cursor_pos : cursor_pos + 1
|
104
116
|
end
|
117
|
+
|
118
|
+
# Handle down arrow key
|
119
|
+
def self.down(_, length)
|
120
|
+
length # Move to the end of the line
|
121
|
+
end
|
122
|
+
|
123
|
+
# Handle up arrow key
|
124
|
+
def self.up(_, _length)
|
125
|
+
0 # Move to the beginning of the line (position 0)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Set cursor position
|
129
|
+
def self.set_position(y, x) # rubocop:disable Naming/MethodParameterName
|
130
|
+
Curses.setpos(y, x)
|
131
|
+
end
|
105
132
|
end
|
106
133
|
|
107
134
|
# Class for deleting characters
|
data/lib/dynamic_curses_input.rb
CHANGED
@@ -2,8 +2,10 @@
|
|
2
2
|
|
3
3
|
# lib/dynamic_curses_input.rb
|
4
4
|
|
5
|
-
|
6
|
-
require_relative
|
5
|
+
require 'readline' # Add the Readline module
|
6
|
+
require_relative 'dynamic_curses_input/version'
|
7
|
+
require_relative 'dynamic_curses_input/input_handler'
|
8
|
+
require_relative 'dynamic_curses_input/color_window'
|
7
9
|
|
8
10
|
# The module entrypoint for our Gem
|
9
11
|
module DynamicCursesInput
|
@@ -13,12 +15,74 @@ module DynamicCursesInput
|
|
13
15
|
InputHandler.catch_input(echo)
|
14
16
|
end
|
15
17
|
|
16
|
-
def self.ask_question(question, echo)
|
18
|
+
def self.ask_question(color = 'white', question, x: 'center', input: true, echo: nil) # rubocop:disable Naming/MethodParameterName
|
17
19
|
Curses.clear
|
18
|
-
|
19
|
-
|
20
|
+
ColorWindow.add_color_window(color, question, y:, x:, input:, echo:)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.print_color_window(color, text, y_value: nil, x: 'center', input: nil, echo: true) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/ParameterLists, Naming/MethodParameterName
|
24
|
+
case x
|
25
|
+
when 'center'
|
26
|
+
terminal_size = `stty size`.split.map(&:to_i)
|
27
|
+
y_value = terminal_size[0] / 2
|
28
|
+
x_value = terminal_size[1] / 2 - text.length / 2 # Adjust x-coordinate to center the window
|
29
|
+
x_value -= 12 if x_value > 1
|
30
|
+
# the above line shifts the X value of the cell coords back by 12 cells if we are trying to center the window
|
31
|
+
# we have to do this because math gets kind of approximate when we convert pixel ratios to character cell coords
|
32
|
+
when 'left'
|
33
|
+
y_value = Curses.lines / 2
|
34
|
+
x_value = 0
|
35
|
+
when 'right'
|
36
|
+
y_value = Curses.lines / 2
|
37
|
+
x_value = Curses.cols - text.length
|
38
|
+
when 'left_center'
|
39
|
+
y_value = Curses.lines / 4
|
40
|
+
x_value = 0
|
41
|
+
when 'right_center'
|
42
|
+
y_value = Curses.lines / 4
|
43
|
+
x_value = Curses.cols - text.length
|
44
|
+
else
|
45
|
+
y_value, x_value = x.split('px').map(&:to_i)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Initialize curses and get the terminal size
|
49
|
+
Curses.init_screen
|
50
|
+
Curses.start_color
|
20
51
|
Curses.refresh
|
21
|
-
|
52
|
+
|
53
|
+
# Set up Readline for proper terminal settings
|
54
|
+
setup_readline
|
55
|
+
|
56
|
+
ColorWindow.new(echo, x_value, y_value).add_color_window(color, text, x_value, y_value, input:, echo:)
|
57
|
+
end
|
58
|
+
|
59
|
+
class << self
|
60
|
+
private
|
61
|
+
|
62
|
+
def process_print_color_window_args(args) # rubocop:disable Metrics/MethodLength
|
63
|
+
case args.size
|
64
|
+
when 2
|
65
|
+
['white', args[0], args[1], 'center', nil, true]
|
66
|
+
when 3
|
67
|
+
['white', args[0], args[1], args[2], nil, true]
|
68
|
+
when 4
|
69
|
+
['white', args[0], args[1], args[2], args[3], true]
|
70
|
+
when 5
|
71
|
+
[args[0], args[1], args[2], args[3], args[4]]
|
72
|
+
else
|
73
|
+
raise ArgumentError, 'print_color_window accepts 2 to 5 arguments: color, text, [position], [input], [echo]'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.setup_readline
|
79
|
+
# Set up Readline for proper terminal settings
|
80
|
+
Readline.emacs_editing_mode
|
81
|
+
# the above line sets Readline to emacs_editing_mode so that terminals behave like they're supposed to
|
82
|
+
Readline.completion_append_character = ' '
|
83
|
+
# we remove Readlines thing where it adds a space to the end of tab completes because it breaks the Curses cursor
|
84
|
+
Readline.completion_proc = proc { |_s| [] }
|
85
|
+
# here we basically are disabling tab completion all together. That's because for some reason it breaks the cursor
|
22
86
|
end
|
23
87
|
end
|
24
88
|
|
data/tester.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dynamic_curses_input'
|
4
|
+
|
5
|
+
# Create and display a red window at the center of the screen
|
6
|
+
DCI.print_color_window('red', 'test', y_value: 60, x: '40')
|
7
|
+
|
8
|
+
# Create and display a magenta window at a specific position
|
9
|
+
DCI.print_color_window('magenta', 'testy-test', y_value: 30, x: '20')
|
10
|
+
|
11
|
+
# Initialize Curses
|
12
|
+
Curses.init_screen
|
13
|
+
Curses.cbreak
|
14
|
+
Curses.noecho
|
15
|
+
|
16
|
+
# Wait for the Enter key to be pressed
|
17
|
+
Curses.stdscr.getch until Curses.stdscr.getch == 10
|
18
|
+
|
19
|
+
# Clean up and close Curses
|
20
|
+
Curses.close_screen
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dynamic_curses_input
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- PixelRidge-Softworks
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-08-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: curses
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: reline
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rubocop
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -47,15 +61,15 @@ description: |-
|
|
47
61
|
allowing the special keys to work as the average user would expect.
|
48
62
|
IE: When you press the left arrow key, the cursor moves to the left and allows you to delete a
|
49
63
|
character you entered that isn't the last character you entered.
|
64
|
+
|
65
|
+
KNOWN BUG: X & Y coords for placing windows appear to be broken right now. Will fix with
|
66
|
+
next update
|
50
67
|
email:
|
51
|
-
-
|
68
|
+
- connorc@pixelridgesoftworks.com
|
52
69
|
executables: []
|
53
70
|
extensions: []
|
54
71
|
extra_rdoc_files: []
|
55
72
|
files:
|
56
|
-
- ".github/workflows/main.yml"
|
57
|
-
- ".gitignore"
|
58
|
-
- ".rubocop.yml"
|
59
73
|
- CHANGELOG.md
|
60
74
|
- CODE_OF_CONDUCT.md
|
61
75
|
- Gemfile
|
@@ -65,18 +79,21 @@ files:
|
|
65
79
|
- Rakefile
|
66
80
|
- bin/console
|
67
81
|
- bin/setup
|
82
|
+
- buildgem.sh
|
68
83
|
- dynamic_curses_input.gemspec
|
69
84
|
- lib/dynamic_curses_input.rb
|
85
|
+
- lib/dynamic_curses_input/color_window.rb
|
70
86
|
- lib/dynamic_curses_input/input_handler.rb
|
71
87
|
- lib/dynamic_curses_input/version.rb
|
72
88
|
- sig/dynamic_curses_input.rbs
|
73
|
-
|
89
|
+
- tester.rb
|
90
|
+
homepage: https://git.pixelridgesoftworks.com/PixelRidge-Softworks/dynamic_curses_input
|
74
91
|
licenses:
|
75
92
|
- MIT
|
76
93
|
metadata:
|
77
|
-
homepage_uri: https://
|
78
|
-
source_code_uri: https://
|
79
|
-
changelog_uri: https://
|
94
|
+
homepage_uri: https://git.pixelridgesoftworks.com/PixelRidge-Softworks/dynamic_curses_input
|
95
|
+
source_code_uri: https://git.pixelridgesoftworks.com/PixelRidge-Softworks/dynamic_curses_input
|
96
|
+
changelog_uri: https://git.pixelridgesoftworks.com/PixelRidge-Softworks/dynamic_curses_input/src/branch/main/CHANGELOG.md
|
80
97
|
post_install_message:
|
81
98
|
rdoc_options: []
|
82
99
|
require_paths:
|
@@ -92,7 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
109
|
- !ruby/object:Gem::Version
|
93
110
|
version: '0'
|
94
111
|
requirements: []
|
95
|
-
rubygems_version: 3.4.
|
112
|
+
rubygems_version: 3.4.16
|
96
113
|
signing_key:
|
97
114
|
specification_version: 4
|
98
115
|
summary: A simple library for making Curses TUI input more dynamic and user-friendly
|
data/.github/workflows/main.yml
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
name: Ruby
|
2
|
-
|
3
|
-
on:
|
4
|
-
push:
|
5
|
-
branches:
|
6
|
-
- master
|
7
|
-
|
8
|
-
pull_request:
|
9
|
-
|
10
|
-
jobs:
|
11
|
-
build:
|
12
|
-
runs-on: ubuntu-latest
|
13
|
-
name: Ruby ${{ matrix.ruby }}
|
14
|
-
strategy:
|
15
|
-
matrix:
|
16
|
-
ruby:
|
17
|
-
- '3.2.2'
|
18
|
-
|
19
|
-
steps:
|
20
|
-
- uses: actions/checkout@v3
|
21
|
-
- name: Set up Ruby
|
22
|
-
uses: ruby/setup-ruby@v1
|
23
|
-
with:
|
24
|
-
ruby-version: ${{ matrix.ruby }}
|
25
|
-
bundler-cache: true
|
26
|
-
- name: Run the default task
|
27
|
-
run: bundle exec rake
|
data/.gitignore
DELETED
data/.rubocop.yml
DELETED