Skip to content

Instantly share code, notes, and snippets.

@HallexCosta
Last active April 24, 2025 13:30
Show Gist options
  • Save HallexCosta/5612b0ee81e88028f09802fcebcde7de to your computer and use it in GitHub Desktop.
Save HallexCosta/5612b0ee81e88028f09802fcebcde7de to your computer and use it in GitHub Desktop.
Quickly Simple CLI to download, install, update and create desktop entry icons for Cursor AI IDE for Ubuntu (24.04)
#!/bin/bash
# Cursor IDE Manager
# A CLI tool to manage Cursor IDE installation, updates and customization on Linux
# Usage: ./cursor.sh
# Author: Hallex Costa
# Check if running on Linux
if [ "$(uname)" != "Linux" ]; then
echo "╔════════════════════════════════════════════════════════════╗"
echo "║ WARNING ║"
echo "║ This script is currently only compatible with Linux. ║"
echo "║ Support for other operating systems coming soon. ║"
echo "╚════════════════════════════════════════════════════════════╝"
exit 1
fi
# Constants for URLs and version history
VERSION_HISTORY_URL="https://raw.githubusercontent.com/oslook/cursor-ai-downloads/refs/heads/main/version-history.json"
ICON_URL="https://gist.github.com/user-attachments/assets/60c27c41-cc6d-4f66-b039-091ce8448454"
# Local installation paths following XDG Base Directory Specification
LOCAL_BIN="$HOME/.local/bin"
LOCAL_SHARE="$HOME/.local/share"
APPIMAGE_PATH="$LOCAL_BIN/cursor"
ICON_PATH="$LOCAL_SHARE/icons/cursor.png"
DESKTOP_ENTRY_PATH="$LOCAL_SHARE/applications/cursor.desktop"
# Function to create required local directories
createDirectories() {
mkdir -p "$LOCAL_BIN"
mkdir -p "$(dirname "$ICON_PATH")"
mkdir -p "$(dirname "$DESKTOP_ENTRY_PATH")"
}
# Function to fetch and display available versions
getVersions() {
echo "Fetching available versions..."
if ! curl -s "$VERSION_HISTORY_URL" > "/tmp/cursor_versions.json"; then
echo "Failed to fetch version history."
exit 1
fi
# Parse versions using jq if available, otherwise use grep
if command -v jq >/dev/null 2>&1; then
# Display versions in a formatted table with dates
echo "╔═══════════════════════════════════════════╗"
echo "║ Available Versions ║"
echo "╠═══════════════════════════════════════════╣"
echo "║ # │ Version │ Release Date ║"
echo "╟─────┼─────────┼────────────────────────╢"
versions=$(jq -r '.versions[] | "\(.version)|\(.date)"' "/tmp/cursor_versions.json")
number=1
while IFS='|' read -r version date; do
printf "║ %2d │ %-7s │ %-22s ║\n" "$number" "$version" "$date"
number=$((number + 1))
done <<< "$versions"
echo "╚═══════════════════════════════════════════╝"
else
# Fallback to simple version list if jq is not available
versions=$(grep -o '"version": "[^"]*"' "/tmp/cursor_versions.json" | cut -d'"' -f4)
echo "Available Versions:"
echo "$versions" | nl
fi
echo
echo "Enter the number of the version you want to install (1-$((number-1))):"
read -r version_number
# Extract version information based on user selection
if command -v jq >/dev/null 2>&1; then
selected_version=$(jq -r ".versions[$((version_number-1))].version" "/tmp/cursor_versions.json")
selected_date=$(jq -r ".versions[$((version_number-1))].date" "/tmp/cursor_versions.json")
else
selected_version=$(echo "$versions" | sed -n "${version_number}p" | cut -d'|' -f1)
fi
if [ -z "$selected_version" ]; then
echo "Invalid version number"
exit 1
fi
# Get download URL for selected version
if command -v jq >/dev/null 2>&1; then
download_url=$(jq -r ".versions[] | select(.version == \"$selected_version\") | .platforms.\"linux-x64\"" "/tmp/cursor_versions.json")
else
download_url=$(grep -A10 "\"version\": \"$selected_version\"" "/tmp/cursor_versions.json" | grep "linux-x64" | cut -d'"' -f4)
fi
echo
echo "Selected version: $selected_version"
if [ ! -z "$selected_date" ]; then
echo "Release date: $selected_date"
fi
echo "Download URL: $download_url"
echo
CURSOR_URL="$download_url"
}
# Function to update icon only
updateIcon() {
echo "Downloading Cursor icon..."
curl -L "$ICON_URL" -o "/tmp/cursor.png" || { echo "Failed to download icon."; exit 1; }
echo "Moving icon to $ICON_PATH..."
mv "/tmp/cursor.png" "$ICON_PATH"
echo "Icon updated successfully!"
}
# Function to create desktop entry following freedesktop.org specifications
createDesktopEntry() {
echo "Creating cursor.desktop entry..."
cat > "$DESKTOP_ENTRY_PATH" <<EOL
[Desktop Entry]
Name=Cursor AI
Comment=A modern IDE powered by AI
Exec=$APPIMAGE_PATH --no-sandbox
Icon=cursor
Type=Application
Categories=Development;
StartupWMClass=cursor
EOL
# Update desktop database to register the new entry
update-desktop-database "$LOCAL_SHARE/applications" 2>/dev/null || true
echo "Desktop entry created at $DESKTOP_ENTRY_PATH"
}
# Function to perform fresh Cursor installation
installCursor() {
echo "Installing Cursor..."
# Get version list and selection
getVersions
# Create required directories
createDirectories
# Download and install AppImage
echo "Downloading Cursor AppImage..."
curl -L "$CURSOR_URL" -o "/tmp/cursor.appimage" || { echo "Failed to download AppImage."; exit 1; }
# Set up installation files
echo "Installing Cursor files..."
mv "/tmp/cursor.appimage" "$APPIMAGE_PATH"
chmod +x "$APPIMAGE_PATH"
# Configure desktop integration
updateIcon
createDesktopEntry
echo "Cursor AI IDE installation complete!"
echo "Please log out and log back in for the desktop entry to take effect."
echo "You can now run Cursor by typing 'cursor' in terminal or from your application menu."
}
# Function to update existing Cursor installation
updateCursor() {
if [ ! -f "$APPIMAGE_PATH" ]; then
echo "Cursor is not installed. Please use the install option instead."
return 1
fi
echo "Updating existing Cursor installation..."
# Get version list and selection
getVersions
# Create backup of current installation
mv "$APPIMAGE_PATH" "${APPIMAGE_PATH}.backup"
# Download and install new version
echo "Downloading new version..."
curl -L "$CURSOR_URL" -o "/tmp/cursor.appimage" || {
echo "Failed to download AppImage. Restoring backup...";
mv "${APPIMAGE_PATH}.backup" "$APPIMAGE_PATH";
exit 1;
}
# Replace with new version
mv "/tmp/cursor.appimage" "$APPIMAGE_PATH"
chmod +x "$APPIMAGE_PATH"
rm "${APPIMAGE_PATH}.backup"
# Update icon and desktop entry
updateIcon
createDesktopEntry
echo "Cursor AI IDE updated successfully!"
}
# Main menu display function
showMenu() {
echo "╔════════════════════════════════════════════════════════╗"
echo "║ Cursor IDE Manager ║"
echo "╠════════════════════════════════════════════════════════╣"
echo "║ 1. Update Icon ║"
echo "║ 2. Install Cursor (Choose version to install) ║"
echo "║ 3. Switch Cursor Version ║"
echo "║ 4. Exit ║"
echo "╚════════════════════════════════════════════════════════╝"
echo
echo "To install a specific version of Cursor:"
echo " - For first installation, choose option 2"
echo " - If Cursor is already installed, choose option 3"
echo
echo "Choose an option (1-4): "
}
# Main program loop
while true; do
showMenu
read -r choice
case $choice in
1)
updateIcon
;;
2)
installCursor
;;
3)
updateCursor
;;
4)
echo "Goodbye!"
exit 0
;;
*)
echo "Invalid option. Please choose 1-4."
;;
esac
echo
echo "Press Enter to continue..."
read -r
clear
done
@HallexCosta
Copy link
Author

cursor icon:

cursor

@HallexCosta
Copy link
Author

chmod +x ./cursor.sh && ./cursor.sh

@HallanCosta
Copy link

Nice, seems to work well

@HallexCosta
Copy link
Author

HallexCosta commented Apr 24, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment