try-cli 1.9.3 → 1.10.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.
Files changed (6) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -4
  3. data/VERSION +1 -1
  4. data/lib/tui.rb +2 -2
  5. data/try.rb +79 -10
  6. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 07dc2d2cbbb24c4c934bffceead77e583ef973e1c7f7a08361863c340a373783
4
- data.tar.gz: 8c110d86811dbecdd9b7a0778605f76d3564f6f9eec697a05da809a98f39b5dd
3
+ metadata.gz: 2886940b1f4b531eac99e082e57083e26e0aedc60f073355868870fc364118c7
4
+ data.tar.gz: 64712394de4b5d48535ce8dc31abb2f50da33e446aed3d01ec465640191c6b0e
5
5
  SHA512:
6
- metadata.gz: c93e4020653e00136115a24cd831e409e00b3e1e9ae48013794b794115f37eae3df599af93c01bd4e571ca45933188c460a4e808e4ad6a78eef5b2384c814ff6
7
- data.tar.gz: 5487462b36084f6f4b5b7ebe553724d9ac1bddd42246a5d9bea5a53f2702a1be311cfbae448686c68fe73a8134ab73af1bda5d2403ed0d19f5bc62589f33b09c
6
+ metadata.gz: a13726660cb156fde7e39a351b439d3a64870fcc637a4fe4189c54a0b3a2ad417f3685ec9a010ed65b7b1f254ee26b46e6b20f1c25ff8ca1caf5ae0d1b1852f1
7
+ data.tar.gz: 448bb7c503410c82052e93ce8dc6b22922be70c80dd1a8c0a9f8c7e84e7f50bc0efa4d435c8c8bec4c0578cb8969185cc624fcd3169e9421eead312aa84f4223
data/README.md CHANGED
@@ -10,7 +10,7 @@ Ever find yourself with 50 directories named `test`, `test2`, `new-test`, `actua
10
10
 
11
11
  **try** is here for your beautifully chaotic mind.
12
12
 
13
- # What it does
13
+ # What it does
14
14
 
15
15
  ![Fuzzy Search Demo](assets/try-fuzzy-search-demo.gif)
16
16
 
@@ -155,6 +155,10 @@ try clone https://github.com/tobi/try.git my-fork
155
155
  # Shorthand syntax (no need to type 'clone')
156
156
  try https://github.com/tobi/try.git
157
157
  # Creates: 2025-08-27-tobi-try
158
+
159
+ # Paste a GitHub pull request URL to clone and check out that PR
160
+ try https://github.com/tobi/try/pull/124
161
+ # Creates: 2025-08-27-tobi-try
158
162
  ```
159
163
 
160
164
  Supported git URI formats:
@@ -162,8 +166,14 @@ Supported git URI formats:
162
166
  - `git@github.com:user/repo.git` (SSH GitHub)
163
167
  - `https://gitlab.com/user/repo.git` (GitLab)
164
168
  - `git@host.com:user/repo.git` (SSH other hosts)
169
+ - `ssh://git@host.com:port/user/repo.git` (SSH other hosts with custom port)
170
+ - `user@host:path/to/repo.git` (nested SCP-style SSH URLs)
171
+ - `https://github.com/user/repo/pull/123` (GitHub pull requests)
165
172
 
166
- The `.git` suffix is automatically removed from URLs when generating directory names.
173
+ A GitHub pull request URL clones the main repository, fetches the PR ref, and
174
+ checks it out in detached HEAD state. The directory name is based on the main
175
+ repository URL, not the `/pull/<number>` suffix. The `.git` suffix is
176
+ automatically removed from URLs when generating directory names.
167
177
 
168
178
  ### Keyboard Shortcuts
169
179
 
@@ -199,9 +209,9 @@ nix run github:tobi/try init ~/my-tries
199
209
  ```nix
200
210
  {
201
211
  inputs.try.url = "github:tobi/try";
202
-
212
+
203
213
  imports = [ inputs.try.homeManagerModules.default ];
204
-
214
+
205
215
  programs.try = {
206
216
  enable = true;
207
217
  path = "~/experiments"; # optional, defaults to ~/src/tries
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.9.3
1
+ 1.10.0
data/lib/tui.rb CHANGED
@@ -90,14 +90,14 @@ module Tui
90
90
  module Palette
91
91
  HEADER = ANSI.sgr(1, "38;5;114")
92
92
  ACCENT = ANSI.sgr(1, "38;5;214")
93
- HIGHLIGHT = "\e[1;33m" # Bold yellow (matches C version)
93
+ HIGHLIGHT = "\e[1m" # Bold only, no fixed color: readable on any theme
94
94
  MUTED = ANSI.fg(245)
95
95
  MATCH = ANSI.sgr(1, "38;5;226")
96
96
  INPUT_HINT = ANSI.fg(244)
97
97
  INPUT_CURSOR_ON = "\e[7m"
98
98
  INPUT_CURSOR_OFF = "\e[27m"
99
99
 
100
- SELECTED_BG = ANSI.bg(238)
100
+ SELECTED_BG = "\e[7m" # reverse video: adapts to terminal's own colors, not just dark themes
101
101
  DANGER_BG = ANSI.bg(52)
102
102
  end
103
103
 
data/try.rb CHANGED
@@ -77,7 +77,7 @@ class TrySelector
77
77
  STDERR.print("#{Tui::ANSI::ALT_SCREEN_ON}#{Tui::ANSI.set_title("try")}#{Tui::ANSI::CURSOR_BLINK}")
78
78
  end
79
79
 
80
- @old_winch_handler = Signal.trap('WINCH') { @needs_redraw = true }
80
+ @old_winch_handler = Signal.trap('WINCH') { @needs_redraw = true } if Signal.list.key?('WINCH')
81
81
  end
82
82
 
83
83
  def restore_terminal
@@ -955,7 +955,7 @@ end
955
955
  # Main execution with OptionParser subcommands
956
956
  if __FILE__ == $0
957
957
 
958
- VERSION = "1.9.3"
958
+ VERSION = "1.10.0"
959
959
 
960
960
  def print_global_help
961
961
  text = <<~HELP
@@ -984,6 +984,7 @@ if __FILE__ == $0
984
984
  try Open interactive selector
985
985
  try project Selector with initial filter
986
986
  try clone https://github.com/user/repo
987
+ try https://github.com/user/repo/pull/123
987
988
  try worktree feature-branch
988
989
 
989
990
  Manual mode (without alias):
@@ -1053,19 +1054,44 @@ if __FILE__ == $0
1053
1054
  # https://gitlab.com/user/repo or other git hosts
1054
1055
  host, user, repo = $1, $2, $3
1055
1056
  return { user: user, repo: repo, host: host }
1056
- elsif uri.match(%r{^git@([^:]+):([^/]+)/([^/]+)})
1057
- # git@host:user/repo
1058
- host, user, repo = $1, $2, $3
1057
+ elsif uri.match(%r{^git@([^:]+):([^/]+)/(.+)})
1058
+ # git@host:user/path/to/repo
1059
+ host, user, path = $1, $2, $3
1060
+ repo = File.basename(path)
1061
+ return { user: user, repo: repo, host: host }
1062
+ elsif uri.match(%r{^ssh://[^@/]+@([^/]+)/([^/]+)/(.+)})
1063
+ # ssh://user@host:port/user/repo
1064
+ host, user, path = $1, $2, $3
1065
+ repo = File.basename(path)
1066
+ return { user: user, repo: repo, host: host }
1067
+ elsif uri.match(%r{^([^@/:]+)@([^:]+):(.+)})
1068
+ # SCP-style SSH: user@host:path/to/repo
1069
+ user, host, path = $1, $2, $3
1070
+ repo = File.basename(path)
1059
1071
  return { user: user, repo: repo, host: host }
1060
1072
  else
1061
1073
  return nil
1062
1074
  end
1063
1075
  end
1064
1076
 
1077
+ def github_pr_details(uri)
1078
+ return nil unless uri
1079
+
1080
+ match = uri.match(%r{\Ahttps?://(?:www\.)?github\.com/([^/]+)/([^/]+)/pull/(\d+)/?\z})
1081
+ return nil unless match
1082
+
1083
+ {
1084
+ user: match[1],
1085
+ repo: match[2].sub(/\.git\z/, ''),
1086
+ pr_id: match[3],
1087
+ git_uri: "https://github.com/#{match[1]}/#{match[2].sub(/\.git\z/, '')}.git"
1088
+ }
1089
+ end
1090
+
1065
1091
  def generate_clone_directory_name(git_uri, custom_name = nil)
1066
1092
  return custom_name if custom_name && !custom_name.empty?
1067
1093
 
1068
- parsed = parse_git_uri(git_uri)
1094
+ parsed = github_pr_details(git_uri) || parse_git_uri(git_uri)
1069
1095
  return nil unless parsed
1070
1096
 
1071
1097
  date_prefix = Time.now.strftime("%Y-%m-%d")
@@ -1166,7 +1192,12 @@ if __FILE__ == $0
1166
1192
  exit 1
1167
1193
  end
1168
1194
 
1169
- script_clone(File.join(tries_path, dir_name), git_uri)
1195
+ path = File.join(tries_path, dir_name)
1196
+ if pr = github_pr_details(git_uri)
1197
+ script_clone_pr(path, pr[:git_uri], pr[:pr_id])
1198
+ else
1199
+ script_clone(path, git_uri)
1200
+ end
1170
1201
  end
1171
1202
 
1172
1203
  def cmd_init!(args, tries_path)
@@ -1355,7 +1386,11 @@ if __FILE__ == $0
1355
1386
  exit 1
1356
1387
  end
1357
1388
  full_path = File.join(tries_path, dir_name)
1358
- return script_clone(full_path, git_uri)
1389
+ if pr = github_pr_details(git_uri)
1390
+ return script_clone_pr(full_path, pr[:git_uri], pr[:pr_id])
1391
+ else
1392
+ return script_clone(full_path, git_uri)
1393
+ end
1359
1394
  end
1360
1395
 
1361
1396
  # Regular interactive selector
@@ -1408,8 +1443,31 @@ if __FILE__ == $0
1408
1443
  end
1409
1444
  end
1410
1445
 
1446
+ # Emit best-effort terminal manager rename commands. Keep these as the final
1447
+ # commands so a missing or broken optional CLI never prevents the directory
1448
+ # change from completing.
1449
+ def terminal_rename_commands(path)
1450
+ name = File.basename(path).sub(/\A\d{4}-\d{2}-\d{2}-/, '')
1451
+ label = "try: #{name}"
1452
+
1453
+ if ENV['HERDR_ENV'] == '1' && ENV['HERDR_PANE_ID'] && !ENV['HERDR_PANE_ID'].empty?
1454
+ commands = [
1455
+ "command -v herdr >/dev/null 2>&1 && herdr pane report-metadata #{q(ENV['HERDR_PANE_ID'])} --source try --title #{q(label)} >/dev/null 2>&1 || true"
1456
+ ]
1457
+ if ENV['HERDR_PANE_ID'].match?(/:p1\z/) && ENV['HERDR_WORKSPACE_ID'] && !ENV['HERDR_WORKSPACE_ID'].empty?
1458
+ commands << "command -v herdr >/dev/null 2>&1 && herdr workspace rename #{q(ENV['HERDR_WORKSPACE_ID'])} #{q(label)} >/dev/null 2>&1 || true"
1459
+ end
1460
+ commands
1461
+ elsif (ENV['CMUX_SOCKET_PATH'] && !ENV['CMUX_SOCKET_PATH'].empty?) ||
1462
+ (ENV['CMUX_BUNDLE_ID'] && !ENV['CMUX_BUNDLE_ID'].empty?)
1463
+ ["command -v cmux >/dev/null 2>&1 && cmux rename-tab #{q(label)} >/dev/null 2>&1 || true"]
1464
+ else
1465
+ []
1466
+ end
1467
+ end
1468
+
1411
1469
  def script_cd(path)
1412
- ["touch #{q(path)}", "echo #{q(path)}", "cd #{q(path)}"]
1470
+ ["touch #{q(path)}", "echo #{q(path)}", "cd #{q(path)}"] + terminal_rename_commands(path)
1413
1471
  end
1414
1472
 
1415
1473
  def script_mkdir_cd(path)
@@ -1420,6 +1478,17 @@ if __FILE__ == $0
1420
1478
  ["mkdir -p #{q(path)}", "echo #{q("Using git clone to create this trial from #{uri}.")}", "git clone '#{uri}' #{q(path)}"] + script_cd(path)
1421
1479
  end
1422
1480
 
1481
+ def script_clone_pr(path, uri, pr_id)
1482
+ ref = "pull/#{pr_id}/head"
1483
+ [
1484
+ "mkdir -p #{q(path)}",
1485
+ "echo #{q("Using git clone to create this trial from #{uri} PR ##{pr_id}.")}",
1486
+ "git clone #{q(uri)} #{q(path)}",
1487
+ "git -C #{q(path)} fetch origin #{q(ref)}",
1488
+ "git -C #{q(path)} checkout --detach FETCH_HEAD"
1489
+ ] + script_cd(path)
1490
+ end
1491
+
1423
1492
  def script_worktree(path, repo = nil)
1424
1493
  r = repo ? q(repo) : nil
1425
1494
  worktree_cmd = if r
@@ -1463,7 +1532,7 @@ if __FILE__ == $0
1463
1532
  "mv #{q(old_name)} #{q(new_name)}",
1464
1533
  "echo #{q(new_path)}",
1465
1534
  "cd #{q(new_path)}"
1466
- ]
1535
+ ] + terminal_rename_commands(new_path)
1467
1536
  end
1468
1537
 
1469
1538
  # Return a unique directory name under tries_path by appending -2, -3, ... if needed
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: try-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.3
4
+ version: 1.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobi Lutke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-03-10 00:00:00.000000000 Z
11
+ date: 2026-08-08 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A CLI tool for managing experimental projects. Creates dated directories
14
14
  for your tries, with fuzzy search and easy navigation.