mirror of
https://github.com/jimeh/.vscode.d.git
synced 2026-02-19 11:26:39 +00:00
feat(ext): expand workspace recommended extensions to extensions shared between Cursor and VSCode
This is done via the help of a new `./siren shared` command, and the `.vscode/extensions.json` file.
This commit is contained in:
117
.vscode/extensions.json
vendored
117
.vscode/extensions.json
vendored
@@ -1,9 +1,112 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
|
||||
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
|
||||
// List of extensions which should be recommended for users of this workspace.
|
||||
"recommendations": [
|
||||
// Allows for use of settings.shared.json and settings.local.json.
|
||||
"swellaby.workspace-config-plus"
|
||||
]
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
|
||||
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
|
||||
// List of extensions which should be recommended for users of this workspace.
|
||||
"recommendations": [
|
||||
// Allows for use of settings.shared.json and settings.local.json.
|
||||
"swellaby.workspace-config-plus",
|
||||
// Below list is produced by `./siren shared --json`
|
||||
"alefragnani.project-manager",
|
||||
"anthropic.claude-code",
|
||||
"antiantisepticeye.vscode-color-picker",
|
||||
"antyos.openscad",
|
||||
"arrterian.nix-env-selector",
|
||||
"arturodent.command-alias",
|
||||
"bibhasdn.unique-lines",
|
||||
"bierner.github-markdown-preview",
|
||||
"bierner.markdown-checkbox",
|
||||
"bierner.markdown-emoji",
|
||||
"bierner.markdown-footnotes",
|
||||
"bierner.markdown-mermaid",
|
||||
"bierner.markdown-preview-github-styles",
|
||||
"bierner.markdown-yaml-preamble",
|
||||
"bmarkovic.haproxy",
|
||||
"bodil.file-browser",
|
||||
"britesnow.vscode-toggle-quotes",
|
||||
"bufbuild.vscode-buf",
|
||||
"carlos-algms.make-task-provider",
|
||||
"christian-kohler.path-intellisense",
|
||||
"connor4312.esbuild-problem-matchers",
|
||||
"connorshea.vscode-ruby-test-adapter",
|
||||
"ctf0.macros",
|
||||
"davidanson.vscode-markdownlint",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"dewski.simplecov",
|
||||
"dnut.rewrap-revived",
|
||||
"editorconfig.editorconfig",
|
||||
"elijah-potter.harper",
|
||||
"emeraldwalk.runonsave",
|
||||
"esbenp.prettier-vscode",
|
||||
"exiasr.hadolint",
|
||||
"fogio.inline-go-struct-tags-syntax-highlight",
|
||||
"github.remotehub",
|
||||
"github.vscode-github-actions",
|
||||
"github.vscode-pull-request-github",
|
||||
"gofenix.go-lines",
|
||||
"golang.go",
|
||||
"gruntfuggly.todo-tree",
|
||||
"hashicorp.terraform",
|
||||
"hbenl.vscode-test-explorer",
|
||||
"hoovercj.vscode-settings-cycler",
|
||||
"humao.rest-client",
|
||||
"hverlin.mise-vscode",
|
||||
"jakearl.search-editor-apply-changes",
|
||||
"jnoortheen.nix-ide",
|
||||
"joshbolduc.commitlint",
|
||||
"joshmu.periscope",
|
||||
"kahole.magit",
|
||||
"karunamurti.haml",
|
||||
"kilocode.kilo-code",
|
||||
"koichisasada.vscode-rdbg",
|
||||
"letrieu.expand-region",
|
||||
"llvm-vs-code-extensions.vscode-clangd",
|
||||
"m4ns0ur.base64",
|
||||
"mads-hartmann.bash-ide-vscode",
|
||||
"matthewpi.caddyfile-support",
|
||||
"mattn.lisp",
|
||||
"mermaidchart.vscode-mermaid-chart",
|
||||
"mhutchie.git-graph",
|
||||
"mkhl.direnv",
|
||||
"mrmlnc.vscode-duplicate",
|
||||
"ms-azuretools.vscode-containers",
|
||||
"ms-dotnettools.vscode-dotnet-runtime",
|
||||
"ms-kubernetes-tools.vscode-kubernetes-tools",
|
||||
"ms-python.debugpy",
|
||||
"ms-python.python",
|
||||
"ms-vscode.cmake-tools",
|
||||
"ms-vscode.extension-test-runner",
|
||||
"ms-vscode.hexeditor",
|
||||
"ms-vscode.remote-repositories",
|
||||
"ms-vscode.test-adapter-converter",
|
||||
"ms-vscode.vscode-speech",
|
||||
"ms-vsliveshare.vsliveshare",
|
||||
"openai.chatgpt",
|
||||
"pflannery.vscode-versionlens",
|
||||
"pkief.material-icon-theme",
|
||||
"pomdtr.excalidraw-editor",
|
||||
"redhat.vscode-xml",
|
||||
"redhat.vscode-yaml",
|
||||
"romanpeshkov.vscode-text-tables",
|
||||
"rrudi.vscode-dired",
|
||||
"rust-lang.rust-analyzer",
|
||||
"shopify.ruby-extensions-pack",
|
||||
"shopify.ruby-lsp",
|
||||
"sidneys1.gitconfig",
|
||||
"sorbet.sorbet-vscode-extension",
|
||||
"streetsidesoftware.code-spell-checker",
|
||||
"stuart.unique-window-colors",
|
||||
"sumneko.lua",
|
||||
"svelte.svelte-vscode",
|
||||
"swellaby.vscode-rust-test-adapter",
|
||||
"tamasfe.even-better-toml",
|
||||
"tootone.org-mode",
|
||||
"tuttieee.emacs-mcx",
|
||||
"tyriar.sort-lines",
|
||||
"vadimcn.vscode-lldb",
|
||||
"viktorzetterstrom.non-breaking-space-highlighter",
|
||||
"wenhoujx.swiper",
|
||||
"zhuangtongfa.material-theme",
|
||||
"ziyasal.vscode-open-in-github",
|
||||
"zxh404.vscode-proto3"
|
||||
]
|
||||
}
|
||||
|
||||
193
siren
193
siren
@@ -57,6 +57,48 @@ get_extensions_lock() {
|
||||
echo "${SCRIPT_DIR}/extensions.${SETUP_EDITOR}.lock"
|
||||
}
|
||||
|
||||
# Get extensions lockfile path for a specific editor name.
|
||||
# Does not rely on SETUP_EDITOR.
|
||||
extensions_lock_for_editor() {
|
||||
local editor_name="$1"
|
||||
echo "${SCRIPT_DIR}/extensions.${editor_name}.lock"
|
||||
}
|
||||
|
||||
# Normalize editor name/synonyms to canonical editor id.
|
||||
# Returns canonical id via STDOUT or empty string if unknown.
|
||||
normalize_editor_name() {
|
||||
local name
|
||||
name="$(echo "${1:-}" | tr '[:upper:]' '[:lower:]')"
|
||||
case "${name}" in
|
||||
cursor | c)
|
||||
echo "cursor"
|
||||
;;
|
||||
vscode | code | vsc | v)
|
||||
echo "vscode"
|
||||
;;
|
||||
vscode-insiders | code-insiders | insiders | vsci | i)
|
||||
echo "vscode-insiders"
|
||||
;;
|
||||
windsurf | wind | surf | w)
|
||||
echo "windsurf"
|
||||
;;
|
||||
kiro | k)
|
||||
echo "kiro"
|
||||
;;
|
||||
*)
|
||||
echo ""
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Read a lockfile and output sorted unique extension ids without versions.
|
||||
extensions_ids_from_lock() {
|
||||
local lock_path="$1"
|
||||
grep -Ev '^\s*(#|$)' "${lock_path}" |
|
||||
cut -d@ -f1 |
|
||||
sort -u
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# Help
|
||||
# ==============================================================================
|
||||
@@ -65,6 +107,7 @@ show_help() {
|
||||
cat << EOF
|
||||
Usage: $(basename "$0") EDITOR COMMAND [OPTIONS]
|
||||
$(basename "$0") config
|
||||
$(basename "$0") shared-extensions [--json] [EDITORS...]
|
||||
|
||||
Editors:
|
||||
cursor, c Cursor editor
|
||||
@@ -79,6 +122,10 @@ Commands:
|
||||
extensions, ext Install editor extensions from a lock file.
|
||||
install Install a specific extension by identifier (e.g., ms-python.python).
|
||||
If no version is specified, installs the latest version.
|
||||
shared-extensions, shared
|
||||
Print extensions present in all specified editors.
|
||||
Defaults to comparing: cursor, vscode
|
||||
Use --json to output a JSON array
|
||||
|
||||
Options:
|
||||
--latest When used with the extensions command, installs the
|
||||
@@ -1210,6 +1257,89 @@ do_install_extension() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# Compute and print the intersection of extensions across editors.
|
||||
do_shared_extensions() {
|
||||
local -a input_editors
|
||||
local -a editors
|
||||
local -A seen
|
||||
local arg
|
||||
local output_json="false"
|
||||
|
||||
# Parse optional flags (currently only --json)
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--json)
|
||||
output_json="true"
|
||||
shift
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
--*)
|
||||
fatal "Unknown option for shared-extensions: '$1'"
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ $# -eq 0 ]]; then
|
||||
input_editors=("cursor" "vscode")
|
||||
else
|
||||
input_editors=("$@")
|
||||
fi
|
||||
|
||||
# Normalize and deduplicate editors.
|
||||
for arg in "${input_editors[@]}"; do
|
||||
local norm
|
||||
norm="$(normalize_editor_name "${arg}")"
|
||||
if [[ -z "${norm}" ]]; then
|
||||
fatal "Unknown editor '${arg}'"
|
||||
fi
|
||||
if [[ -z "${seen[${norm}]:-}" ]]; then
|
||||
editors+=("${norm}")
|
||||
seen["${norm}"]=1
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ${#editors[@]} -eq 0 ]]; then
|
||||
fatal "No valid editors specified"
|
||||
fi
|
||||
|
||||
# Build intersection iteratively.
|
||||
local result=""
|
||||
local idx=0
|
||||
for arg in "${editors[@]}"; do
|
||||
local lock
|
||||
lock="$(extensions_lock_for_editor "${arg}")"
|
||||
if [[ ! -f "${lock}" ]]; then
|
||||
fatal "Lock file not found for ${arg}: ${lock}"
|
||||
fi
|
||||
|
||||
local current
|
||||
current="$(extensions_ids_from_lock "${lock}")"
|
||||
|
||||
if [[ ${idx} -eq 0 ]]; then
|
||||
result="${current}"
|
||||
else
|
||||
# 'comm' requires sorted input; our helper already sorts.
|
||||
result="$(comm -12 <(printf '%s\n' "${result}") \
|
||||
<(printf '%s\n' "${current}"))"
|
||||
fi
|
||||
idx=$((idx + 1))
|
||||
done
|
||||
|
||||
# Print final result.
|
||||
if [[ "${output_json}" == "true" ]]; then
|
||||
# Convert newline-separated list to JSON array using jq safely
|
||||
printf '%s\n' "${result}" | jq -R -s 'split("\n") | map(select(length>0))'
|
||||
else
|
||||
printf '%s\n' "${result}"
|
||||
fi
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# Main
|
||||
# ==============================================================================
|
||||
@@ -1224,18 +1354,39 @@ main() {
|
||||
fi
|
||||
|
||||
# Handle help command.
|
||||
if [[ "$1" == "help" || "$1" == "--help" || "$1" == "-h" ]]; then
|
||||
if [[ "$1" == "help" || " $* " == *" --help "* || " $* " == *" -h "* ]]; then
|
||||
show_help
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Handle standalone config command.
|
||||
# Normalize first argument.
|
||||
local first_arg
|
||||
first_arg="$(echo "${1}" | tr '[:upper:]' '[:lower:]')"
|
||||
if [[ "${first_arg}" == "config" || "${first_arg}" == "conf" ]]; then
|
||||
define_settings
|
||||
do_static_config
|
||||
exit 0
|
||||
|
||||
# Handle standalone top-level commands.
|
||||
case "${first_arg}" in
|
||||
config | conf)
|
||||
define_settings
|
||||
do_static_config
|
||||
exit 0
|
||||
;;
|
||||
shared-extensions | shared)
|
||||
shift 1
|
||||
# Remaining arguments are optional editor names
|
||||
do_shared_extensions "$@"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# Set editor from first argument using normalization.
|
||||
SETUP_EDITOR="$(normalize_editor_name "${first_arg}")"
|
||||
if [[ -z "${SETUP_EDITOR}" ]]; then
|
||||
error "Unsupported editor '${first_arg}'"
|
||||
show_help
|
||||
exit 1
|
||||
fi
|
||||
if [[ "${SETUP_EDITOR}" == "kiro" ]]; then
|
||||
PREFER_OPENVSX="true"
|
||||
fi
|
||||
|
||||
# Require at least two arguments from this point on (editor and command).
|
||||
@@ -1245,32 +1396,6 @@ main() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set editor from first argument.
|
||||
local editor="${first_arg}"
|
||||
case "${editor}" in
|
||||
"vscode" | "code" | "vsc" | "v")
|
||||
SETUP_EDITOR="vscode"
|
||||
;;
|
||||
"vscode-insiders" | "code-insiders" | "insiders" | "vsci" | "i")
|
||||
SETUP_EDITOR="vscode-insiders"
|
||||
;;
|
||||
"cursor" | "c")
|
||||
SETUP_EDITOR="cursor"
|
||||
;;
|
||||
"windsurf" | "wind" | "surf" | "w")
|
||||
SETUP_EDITOR="windsurf"
|
||||
;;
|
||||
"kiro" | "k")
|
||||
SETUP_EDITOR="kiro"
|
||||
PREFER_OPENVSX="true"
|
||||
;;
|
||||
*)
|
||||
error "Unsupported editor '${editor}'"
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Initialize settings now that SETUP_EDITOR is known.
|
||||
define_settings
|
||||
|
||||
@@ -1301,6 +1426,10 @@ main() {
|
||||
|
||||
# Handle commands.
|
||||
case "${command}" in
|
||||
"help" | "h")
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
"config" | "conf")
|
||||
do_config
|
||||
;;
|
||||
|
||||
Reference in New Issue
Block a user