hyperlist 1.2.4 → 1.2.6

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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/hyperlist +247 -52
  3. data/hyperlist.gemspec +1 -1
  4. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 03eb9614c8726c4e597cadde5b213e195a352ccaeae0234cb93b4114dddd9729
4
- data.tar.gz: 557a147e2874dcb0aa1e0acbe13d28f5de51954661a7fd7e6b3cc4408e73ff94
3
+ metadata.gz: bbd169877052f1ab57f546b6dbd8cdcc8c7f32bff29fdabb0722e529827e8139
4
+ data.tar.gz: f3e095c33a6cc73df1d0e04f8d77dd0e07f35510a50a98b2a372ca76b19a65a9
5
5
  SHA512:
6
- metadata.gz: d3ee01faf4256502806d37700f64217fccd29fea0c4d131d86693adf6f83f18e2b7477597cae4cc8fff61b507a7012f0219b21b24a8795319765f2a455359f9f
7
- data.tar.gz: 156252aaa0cdc6ba380049b04ae8812c48906cf4fa67ae2e0af060868fba9d8ddbc97af5a6a8fe000714bd5371149e929e2dda4afa3842daaf391383689d7f15
6
+ metadata.gz: 8299b5c733b268225f56ea4eb1e8bcd3af25aa970baa999b9213f2b0561314dcf07a9223610c36ba95fe31a5acc5a92a631a3878489bfa4281de8a5b7e52426c
7
+ data.tar.gz: e24fcb589303ce626689de3a946d9f1db02b8b01fdf0142a8f3bb7b3b962ef41f3af799030b4b2b7fe03fc83231638398a102881ce66a3b5015be61c2d13d065
data/hyperlist CHANGED
@@ -783,13 +783,16 @@ class HyperListApp
783
783
  end
784
784
  end
785
785
 
786
- # Apply current item highlighting
786
+ # Apply current item highlighting (but not in presentation mode for focused items)
787
787
  if idx == @current
788
- bg_color = (!@split_view || @active_pane == :main) ? "237" : "234"
789
- if bg_color
790
- bg_code = "\e[48;5;#{bg_color}m"
791
- reset_bg = "\e[49m"
792
- line = bg_code + line.gsub(/\e\[49m/, '') + reset_bg
788
+ # Skip background highlighting in presentation mode for items in focus
789
+ if !(@presentation_mode && is_item_in_presentation_focus?(item))
790
+ bg_color = (!@split_view || @active_pane == :main) ? "237" : "234"
791
+ if bg_color
792
+ bg_code = "\e[48;5;#{bg_color}m"
793
+ reset_bg = "\e[49m"
794
+ line = bg_code + line.gsub(/\e\[49m/, '') + reset_bg
795
+ end
793
796
  end
794
797
  end
795
798
 
@@ -1280,38 +1283,116 @@ class HyperListApp
1280
1283
  end
1281
1284
 
1282
1285
  def move_up
1283
- max_items = get_visible_items.length - 1
1284
-
1285
- if @current == 0
1286
- # Wrap around to last item
1287
- @current = max_items
1286
+ if @presentation_mode
1287
+ # In presentation mode, we need to handle navigation differently
1288
+ visible_before = get_visible_items
1289
+
1290
+ if @current == 0
1291
+ # Wrap around to last item
1292
+ target_index = visible_before.length - 1
1293
+ else
1294
+ target_index = @current - 1
1295
+ end
1296
+
1297
+ # Get the actual item we want to move to
1298
+ target_item = visible_before[target_index]
1299
+ target_real_idx = get_real_index(target_item)
1300
+
1301
+ # Update presentation focus for the target item
1302
+ @current = target_index
1303
+ update_presentation_focus
1304
+
1305
+ # Now find where the target item ended up after reorganization
1306
+ visible_after = get_visible_items
1307
+ visible_after.each_with_index do |item, idx|
1308
+ if get_real_index(item) == target_real_idx
1309
+ @current = idx
1310
+ break
1311
+ end
1312
+ end
1288
1313
  else
1289
- @current = [@current - 1, 0].max
1314
+ # Normal mode navigation
1315
+ max_items = get_visible_items.length - 1
1316
+
1317
+ if @current == 0
1318
+ # Wrap around to last item
1319
+ @current = max_items
1320
+ else
1321
+ @current = [@current - 1, 0].max
1322
+ end
1290
1323
  end
1291
-
1292
- update_presentation_focus if @presentation_mode
1293
1324
  end
1294
1325
 
1295
1326
  def move_down
1296
- max = get_visible_items.length - 1
1297
-
1298
- if @current == max
1299
- # Wrap around to first item
1300
- @current = 0
1327
+ if @presentation_mode
1328
+ # In presentation mode, we need to handle navigation differently
1329
+ visible_before = get_visible_items
1330
+ max = visible_before.length - 1
1331
+
1332
+ if @current == max
1333
+ # Wrap around to first item
1334
+ target_index = 0
1335
+ else
1336
+ target_index = @current + 1
1337
+ end
1338
+
1339
+ # Get the actual item we want to move to
1340
+ target_item = visible_before[target_index]
1341
+ target_real_idx = get_real_index(target_item)
1342
+
1343
+ # Update presentation focus for the target item
1344
+ @current = target_index
1345
+ update_presentation_focus
1346
+
1347
+ # Now find where the target item ended up after reorganization
1348
+ visible_after = get_visible_items
1349
+ visible_after.each_with_index do |item, idx|
1350
+ if get_real_index(item) == target_real_idx
1351
+ @current = idx
1352
+ break
1353
+ end
1354
+ end
1301
1355
  else
1302
- @current = [@current + 1, max].min
1356
+ # Normal mode navigation
1357
+ max = get_visible_items.length - 1
1358
+
1359
+ if @current == max
1360
+ # Wrap around to first item
1361
+ @current = 0
1362
+ else
1363
+ @current = [@current + 1, max].min
1364
+ end
1303
1365
  end
1304
-
1305
- update_presentation_focus if @presentation_mode
1306
1366
  end
1307
1367
 
1308
1368
  def page_up
1309
1369
  if @split_view && @active_pane == :split
1310
1370
  @split_current = [@split_current - (@split_pane.h - 1), 0].max
1371
+ elsif @presentation_mode
1372
+ # In presentation mode, handle page navigation differently
1373
+ visible_before = get_visible_items
1374
+ target_index = [@current - (@main.h - 1), 0].max
1375
+
1376
+ if target_index < visible_before.length
1377
+ target_item = visible_before[target_index]
1378
+ target_real_idx = get_real_index(target_item)
1379
+
1380
+ @current = target_index
1381
+ update_presentation_focus
1382
+
1383
+ # Find where the target item ended up
1384
+ visible_after = get_visible_items
1385
+ visible_after.each_with_index do |item, idx|
1386
+ if get_real_index(item) == target_real_idx
1387
+ @current = idx
1388
+ break
1389
+ end
1390
+ end
1391
+ end
1392
+ @offset = [@offset - (@main.h - 1), 0].max
1311
1393
  else
1312
1394
  @current = [@current - (@main.h - 1), 0].max
1313
1395
  @offset = [@offset - (@main.h - 1), 0].max
1314
- update_presentation_focus if @presentation_mode
1315
1396
  end
1316
1397
  end
1317
1398
 
@@ -1319,10 +1400,29 @@ class HyperListApp
1319
1400
  if @split_view && @active_pane == :split
1320
1401
  max = get_visible_split_items.length - 1
1321
1402
  @split_current = [@split_current + (@split_pane.h - 1), max].min
1403
+ elsif @presentation_mode
1404
+ # In presentation mode, handle page navigation differently
1405
+ visible_before = get_visible_items
1406
+ max = visible_before.length - 1
1407
+ target_index = [@current + (@main.h - 1), max].min
1408
+
1409
+ target_item = visible_before[target_index]
1410
+ target_real_idx = get_real_index(target_item)
1411
+
1412
+ @current = target_index
1413
+ update_presentation_focus
1414
+
1415
+ # Find where the target item ended up
1416
+ visible_after = get_visible_items
1417
+ visible_after.each_with_index do |item, idx|
1418
+ if get_real_index(item) == target_real_idx
1419
+ @current = idx
1420
+ break
1421
+ end
1422
+ end
1322
1423
  else
1323
1424
  max = get_visible_items.length - 1
1324
1425
  @current = [@current + (@main.h - 1), max].min
1325
- update_presentation_focus if @presentation_mode
1326
1426
  end
1327
1427
  end
1328
1428
 
@@ -1333,12 +1433,39 @@ class HyperListApp
1333
1433
  current_level = visible[@current]["level"]
1334
1434
  return if current_level == 0
1335
1435
 
1336
- # Search upward for parent
1337
- (@current - 1).downto(0) do |i|
1338
- if visible[i]["level"] < current_level
1339
- @current = i
1340
- update_presentation_focus if @presentation_mode
1341
- break
1436
+ if @presentation_mode
1437
+ # Find parent and navigate to it properly
1438
+ target_idx = nil
1439
+ (@current - 1).downto(0) do |i|
1440
+ if visible[i]["level"] < current_level
1441
+ target_idx = i
1442
+ break
1443
+ end
1444
+ end
1445
+
1446
+ if target_idx
1447
+ target_item = visible[target_idx]
1448
+ target_real_idx = get_real_index(target_item)
1449
+
1450
+ @current = target_idx
1451
+ update_presentation_focus
1452
+
1453
+ # Find where the target item ended up
1454
+ visible_after = get_visible_items
1455
+ visible_after.each_with_index do |item, idx|
1456
+ if get_real_index(item) == target_real_idx
1457
+ @current = idx
1458
+ break
1459
+ end
1460
+ end
1461
+ end
1462
+ else
1463
+ # Search upward for parent
1464
+ (@current - 1).downto(0) do |i|
1465
+ if visible[i]["level"] < current_level
1466
+ @current = i
1467
+ break
1468
+ end
1342
1469
  end
1343
1470
  end
1344
1471
  end
@@ -1349,8 +1476,62 @@ class HyperListApp
1349
1476
 
1350
1477
  current_level = visible[@current]["level"]
1351
1478
  if visible[@current + 1]["level"] > current_level
1352
- @current += 1
1353
- update_presentation_focus if @presentation_mode
1479
+ if @presentation_mode
1480
+ target_item = visible[@current + 1]
1481
+ target_real_idx = get_real_index(target_item)
1482
+
1483
+ @current += 1
1484
+ update_presentation_focus
1485
+
1486
+ # Find where the target item ended up
1487
+ visible_after = get_visible_items
1488
+ visible_after.each_with_index do |item, idx|
1489
+ if get_real_index(item) == target_real_idx
1490
+ @current = idx
1491
+ break
1492
+ end
1493
+ end
1494
+ else
1495
+ @current += 1
1496
+ end
1497
+ end
1498
+ end
1499
+
1500
+ def jump_to_next_sibling
1501
+ visible = get_visible_items
1502
+ return if @current >= visible.length - 1
1503
+
1504
+ current_level = visible[@current]["level"]
1505
+
1506
+ # Search forward for the next item at the same level
1507
+ (@current + 1...visible.length).each do |i|
1508
+ if visible[i]["level"] == current_level
1509
+ @current = i
1510
+ update_presentation_focus if @presentation_mode
1511
+ return
1512
+ elsif visible[i]["level"] < current_level
1513
+ # We've gone up a level, no more siblings
1514
+ return
1515
+ end
1516
+ end
1517
+ end
1518
+
1519
+ def jump_to_prev_sibling
1520
+ visible = get_visible_items
1521
+ return if @current <= 0
1522
+
1523
+ current_level = visible[@current]["level"]
1524
+
1525
+ # Search backward for the previous item at the same level
1526
+ (@current - 1).downto(0) do |i|
1527
+ if visible[i]["level"] == current_level
1528
+ @current = i
1529
+ update_presentation_focus if @presentation_mode
1530
+ return
1531
+ elsif visible[i]["level"] < current_level
1532
+ # We've gone up a level, no more siblings before this
1533
+ return
1534
+ end
1354
1535
  end
1355
1536
  end
1356
1537
 
@@ -1444,9 +1625,11 @@ class HyperListApp
1444
1625
  item["presentation_focus"] = false
1445
1626
  end
1446
1627
 
1447
- # Mark current item as in focus and unfold it
1448
- current_item["presentation_focus"] = true
1449
- current_item["fold"] = false
1628
+ # Mark current item as in focus and unfold it in the main items array
1629
+ if current_real_idx && current_real_idx < @items.length
1630
+ @items[current_real_idx]["presentation_focus"] = true
1631
+ @items[current_real_idx]["fold"] = false
1632
+ end
1450
1633
 
1451
1634
  # Unfold all ancestors of current item
1452
1635
  ancestor_indices = []
@@ -2314,11 +2497,13 @@ class HyperListApp
2314
2497
  help_lines << help_line("#{"h".fg("10")}", "Go to parent", "#{"l".fg("10")}", "Go to first child")
2315
2498
  help_lines << help_line("#{"PgUp".fg("10")}", "Page up", "#{"PgDn".fg("10")}", "Page down")
2316
2499
  help_lines << help_line("#{"g/Home".fg("10")}", "Go to top", "#{"G/End".fg("10")}", "Go to bottom")
2317
- help_lines << help_line("#{"/".fg("10")}", "Search", "#{"n".fg("10")}", "Next match")
2318
- help_lines << help_line("#{"?".fg("10")}", "This help", "#{"??".fg("10")}", "Full documentation")
2500
+ help_lines << help_line("#{"R".fg("10")}", "Jump to reference", "#{"F".fg("10")}", "Open file/URL")
2319
2501
  help_lines << help_line("#{"ma".fg("10")}", "Set mark 'a'", "#{"'a".fg("10")}", "Jump to mark 'a'")
2320
2502
  help_lines << help_line("#{"''".fg("10")}", "Jump to prev position", "#{"N".fg("10")}", "Next = template marker")
2321
2503
  help_lines << ""
2504
+ help_lines << "#{"SEARCH".fg("14")}"
2505
+ help_lines << help_line("#{"/".fg("10")}", "Search forward", "#{"n".fg("10")}", "Next match")
2506
+ help_lines << ""
2322
2507
  help_lines << "#{"FOLDING".fg("14")}"
2323
2508
  help_lines << help_line("#{"Space".fg("10")}", "Toggle fold", "#{"za".fg("10")}", "Toggle all folds")
2324
2509
  help_lines << help_line("#{"zo".fg("10")}", "Open fold", "#{"zc".fg("10")}", "Close fold")
@@ -2341,14 +2526,12 @@ class HyperListApp
2341
2526
  help_lines << help_line("#{"Tab".fg("10")}", "Indent item+kids", "#{"S-Tab".fg("10")}", "Unindent item+kids")
2342
2527
  help_lines << help_line("#{"→".fg("10")}", "Indent item only", "#{"←".fg("10")}", "Unindent item only")
2343
2528
  help_lines << ""
2344
- help_lines << "#{"FEATURES".fg("14")}"
2529
+ help_lines << "#{"SPECIAL FEATURES".fg("14")}"
2345
2530
  help_lines << help_line("#{"v".fg("10")}", "Toggle checkbox", "#{"V".fg("10")}", "Checkbox with date")
2346
2531
  help_lines << help_line("#{"C-E".fg("10")}", "Encrypt/decrypt line", "#{"C-U".fg("10")}", "Toggle State/Trans underline")
2347
- help_lines << help_line("#{"R".fg("10")}", "Go to reference", "#{"F".fg("10")}", "Open file")
2348
- help_lines << help_line("#{"N".fg("10")}", "Next = marker", "#{"P".fg("10")}", "Presentation mode")
2349
- help_lines << help_line("#{"t".fg("10")}", "Insert template", "#{":st".fg("10")}", "Save as template")
2532
+ help_lines << help_line("#{"P".fg("10")}", "Presentation mode", "#{"Tab/S-Tab".fg("10")}", "Next/prev sibling (in P)")
2350
2533
  help_lines << help_line("#{"Ma".fg("10")}", "Record macro 'a'", "#{"@a".fg("10")}", "Play macro 'a'")
2351
- help_lines << help_line("#{":vsplit".fg("10")}", "Split view vertically", "#{"w".fg("10")}", "Switch panes")
2534
+ help_lines << help_line("#{"w".fg("10")}", "Switch panes (split view)", "", "")
2352
2535
  help_lines << ""
2353
2536
  help_lines << "#{"FILE OPERATIONS".fg("14")}"
2354
2537
  help_lines << help_line("#{":w".fg("10")}", "Save", "#{":q".fg("10")}", "Quit")
@@ -2359,9 +2542,11 @@ class HyperListApp
2359
2542
  help_lines << help_line("#{":as N".fg("10")}", "Set interval (secs)", "#{":as".fg("10")}", "Show autosave status")
2360
2543
  help_lines << ""
2361
2544
  help_lines << "#{"TEMPLATES".fg("14")}"
2362
- help_lines << help_line("#{":st".fg("10")}", "Save as template", "#{":dt".fg("10")}", "Delete template")
2363
- help_lines << help_line("#{":lt".fg("10")}", "List user templates", "#{"t".fg("10")}", "Insert template")
2545
+ help_lines << help_line("#{"t".fg("10")}", "Insert template", "#{":st".fg("10")}", "Save as template")
2546
+ help_lines << help_line("#{":dt".fg("10")}", "Delete template", "#{":lt".fg("10")}", "List user templates")
2364
2547
  help_lines << ""
2548
+ help_lines << "#{"HELP & QUIT".fg("14")}"
2549
+ help_lines << help_line("#{"?".fg("10")}", "This help", "#{"??".fg("10")}", "Full documentation")
2365
2550
  help_lines << help_line("#{"q".fg("10")}", "Quit (asks to save)", "#{"Q".fg("10")}", "Force quit")
2366
2551
  help_lines << ""
2367
2552
  help_lines << "#{"COLOR SCHEME".fg("14")}"
@@ -4986,18 +5171,28 @@ class HyperListApp
4986
5171
  when "C-K" # Alternative: Move item and descendants up (for terminals that intercept C-UP)
4987
5172
  move_item_up(true)
4988
5173
  when "TAB"
4989
- # Indent with all children
4990
- if @split_view && @active_pane == :split
4991
- indent_split_right(true)
5174
+ if @presentation_mode
5175
+ # In presentation mode, Tab goes to next sibling
5176
+ jump_to_next_sibling
4992
5177
  else
4993
- indent_right(true)
5178
+ # Normal mode: Indent with all children
5179
+ if @split_view && @active_pane == :split
5180
+ indent_split_right(true)
5181
+ else
5182
+ indent_right(true)
5183
+ end
4994
5184
  end
4995
5185
  when "S-TAB" # Shift-Tab
4996
- # Unindent with all children
4997
- if @split_view && @active_pane == :split
4998
- indent_split_left(true)
5186
+ if @presentation_mode
5187
+ # In presentation mode, Shift-Tab goes to previous sibling
5188
+ jump_to_prev_sibling
4999
5189
  else
5000
- indent_left(true)
5190
+ # Normal mode: Unindent with all children
5191
+ if @split_view && @active_pane == :split
5192
+ indent_split_left(true)
5193
+ else
5194
+ indent_left(true)
5195
+ end
5001
5196
  end
5002
5197
  when "u"
5003
5198
  undo
data/hyperlist.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "hyperlist"
3
- spec.version = "1.2.4"
3
+ spec.version = "1.2.6"
4
4
  spec.authors = ["Geir Isene"]
5
5
  spec.email = ["g@isene.com"]
6
6
 
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.2.4
4
+ version: 1.2.6
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-23 00:00:00.000000000 Z
11
+ date: 2025-08-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rcurses