typr 1.1.0 → 1.1.2
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 +49 -0
- data/Gemfile +10 -0
- data/LICENSE +21 -0
- data/README.md +207 -0
- data/lib/terminal.rb +0 -1
- data/typr.gemspec +17 -0
- metadata +6 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 756f4c526a47e141947600b8ab1f712f5f55809709415bdc08182f7c84a02885
|
|
4
|
+
data.tar.gz: 0ffb023fb815985b242d77c95e0b7fb314ffe1025c3eaa309b1df615ee7575bd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f5bcf29384273fe9a5fbdf47474b7160485d180b0c29ddb963644a38eaf3a9695cd54d74dc7a2955fa8e25331701f3bc0295f0a8570f85a66c9b8250ef460290
|
|
7
|
+
data.tar.gz: a05c2a49dfaf00d42510e9961ba21eb0a5075ee9f37fb2be685b212dd91a17c10e4622bbac1b958c44f5fdb385e5895f3f4d8dbbb68e8b31b949fc70252fb192
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
|
|
2
|
+
## [v1.1.0] — 2026-07-26
|
|
3
|
+
|
|
4
|
+
### Added
|
|
5
|
+
- _nothing yet (update this section)_
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [v1.0.1] — 2026-07-26
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
- _nothing yet (update this section)_
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# Changelog
|
|
26
|
+
|
|
27
|
+
## [v1.0.0] — 2026-07-25
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
- `Typr::Grid` — tabular data layer with sorting, filtering, and column formatting
|
|
31
|
+
- `Typr::Line` — single-line input component with prompt and bindings
|
|
32
|
+
- `Typr::Text` — scrollable multiline text display (wraps StringIO-backed streams)
|
|
33
|
+
- `Typr::Browser` — directory browser inheriting from Grid with file tree navigation
|
|
34
|
+
- `Typr::Space` — base layout class providing width/height/border support for the TUI hierarchy
|
|
35
|
+
- `Typr::Stack` — stack-based UI widget with headspace, scrolling (up/down/page_up/page_down), row/col/field selection, and per-row per-cell color control
|
|
36
|
+
- Terminal frontend (`Typr::Terminal`) — ANSI escape-code rendering on STDOUT/stdin with proper Unicode display width via `unicode-display_width ~> 3.1`
|
|
37
|
+
- Curses frontend (`Visuals::Curses`) — ncurses-backed rendering
|
|
38
|
+
- Graphical/Window frontend stub (`Visuals::Graphical`) — OpenGL-backed rendering stub
|
|
39
|
+
- Color support across all frontends (named palette: black/red/green/yellow/blue/magenta/cyan/white, plus 9 grey shades)
|
|
40
|
+
- Header constants auto-generated from `Grid#header=` (e.g., `Typr::NAME`, `Typr::COUNT`)
|
|
41
|
+
- Pre-built .gem artifacts and full rake deployment tasks (`build`, `release[minor]`, `test`, `clean`)
|
|
42
|
+
|
|
43
|
+
### Changed
|
|
44
|
+
- *(none yet — 1.0.0 is the initial release)*
|
|
45
|
+
|
|
46
|
+
### Fixed
|
|
47
|
+
- *(none yet — 1.0.0 is the initial release)*
|
|
48
|
+
|
|
49
|
+
---
|
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kilian Reitmayr
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# typr — Terminal UI Toolkit
|
|
2
|
+
|
|
3
|
+
typr is a Ruby library for building interactive terminal-based user interfaces. It provides data-object based views and keyboard-driven interaction.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
### Views
|
|
8
|
+
|
|
9
|
+
- **Grid** — sortable, filterable table with formatted columns, colors, and row selection
|
|
10
|
+
- **Text** — scrollable text viewer with word/line picking, search, and borders
|
|
11
|
+
- **Browser** — file-system directory browser with MIME type detection
|
|
12
|
+
- **Stack, Space** — layout containers for composing views
|
|
13
|
+
- **Line** — interactive prompt/input with colored questions and answers
|
|
14
|
+
|
|
15
|
+
### Frontends
|
|
16
|
+
|
|
17
|
+
typr supports two rendering backends, selectable via `require`:
|
|
18
|
+
|
|
19
|
+
- **Terminal** (`require 'typr'`) — raw terminal IO, no dependencies beyond Ruby stdlib
|
|
20
|
+
- **Graphical** (`require 'typr/graphical'`) — SDL2-based, for desktop GUI windows
|
|
21
|
+
|
|
22
|
+
All views work identically across frontends.
|
|
23
|
+
|
|
24
|
+
### Keyboard interaction
|
|
25
|
+
|
|
26
|
+
Navigation uses **hint numbers** displayed next to selectable items — rows in grids, columns, or other elements. Press the number to select that item directly. When more items are visible than fit in one set of hints (1-9, 0), press **Tab** to cycle through hint groups. Arrow keys, Page Up/Down, Home/End work as expected. All keys are dispatched through a configurable keymap.
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
gem install typr
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Or in your Gemfile:
|
|
35
|
+
|
|
36
|
+
```ruby
|
|
37
|
+
gem 'typr', '~> 1.0'
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Usage
|
|
41
|
+
|
|
42
|
+
### Grid (table)
|
|
43
|
+
|
|
44
|
+
```ruby
|
|
45
|
+
require 'typr'
|
|
46
|
+
|
|
47
|
+
Typr.init
|
|
48
|
+
|
|
49
|
+
@grid = Typr::Grid.new(
|
|
50
|
+
input: [
|
|
51
|
+
["Alice", 30, "engineer"],
|
|
52
|
+
["Bob", 25, "designer"],
|
|
53
|
+
["Carol", 35, "manager"]
|
|
54
|
+
],
|
|
55
|
+
header: ["Name", "Age", "Role"],
|
|
56
|
+
format: [:min, :right, :max],
|
|
57
|
+
colors: { columns: [:yellow, :cyan, :magenta] }
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
Typr.clear
|
|
61
|
+
@grid.draw
|
|
62
|
+
key = Typr.read(:key) # reads a single keypress
|
|
63
|
+
@grid.reset # reset grid to default view
|
|
64
|
+
Typr.exit
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Text viewer
|
|
68
|
+
|
|
69
|
+
```ruby
|
|
70
|
+
require 'typr'
|
|
71
|
+
|
|
72
|
+
Typr.init
|
|
73
|
+
|
|
74
|
+
@text = Typr::Text.new(
|
|
75
|
+
input: IO.popen(%w[cat /usr/share/dict/words]),
|
|
76
|
+
header: "Words",
|
|
77
|
+
top: 2, left: 0.1, right: 0.9, bottom: -4,
|
|
78
|
+
border: :round,
|
|
79
|
+
colors: { header: [:yellow, :grey30] }
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
Typr.clear
|
|
83
|
+
loop do
|
|
84
|
+
@text.draw
|
|
85
|
+
key = Typr.read(:key)
|
|
86
|
+
case key
|
|
87
|
+
when ?q then break
|
|
88
|
+
else @text.send(key) # spacebar scrolls, j/k move up/down, etc.
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
Typr.exit
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Browser (file picker)
|
|
95
|
+
|
|
96
|
+
```ruby
|
|
97
|
+
require 'typr'
|
|
98
|
+
|
|
99
|
+
Typr.init
|
|
100
|
+
|
|
101
|
+
@browser = Typr::Browser.new(
|
|
102
|
+
directory: "/tmp",
|
|
103
|
+
right: -1, bottom: -1,
|
|
104
|
+
colors: { hints: [:white, :black] }
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
selected = @browser.pick("/home") # interactive file picker, returns path
|
|
108
|
+
puts "You selected: #{selected}"
|
|
109
|
+
Typr.exit
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Combined example (Grid + prompt line)
|
|
113
|
+
|
|
114
|
+
```ruby
|
|
115
|
+
require 'typr'
|
|
116
|
+
|
|
117
|
+
class MyApp
|
|
118
|
+
include Typr
|
|
119
|
+
|
|
120
|
+
def initialize
|
|
121
|
+
Typr.init
|
|
122
|
+
@grid = Typr::Grid.new(
|
|
123
|
+
input: [
|
|
124
|
+
["Item A", 10, true],
|
|
125
|
+
["Item B", 5, false],
|
|
126
|
+
["Item C", 20, true]
|
|
127
|
+
],
|
|
128
|
+
header: ["Name", "Qty", "Active"],
|
|
129
|
+
format: [:max, :right, :min],
|
|
130
|
+
colors: { columns: [:yellow, :cyan, :green] }
|
|
131
|
+
)
|
|
132
|
+
@prompt = Typr::Line.new(
|
|
133
|
+
top: -1,
|
|
134
|
+
default: "(s)ort (f)ilter [esc] quit"
|
|
135
|
+
)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def run
|
|
139
|
+
Typr.clear
|
|
140
|
+
loop do
|
|
141
|
+
@grid.draw
|
|
142
|
+
@prompt.draw
|
|
143
|
+
key = Typr.read(:key)
|
|
144
|
+
case key
|
|
145
|
+
when ?s then @grid.sort_by(@prompt.ask("sort column": [@grid, :column]))
|
|
146
|
+
when ?f then @grid.add_filter(*@prompt.ask("filter column": [@grid, :column], with: :line))
|
|
147
|
+
when KEY_ESCAPE then break
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def shutdown; Typr.exit; end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
app = MyApp.new
|
|
156
|
+
begin
|
|
157
|
+
app.run
|
|
158
|
+
ensure
|
|
159
|
+
app.shutdown
|
|
160
|
+
end
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## API Reference
|
|
164
|
+
|
|
165
|
+
### `Typr.init` / `Typr.exit`
|
|
166
|
+
Initialize and tear down the terminal UI. Always call these at the start and end of your program.
|
|
167
|
+
|
|
168
|
+
### `Typr.clear([scope])`
|
|
169
|
+
Clears the full screen or a single line (`:line`).
|
|
170
|
+
|
|
171
|
+
### `Typr.read(type)`
|
|
172
|
+
Reads input from the terminal. Types:
|
|
173
|
+
- `:key` — a single keypress (returns `KEY_ESCAPE`, `?q`, etc.)
|
|
174
|
+
- `:line` — a full line of text input
|
|
175
|
+
|
|
176
|
+
### Layout properties (all views)
|
|
177
|
+
- `top`, `bottom`, `left`, `right` — placement. Integers for absolute offsets, floats (0-1) for relative sizing. Negative values position from the opposite edge. (`bottom: -1` = last row)
|
|
178
|
+
|
|
179
|
+
### Grid options
|
|
180
|
+
| Option | Description |
|
|
181
|
+
|---|---|
|
|
182
|
+
| `input` | Array of arrays (data rows) |
|
|
183
|
+
| `header` | Column titles array |
|
|
184
|
+
| `format` | Per-column format: `:min`, `:max`, or a number for fixed width |
|
|
185
|
+
| `colors` | `{ columns: [:yellow, :cyan], header: [:white, :black] }` etc. |
|
|
186
|
+
| `sorted_by` | Column index the grid is sorted by (setter) |
|
|
187
|
+
| `filters` | Active filters array (getter) |
|
|
188
|
+
| `selected` | Selected row indices (getter/setter) |
|
|
189
|
+
| `.sort_by` | Sort the grid on a given column |
|
|
190
|
+
| `.select_rows / select_columns` | Multi-select via index picker |
|
|
191
|
+
|
|
192
|
+
### Text options
|
|
193
|
+
| Option | Description |
|
|
194
|
+
|---|---|
|
|
195
|
+
| `input` | String or IO-like stream to display |
|
|
196
|
+
| `header` | Header bar text |
|
|
197
|
+
| `border` | Border style: `:round`, `" "`, etc. |
|
|
198
|
+
|
|
199
|
+
### Browser options
|
|
200
|
+
| Option | Description |
|
|
201
|
+
|---|---|
|
|
202
|
+
| `directory` | Root directory to start browsing |
|
|
203
|
+
| `.pick(start_dir)` | Interactive file picker, returns the selected path |
|
|
204
|
+
|
|
205
|
+
## License
|
|
206
|
+
|
|
207
|
+
MIT
|
data/lib/terminal.rb
CHANGED
data/typr.gemspec
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
Gem::Specification.new do |s|
|
|
4
|
+
s.name = "typr"
|
|
5
|
+
s.version = "1.1.2"
|
|
6
|
+
s.date = "2026-07-25"
|
|
7
|
+
s.homepage = "https://codeberg.org/typr/typr"
|
|
8
|
+
s.licenses = ["MIT"]
|
|
9
|
+
s.require_paths = ["lib"]
|
|
10
|
+
s.authors = ["Kilian Reitmayr"]
|
|
11
|
+
s.summary = "Terminal UI Toolkit"
|
|
12
|
+
s.email = ["reitmayr@protonmail.com"]
|
|
13
|
+
s.files = Dir["lib/*.rb"] + ["LICENSE", "README.md", "CHANGELOG.md", "Gemfile", "typr.gemspec",
|
|
14
|
+
"example/grid", "example/browser", "example/text", "example/top500.csv", "share/mimetypes"]
|
|
15
|
+
s.required_ruby_version = Gem::Requirement.new(">= 3.1")
|
|
16
|
+
s.add_runtime_dependency("unicode-display_width", ["~> 3.1"])
|
|
17
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: typr
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.1.
|
|
4
|
+
version: 1.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kilian Reitmayr
|
|
@@ -31,6 +31,10 @@ executables: []
|
|
|
31
31
|
extensions: []
|
|
32
32
|
extra_rdoc_files: []
|
|
33
33
|
files:
|
|
34
|
+
- CHANGELOG.md
|
|
35
|
+
- Gemfile
|
|
36
|
+
- LICENSE
|
|
37
|
+
- README.md
|
|
34
38
|
- example/browser
|
|
35
39
|
- example/grid
|
|
36
40
|
- example/text
|
|
@@ -47,6 +51,7 @@ files:
|
|
|
47
51
|
- lib/text.rb
|
|
48
52
|
- lib/typr.rb
|
|
49
53
|
- share/mimetypes
|
|
54
|
+
- typr.gemspec
|
|
50
55
|
homepage: https://codeberg.org/typr/typr
|
|
51
56
|
licenses:
|
|
52
57
|
- MIT
|