hyperlist 1.4.3 → 1.4.5

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: 735c8dad200fdf5f2ac019def34b0b9f11eed7df0c49f962385bc723b0263cf4
4
- data.tar.gz: db4f459832acaa5d04509d070797aae448062cd507810666a743c1194e61fd32
3
+ metadata.gz: 0b5da858aef9693451d436d48156170ebebfffa6f9ff08bf6fb71848bca3970e
4
+ data.tar.gz: f4f82de4e9d76bf55611628f9a9031d2e4eccf0625536964e6615423fc3a43cb
5
5
  SHA512:
6
- metadata.gz: fb8aa40308aad944488acfcaf2c1319fa65dfed27ce2135d74384b240deb8b2f3fd327def196206f501f134995dd17affae874e6800bb42a440789b9610bc588
7
- data.tar.gz: 88e64082e113bdb8f38ae69f6579fdb4711a62c6699bd7f58ded56a08d32e52367e00062e41b1ecf0d6c80742d2467f833ef05d42fe476f816e1aaa83d8a697b
6
+ metadata.gz: f828786e61e63348ace5b6684afc23a8b8b4630a05c8ba73381907d5b6f874b9b2438e5bdb393944503e01b4e07f336e74a4c385dd803569ced68bacd2a35192
7
+ data.tar.gz: d7e22aa25b76906372edf1d80fa88dd73778fd25de5e4b0ae88b80ac77cd7b6a7a10e6eaf178c205805bd00608eecdfe89fa2833e80e410de01bb9461527a6d3
data/CHANGELOG.md CHANGED
@@ -2,6 +2,36 @@
2
2
 
3
3
  All notable changes to the HyperList Ruby TUI will be documented in this file.
4
4
 
5
+ ## [1.4.5] - 2025-09-02
6
+
7
+ ### Added
8
+ - **Terminal resize handling**
9
+ - Implemented Signal.trap('WINCH') to catch terminal resize events
10
+ - Application now properly adapts when terminal window is resized
11
+ - UI components (panes) automatically adjust to new dimensions
12
+ - Follows same pattern as RTFM for robust resize handling
13
+
14
+ ## [1.4.4] - 2025-09-01
15
+
16
+ ### Added
17
+ - **Case conversion commands**
18
+ - `gU` to convert current line to UPPERCASE
19
+ - `gu` to convert current line to lowercase
20
+ - Works with all HyperList elements (checkboxes, operators, etc.)
21
+
22
+ ### Fixed
23
+ - **Color code display issues**
24
+ - Fixed bracket content extraction in safe_regex_replace to preserve qualifier text
25
+ - Updated operator regex pattern to match after ANSI placeholders
26
+ - Both numbered lists (1.) and operators (NOT:) now color correctly when combined
27
+
28
+ ## [1.4.3] - 2025-08-30
29
+
30
+ ### Fixed
31
+ - **Multi-line item handling**
32
+ - Proper handling of multi-line items per HyperList specification
33
+ - Fixed display and editing of items with embedded newlines
34
+
5
35
  ## [1.4.2] - 2025-08-29
6
36
 
7
37
  ### Fixed
data/README.md CHANGED
@@ -29,7 +29,19 @@ For historical context and the original VIM implementation, see: [hyperlist.vim]
29
29
  ### Help Screen
30
30
  ![HyperList Help](img/screenshot_help.png)
31
31
 
32
- ## What's New in v1.4.0
32
+ ## What's New in v1.4.4
33
+
34
+ ### 🔧 Case Conversion Commands
35
+ - **`gU`**: Convert current line to UPPERCASE
36
+ - **`gu`**: Convert current line to lowercase
37
+ - Works with all HyperList elements (checkboxes, operators, etc.)
38
+
39
+ ### 🐛 Bug Fixes
40
+ - Fixed color code display issues with numbered lists and operators
41
+ - Improved handling of qualifiers like `[? conditional]`
42
+ - Better coloring when combining numbered lists with operators (e.g., `1. NOT: item`)
43
+
44
+ ## Previous Version Features (v1.4.0)
33
45
 
34
46
  ### 🎨 Configuration Lines & Theming
35
47
  - **Configuration Lines**: Add settings at the bottom of HyperList files using `((option=value, option2=value))`
data/hyperlist CHANGED
@@ -72,7 +72,7 @@ class HyperListApp
72
72
  include Rcurses::Input
73
73
  include Rcurses::Cursor
74
74
 
75
- VERSION = "1.4.3"
75
+ VERSION = "1.4.5"
76
76
 
77
77
  def initialize(filename = nil)
78
78
  @filename = filename ? File.expand_path(filename) : nil
@@ -138,6 +138,9 @@ class HyperListApp
138
138
  # Debug: uncomment to see terminal size
139
139
  # puts "Terminal size: #{@rows}x#{@cols}"
140
140
 
141
+ # Setup terminal resize handler
142
+ setup_resize_handler
143
+
141
144
  # Setup UI first (to initialize @footer) before loading file
142
145
  setup_ui
143
146
 
@@ -194,6 +197,33 @@ class HyperListApp
194
197
  end
195
198
  end
196
199
 
200
+ def setup_resize_handler
201
+ # Catch terminal resize signal
202
+ Signal.trap('WINCH') do
203
+ refresh_on_resize
204
+ end
205
+ rescue
206
+ # Ignore if signal handling not available on this platform
207
+ end
208
+
209
+ def refresh_on_resize
210
+ # Get new terminal dimensions
211
+ if IO.console
212
+ @rows, @cols = IO.console.winsize
213
+ else
214
+ @rows = ENV['LINES']&.to_i || 24
215
+ @cols = ENV['COLUMNS']&.to_i || 80
216
+ end
217
+
218
+ # Reinitialize UI with new dimensions
219
+ setup_ui
220
+
221
+ # Force full redraw
222
+ render
223
+ rescue
224
+ # Ignore errors during resize to prevent crashes
225
+ end
226
+
197
227
  def load_file(file)
198
228
  @items = []
199
229
  @encrypted_lines = {}
@@ -1337,7 +1367,10 @@ class HyperListApp
1337
1367
  elsif !processed_checkbox
1338
1368
  # Only handle other qualifiers if we didn't process a checkbox
1339
1369
  # Based on hyperlist.vim: '\[.\{-}\]'
1340
- result.gsub!(/\[([^\]]*)\]/) { "[#{$1}]".fg(colors["green"]) } # Green for all qualifiers
1370
+ result = safe_regex_replace(result, /\[([^\]]*)\]/) do |match|
1371
+ content = match[1..-2] # Extract content between brackets
1372
+ "[#{content}]".fg(colors["green"]) # Green for all qualifiers
1373
+ end
1341
1374
  end
1342
1375
 
1343
1376
  # We'll handle parentheses AFTER operators/properties to avoid conflicts
@@ -1351,21 +1384,27 @@ class HyperListApp
1351
1384
  # Handle operators and properties with colon pattern
1352
1385
  # Operators: ALL-CAPS followed by colon (with or without space)
1353
1386
  # Properties: Mixed case followed by colon and space
1354
- result.gsub!(/(\A|\s+)([a-zA-Z][a-zA-Z0-9_\-() .\/=]*):(\s*)/) do
1355
- prefix_space = $1
1356
- text_part = $2
1357
- space_after = $3 || ""
1358
- colon_space = ":#{space_after}"
1359
-
1360
- # Check if it's an operator (ALL-CAPS with optional _, -, (), /, =, spaces)
1361
- if text_part =~ /^[A-Z][A-Z_\-() \/=]*$/
1362
- prefix_space + text_part.fg(colors["blue"]) + colon_space.fg(colors["blue"]) # Blue for operators (including S: and T:)
1363
- elsif text_part.length >= 2 && space_after.include?(" ")
1364
- # It's a property (mixed case, at least 2 chars, has space after colon)
1365
- prefix_space + text_part.fg(colors["red"]) + colon_space.fg(colors["red"]) # Red for properties
1387
+ # Modified pattern to also match after ANSI placeholders (⟨ANSI\d+⟩)
1388
+ result = safe_regex_replace(result, /(\A|\s+|⟨ANSI\d+⟩)([a-zA-Z][a-zA-Z0-9_\-() .\/=]*):(\s*)/) do |match|
1389
+ # Extract parts from the match
1390
+ if match =~ /(\A|\s+|⟨ANSI\d+⟩)([a-zA-Z][a-zA-Z0-9_\-() .\/=]*):(\s*)/
1391
+ prefix_space = $1
1392
+ text_part = $2
1393
+ space_after = $3 || ""
1394
+ colon_space = ":#{space_after}"
1395
+
1396
+ # Check if it's an operator (ALL-CAPS with optional _, -, (), /, =, spaces)
1397
+ if text_part =~ /^[A-Z][A-Z_\-() \/=]*$/
1398
+ prefix_space + text_part.fg(colors["blue"]) + colon_space.fg(colors["blue"]) # Blue for operators (including S: and T:)
1399
+ elsif text_part.length >= 2 && space_after.include?(" ")
1400
+ # It's a property (mixed case, at least 2 chars, has space after colon)
1401
+ prefix_space + text_part.fg(colors["red"]) + colon_space.fg(colors["red"]) # Red for properties
1402
+ else
1403
+ # Leave as is
1404
+ match
1405
+ end
1366
1406
  else
1367
- # Leave as is
1368
- prefix_space + text_part + colon_space
1407
+ match
1369
1408
  end
1370
1409
  end
1371
1410
 
@@ -2334,6 +2373,34 @@ class HyperListApp
2334
2373
  clear_cache # Clear cache when content changes
2335
2374
  end
2336
2375
 
2376
+ def uppercase_line
2377
+ visible = get_visible_items
2378
+ return if @current >= visible.length
2379
+
2380
+ item = visible[@current]
2381
+ real_idx = get_real_index(item)
2382
+
2383
+ save_undo_state # Save state before modification
2384
+ @items[real_idx]["text"] = item["text"].upcase
2385
+ @modified = true
2386
+ clear_cache # Clear cache when content changes
2387
+ @message = "Line converted to uppercase"
2388
+ end
2389
+
2390
+ def lowercase_line
2391
+ visible = get_visible_items
2392
+ return if @current >= visible.length
2393
+
2394
+ item = visible[@current]
2395
+ real_idx = get_real_index(item)
2396
+
2397
+ save_undo_state # Save state before modification
2398
+ @items[real_idx]["text"] = item["text"].downcase
2399
+ @modified = true
2400
+ clear_cache # Clear cache when content changes
2401
+ @message = "Line converted to lowercase"
2402
+ end
2403
+
2337
2404
  def delete_line(with_children = false)
2338
2405
  visible = get_visible_items
2339
2406
  return if visible.empty?
@@ -2883,6 +2950,7 @@ class HyperListApp
2883
2950
  help_lines << help_line("#{"i/Enter".fg("10")}", "Edit line", "#{"o".fg("10")}", "Insert line below")
2884
2951
  help_lines << help_line("#{"O".fg("10")}", "Insert line above", "#{"a".fg("10")}", "Insert child")
2885
2952
  help_lines << help_line("#{"A".fg("10")}", "Insert outdented", "#{"W".fg("10")}", "Save and quit")
2953
+ help_lines << help_line("#{"gU".fg("10")}", "Uppercase line", "#{"gu".fg("10")}", "Lowercase line")
2886
2954
  help_lines << help_line("#{"I".fg("10")}", "Cycle indent (2-5)")
2887
2955
  help_lines << help_line("#{"D".fg("10")}", "Delete+yank line", "#{"C-D".fg("10")}", "Delete+yank item&descendants")
2888
2956
  help_lines << help_line("#{"y".fg("10")}" + "/".fg("10") + "#{"Y".fg("10")}", "Copy line/tree", "#{"p".fg("10")}", "Paste")
@@ -5613,13 +5681,21 @@ class HyperListApp
5613
5681
  @current = [visible.length - 1, 0].max
5614
5682
  update_presentation_focus if @presentation_mode
5615
5683
  end
5616
- when "g" # Go to top (was gg)
5617
- if @split_view && @active_pane == :split
5618
- @split_current = 0
5619
- else
5620
- @current = 0
5621
- @offset = 0
5622
- update_presentation_focus if @presentation_mode
5684
+ when "g" # Go to top (gg) or text case commands (gU/gu)
5685
+ next_c = getchr
5686
+ case next_c
5687
+ when "g" # gg - go to top
5688
+ if @split_view && @active_pane == :split
5689
+ @split_current = 0
5690
+ else
5691
+ @current = 0
5692
+ @offset = 0
5693
+ update_presentation_focus if @presentation_mode
5694
+ end
5695
+ when "U" # gU - uppercase line
5696
+ uppercase_line
5697
+ when "u" # gu - lowercase line
5698
+ lowercase_line
5623
5699
  end
5624
5700
  when "G" # Go to bottom
5625
5701
  if @split_view && @active_pane == :split
data/hyperlist.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "hyperlist"
3
- spec.version = "1.4.3"
3
+ spec.version = "1.4.5"
4
4
  spec.authors = ["Geir Isene"]
5
5
  spec.email = ["g@isene.com"]
6
6
 
data/test_resize.hl ADDED
@@ -0,0 +1,16 @@
1
+ Test HyperList for Terminal Resize
2
+ This is a test file
3
+ To verify terminal resize works
4
+ When you resize the terminal
5
+ The display should update correctly
6
+ Items to check:
7
+ Main content area adjusts
8
+ Footer stays at bottom
9
+ Split view (if active) rebalances
10
+ No visual corruption
11
+ Test scenarios:
12
+ Make terminal wider
13
+ Make terminal narrower
14
+ Make terminal taller
15
+ Make terminal shorter
16
+ Quick multiple resizes
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hyperlist
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.3
4
+ version: 1.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Geir Isene
8
8
  autorequire:
9
9
  bindir: "."
10
10
  cert_chain: []
11
- date: 2025-08-30 00:00:00.000000000 Z
11
+ date: 2025-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rcurses
@@ -79,7 +79,7 @@ files:
79
79
  - img/screenshot_help.png
80
80
  - img/screenshot_sample.png
81
81
  - sample.hl
82
- - test.hl
82
+ - test_resize.hl
83
83
  homepage: https://github.com/isene/HyperList
84
84
  licenses:
85
85
  - Unlicense
data/test.hl DELETED
@@ -1,154 +0,0 @@
1
- HyperList Ruby TUI Test Suite v1.0
2
- About This Test Suite
3
- Purpose: Test all features of the HyperList Ruby TUI application
4
- Run with: ./hyperlist test.hl
5
- Navigate through and test each feature systematically
6
- SYNTAX HIGHLIGHTING & COLORS
7
- Check: Property in red; Dates like 2025-08-12 should be red
8
- AND: OR: IF: THEN: Operators should appear in blue
9
- [?] Conditional checkboxes should be green
10
- #hashtags should appear in yellow/orange
11
- <references> should appear in magenta
12
- (parentheses content) should be in cyan
13
- "quoted strings" should be in bright cyan
14
- *bold text* should appear bold
15
- /italic text/ should appear italic
16
- _underlined text_ should appear underlined
17
- Templates with = markers for filling
18
- NAVIGATION TESTS
19
- Basic Movement
20
- j/↓ Move down through items
21
- k/↑ Move up through items
22
- h Go to parent item (move cursor here and press h)
23
- l Go to first child (press l from parent)
24
- g/Home Go to top of document
25
- G/End Go to bottom of document
26
- PgUp/PgDn Page up and down
27
- Search
28
- Slash key: Search for text (try searching for "test")
29
- n Jump to next search match
30
- Marks and Jumps
31
- ma Set mark 'a' at current position
32
- 'a Jump back to mark 'a'
33
- '' Jump to previous position
34
- R Jump to reference (place cursor on <NAVIGATION TESTS> and press R)
35
- Template Navigation
36
- First template =
37
- Second template =
38
- Third template =
39
- Press N to jump to next template marker and edit
40
- FOLDING TESTS
41
- Space Toggle fold on this item
42
- This child should hide/show when parent is folded
43
- And this grandchild too
44
- Even deeper nesting works
45
- za Toggle all folds recursively
46
- zo Open fold / zc Close fold
47
- zR Open all folds / zM Close all folds
48
- 1-9 Expand to specific level (try pressing 2)
49
- Level 2 item
50
- Level 3 item
51
- Level 4 item
52
- Level 5 item
53
- 0 Multi-digit fold level (press 0 then 1 then 2 for level 12)
54
- EDITING TESTS
55
- Basic Editing
56
- i/Enter Edit current line
57
- o Insert new line below
58
- O Insert new line above
59
- a Insert child item
60
- Delete Operations
61
- D Delete and yank current line only
62
- C-D Delete and yank item with all descendants
63
- Copy/Paste
64
- y Copy current line only
65
- Y Copy item with descendants
66
- p Paste yanked content
67
- Undo/Redo
68
- u Undo last change
69
- r/C-R Redo undone change
70
- . Repeat last action
71
- Moving Items
72
- S-UP/S-DOWN Move single item up/down
73
- C-UP/C-DOWN Move item with descendants up/down
74
- Indentation
75
- Tab Indent item and children
76
- S-Tab Unindent item and children
77
- → Indent item only
78
- ← Unindent item only
79
- CHECKBOX TESTS
80
- [ ] Press v to add/toggle checkbox
81
- [X] Completed checkbox (green)
82
- [O] In progress checkbox (bright green bold)
83
- [-] Partial checkbox (dim green)
84
- [?] Conditional checkbox (green)
85
- [3] Numbered checkbox
86
- [2025-08-12 14:30] Date checkbox
87
- Press V to toggle with timestamp
88
- SPECIAL FEATURES
89
- Presentation Mode
90
- Press P to enter presentation mode
91
- Current item and ancestors shown, rest hidden
92
- Press P again to exit
93
- Underline Toggle
94
- \u Toggle underlining of state/transition items
95
- S: State items (descriptive)
96
- T: Transition items (actions)
97
- File Operations
98
- F Open file reference (place cursor on file path)
99
- <sample.hl> Try opening this reference with F
100
- FILE COMMANDS
101
- :w Save file
102
- :q Quit (asks to save if modified)
103
- :wq Save and quit
104
- Q Force quit without saving
105
- :e filename Open another file
106
- :recent Show recent files
107
- :export md Export to Markdown
108
- :export html Export to HTML
109
- :export txt Export to plain text
110
- :graph Generate PNG graph visualization
111
- :vsplit Split view vertically
112
- ww Switch between split panes
113
- :as on Enable autosave
114
- :as off Disable autosave
115
- :as 30 Set autosave interval to 30 seconds
116
- ADVANCED TESTS
117
- Complex Nesting
118
- Parent 1
119
- Child 1.1
120
- Grandchild 1.1.1
121
- Great-grandchild 1.1.1.1
122
- Great-great-grandchild 1.1.1.1.1
123
- Child 1.2
124
- Grandchild 1.2.1
125
- Grandchild 1.2.2
126
- Parent 2
127
- Child 2.1
128
- Child 2.2
129
- Mixed Formatting
130
- Item with *bold* and /italic/ and _underline_
131
- Item with #multiple #hash #tags
132
- Item with <reference> and (parentheses) and "quotes"
133
- AND: Operator with [X] checkbox and 2025-08-12: date
134
- Long Lines
135
- This is a very long line that should wrap properly in the terminal display and maintain proper indentation when it continues on the next visual line without breaking the hierarchical structure of the HyperList
136
- Special Characters
137
- Item with special chars: @#$%^&*(){}[]|\\:;"'<>,.?/
138
- Unicode: ★ ☆ ♠ ♣ ♥ ♦ → ← ↑ ↓
139
- Emojis: 😀 🎉 ✓ ✗ ⚠️ 📝
140
- HELP SYSTEM
141
- ? Show help screen with key bindings
142
- ?? Show full documentation
143
- Use UP/DOWN to scroll through help
144
- Press any other key to exit help
145
- TEST COMPLETION
146
- [ ] All syntax highlighting verified
147
- [ ] All navigation features tested
148
- [ ] All folding operations work
149
- [ ] All editing functions tested
150
- [ ] Checkboxes functioning correctly
151
- [ ] Special features operational
152
- [ ] File commands working
153
- [ ] Help system accessible
154
- If all tests pass, the Ruby HyperList TUI is working correctly!