hyperlist 1.9.0 → 1.9.1
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 +43 -0
- data/README.md +23 -11
- data/hyperlist +64 -13
- data/hyperlist.gemspec +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 485f51c3f998ca45514979e831f928a2ca907674483ba1ceef644ce6db22423e
|
|
4
|
+
data.tar.gz: ca21fe8db31f2b1ac1a1e8059c92f94dbc17a8d42790247238f8073c77ef973d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d40e130fbff4cb2564f8a9c541257cd084072f1917067d529a86427c63b0e3716b7a6704f584cf64dc3e204fd0c63a71a20443f3bcef99bc5377bb43c657b7f3
|
|
7
|
+
data.tar.gz: 5e6a7cdf9f8b2fb7e93382e41ba8d6e2e39d0403a0e64480d763d8385f5e4d7320684ea4b1fd7503d5a4ed08fe515d5176a04d8ab8723f9e43b7ab9d04a9e2b8
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,49 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to the HyperList Ruby TUI will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.9.1] - 2025-12-02
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **External file change detection**
|
|
9
|
+
- Automatically detects when the file is modified by other processes (vim, another Claude Code session, etc.)
|
|
10
|
+
- Prompts user to reload with "File changed externally. Reload? (y/n)"
|
|
11
|
+
- Preserves cursor position after reload
|
|
12
|
+
- Option to ignore external changes (updates internal timestamp to avoid repeated prompts)
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- **Quote coloring inside parentheses (comments)**
|
|
16
|
+
- Fixed issue where quotes inside parentheses like `(this is a "comment" in here)` would break the cyan coloring
|
|
17
|
+
- The closing quote would terminate coloring, leaving the rest of the comment white
|
|
18
|
+
- Now the entire parentheses content stays cyan as intended
|
|
19
|
+
|
|
20
|
+
## [1.9.0] - 2025-10-24
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
- **Item Tagging & Batch Operations**
|
|
24
|
+
- Tag items with 't' key for batch operations (auto-advance cursor)
|
|
25
|
+
- Visual feedback: dark blue background for tagged items, lighter blue for tagged+selected
|
|
26
|
+
- Status bar shows [T:N] count of tagged items
|
|
27
|
+
- Clear all tags with 'u' key
|
|
28
|
+
- Regex tagging with 'C-T' - tag all items matching a pattern
|
|
29
|
+
- Batch operations: D/C-D (delete), y/Y (yank), Tab/S-Tab (indent) work on all tagged items
|
|
30
|
+
|
|
31
|
+
- **External Editor Support**
|
|
32
|
+
- Press 'E' to spawn $EDITOR (vim, nano, etc.)
|
|
33
|
+
- Automatic save/reload workflow
|
|
34
|
+
- Proper terminal state management
|
|
35
|
+
- Full screen refresh on return
|
|
36
|
+
|
|
37
|
+
- **Enhanced Paste & Navigation**
|
|
38
|
+
- 'P' to paste above current item (vim-style)
|
|
39
|
+
- Presentation mode moved to 'C-P'
|
|
40
|
+
- Templates moved to 'T' key
|
|
41
|
+
- Undo moved to 'U' key (RTFM-consistent)
|
|
42
|
+
|
|
43
|
+
### Enhanced
|
|
44
|
+
- **Smart Modified Flag**
|
|
45
|
+
- [+] indicator removed when undoing back to original file state
|
|
46
|
+
- Tracks original state to detect true modifications
|
|
47
|
+
|
|
5
48
|
## [1.8.0] - 2025-09-22
|
|
6
49
|
|
|
7
50
|
### Enhanced
|
data/README.md
CHANGED
|
@@ -29,9 +29,21 @@ For historical context and the original VIM implementation, see: [hyperlist.vim]
|
|
|
29
29
|
### Help Screen
|
|
30
30
|

|
|
31
31
|
|
|
32
|
-
## What's New in v1.9.
|
|
32
|
+
## What's New in v1.9.1
|
|
33
33
|
|
|
34
|
-
###
|
|
34
|
+
### External File Change Detection
|
|
35
|
+
- **Auto-detect external changes**: HyperList now monitors when the file is modified by other processes (vim, another Claude Code session, etc.)
|
|
36
|
+
- **Reload prompt**: Shows "File changed externally. Reload? (y/n)" when changes are detected
|
|
37
|
+
- **Cursor preservation**: Your cursor position is preserved after reload
|
|
38
|
+
- **Skip option**: Press 'n' to ignore external changes and continue editing
|
|
39
|
+
|
|
40
|
+
### Bug Fix: Quote Coloring in Comments
|
|
41
|
+
- Fixed an issue where quotes inside parentheses (comments) like `(this is a "comment" in here)` would break the cyan coloring
|
|
42
|
+
- The entire parentheses content now stays cyan as intended
|
|
43
|
+
|
|
44
|
+
## Previous Release: v1.9.0
|
|
45
|
+
|
|
46
|
+
### Item Tagging & Batch Operations
|
|
35
47
|
- **Tag items**: Press 't' to tag/untag items for batch operations
|
|
36
48
|
- **Auto-advance**: Cursor automatically moves to next item after tagging for fast consecutive tagging
|
|
37
49
|
- **Visual feedback**: Tagged items show dark blue background, lighter blue when selected
|
|
@@ -41,47 +53,47 @@ For historical context and the original VIM implementation, see: [hyperlist.vim]
|
|
|
41
53
|
- **Batch operations**: Delete (D/C-D), yank (y/Y), and indent (Tab/S-Tab) work on all tagged items
|
|
42
54
|
- Tag consecutive or non-consecutive items, then perform operations on the entire set
|
|
43
55
|
|
|
44
|
-
###
|
|
56
|
+
### External Editor Support
|
|
45
57
|
- **Edit in $EDITOR**: Press 'E' to spawn your preferred editor (vim, nano, emacs, etc.)
|
|
46
58
|
- **Seamless workflow**: File saved automatically, editor launched, changes reloaded on exit
|
|
47
59
|
- **Terminal management**: Terminal state properly saved and restored
|
|
48
60
|
- Uses `$EDITOR` environment variable (defaults to vi if not set)
|
|
49
61
|
|
|
50
|
-
###
|
|
62
|
+
### Enhanced Paste & Navigation
|
|
51
63
|
- **Paste above**: Press 'P' to paste above current item (vim-style)
|
|
52
64
|
- **Paste below**: Press 'p' to paste below current item (existing)
|
|
53
65
|
- **Presentation mode**: Moved to 'C-P' (was 'P') for consistency
|
|
54
66
|
- **Templates**: Moved to 'T' key (was 't')
|
|
55
67
|
- **Undo**: Moved to 'U' key (was 'u') - consistent with RTFM
|
|
56
68
|
|
|
57
|
-
###
|
|
69
|
+
### Smart Modified Flag
|
|
58
70
|
- **Intelligent tracking**: `[+]` indicator automatically removed when undoing back to original file state
|
|
59
71
|
- **Clean status**: No false "modified" indicator after complete undo to original
|
|
60
72
|
|
|
61
73
|
## Previous Release: v1.8.0
|
|
62
74
|
|
|
63
|
-
###
|
|
75
|
+
### Multi-Line Paste Support
|
|
64
76
|
- **Paste multiple lines**: When pasting multi-line content into item insertion prompts ('o', 'O', 'a', 'A'), each line becomes a separate item
|
|
65
77
|
- **Visual feedback**: Shows `[+N lines]` indicator during multi-line paste
|
|
66
78
|
- **Smart insertion**: All pasted lines inserted as siblings at the same level
|
|
67
79
|
- Great for importing bullet lists from PDFs, emails, or other documents
|
|
68
80
|
- Requires rcurses 6.1.5+
|
|
69
81
|
|
|
70
|
-
###
|
|
82
|
+
### PDF/LaTeX Export
|
|
71
83
|
- **Export to PDF**: `:export pdf filename.pdf` - Full LaTeX-based PDF generation
|
|
72
84
|
- **Export to LaTeX**: `:export latex filename.tex` - Get the LaTeX source
|
|
73
85
|
- **Professional output**: Color-coded elements, table of contents, headers
|
|
74
86
|
- **Complete HyperList support**: All syntax elements rendered beautifully
|
|
75
87
|
- Requires: texlive-latex-base and texlive-latex-extra packages
|
|
76
88
|
|
|
77
|
-
###
|
|
89
|
+
### System Clipboard Integration
|
|
78
90
|
- **Yank to clipboard**: 'y' and 'Y' now copy to system clipboard
|
|
79
91
|
- **Middle-click paste**: Yanked items can be pasted into other terminals
|
|
80
92
|
- **Preserves indentation**: Copied text maintains proper structure
|
|
81
93
|
|
|
82
94
|
## Previous Version Features (v1.4.0)
|
|
83
95
|
|
|
84
|
-
###
|
|
96
|
+
### Configuration Lines & Theming
|
|
85
97
|
- **Configuration Lines**: Add settings at the bottom of HyperList files using `((option=value, option2=value))`
|
|
86
98
|
- **Theme Support**: Three color themes - `light` (bright colors), `normal` (standard), `dark` (for light terminals)
|
|
87
99
|
- **Line Wrapping**: Enable with `wrap=yes` - wrapped lines use `+` prefix per HyperList spec
|
|
@@ -142,13 +154,13 @@ All `:set` commands automatically update the file's configuration line.
|
|
|
142
154
|
- Secure AES-256-CBC encryption with PBKDF2 key derivation
|
|
143
155
|
- Password caching for the session
|
|
144
156
|
|
|
145
|
-
###
|
|
157
|
+
### Enhanced Presentation Mode
|
|
146
158
|
- **Auto-collapse** everything outside the current context
|
|
147
159
|
- **Smart focus**: Shows only current item, ancestors, and immediate children
|
|
148
160
|
- **Visual hierarchy**: Focused items in full color, others greyed out
|
|
149
161
|
- Improved navigation with proper cursor tracking
|
|
150
162
|
|
|
151
|
-
###
|
|
163
|
+
### Better Visual Experience
|
|
152
164
|
- **Improved highlighting**: Dark gray background preserves syntax colors
|
|
153
165
|
- **Subtle selection**: No more harsh reverse video
|
|
154
166
|
- **Preserved colors**: All HyperList elements maintain their colors when selected
|
data/hyperlist
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
# Check for help/version BEFORE loading any libraries
|
|
8
8
|
if ARGV[0] == '-h' || ARGV[0] == '--help'
|
|
9
9
|
puts <<~HELP
|
|
10
|
-
HyperList v1.9.
|
|
10
|
+
HyperList v1.9.1 - Terminal User Interface for HyperList files
|
|
11
11
|
|
|
12
12
|
USAGE
|
|
13
13
|
hyperlist [OPTIONS] [FILE]
|
|
@@ -52,7 +52,7 @@ if ARGV[0] == '-h' || ARGV[0] == '--help'
|
|
|
52
52
|
HELP
|
|
53
53
|
exit 0
|
|
54
54
|
elsif ARGV[0] == '-v' || ARGV[0] == '--version'
|
|
55
|
-
puts "HyperList v1.9.
|
|
55
|
+
puts "HyperList v1.9.1"
|
|
56
56
|
exit 0
|
|
57
57
|
end
|
|
58
58
|
|
|
@@ -73,7 +73,7 @@ class HyperListApp
|
|
|
73
73
|
include Rcurses::Input
|
|
74
74
|
include Rcurses::Cursor
|
|
75
75
|
|
|
76
|
-
VERSION = "1.9.
|
|
76
|
+
VERSION = "1.9.1"
|
|
77
77
|
|
|
78
78
|
def initialize(filename = nil)
|
|
79
79
|
@filename = filename ? File.expand_path(filename) : nil
|
|
@@ -124,7 +124,8 @@ class HyperListApp
|
|
|
124
124
|
@split_offset = 0 # Second view scroll offset
|
|
125
125
|
@active_pane = :main # :main or :split
|
|
126
126
|
@message_timeout = nil # For timed message display
|
|
127
|
-
|
|
127
|
+
@file_mtime = nil # Track file modification time for external change detection
|
|
128
|
+
|
|
128
129
|
# Global configuration
|
|
129
130
|
@config_file = File.expand_path("~/.hyperlist/config.yml")
|
|
130
131
|
@indent_size = 2 # Default indentation (2-5 spaces)
|
|
@@ -228,6 +229,9 @@ class HyperListApp
|
|
|
228
229
|
@config_line = nil # Reset config line before loading
|
|
229
230
|
@tagged_items = [] # Clear tags when loading new file
|
|
230
231
|
|
|
232
|
+
# Track file modification time for external change detection
|
|
233
|
+
@file_mtime = File.mtime(file) rescue nil
|
|
234
|
+
|
|
231
235
|
# Read file content
|
|
232
236
|
content = File.read(file) rescue ""
|
|
233
237
|
|
|
@@ -527,12 +531,48 @@ class HyperListApp
|
|
|
527
531
|
def load_command_history
|
|
528
532
|
history_file = File.expand_path("~/.hyperlist_command_history")
|
|
529
533
|
return [] unless File.exist?(history_file)
|
|
530
|
-
|
|
534
|
+
|
|
531
535
|
File.readlines(history_file).map(&:strip).reject(&:empty?).last(100)
|
|
532
536
|
rescue
|
|
533
537
|
[]
|
|
534
538
|
end
|
|
535
|
-
|
|
539
|
+
|
|
540
|
+
# Check if file was modified externally and prompt for reload
|
|
541
|
+
def check_file_changed
|
|
542
|
+
return unless @filename && File.exist?(@filename) && @file_mtime
|
|
543
|
+
|
|
544
|
+
current_mtime = File.mtime(@filename) rescue nil
|
|
545
|
+
return unless current_mtime && current_mtime > @file_mtime
|
|
546
|
+
|
|
547
|
+
# File changed externally - prompt user
|
|
548
|
+
@footer.text = "File changed externally. Reload? (y/n): "
|
|
549
|
+
@footer.refresh
|
|
550
|
+
|
|
551
|
+
response = getchr
|
|
552
|
+
if response&.downcase == 'y'
|
|
553
|
+
# Save cursor position
|
|
554
|
+
saved_current = @current
|
|
555
|
+
saved_offset = @offset
|
|
556
|
+
|
|
557
|
+
load_file(@filename)
|
|
558
|
+
|
|
559
|
+
# Restore cursor position (clamped to new file size)
|
|
560
|
+
visible = get_visible_items
|
|
561
|
+
@current = [saved_current, visible.length - 1, 0].max
|
|
562
|
+
@current = [@current, visible.length - 1].min if visible.length > 0
|
|
563
|
+
@offset = saved_offset
|
|
564
|
+
|
|
565
|
+
@message = "File reloaded"
|
|
566
|
+
@modified = false
|
|
567
|
+
clear_cache
|
|
568
|
+
render
|
|
569
|
+
else
|
|
570
|
+
# Update mtime to avoid repeated prompts
|
|
571
|
+
@file_mtime = current_mtime
|
|
572
|
+
@message = "External changes ignored"
|
|
573
|
+
end
|
|
574
|
+
end
|
|
575
|
+
|
|
536
576
|
def save_command_history
|
|
537
577
|
history_file = File.expand_path("~/.hyperlist_command_history")
|
|
538
578
|
File.open(history_file, 'w') do |f|
|
|
@@ -712,6 +752,7 @@ class HyperListApp
|
|
|
712
752
|
@modified = false
|
|
713
753
|
@original_items = @items.map { |item| item.dup } # Save state after save
|
|
714
754
|
@last_auto_save = Time.now if @auto_save_enabled
|
|
755
|
+
@file_mtime = File.mtime(@filename) rescue nil # Update mtime after save
|
|
715
756
|
end
|
|
716
757
|
|
|
717
758
|
def check_auto_save
|
|
@@ -1606,9 +1647,10 @@ class HyperListApp
|
|
|
1606
1647
|
|
|
1607
1648
|
# Handle parentheses content (moved here to avoid conflicts with properties)
|
|
1608
1649
|
# Based on hyperlist.vim: '(.\{-})'
|
|
1650
|
+
# Color entire parentheses content as cyan - quotes inside are also cyan
|
|
1609
1651
|
result = safe_regex_replace(result, /\(([^)]*)\)/) do |match|
|
|
1610
|
-
|
|
1611
|
-
|
|
1652
|
+
# Just color the whole thing cyan - no special handling for quotes inside
|
|
1653
|
+
match.fg(colors["cyan"])
|
|
1612
1654
|
end
|
|
1613
1655
|
|
|
1614
1656
|
# Handle semicolons as separators (they separate items on the same line)
|
|
@@ -1624,11 +1666,17 @@ class HyperListApp
|
|
|
1624
1666
|
|
|
1625
1667
|
# Handle quoted strings (only double quotes are special in HyperList)
|
|
1626
1668
|
# Based on hyperlist.vim: '".\{-}"'
|
|
1627
|
-
|
|
1628
|
-
|
|
1669
|
+
# Use safe_regex_replace to avoid processing quotes inside already-colored parentheses
|
|
1670
|
+
result = safe_regex_replace(result, /"([^"]*)"/) do |match|
|
|
1671
|
+
content = match[1..-2] # Extract content between quotes
|
|
1629
1672
|
# Color any ## sequences inside the quotes as red
|
|
1630
|
-
content.gsub
|
|
1631
|
-
|
|
1673
|
+
colored_content = content.gsub(/(##[<>-]+)/) { $1.fg(colors["red"]) }
|
|
1674
|
+
# If no ## sequences were found, just color the whole thing cyan
|
|
1675
|
+
if colored_content == content
|
|
1676
|
+
match.fg(colors["cyan"]) # Color entire quoted string cyan
|
|
1677
|
+
else
|
|
1678
|
+
'"'.fg(colors["cyan"]) + colored_content + '"'.fg(colors["cyan"])
|
|
1679
|
+
end
|
|
1632
1680
|
end
|
|
1633
1681
|
|
|
1634
1682
|
# Handle change markup - all double-hashes should be red
|
|
@@ -6397,7 +6445,10 @@ class HyperListApp
|
|
|
6397
6445
|
loop do
|
|
6398
6446
|
# Check for auto-save
|
|
6399
6447
|
check_auto_save if @auto_save_enabled
|
|
6400
|
-
|
|
6448
|
+
|
|
6449
|
+
# Check for external file changes
|
|
6450
|
+
check_file_changed
|
|
6451
|
+
|
|
6401
6452
|
c = getchr
|
|
6402
6453
|
|
|
6403
6454
|
# Skip nil input (shouldn't happen normally)
|
data/hyperlist.gemspec
CHANGED
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.9.
|
|
4
|
+
version: 1.9.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Geir Isene
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: "."
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-12-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rcurses
|