Created
January 22, 2025 02:59
-
-
Save kigster/fcf644441be8f5d9e1c5434ca9f1723a to your computer and use it in GitHub Desktop.
Import VSCode Extensions into Cursor via CLI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# vim: ft=bash | |
# | |
# © 2025 Konstantin Gredeskoul | |
# http://github.com/kigster | https://kig.re | |
# | |
# This script allows you to export the list of your VSCode | |
# extensions and import them into, eg. Cursor IDE. Or the | |
# other way around. By the default the script continues on | |
# import errors because there are typically quite a few. | |
# If you'd rather it abort upon an error, then pass -s flag. | |
# | |
# USAGE: | |
# code --list-extensions > extensions.list | |
# ./cursor-extension-importer.sh cursor extensions.list | |
#–————————————————————————————————————————————————————————— | |
set +e | |
export script="$(basename $0)" | |
export ignore_errors=true | |
main() { | |
local executable="${1:-"cursor"}" | |
local extension_list="${2:-"extensions.list"}" | |
if [[ $* =~ -h|--help || -z "$*" ]]; then | |
usage | |
return 0 | |
fi | |
if [[ $* =~ -s|--strict ]]; then | |
export ignore_errors=false | |
fi | |
command -V "${executable}" >/dev/null 2>&1 || { | |
echo "ERROR: executable [${executable}] is not in the \$PATH" | |
return 1 | |
} | |
[[ -s "${extension_list}" ]] || { | |
echo "ERROR: extension listing file [${extension_list}] does not exist or is empty." | |
echo " HINT: generate the file with eg 'code --list-extensions > extensions.list'." | |
return 2 | |
} | |
local -a extensions | |
extensions=( $(tr '\n' ' ' <${extension_list}) ) | |
local existing_extensions=$(mktemp) | |
${executable} --list-extensions > ${existing_extensions} 2>&1 | |
echo "Installing ${#extensions[@]} extensions..." | |
${ignore_errors} || set -e | |
local extension | |
local code | |
local -a failures | |
for extension in "${extensions[@]}"; do | |
printf "\n→ \e[4;33m%-40.40s \e[0m\n" \ | |
"${extension}" | |
grep -q -E "^${extension}$" ${existing_extensions} && { | |
printf "→ \e[0;32mAlready installed, skipping.\e[0m\n" | |
continue | |
} | |
${executable} --force --install-extension ${extension} | |
code=$? | |
if [[ ${code} -ne 0 ]] ; then | |
failures+=( ${extension} ) | |
printf "\n→ \e[4;34mIgnoring error and continuing...\e[0m\n" | |
fi | |
done | |
if [[ ${#failures[@]} -gt 0 ]]; then | |
local error_file="${extension_list}.errors" | |
printf "\n\e[0;33mWARNING:\e[0m" | |
printf "The following extensions failed to install:\n" | |
echo "NOTE: the list is also saved into the file [${error_file}]." | |
# dump them to stderr AND and a file | |
echo "${failures[@]}" | tr ' ' '\n' >&2 | |
echo "${failures[@]}" | tr ' ' '\n' >"${error_file}" | |
fi | |
return "${#failures[@]}" | |
} | |
usage() { | |
printf "\ | |
\e[1;34mDESCRIPTION:\e[0m | |
This script allows you to export the list of your VSCode | |
extensions and import them into, eg. Cursor IDE. Or the | |
other way around. By the default the script continues on | |
import errors because there are typically quite a few. | |
If you'd rather it abort upon an error, then pass -s flag. | |
\e[1;34mUSAGE:\e[0m | |
\e[0;33m./${script} executable extensions-list [ -s | --strict ]\e[0m | |
\e[1;34mFLAGS:\e[0m | |
-s | --strict If passed causes the script to abort | |
upon ANY error importing the extension. | |
-h | --help This help message. Doh! | |
\e[1;34mEXAMPLE:\e[0m | |
\e[1mImport VSCode Extensions into Cursor\e[0m | |
Assuming your VSCode command is 'code' (the 'executable' | |
argument in the usage above) and your Cursor AI command is | |
'cursor', and you'd like to migrate extensions from VSCode | |
to Cursor, you would then run:\e[0;32m | |
code --list-extensions > extensions.list | |
\e[3;37m# Potentially edit the list manually \e[0;32m | |
vim extensions.list | |
./${script} cursor extensions.list\e[0m | |
NOTE: while the export step could've been automated, we | |
chose this method because it allows you to manually edit | |
the extensions.list file before importing it and remove | |
any extensions you do not want to have in both places. | |
The script's exit code is the number of failed extensions. | |
The list of failed extensions will be also dumped to a file. | |
\e[0m" | |
} | |
main "$@" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment