Ostatnio aktywny 6 days ago

Bundled installer scripts. VS Code: install.{sh,ps1}. JetBrains IDEs (incl. Gateway / remote-dev-server): install-jetbrains.{sh,ps1}. Each script detects your OS (Windows / macOS / Ubuntu / WSL2) and is interactive.

weehong zrewidował ten Gist 2 weeks ago. Przejdź do rewizji

1 file changed, 20 insertions

typescript_react.json(stworzono plik)

@@ -0,0 +1,20 @@
1 + {
2 + "recommendations": [
3 + "dsznajder.es7-react-js-snippets",
4 + "planbcoding.vscode-react-refactor",
5 + "bradlc.vscode-tailwindcss",
6 + "WallabyJs.console-ninja",
7 + "ms-vscode.vscode-typescript-next",
8 + "yoavbls.pretty-ts-errors",
9 + "christian-kohler.path-intellisense",
10 + "christian-kohler.npm-intellisense",
11 + "dbaeumer.vscode-eslint",
12 + "esbenp.prettier-vscode",
13 + "usernamehw.errorlens",
14 + "eamodio.gitlens",
15 + "rangav.vscode-thunder-client",
16 + "formulahendry.auto-rename-tag",
17 + "GitHub.copilot",
18 + "Codeium.codeium"
19 + ]
20 + }

weehong zrewidował ten Gist 3 weeks ago. Przejdź do rewizji

Brak zmian

weehong zrewidował ten Gist 3 weeks ago. Przejdź do rewizji

1 file changed, 1 insertion, 1 deletion

install-jetbrains.sh

@@ -29,7 +29,7 @@ readonly PLUGIN_CATALOG=(
29 29 "izhangzhihao.rainbow.brackets|Rainbow Brackets"
30 30 "IdeaVIM|IdeaVim"
31 31 "org.sonarlint.idea|SonarQube for IDE (SonarLint)"
32 - "'Key Promoter X'|Key Promoter X"
32 + "Key Promoter X|Key Promoter X"
33 33 "net.ashald.envfile|EnvFile"
34 34 "org.intellij.qodana|Qodana"
35 35 )

weehong zrewidował ten Gist 3 weeks ago. Przejdź do rewizji

1 file changed, 1 insertion, 1 deletion

install-jetbrains.sh

@@ -29,7 +29,7 @@ readonly PLUGIN_CATALOG=(
29 29 "izhangzhihao.rainbow.brackets|Rainbow Brackets"
30 30 "IdeaVIM|IdeaVim"
31 31 "org.sonarlint.idea|SonarQube for IDE (SonarLint)"
32 - "9792|Key Promoter X"
32 + "'Key Promoter X'|Key Promoter X"
33 33 "net.ashald.envfile|EnvFile"
34 34 "org.intellij.qodana|Qodana"
35 35 )

weehong zrewidował ten Gist 3 weeks ago. Przejdź do rewizji

1 file changed, 2 insertions, 2 deletions

install-jetbrains.sh

@@ -500,7 +500,7 @@ handle_single_instance_abort() {
500 500 shift 2
501 501 echo
502 502 echo " ! '${ide_label}' is still running. Skipping remaining plugins for this IDE." >&2
503 - echo " ! Close the IDE and re-run the script to finish." >&2
503 + echo " ! Close the IDE and re-run the script to finish." >&2
504 504 # Mark current and remaining-for-this-IDE plugins as failed.
505 505 local mark_from=0 p
506 506 for p in "${SELECTED_PLUGIN_IDS[@]}"; do
@@ -520,7 +520,7 @@ for ide_label in "${SELECTED_IDES[@]}"; do
520 520 ide_aborted=0
521 521 for pid in "${SELECTED_PLUGIN_IDS[@]}"; do
522 522 (( ide_aborted )) && break
523 - printf ' %-34s ' "$pid"
523 + printf ' %-34s ' "$pid"
524 524 rc=0
525 525 case "$itype" in
526 526 ide|remotedev)

weehong zrewidował ten Gist 1 month ago. Przejdź do rewizji

Brak zmian

weehong zrewidował ten Gist 1 month ago. Przejdź do rewizji

Brak zmian

weehong zrewidował ten Gist 1 month ago. Przejdź do rewizji

1 file changed, 66 insertions, 20 deletions

install-jetbrains.sh

@@ -9,8 +9,9 @@
9 9 #
10 10 # Picker UX:
11 11 # - Uses fzf with --multi when fzf is on PATH (TAB to toggle, Enter to confirm).
12 - # - Otherwise prints a numbered list and accepts comma-separated indexes
13 - # (e.g. "1,3,5") or "a" for all.
12 + # - Otherwise prints a numbered list and accepts space-separated indexes
13 + # (e.g. "1 3 5"), exclusions (e.g. "!1 !4" to select all except 1 and 4),
14 + # or "a" for all.
14 15 #
15 16 # Usage:
16 17 # ./install-jetbrains.sh # interactive
@@ -28,7 +29,7 @@ readonly PLUGIN_CATALOG=(
28 29 "izhangzhihao.rainbow.brackets|Rainbow Brackets"
29 30 "IdeaVIM|IdeaVim"
30 31 "org.sonarlint.idea|SonarQube for IDE (SonarLint)"
31 - "Key Promoter X|Key Promoter X"
32 + "9792|Key Promoter X"
32 33 "net.ashald.envfile|EnvFile"
33 34 "org.intellij.qodana|Qodana"
34 35 )
@@ -260,7 +261,7 @@ if [[ ${#CANDIDATES[@]} -eq 0 ]]; then
260 261 fi
261 262
262 263 # ------------------------------------------------------------------
263 - # Multi-select picker
264 + # Multi-select picker (Handles Space separation & Exclusions via !)
264 265 # Reads newline-separated options on stdin, prints selected lines on stdout.
265 266 # ------------------------------------------------------------------
266 267 pick_multi() {
@@ -270,7 +271,7 @@ pick_multi() {
270 271 return
271 272 fi
272 273
273 - # Fallback: numbered list + comma-input.
274 + # Fallback: numbered list + space-separated input with exclusion support.
274 275 local -a items=()
275 276 local line
276 277 while IFS= read -r line; do items+=("$line"); done
@@ -282,7 +283,7 @@ pick_multi() {
282 283 for (( i=0; i<total; i++ )); do
283 284 printf ' %2d) %s\n' "$((i+1))" "${items[i]}"
284 285 done
285 - printf '%s' "$prompt (e.g. 1,3,5 or a for all): "
286 + printf '%s' "$prompt (e.g. 1 3, !2 to exclude 2, or a for all): "
286 287 } >&2
287 288
288 289 local input
@@ -295,18 +296,63 @@ pick_multi() {
295 296 printf '%s\n' "${items[@]}"
296 297 return
297 298 fi
298 - [[ -z "$input" ]] && { echo " please enter at least one number, or 'a'." >&2; continue; }
299 -
300 - local -a picked=() bad=0
301 - local tok
302 - IFS=',' read -r -a toks <<<"$input"
303 - for tok in "${toks[@]}"; do
304 - tok="${tok// /}"
305 - [[ -z "$tok" ]] && continue
306 - if [[ ! "$tok" =~ ^[0-9]+$ ]]; then bad=1; break; fi
307 - if (( tok < 1 || tok > total )); then bad=1; break; fi
308 - picked+=("${items[tok-1]}")
299 + [[ -z "$input" ]] && { echo " please enter at least one number, an exclusion, or 'a'." >&2; continue; }
300 +
301 + local -a toks=()
302 + IFS=' ' read -r -a toks <<<"$input"
303 +
304 + # Determine if this is an exclusion request (checks if any token starts with !)
305 + local is_exclusion=0
306 + local t
307 + for t in "${toks[@]}"; do
308 + if [[ "$t" =~ ^\! ]]; then
309 + is_exclusion=1
310 + break
311 + fi
309 312 done
313 +
314 + local -a picked=()
315 + local bad=0
316 +
317 + if (( is_exclusion )); then
318 + # Track which indices are explicitly excluded using an associative array map
319 + local -A excluded_map=()
320 +
321 + for t in "${toks[@]}"; do
322 + [[ -z "$t" ]] && continue
323 + if [[ ! "$t" =~ ^\![0-9]+$ ]]; then
324 + echo " Error: When using exclusions, all items must start with '!' (e.g., !1 !3)" >&2
325 + bad=1
326 + break
327 + fi
328 +
329 + local idx="${t#\!}" # Strip the '!' character
330 + if (( idx < 1 || idx > total )); then bad=1; break; fi
331 + excluded_map[$((idx-1))]=1
332 + done
333 +
334 + if (( bad )); then
335 + echo " invalid exclusion input; try again." >&2
336 + continue
337 + fi
338 +
339 + # Build final selection list by adding everything NOT in our exclusion map
340 + for (( i=0; i<total; i++ )); do
341 + if [[ -z "${excluded_map[$i]+abc}" ]]; then
342 + picked+=("${items[i]}")
343 + fi
344 + done
345 + else
346 + # Standard additive parsing (space-separated)
347 + for t in "${toks[@]}"; do
348 + t="${t// /}"
349 + [[ -z "$t" ]] && continue
350 + if [[ ! "$t" =~ ^[0-9]+$ ]]; then bad=1; break; fi
351 + if (( t < 1 || t > total )); then bad=1; break; fi
352 + picked+=("${items[t-1]}")
353 + done
354 + fi
355 +
310 356 if (( bad )); then
311 357 echo " invalid input; try again." >&2
312 358 continue
@@ -340,7 +386,7 @@ done
340 386 echo "Detected ${#CANDIDATES[@]} JetBrains target(s)."
341 387 mapfile -t SELECTED_IDES < <(
342 388 printf '%s\n' "${ide_lines[@]}" |
343 - pick_multi "IDEs>" "Pick IDE(s) — TAB to toggle (fzf) or comma indexes"
389 + pick_multi "IDEs>" "Pick IDE(s) — TAB to toggle (fzf) or spaced indexes"
344 390 )
345 391
346 392 if (( ${#SELECTED_IDES[@]} == 0 )); then
@@ -362,7 +408,7 @@ done
362 408
363 409 mapfile -t SELECTED_PLUGIN_LINES < <(
364 410 printf '%s\n' "${plugin_lines[@]}" |
365 - pick_multi "Plugins>" "Pick plugin(s) — TAB to toggle (fzf) or comma indexes"
411 + pick_multi "Plugins>" "Pick plugin(s) — TAB to toggle (fzf) or spaced indexes"
366 412 )
367 413
368 414 if (( ${#SELECTED_PLUGIN_LINES[@]} == 0 )); then
@@ -510,4 +556,4 @@ if (( failed > 0 )); then
510 556 echo " - $f" >&2
511 557 done
512 558 exit 1
513 - fi
559 + fi

weehong zrewidował ten Gist 1 month ago. Przejdź do rewizji

1 file changed, 5 insertions, 5 deletions

README.md

@@ -19,15 +19,15 @@ Replace `<GIST>` with the raw base of this Gist (everything up to and including
19 19
20 20 ```bash
21 21 # macOS / Ubuntu (default profile)
22 - curl -sSL <GIST>/install.sh | bash
22 + curl -sSL https://opengist.rmrf.online/weehong/b2a7c0a2ae6d40e8a14f8d85964a9186/raw/HEAD/install.sh | bash
23 23
24 24 # named profile
25 - bash <(curl -sSL <GIST>/install.sh) --profile "WorkSetup"
25 + bash <(curl -sSL https://opengist.rmrf.online/weehong/b2a7c0a2ae6d40e8a14f8d85964a9186/raw/HEAD/install.sh) --profile "WorkSetup"
26 26 ```
27 27
28 28 ```powershell
29 29 # Windows
30 - iwr -useb <GIST>/install.ps1 | iex
30 + iwr -useb https://opengist.rmrf.online/weehong/b2a7c0a2ae6d40e8a14f8d85964a9186/raw/HEAD/install.ps1 | iex
31 31
32 32 # named profile
33 33 .\install.ps1 -ProfileName "WorkSetup"
@@ -37,12 +37,12 @@ iwr -useb <GIST>/install.ps1 | iex
37 37
38 38 ```bash
39 39 # macOS / Ubuntu / WSL2 — interactive picker for IDEs and plugins
40 - bash <(curl -sSL <GIST>/install-jetbrains.sh)
40 + bash <(curl -sSL https://opengist.rmrf.online/weehong/b2a7c0a2ae6d40e8a14f8d85964a9186/raw/HEAD/install-jetbrains.sh)
41 41 ```
42 42
43 43 ```powershell
44 44 # Windows — interactive picker
45 - iwr -useb <GIST>/install-jetbrains.ps1 | iex
45 + iwr -useb https://opengist.rmrf.online/weehong/b2a7c0a2ae6d40e8a14f8d85964a9186/raw/HEAD/install-jetbrains.ps1 | iex
46 46 ```
47 47
48 48 ---

weehong zrewidował ten Gist 1 month ago. Przejdź do rewizji

3 files changed, 147 insertions, 22 deletions

README.md

@@ -151,6 +151,8 @@ powershell -ExecutionPolicy Bypass -File .\install.ps1
151 151
152 152 **`installPlugins` reports a plugin is already installed.** Harmless — it's a no-op. Both scripts treat it as success.
153 153
154 + **"Only one instance of IDEA can be run at a time."** The IDE is currently open and holds the config-dir lock. Both JetBrains installers run a preflight check before installing: if a target IDE looks running, they prompt you to close it and press Enter to retry. If a process slips past the preflight, the install loop short-circuits with the same hint instead of repeating the error per plugin.
155 +
154 156 **No JetBrains IDEs detected.** Install one via the [JetBrains Toolbox](https://www.jetbrains.com/toolbox-app/) (which sets up the standard paths the script scans), or install standalone — both layouts are supported.
155 157
156 158 **WSL2 picker is empty.** Verify the Windows username is resolved: in WSL run `cmd.exe /c 'echo %USERNAME%'`. If that prints nothing, your `interop.appendWindowsPath` may be disabled; either re-enable it in `/etc/wsl.conf` or run `install-jetbrains.ps1` natively on Windows instead.

install-jetbrains.ps1

@@ -211,6 +211,39 @@ if ($selectedPlugins.Count -eq 0) {
211 211 exit 1
212 212 }
213 213
214 + # ------------------------------------------------------------------
215 + # Running-IDE preflight
216 + # installPlugins refuses to run while the IDE GUI holds the config-dir lock
217 + # ("Only one instance of IDEA can be run at a time."). Best-effort detection
218 + # via Get-Process. Gateway Client type doesn't need this (no CLI invoked).
219 + # ------------------------------------------------------------------
220 + function Test-IdeRunning {
221 + param([Parameter(Mandatory)] [psobject]$Ide)
222 + if ($Ide.Type -eq 'Gateway') { return $false }
223 +
224 + # For standalone IDE launchers the process name is the exe basename.
225 + # For Toolbox .cmd shims, the spawned process is e.g. idea64 -> use prefix.
226 + $stem = [System.IO.Path]::GetFileNameWithoutExtension($Ide.Launcher)
227 + $patterns = @($stem)
228 + if ($stem -notmatch '64$') { $patterns += ($stem + '64') }
229 +
230 + foreach ($pat in $patterns) {
231 + if (Get-Process -Name $pat -ErrorAction SilentlyContinue) { return $true }
232 + }
233 + return $false
234 + }
235 +
236 + while ($true) {
237 + $running = @($selectedIdes | Where-Object { Test-IdeRunning $_ })
238 + if ($running.Count -eq 0) { break }
239 +
240 + Write-Host ""
241 + Write-Host "The following IDE(s) appear to be running — installPlugins needs them closed:" -ForegroundColor Yellow
242 + foreach ($r in $running) { Write-Host (" - {0}" -f $r.Label) -ForegroundColor Yellow }
243 + Write-Host ""
244 + Read-Host "Close them, then press Enter to retry (Ctrl+C to abort)" | Out-Null
245 + }
246 +
214 247 # ------------------------------------------------------------------
215 248 # Install loop
216 249 # ------------------------------------------------------------------
@@ -236,10 +269,16 @@ foreach ($ide in $selectedIdes) {
236 269 Write-Host (" all {0} plugin(s) ok" -f $selectedPlugins.Count) -ForegroundColor Green
237 270 $installed += $selectedPlugins.Count
238 271 } else {
239 - Write-Host (" installPlugins exited {0} FAILED" -f $LASTEXITCODE) -ForegroundColor Red
272 + $joined = ($output | Out-String)
273 + if ($joined -match 'Only one instance') {
274 + Write-Host " IDE is running SKIPPED" -ForegroundColor Yellow
275 + Write-Host " Close the IDE and re-run the script to finish." -ForegroundColor DarkYellow
276 + } else {
277 + Write-Host (" installPlugins exited {0} FAILED" -f $LASTEXITCODE) -ForegroundColor Red
278 + $output | ForEach-Object { Write-Host " $_" -ForegroundColor DarkRed }
279 + }
240 280 $failed += $selectedPlugins.Count
241 281 foreach ($p in $selectedPlugins) { $failedList += ("{0} :: {1}" -f $ide.Label, $p.Id) }
242 - $output | ForEach-Object { Write-Host " $_" -ForegroundColor DarkRed }
243 282 }
244 283 } catch {
245 284 Write-Host (" launcher invocation threw FAILED") -ForegroundColor Red
@@ -258,10 +297,16 @@ foreach ($ide in $selectedIdes) {
258 297 Write-Host (" all {0} plugin(s) ok" -f $selectedPlugins.Count) -ForegroundColor Green
259 298 $installed += $selectedPlugins.Count
260 299 } else {
261 - Write-Host (" installPlugins exited {0} FAILED" -f $LASTEXITCODE) -ForegroundColor Red
300 + $joined = ($output | Out-String)
301 + if ($joined -match 'Only one instance') {
302 + Write-Host " IDE is running SKIPPED" -ForegroundColor Yellow
303 + Write-Host " Close the IDE and re-run the script to finish." -ForegroundColor DarkYellow
304 + } else {
305 + Write-Host (" installPlugins exited {0} FAILED" -f $LASTEXITCODE) -ForegroundColor Red
306 + $output | ForEach-Object { Write-Host " $_" -ForegroundColor DarkRed }
307 + }
262 308 $failed += $selectedPlugins.Count
263 309 foreach ($p in $selectedPlugins) { $failedList += ("{0} :: {1}" -f $ide.Label, $p.Id) }
264 - $output | ForEach-Object { Write-Host " $_" -ForegroundColor DarkRed }
265 310 }
266 311 } catch {
267 312 Write-Host (" cmd.exe invocation threw FAILED") -ForegroundColor Red

install-jetbrains.sh

@@ -375,6 +375,66 @@ for line in "${SELECTED_PLUGIN_LINES[@]}"; do
375 375 SELECTED_PLUGIN_IDS+=("${label_to_id[$line]}")
376 376 done
377 377
378 + # ------------------------------------------------------------------
379 + # Running-IDE preflight
380 + # JetBrains' `installPlugins` refuses to run while the IDE GUI is open
381 + # ("Only one instance of IDEA can be run at a time."). We do a best-effort
382 + # pgrep against the IDE app directory so the user can close them upfront
383 + # instead of seeing N identical errors during the install loop.
384 + # ------------------------------------------------------------------
385 + ide_is_running() {
386 + local launcher="$1" type="$2"
387 +
388 + # remote-dev-server.sh spawns short-lived workers; WSL2->Windows lookups
389 + # would need tasklist.exe — skip in both cases.
390 + case "$type" in
391 + remotedev|wincmd) return 1 ;;
392 + esac
393 +
394 + case "$launcher" in
395 + */Toolbox/apps/*)
396 + # /.../Toolbox/apps/<ide-dir>/[ch-N/<ver>/]bin/idea.sh -> match "<ide-dir>"
397 + local rest="${launcher#*/Toolbox/apps/}"
398 + local ide_dir="${rest%%/*}"
399 + [[ -n "$ide_dir" ]] && pgrep -f -- "/Toolbox/apps/${ide_dir}/" >/dev/null 2>&1
400 + ;;
401 + */Applications/*.app/*)
402 + local app_path="${launcher%/Contents/MacOS/*}"
403 + pgrep -f -- "${app_path}/Contents/" >/dev/null 2>&1
404 + ;;
405 + *)
406 + local b
407 + b="$(basename "$launcher")"
408 + b="${b%.sh}"
409 + pgrep -fi -- "$b" >/dev/null 2>&1
410 + ;;
411 + esac
412 + }
413 +
414 + while :; do
415 + declare -a _running=()
416 + for ide_label in "${SELECTED_IDES[@]}"; do
417 + if ide_is_running "${label_launcher[$ide_label]}" "${label_type[$ide_label]}"; then
418 + _running+=("$ide_label")
419 + fi
420 + done
421 + (( ${#_running[@]} == 0 )) && break
422 +
423 + {
424 + echo
425 + echo "The following IDE(s) appear to be running — installPlugins needs them closed:"
426 + for r in "${_running[@]}"; do
427 + echo " - $r"
428 + done
429 + echo
430 + printf 'Close them, then press Enter to retry (or Ctrl+C to abort): '
431 + } >&2
432 + if ! IFS= read -r _ </dev/tty; then
433 + echo "no tty; aborting" >&2
434 + exit 1
435 + fi
436 + done
437 +
378 438 # ------------------------------------------------------------------
379 439 # Install loop
380 440 # ------------------------------------------------------------------
@@ -389,37 +449,55 @@ echo
389 449 echo "Installing ${#SELECTED_PLUGIN_IDS[@]} plugin(s) into ${#SELECTED_IDES[@]} IDE(s)..."
390 450 echo
391 451
452 + handle_single_instance_abort() {
453 + local ide_label="$1" current_pid="$2"
454 + shift 2
455 + echo
456 + echo " ! '${ide_label}' is still running. Skipping remaining plugins for this IDE." >&2
457 + echo " ! Close the IDE and re-run the script to finish." >&2
458 + # Mark current and remaining-for-this-IDE plugins as failed.
459 + local mark_from=0 p
460 + for p in "${SELECTED_PLUGIN_IDS[@]}"; do
461 + if (( mark_from )) || [[ "$p" == "$current_pid" ]]; then
462 + mark_from=1
463 + failed=$((failed + 1))
464 + FAILED_LIST+=("${ide_label} :: ${p} (IDE running — close it and re-run)")
465 + fi
466 + done
467 + }
468 +
392 469 for ide_label in "${SELECTED_IDES[@]}"; do
393 470 itype="${label_type[$ide_label]}"
394 471 launcher="${label_launcher[$ide_label]}"
395 472
396 473 echo ">>> $ide_label"
474 + ide_aborted=0
397 475 for pid in "${SELECTED_PLUGIN_IDS[@]}"; do
476 + (( ide_aborted )) && break
398 477 printf ' %-34s ' "$pid"
478 + rc=0
399 479 case "$itype" in
400 480 ide|remotedev)
401 - if "$launcher" installPlugins "$pid" >"$LOG_FILE" 2>&1; then
402 - echo "ok"
403 - installed=$((installed + 1))
404 - else
405 - echo "FAILED"
406 - failed=$((failed + 1))
407 - FAILED_LIST+=("${ide_label} :: ${pid}")
408 - sed 's/^/ /' "$LOG_FILE" >&2 || true
409 - fi
481 + "$launcher" installPlugins "$pid" >"$LOG_FILE" 2>&1 || rc=$?
410 482 ;;
411 483 wincmd)
412 - if cmd.exe /c "$launcher" installPlugins "$pid" >"$LOG_FILE" 2>&1; then
413 - echo "ok"
414 - installed=$((installed + 1))
415 - else
416 - echo "FAILED"
417 - failed=$((failed + 1))
418 - FAILED_LIST+=("${ide_label} :: ${pid}")
419 - sed 's/^/ /' "$LOG_FILE" >&2 || true
420 - fi
484 + cmd.exe /c "$launcher" installPlugins "$pid" >"$LOG_FILE" 2>&1 || rc=$?
421 485 ;;
422 486 esac
487 +
488 + if (( rc == 0 )); then
489 + echo "ok"
490 + installed=$((installed + 1))
491 + elif grep -q "Only one instance" "$LOG_FILE" 2>/dev/null; then
492 + echo "SKIPPED"
493 + handle_single_instance_abort "$ide_label" "$pid"
494 + ide_aborted=1
495 + else
496 + echo "FAILED"
497 + failed=$((failed + 1))
498 + FAILED_LIST+=("${ide_label} :: ${pid}")
499 + sed 's/^/ /' "$LOG_FILE" >&2 || true
500 + fi
423 501 done
424 502 echo
425 503 done