hyperlist 1.6.0 → 1.7.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 +19 -0
- data/hyperlist +246 -121
- 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: 014e81876165c457903e5f20e8f848f2c59fce0d2672e700ff909873c03c260a
|
4
|
+
data.tar.gz: c60b73c642984f70ba2bfdcceb7ca6a9bc501c46071cb362d9e9343778cd8f40
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 37ba0da349a30af46424cc374ece24e315c32a22ee48bf81f4893c43e20cdf18f42ec71c3b3fe123688f9b97597a29e8aa583884cceb361d44583645546aaf25
|
7
|
+
data.tar.gz: 5a8737705ad4d231e6ce1a8a1b8f440cf8b0f3c2ffa7586052dc64be5a55d8bc4491ed721b07adb192e6674f0560a9ac35a6a067ed27831b200066b786456081
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,25 @@
|
|
2
2
|
|
3
3
|
All notable changes to the HyperList Ruby TUI will be documented in this file.
|
4
4
|
|
5
|
+
## [1.7.0] - 2025-09-18
|
6
|
+
|
7
|
+
### Added
|
8
|
+
- **Checkbox removal feature**
|
9
|
+
- **C-X key**: Remove checkboxes from items
|
10
|
+
- Removes all checkbox patterns: `[ ]`, `[X]`, `[x]`, `[O]`, `[-]`, `[_]`
|
11
|
+
- Also removes associated timestamps (YYYY-MM-DD HH.MM: format)
|
12
|
+
- Provides feedback messages for successful removal or no checkbox found
|
13
|
+
- Added to help documentation under SPECIAL FEATURES
|
14
|
+
- Complements existing v/V checkbox toggle functionality
|
15
|
+
|
16
|
+
### Enhanced
|
17
|
+
- **Cross-parent movement improvements**
|
18
|
+
- C-UP/C-DOWN now respect visibility principle (move only item if uncollapsed, item+children if collapsed)
|
19
|
+
- Added orphaned children reunification logic
|
20
|
+
- Items moved into collapsed areas automatically unfold destination
|
21
|
+
- Moved items are guaranteed to remain visible (safety net protection)
|
22
|
+
- Single-step movement: C-DOWN moves exactly one position down, not to end of descendants
|
23
|
+
|
5
24
|
## [1.6.0] - 2025-09-18
|
6
25
|
|
7
26
|
### BREAKING CHANGES
|
data/hyperlist
CHANGED
@@ -72,7 +72,7 @@ class HyperListApp
|
|
72
72
|
include Rcurses::Input
|
73
73
|
include Rcurses::Cursor
|
74
74
|
|
75
|
-
VERSION = "1.
|
75
|
+
VERSION = "1.7.0"
|
76
76
|
|
77
77
|
def initialize(filename = nil)
|
78
78
|
@filename = filename ? File.expand_path(filename) : nil
|
@@ -2632,26 +2632,132 @@ class HyperListApp
|
|
2632
2632
|
@message = "Pasted #{@clipboard.length} item(s)"
|
2633
2633
|
record_last_action(:paste, nil)
|
2634
2634
|
end
|
2635
|
-
|
2635
|
+
|
2636
|
+
def calculate_level_for_position(target_real_idx)
|
2637
|
+
# Calculate appropriate level for an item at target_real_idx position
|
2638
|
+
# based on surrounding items in the @items array
|
2639
|
+
|
2640
|
+
# If at the beginning, level 0
|
2641
|
+
return 0 if target_real_idx == 0
|
2642
|
+
|
2643
|
+
# Look at the previous item
|
2644
|
+
prev_item = @items[target_real_idx - 1]
|
2645
|
+
prev_level = prev_item["level"]
|
2646
|
+
|
2647
|
+
# Look at the next item if it exists
|
2648
|
+
if target_real_idx < @items.length
|
2649
|
+
next_item = @items[target_real_idx]
|
2650
|
+
next_level = next_item["level"]
|
2651
|
+
|
2652
|
+
# If next item is at same or lower level than previous,
|
2653
|
+
# we can be at the same level as previous (sibling)
|
2654
|
+
if next_level <= prev_level
|
2655
|
+
return prev_level
|
2656
|
+
else
|
2657
|
+
# Next item is deeper, so we could be parent (prev_level)
|
2658
|
+
# or child (prev_level + 1), choose to be sibling of previous
|
2659
|
+
return prev_level
|
2660
|
+
end
|
2661
|
+
else
|
2662
|
+
# At the end, can be sibling of previous item
|
2663
|
+
return prev_level
|
2664
|
+
end
|
2665
|
+
end
|
2666
|
+
|
2667
|
+
def find_orphaned_children(item_text, target_real_idx)
|
2668
|
+
# Look for children that might belong to the item being moved
|
2669
|
+
orphaned_children = []
|
2670
|
+
|
2671
|
+
# Search from target position onwards for potential children
|
2672
|
+
# Look for items at level 2 or higher that could be children
|
2673
|
+
(target_real_idx...@items.length).each do |i|
|
2674
|
+
item_level = @items[i]["level"]
|
2675
|
+
|
2676
|
+
# Stop if we hit an item at level 0 or 1 (new parent/sibling)
|
2677
|
+
break if item_level <= 1
|
2678
|
+
|
2679
|
+
# If we find items at level 2+, they could be orphaned children
|
2680
|
+
# (In the example: Subtask A1.1, A1.2 are level 2)
|
2681
|
+
if item_level >= 2
|
2682
|
+
orphaned_children << i
|
2683
|
+
else
|
2684
|
+
break # Hit a sibling, stop looking
|
2685
|
+
end
|
2686
|
+
end
|
2687
|
+
|
2688
|
+
orphaned_children
|
2689
|
+
end
|
2690
|
+
|
2691
|
+
def ensure_destination_visible(target_real_idx, item_level)
|
2692
|
+
# Unfold any collapsed areas that would hide an item at target_real_idx with item_level
|
2693
|
+
return if target_real_idx >= @items.length || target_real_idx < 0
|
2694
|
+
|
2695
|
+
# Walk backwards from the target position to find potential ancestor items
|
2696
|
+
(target_real_idx - 1).downto(0) do |i|
|
2697
|
+
item = @items[i]
|
2698
|
+
|
2699
|
+
# If this item is at a higher level (lower number) than our item will be, it's a potential ancestor
|
2700
|
+
if item["level"] < item_level
|
2701
|
+
# If this ancestor is folded, unfold it to make the destination visible
|
2702
|
+
if item["fold"] && has_children?(i, @items)
|
2703
|
+
item["fold"] = false
|
2704
|
+
end
|
2705
|
+
|
2706
|
+
# Update item_level to continue searching for higher ancestors
|
2707
|
+
item_level = item["level"]
|
2708
|
+
|
2709
|
+
# If we reach level 0, we're done
|
2710
|
+
break if item_level == 0
|
2711
|
+
end
|
2712
|
+
end
|
2713
|
+
end
|
2714
|
+
|
2715
|
+
def force_item_visible(target_real_idx)
|
2716
|
+
# Absolutely ensure the item at target_real_idx is visible - last resort safety net
|
2717
|
+
return if target_real_idx >= @items.length || target_real_idx < 0
|
2718
|
+
|
2719
|
+
target_item = @items[target_real_idx]
|
2720
|
+
target_level = target_item["level"]
|
2721
|
+
|
2722
|
+
# Walk backwards and unfold ALL ancestors, no matter what
|
2723
|
+
(target_real_idx - 1).downto(0) do |i|
|
2724
|
+
item = @items[i]
|
2725
|
+
|
2726
|
+
# If this item could be an ancestor (higher in hierarchy)
|
2727
|
+
if item["level"] < target_level
|
2728
|
+
# Force unfold it, regardless of whether it has children
|
2729
|
+
item["fold"] = false if item.has_key?("fold")
|
2730
|
+
|
2731
|
+
# Update target_level to continue searching
|
2732
|
+
target_level = item["level"]
|
2733
|
+
|
2734
|
+
# Continue until we reach level 0
|
2735
|
+
break if target_level == 0
|
2736
|
+
end
|
2737
|
+
end
|
2738
|
+
|
2739
|
+
# Force a cache clear to ensure visibility updates
|
2740
|
+
clear_cache if respond_to?(:clear_cache)
|
2741
|
+
end
|
2742
|
+
|
2636
2743
|
def move_item_up(with_children = false)
|
2637
2744
|
visible = get_visible_items
|
2638
2745
|
return if @current >= visible.length || @current == 0
|
2639
|
-
|
2746
|
+
|
2640
2747
|
save_undo_state # Save state before modification
|
2641
|
-
|
2642
|
-
|
2643
|
-
|
2644
|
-
|
2645
|
-
#
|
2646
|
-
|
2647
|
-
|
2648
|
-
|
2649
|
-
|
2650
|
-
|
2748
|
+
|
2749
|
+
current_item = visible[@current]
|
2750
|
+
current_real_idx = get_real_index(current_item)
|
2751
|
+
|
2752
|
+
# Get the previous visible item
|
2753
|
+
prev_visible_item = visible[@current - 1]
|
2754
|
+
prev_real_idx = get_real_index(prev_visible_item)
|
2755
|
+
|
2756
|
+
# Collect items to move (current item + children if requested)
|
2757
|
+
items_to_move = [current_item]
|
2651
2758
|
if with_children
|
2652
|
-
|
2653
|
-
|
2654
|
-
((real_idx + 1)...@items.length).each do |i|
|
2759
|
+
level = current_item["level"]
|
2760
|
+
((current_real_idx + 1)...@items.length).each do |i|
|
2655
2761
|
if @items[i]["level"] > level
|
2656
2762
|
items_to_move << @items[i]
|
2657
2763
|
else
|
@@ -2659,46 +2765,42 @@ class HyperListApp
|
|
2659
2765
|
end
|
2660
2766
|
end
|
2661
2767
|
end
|
2662
|
-
|
2663
|
-
#
|
2664
|
-
|
2665
|
-
|
2666
|
-
|
2667
|
-
#
|
2668
|
-
(
|
2669
|
-
|
2670
|
-
|
2671
|
-
|
2672
|
-
|
2673
|
-
|
2674
|
-
|
2675
|
-
|
2768
|
+
|
2769
|
+
# Calculate what level the moved item should have at the target position
|
2770
|
+
new_level = calculate_level_for_position(prev_real_idx)
|
2771
|
+
level_diff = new_level - items_to_move.first["level"]
|
2772
|
+
|
2773
|
+
# Unfold destination area BEFORE moving if needed
|
2774
|
+
ensure_destination_visible(prev_real_idx, new_level)
|
2775
|
+
|
2776
|
+
# Remove the items to move
|
2777
|
+
items_to_move.length.times { @items.delete_at(current_real_idx) }
|
2778
|
+
|
2779
|
+
# Adjust target position since we removed items after it
|
2780
|
+
adjusted_target = prev_real_idx
|
2781
|
+
if prev_real_idx > current_real_idx
|
2782
|
+
adjusted_target -= items_to_move.length
|
2676
2783
|
end
|
2677
|
-
|
2678
|
-
#
|
2679
|
-
|
2680
|
-
|
2681
|
-
|
2682
|
-
first_moved_item = items_to_move.first
|
2683
|
-
|
2684
|
-
# Remove items from their current position
|
2685
|
-
items_to_move.length.times { @items.delete_at(real_idx) }
|
2686
|
-
|
2687
|
-
# Insert before the target sibling
|
2688
|
-
items_to_move.reverse.each do |item_to_move|
|
2689
|
-
@items.insert(target_idx, item_to_move)
|
2784
|
+
|
2785
|
+
# Adjust levels of moved items
|
2786
|
+
items_to_move.each do |moved_item|
|
2787
|
+
moved_item["level"] += level_diff
|
2788
|
+
moved_item["level"] = [moved_item["level"], 0].max # Ensure level doesn't go negative
|
2690
2789
|
end
|
2691
|
-
|
2692
|
-
#
|
2693
|
-
|
2694
|
-
|
2790
|
+
|
2791
|
+
# Insert items at target position
|
2792
|
+
items_to_move.each_with_index do |item_to_move, idx|
|
2793
|
+
@items.insert(adjusted_target + idx, item_to_move)
|
2794
|
+
end
|
2795
|
+
|
2796
|
+
# FORCE the moved item to be visible (safety net)
|
2797
|
+
force_item_visible(adjusted_target)
|
2798
|
+
|
2799
|
+
# Update cursor to follow the moved item
|
2695
2800
|
new_visible = get_visible_items
|
2696
|
-
new_item_idx = new_visible.find_index { |v| v
|
2801
|
+
new_item_idx = new_visible.find_index { |v| get_real_index(v) == adjusted_target }
|
2697
2802
|
@current = new_item_idx if new_item_idx
|
2698
|
-
|
2699
|
-
# Renumber siblings at the moved item's level
|
2700
|
-
renumber_siblings(first_moved_item["level"])
|
2701
|
-
|
2803
|
+
|
2702
2804
|
@modified = true
|
2703
2805
|
@message = "Moved #{items_to_move.length} item(s) up"
|
2704
2806
|
record_last_action(:move_item_up, with_children)
|
@@ -2707,81 +2809,71 @@ class HyperListApp
|
|
2707
2809
|
def move_item_down(with_children = false)
|
2708
2810
|
visible = get_visible_items
|
2709
2811
|
return if @current >= visible.length - 1
|
2710
|
-
|
2812
|
+
|
2711
2813
|
save_undo_state # Save state before modification
|
2712
|
-
|
2713
|
-
|
2714
|
-
|
2715
|
-
|
2716
|
-
#
|
2717
|
-
|
2718
|
-
|
2719
|
-
|
2814
|
+
|
2815
|
+
current_item = visible[@current]
|
2816
|
+
current_real_idx = get_real_index(current_item)
|
2817
|
+
|
2818
|
+
# Get the next visible item
|
2819
|
+
next_visible_item = visible[@current + 1]
|
2820
|
+
next_real_idx = get_real_index(next_visible_item)
|
2821
|
+
|
2822
|
+
# Collect items to move (current item + children if requested)
|
2823
|
+
items_to_move = [current_item]
|
2720
2824
|
if with_children
|
2721
|
-
|
2722
|
-
|
2723
|
-
((real_idx + 1)...@items.length).each do |i|
|
2825
|
+
level = current_item["level"]
|
2826
|
+
((current_real_idx + 1)...@items.length).each do |i|
|
2724
2827
|
if @items[i]["level"] > level
|
2725
2828
|
items_to_move << @items[i]
|
2726
|
-
last_idx = i
|
2727
2829
|
else
|
2728
2830
|
break
|
2729
2831
|
end
|
2730
2832
|
end
|
2731
2833
|
end
|
2732
|
-
|
2733
|
-
#
|
2734
|
-
|
2735
|
-
|
2736
|
-
|
2737
|
-
|
2738
|
-
|
2739
|
-
|
2740
|
-
|
2741
|
-
# Found next sibling, now find where it ends (including its children)
|
2742
|
-
next_sibling_end = i
|
2743
|
-
((i + 1)...@items.length).each do |j|
|
2744
|
-
if @items[j]["level"] > target_level
|
2745
|
-
next_sibling_end = j
|
2746
|
-
else
|
2747
|
-
break
|
2748
|
-
end
|
2749
|
-
end
|
2750
|
-
target_idx = next_sibling_end + 1
|
2751
|
-
break
|
2752
|
-
elsif @items[i]["level"] < target_level
|
2753
|
-
# Hit a parent level, can't move down
|
2754
|
-
return
|
2755
|
-
end
|
2834
|
+
|
2835
|
+
# Target is immediately after the next visible item (not after its children)
|
2836
|
+
target_real_idx = next_real_idx + 1
|
2837
|
+
|
2838
|
+
# Check if there are orphaned children at the target position
|
2839
|
+
# If so, position before them to reunite
|
2840
|
+
orphaned_children = find_orphaned_children(current_item["text"], target_real_idx)
|
2841
|
+
if !orphaned_children.empty?
|
2842
|
+
target_real_idx = orphaned_children.first
|
2756
2843
|
end
|
2757
|
-
|
2758
|
-
#
|
2759
|
-
|
2760
|
-
|
2761
|
-
|
2762
|
-
|
2763
|
-
|
2764
|
-
|
2765
|
-
|
2766
|
-
|
2767
|
-
|
2768
|
-
|
2769
|
-
|
2770
|
-
|
2844
|
+
|
2845
|
+
# Calculate what level the moved item should have at the target position
|
2846
|
+
new_level = calculate_level_for_position(target_real_idx)
|
2847
|
+
level_diff = new_level - items_to_move.first["level"]
|
2848
|
+
|
2849
|
+
# Unfold destination area BEFORE moving if needed
|
2850
|
+
ensure_destination_visible(target_real_idx, new_level)
|
2851
|
+
|
2852
|
+
# Remove the items to move
|
2853
|
+
items_to_move.length.times { @items.delete_at(current_real_idx) }
|
2854
|
+
|
2855
|
+
# Adjust target position since we removed items before it
|
2856
|
+
adjusted_target = target_real_idx - items_to_move.length
|
2857
|
+
|
2858
|
+
# Adjust levels of moved items
|
2859
|
+
items_to_move.each do |moved_item|
|
2860
|
+
moved_item["level"] += level_diff
|
2861
|
+
moved_item["level"] = [moved_item["level"], 0].max # Ensure level doesn't go negative
|
2862
|
+
end
|
2863
|
+
|
2864
|
+
# Insert items at target position
|
2771
2865
|
items_to_move.each_with_index do |item_to_move, idx|
|
2772
|
-
@items.insert(
|
2866
|
+
@items.insert(adjusted_target + idx, item_to_move)
|
2773
2867
|
end
|
2774
|
-
|
2775
|
-
#
|
2776
|
-
|
2777
|
-
|
2868
|
+
|
2869
|
+
# FORCE the moved item to be visible (safety net)
|
2870
|
+
force_item_visible(adjusted_target)
|
2871
|
+
|
2872
|
+
# Update cursor to follow the moved item
|
2778
2873
|
new_visible = get_visible_items
|
2779
|
-
new_item_idx = new_visible.find_index { |v| v
|
2874
|
+
new_item_idx = new_visible.find_index { |v| get_real_index(v) == adjusted_target }
|
2780
2875
|
@current = new_item_idx if new_item_idx
|
2781
|
-
|
2782
|
-
# Renumber siblings at the moved item's level
|
2783
|
-
renumber_siblings(first_moved_item["level"])
|
2784
|
-
|
2876
|
+
|
2785
2877
|
@modified = true
|
2786
2878
|
@message = "Moved #{items_to_move.length} item(s) down"
|
2787
2879
|
record_last_action(:move_item_down, with_children)
|
@@ -2930,7 +3022,35 @@ class HyperListApp
|
|
2930
3022
|
@modified = true
|
2931
3023
|
record_last_action(:toggle_checkbox_with_date, nil)
|
2932
3024
|
end
|
2933
|
-
|
3025
|
+
|
3026
|
+
def remove_checkbox
|
3027
|
+
visible = get_visible_items
|
3028
|
+
return if @current >= visible.length
|
3029
|
+
|
3030
|
+
save_undo_state # Save state before modification
|
3031
|
+
|
3032
|
+
item = visible[@current]
|
3033
|
+
real_idx = get_real_index(item)
|
3034
|
+
text = @items[real_idx]["text"]
|
3035
|
+
|
3036
|
+
# Remove checkbox patterns: [ ], [X], [x], [O], [-], [_]
|
3037
|
+
if text =~ /^\[[ X_Ox-]\]/
|
3038
|
+
# Remove the checkbox and any following space
|
3039
|
+
text = text.sub(/^\[[ X_Ox-]\]\s*/, '')
|
3040
|
+
|
3041
|
+
# Also remove any timestamp that might be associated with checkbox
|
3042
|
+
# Format: YYYY-MM-DD HH.MM: or similar
|
3043
|
+
text = text.sub(/^\d{4}-\d{2}-\d{2} \d{2}\.\d{2}:\s*/, '')
|
3044
|
+
|
3045
|
+
@items[real_idx]["text"] = text
|
3046
|
+
@modified = true
|
3047
|
+
@message = "Removed checkbox"
|
3048
|
+
record_last_action(:remove_checkbox, nil)
|
3049
|
+
else
|
3050
|
+
@message = "No checkbox to remove"
|
3051
|
+
end
|
3052
|
+
end
|
3053
|
+
|
2934
3054
|
def search_forward
|
2935
3055
|
@mode = :search
|
2936
3056
|
@search = @footer.ask("Search: ", @search || "")
|
@@ -3067,12 +3187,13 @@ class HyperListApp
|
|
3067
3187
|
help_lines << help_line("#{"u".fg("10")}", "Undo", "#{".".fg("10")}", "Repeat last action")
|
3068
3188
|
help_lines << help_line("#{"r".fg("10")}" + ", ".fg("10") + "#{"C-R".fg("10")}", "Redo")
|
3069
3189
|
help_lines << help_line("#{"S-UP".fg("10")}", "Move item up", "#{"S-DOWN".fg("10")}", "Move item down")
|
3070
|
-
help_lines << help_line("#{"C-UP".fg("10")}", "Move
|
3190
|
+
help_lines << help_line("#{"C-UP".fg("10")}", "Move up in visible list", "#{"C-DOWN".fg("10")}", "Move down in visible list")
|
3071
3191
|
help_lines << help_line("#{"→".fg("10")}", "Uncollapse item", "#{"←".fg("10")}", "Collapse item")
|
3072
3192
|
help_lines << help_line("#{"Tab".fg("10")}", "Indent item+kids", "#{"S-Tab".fg("10")}", "Unindent item+kids")
|
3073
3193
|
help_lines << ""
|
3074
3194
|
help_lines << "#{"SPECIAL FEATURES".fg("14")}"
|
3075
3195
|
help_lines << help_line("#{"v".fg("10")}", "Toggle checkbox", "#{"V".fg("10")}", "Checkbox with date")
|
3196
|
+
help_lines << help_line("#{"C-X".fg("10")}", "Remove checkbox", "", "")
|
3076
3197
|
help_lines << help_line("#{"C-E".fg("10")}", "Encrypt/decrypt line", "#{"C-U".fg("10")}", "Toggle State/Trans underline")
|
3077
3198
|
help_lines << help_line("#{"P".fg("10")}", "Presentation mode", "#{"Tab/S-Tab".fg("10")}", "Next/prev sibling (in P)")
|
3078
3199
|
help_lines << help_line("#{"Ma".fg("10")}", "Record macro 'a'", "#{"@a".fg("10")}", "Play macro 'a'")
|
@@ -4948,6 +5069,8 @@ class HyperListApp
|
|
4948
5069
|
toggle_checkbox
|
4949
5070
|
when "V"
|
4950
5071
|
toggle_checkbox_with_date
|
5072
|
+
when "C-X" # Ctrl-Shift-X for remove checkbox
|
5073
|
+
remove_checkbox
|
4951
5074
|
when "TAB"
|
4952
5075
|
# Indent with move conditions (moved from RIGHT key)
|
4953
5076
|
should_move_children = should_move_with_children?
|
@@ -5895,12 +6018,12 @@ class HyperListApp
|
|
5895
6018
|
move_item_up(false)
|
5896
6019
|
when "S-DOWN" # Move item down
|
5897
6020
|
move_item_down(false)
|
5898
|
-
when "C-UP" # Move
|
5899
|
-
move_item_up(
|
5900
|
-
when "C-DOWN" # Move
|
5901
|
-
move_item_down(
|
5902
|
-
when "C-K" # Alternative: Move
|
5903
|
-
move_item_up(
|
6021
|
+
when "C-UP" # Move up in visible list (with children only if collapsed)
|
6022
|
+
move_item_up(should_move_with_children?)
|
6023
|
+
when "C-DOWN" # Move down in visible list (with children only if collapsed)
|
6024
|
+
move_item_down(should_move_with_children?)
|
6025
|
+
when "C-K" # Alternative: Move up in visible list (for terminals that intercept C-UP)
|
6026
|
+
move_item_up(should_move_with_children?)
|
5904
6027
|
when "TAB"
|
5905
6028
|
if @presentation_mode
|
5906
6029
|
# In presentation mode, Tab goes to next sibling
|
@@ -5935,6 +6058,8 @@ class HyperListApp
|
|
5935
6058
|
toggle_checkbox
|
5936
6059
|
when "V"
|
5937
6060
|
toggle_checkbox_with_date
|
6061
|
+
when "C-X" # Ctrl-Shift-X for remove checkbox
|
6062
|
+
remove_checkbox
|
5938
6063
|
when "."
|
5939
6064
|
repeat_last_action
|
5940
6065
|
when "/"
|
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.
|
4
|
+
version: 1.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Geir Isene
|
8
8
|
autorequire:
|
9
9
|
bindir: "."
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-09-
|
11
|
+
date: 2025-09-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rcurses
|