Skip to content

Instantly share code, notes, and snippets.

@jorcelinojunior
Last active November 12, 2024 18:18
Show Gist options
  • Save jorcelinojunior/131748e12a039c02148a6f66e1fb312c to your computer and use it in GitHub Desktop.
Save jorcelinojunior/131748e12a039c02148a6f66e1fb312c to your computer and use it in GitHub Desktop.
Automate the integration of Cursor .AppImage on Linux: updates .desktop, manages icons, ensures the latest version, and configures AppArmor (Required for Ubuntu 24.04).
#!/bin/bash
set -euo pipefail
# Definition of colors for terminal output
readonly RED_COLOR="\e[31m"
readonly GREEN_COLOR="\e[32m"
readonly YELLOW_COLOR="\e[33m"
readonly BLUE_COLOR="\e[34m"
readonly MAGENTA_COLOR="\e[35m"
readonly RESET_COLOR="\e[0m"
# General settings
readonly DOWNLOAD_APP_DIR="$HOME/Downloads/.AppImage"
readonly ICON_DIR="$HOME/.local/share/icons"
readonly ICON_URL="https://www.cursor.com/brand/icon.svg"
readonly DESKTOP_FILE_PATH="$HOME/.local/share/applications/cursor.desktop"
readonly APPARMOR_PROFILE="/etc/apparmor.d/cursor-appimage"
readonly DOWNLOAD_URL="https://downloader.cursor.sh/linux/appImage/x64"
readonly TEMP_DIR="/tmp/AppImage"
readonly VERSION_CHECK_TIMEOUT=10
cursor_appimage_path=""
cursor_icon_path=""
# Support function to print steps
print_step() {
echo -e "${YELLOW_COLOR}$1${RESET_COLOR}"
}
# Support function to print success
print_success() {
echo -e "${GREEN_COLOR}$1${RESET_COLOR}"
}
# Support function for error handling
error_exit() {
echo -e "${RED_COLOR}$1${RESET_COLOR}" >&2
kill $$
}
# Check necessary dependencies
check_dependencies() {
print_step "Checking necessary dependencies..."
for cmd in curl chmod find mkdir wget; do
if ! command -v "$cmd" >/dev/null 2>&1; then
error_exit "This script requires $cmd, but it is not installed.\nPlease install it with 'sudo apt install $cmd' and try again."
fi
done
print_success "All necessary dependencies are installed."
}
# Function to get the name of the latest version available for download
fetch_online_version() {
local HEADERS=$(timeout $VERSION_CHECK_TIMEOUT wget -S "$DOWNLOAD_URL" -q -O /dev/null 2>&1)
local FILENAME=$(echo "$HEADERS" | grep -o -E 'filename="[^"]+"' | sed 's/filename="//;s/"//')
if [[ -n "$FILENAME" ]]; then
echo "$FILENAME"
else
error_exit "Failed to fetch the latest version. If your connection is slow, try increasing \"VERSION_CHECK_TIMEOUT\"."
fi
}
# Function to get the path of latest version of the AppImage in the local directory
get_path_local_version() {
mkdir -p "$DOWNLOAD_APP_DIR" # Ensure the directory exists
local appimage_files
mapfile -t appimage_files < <(find "$DOWNLOAD_APP_DIR" -name 'cursor-*.AppImage' -printf '%T@ %p\n' | sort -nr | cut -d' ' -f2-)
if [ "${#appimage_files[@]}" -eq 0 ]; then
return 0
fi
echo "${appimage_files[0]}"
}
# Search for the most recent AppImage file path
fetch_app_path() {
print_step "Searching for the most recent AppImage path of cursor.sh"
local appimage_files
mapfile -t appimage_files < <(find "$DOWNLOAD_APP_DIR" -name "cursor-*.AppImage" -printf '%T@ %p\n' | sort -rn | cut -d' ' -f2-)
if [ "${#appimage_files[@]}" -eq 0 ]; then
echo -e "${RED_COLOR}No cursor.sh AppImage files found in $DOWNLOAD_APP_DIR/${RESET_COLOR}"
error_exit "You need to download the latest version first (OPTION 1) and run this script again."
fi
cursor_appimage_path=${appimage_files[0]}
print_success "Path found: $cursor_appimage_path"
}
# Download the application icon
download_logo() {
print_step "Downloading the logo"
cursor_icon_path="$ICON_DIR/cursor-icon.svg"
mkdir -p "$ICON_DIR"
if ! curl -s -o "$cursor_icon_path" "$ICON_URL"; then
error_exit "Failed to download the logo from $ICON_URL"
fi
print_success "Logo downloaded: $ICON_DIR/cursor-icon.svg"
}
# Create the .desktop file for the application
create_desktop_file() {
print_step "Creating the .desktop file"
cat <<-EOF >"$DESKTOP_FILE_PATH"
[Desktop Entry]
Type=Application
Name=Cursor
Exec=$cursor_appimage_path
Icon=$cursor_icon_path
Categories=Utility;Development
Terminal=false
StartupWMClass=Cursor
X-AppImage-Version=latest
Comment=Cursor is an AI-first coding environment.
MimeType=x-scheme-handler/cursor;
EOF
print_success "Desktop file created: $DESKTOP_FILE_PATH"
}
# Configure the AppArmor profile for the application
create_apparmor_profile() {
local appimage_path=${1-""}
if [[ -z $appimage_path ]]; then
appimage_path=$(get_path_local_version)
if [[ -z "$appimage_path" ]]; then
error_exit "No local version found. Please download the latest version first (OPTION 1) and run this script again."
fi
fi
print_step "Configuring the AppArmor profile..."
cat <<-EOF | sudo tee $APPARMOR_PROFILE > /dev/null
# This profile allows everything and only exists to give the
# application a name instead of having the label "unconfined"
abi <abi/4.0>,
include <tunables/global>
profile cursor $appimage_path flags=(unconfined) {
userns,
# Site-specific additions and overrides. See local/README for details.
include if exists <local/cursor>
}
EOF
sudo apparmor_parser -r $APPARMOR_PROFILE || error_exit "Failed to apply the AppArmor profile."
print_success "AppArmor profile successfully configured for $appimage_path"
}
# Main function that checks and downloads the latest version if it is not yet locally present
check_and_download_version() {
print_step "Checking for updates and downloading if a newer version is available"
check_dependencies
mkdir -p "$DOWNLOAD_APP_DIR" # Ensure the directory exists
local filename_local_version
local path_local_version=$(get_path_local_version)
if [[ -z "$path_local_version" ]]; then
echo -e "${YELLOW_COLOR}No local version found. A new version will be downloaded.${RESET_COLOR}"
else
filename_local_version=$(basename "$path_local_version")
echo -e "${BLUE_COLOR}Latest local version: ${filename_local_version}${RESET_COLOR}"
fi
# Gets the name of the latest online version
echo -e "${YELLOW_COLOR}Searching for the latest version. Please wait...${RESET_COLOR}"
local filename_online_version=$(fetch_online_version)
local path_online_version="$DOWNLOAD_APP_DIR/$filename_online_version"
# Compares versions and downloads if necessary
if [[ -z "$path_local_version" ]] || [[ "$filename_local_version" != "$filename_online_version" ]]; then
echo -e "${YELLOW_COLOR}A new version is available: ${RESET_COLOR}${GREEN_COLOR}$filename_online_version${RESET_COLOR}"
echo -e "${YELLOW_COLOR}Downloading the newest version...${RESET_COLOR}"
wget --quiet --show-progress --content-disposition -P "$DOWNLOAD_APP_DIR" --trust-server-names "$DOWNLOAD_URL"
echo -e "${GREEN_COLOR}Download completed: ${path_online_version}${RESET_COLOR}"
if [[ -f "${path_online_version}" ]]; then
chmod +x "${path_online_version}"
echo -e "${GREEN_COLOR}Made the AppImage executable: ${path_online_version}${RESET_COLOR}"
echo -e "${MAGENTA_COLOR}Now run the script again and choose option 2 to install the latest version.${RESET_COLOR}"
else
error_exit "Downloaded AppImage file not found at ${path_online_version}"
fi
else
echo -e "${GREEN_COLOR}No download needed — your local version ($filename_online_version) is the most current.${RESET_COLOR}"
fi
}
# Function to search and prepare the AppImage
fetch_and_prepare_appimage() {
check_dependencies
fetch_app_path
download_logo
create_desktop_file
create_apparmor_profile
echo -e "${GREEN_COLOR}Application installed and ready to use.${RESET_COLOR}"
}
# Function to create the AppArmor profile
setup_apparmor_profile() {
check_dependencies
fetch_app_path
create_apparmor_profile
}
# Interactive menu
PS3='Please choose an option: '
options=(
"Fetch the latest version and download (if not already present)"
"Re/Install the latest downloaded version"
"Just configure AppArmor (Required for Ubuntu 24.04)"
"Exit"
)
select opt in "${options[@]}"
do
case $opt in
"Fetch the latest version and download (if not already present)")
check_and_download_version
;;
"Re/Install the latest downloaded version")
fetch_and_prepare_appimage
;;
"Just configure AppArmor (Required for Ubuntu 24.04)")
setup_apparmor_profile
;;
"Exit")
break
;;
*) echo "Invalid option $REPLY";;
esac
done
@jorcelinojunior
Copy link
Author

jorcelinojunior commented Sep 25, 2024

Cursor Icon

Automated Cursor App Manager for Linux Desktops

This Bash script streamlines the integration of the Cursor app in Linux environments by automating several cumbersome manual steps. It is designed for users who frequently update the Cursor .AppImage and wish to simplify the process.

Why This Script?

Created in response to the tedious manual updates required for Linux users of the Cursor app, this script offers a comprehensive, interactive solution not found in other similar gists. It addresses common frustrations by automating the entire update and integration process, allowing you to manage the Cursor app more effectively and with significantly less manual intervention.

Cursor App 0

Installation and Usage Instructions

  • Prepare the Script Directory:
    • Create a directory for scripts if it doesn't exist: mkdir -p $HOME/scripts
    • Navigate to this directory: cd $HOME/scripts
  • Script Setup:
    • Create a new file named cursor_appimage_manager.sh: touch cursor_appimage_manager.sh
    • Open this file in your text editor and paste the script content.
    • Give the script execution permission: chmod +x cursor_appimage_manager.sh
  • Running the Script:
    • From your terminal, run the script: ./cursor_appimage_manager.sh
    • Follow the on-screen prompts to update or manage your Cursor app.

Creating an Alias:

For easier access, you can create an alias in your .bashrc or .zshrc file:

  • Open your shell configuration file in an editor, e.g., nano $HOME/.bashrc or nano $HOME/.zshrc
  • Add the following line at the end of the file: alias cursorupdate='$HOME/scripts/cursor_appimage_manager.sh'
  • Save the file and reload your shell configuration: source $HOME/.bashrc or source $HOME/.zshrc
  • Now, you can simply type cursorupdate in your terminal to run the script.

Key Features:

  • Automatic Updates: Downloads the latest Cursor .AppImage automatically, keeping your application up-to-date.
  • Desktop Integration: Ensures desktop shortcuts always launch the latest version by managing symlinks.
  • Icon Management: Downloads or updates the Cursor app icon as necessary.
  • .desktop File Management: Manages the .desktop file for seamless integration into the Linux desktop.

Customization:

ConstantDefault ValueDescription
DOWNLOAD_APP_DIR$HOME/Downloads/.AppImageDirectory where AppImages are stored.
ICON_DIR$HOME/.local/share/iconsDirectory to store the app icons.
ICON_URLhttps://www.cursor.com/brand/icon.svgURL to download the app's icon.
DESKTOP_FILE_PATH$HOME/.local/share/applications/cursor.desktopPath for the desktop shortcut file.
APPARMOR_PROFILE/etc/apparmor.d/cursor-appimagePath for the AppArmor profile configuration file.
DOWNLOAD_URLhttps://downloader.cursor.sh/linux/appImage/x64URL to download the latest AppImage version.
TEMP_DIR/tmp/AppImageTemporary directory for initial downloads.
VERSION_CHECK_TIMEOUT10Time in seconds to fetch file headers. Adjust based on your internet speed—increase for slow connections, decrease for faster ones.

Screenshots:

Downloading the Latest Cursor App Version

Downloading the Latest Cursor App Version

Local Version Is Up-to-Date

Local Version Is Up-to-Date

Reinstalling or Updating to the Latest Downloaded Version

Reinstalling or Updating to the Latest Downloaded Version

Error: No Downloaded Version Available

This error occurs if no .AppImage files are found in the designated download directory, or if you haven't run the script using option 1 first. To resolve this, simply run the script again and choose option 1 to download the latest version before proceeding.

Error: No Downloaded Version Available

I hope this gist proves helpful to others as well. It's one of my first contributions, and I look forward to making more tools that can assist the community. Feedback and improvements are always welcome!

@gjain-7
Copy link

gjain-7 commented Sep 26, 2024

Really helpful script, Thanks!

Just a quick question, should you not be making the app image executable instead of .desktop file here? I had to do that manually

@Coldmooon
Copy link

great work

@DreamCasterX
Copy link

Thanks for the script. I'd recommend to make the app image file executable as soon as it's downloaded (add something like chmod +x *.AppImage)

@jorcelinojunior
Copy link
Author

Thanks so much, @gjain-7 and @DreamCasterX, for the helpful suggestions!

I’ve made sure the AppImage is now automatically set as executable after downloading, so no need to do it manually anymore. It didn't really make sense to make the .desktop file executable—good catch! I also took the chance to improve how the script grabs the latest version's filename and made other improvements.

Really appreciate the feedback—it helped make the script better! Feel free to share any other thoughts or ideas anytime—always happy to improve it further. 😃 👍

@humbleshuttler
Copy link

thanks for making this. This is super helpful!

@chauminhvu
Copy link

I run the script successfully on Ubuntu 24.04.1, but Cursor cannot be launch from Application. How to fix it?

@abewartech
Copy link

root@user-B760M-DS3H:~/scripts# ./cursor_appimage_manager.sh

  1. Fetch the latest version and download (if not already present) 3) Just configure AppArmor (Required for Ubuntu 24.04)
  2. Re/Install the latest downloaded version 4) Exit
    Please choose an option: 2
    Checking necessary dependencies...
    All necessary dependencies are installed.
    Searching for the most recent AppImage path of cursor.sh
    Path found: /root/Downloads/.AppImage/cursor-0.41.3x86_64.AppImage
    Downloading the logo
    Logo downloaded: /root/.local/share/icons/cursor-icon.svg
    Creating the .desktop file
    ./cursor_appimage_manager.sh: line 103: /root/.local/share/applications/cursor.desktop: No such file or directory

@Gords
Copy link

Gords commented Oct 11, 2024

The icon is out of date, the rest works perfectly, thank you very much!

@mathmul
Copy link

mathmul commented Oct 11, 2024

The icon is out of date, the rest works perfectly, thank you very much!

readonly ICON_URL="https://mintlify.s3-us-west-1.amazonaws.com/cursor/images/logo/app-logo.svg"

@jmeg-sfy
Copy link

It is working properly , thanks a lot !

@dalpat
Copy link

dalpat commented Oct 16, 2024

That worked well. thank you

@okwareddevnest
Copy link

This is perfect, thank you

@jicastaneda
Copy link

Works like a charm! Thank you very much man!

@abewartech
Copy link

Please choose an option: 1
Checking for updates and downloading if a newer version is available
Checking necessary dependencies...
All necessary dependencies are installed.
Latest local version: cursor-0.42.3x86_64.AppImage
Searching for the latest version. Please wait...
No download needed — your local version (cursor-0.42.3x86_64.AppImage) is the most current.
Please choose an option: 2
Checking necessary dependencies...
All necessary dependencies are installed.
Searching for the most recent AppImage path of cursor.sh
Path found: /root/Downloads/.AppImage/cursor-0.42.3x86_64.AppImage
Downloading the logo
Logo downloaded: /root/.local/share/icons/cursor-icon.svg
Creating the .desktop file
./cursor_appimage_manager.sh: line 103: /root/.local/share/applications/cursor.desktop: No such file or directory

@rgBoss12
Copy link

worked seamlessly! thank you very much!

@chubuntuarc
Copy link

This is amazing! 🔥 Thanks.

@hnmike
Copy link

hnmike commented Oct 27, 2024

Million thanks

@OriginalEXE
Copy link

Worked like a charm, thank you ❤️

@leifmetcalf
Copy link

You're one the coolest people for sure.

@umstek
Copy link

umstek commented Nov 8, 2024

Thanks, this is nice. Any way to get rid of double title bars?

@GaneeshaEd
Copy link

Everything on script worked well, but after cursor installation cannot launch the cursor app on Ubuntu 24.04 LTS. Anyone got the same issue?

Output of the option 2

Checking necessary dependencies...
All necessary dependencies are installed.
Searching for the most recent AppImage path of cursor.sh
Path found: /home/user/Downloads/.AppImage/cursor-0.42.4x86_64.AppImage
Downloading the logo
Logo downloaded: /home/user/.local/share/icons/cursor-icon.svg
Creating the .desktop file
Desktop file created: /home/user/.local/share/applications/cursor.desktop
Configuring the AppArmor profile...
AppArmor profile successfully configured for /home/user/Downloads/.AppImage/cursor-0.42.4x86_64.AppImage
Application installed and ready to use.

@mathmul
Copy link

mathmul commented Nov 11, 2024

Everything on script worked well, but after cursor installation cannot launch the cursor app on Ubuntu 24.04 LTS. Anyone got the same issue?

Yea, here as well.. The icon is created in the app menu. I think it even worked for a bit on first install, not sure. But I since only use terminal to start it, or once started, pin the icon in dash

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