Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,9 @@ Windows_and_Linux/config.json

# Xcode user-specific data
**/xcuserdata/
**/project.xcworkspace/xcuserdata/
**/project.xcworkspace/xcuserdata/

Windows_and_Linux/.venv/
Windows_and_Linux/packaging/
Windows_and_Linux/dist/
Windows_and_Linux/Writing Tools.spec
53 changes: 40 additions & 13 deletions README's Linked Content/To Compile the Application Yourself.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,59 @@
### Windows and Linux Version build instructions:
Here's how to compile it with PyInstaller and a virtual environment:

1. First, create and activate a virtual environment:
1. Open Terminal (or Command Prompt) and enter the Windows/Linux app folder:
```bash
# Install virtualenv if you haven't already
pip install virtualenv
cd /path/to/WritingTools/Windows_and_Linux
```

# Create a new virtual environment
virtualenv myvenv
2. Create and activate a virtual environment:
```bash
python3 -m venv .venv

# Activate it
# On Windows:
myvenv\Scripts\activate
# On Linux:
source myvenv/bin/activate
```
# Linux:
source .venv/bin/activate

2. Once activated, install the required packages:
# Windows (PowerShell):
.venv\Scripts\Activate.ps1

# Windows (cmd):
.venv\Scripts\activate.bat
```

3. Install dependencies:
```bash
python -m pip install --upgrade pip
pip install -r requirements.txt
```

3. Build Writing Tools:
4. Build Writing Tools:
```bash
python pyinstaller-build-script.py
```

The compiled binary is written to: ~/Windows_and_Linux/dist/Writing Tools

5. Linux only (optional, recommended): install locally with launcher icon:
```bash
bash build-and-install-local-linux.sh
```

This creates:
- `~/.local/bin/writing-tools`
- `~/.local/share/applications/writing-tools.desktop`

Optional autostart:
```bash
bash build-and-install-local-linux.sh --enable-autostart
```

After local install, you can launch Writing Tools with:
```bash
writing-tools
```

No daily recompilation is needed unless you changed source code and want a newer build.

### macOS Version (by [Aryamirsepasi](https://github.com/Aryamirsepasi)) build instructions:

1. **Install Xcode**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,13 @@ Of course, you'll need to have [Python installed](https://www.python.org/downloa
python3 main.py
```

If you want a launcher icon in your app menu and a reusable local install (so you do not need to run from terminal every day), use:

```bash
bash build-and-install-local-linux.sh
```

from the `Windows_and_Linux` folder.


### [**◀️ Back to main page**](https://github.com/theJayTea/WritingTools)
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ Aside from being the only Windows/Linux program like Apple's Writing Tools, and
### **🐧 Linux (work-in-progress)**:
[Run it from the source code](https://github.com/theJayTea/WritingTools/blob/main/README's%20Linked%20Content/To%20Run%20Writing%20Tools%20Directly%20from%20the%20Source%20Code.md)

[Compile and install locally with launcher icon](https://github.com/theJayTea/WritingTools/blob/main/README's%20Linked%20Content/To%20Compile%20the%20Application%20Yourself.md)

Writing Tools works well on x11. On Wayland, there are a few caveats:
- [it works on XWayland apps](https://github.com/theJayTea/WritingTools/issues/34#issuecomment-2461633556)
- [and it works if you disable Wayland for individual Flatpaks with Flatseal.](https://github.com/theJayTea/WritingTools/issues/93#issuecomment-2576511041)
Expand Down Expand Up @@ -220,7 +222,7 @@ These instructions are for any Writing Tools version, using the OpenAI-Compatibl

## 👨‍💻 To Compile the Application Yourself:

[Instructions here!](https://github.com/theJayTea/WritingTools/blob/8713e5a5de63a7892b05a43b9753172e692768fb/README's%20Linked%20Content/To%20Compile%20the%20Application%20Yourself.md)
[Instructions here!](https://github.com/theJayTea/WritingTools/blob/main/README's%20Linked%20Content/To%20Compile%20the%20Application%20Yourself.md)

## 🌟 Contributors

Expand Down
75 changes: 75 additions & 0 deletions Windows_and_Linux/build-and-install-local-linux.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/usr/bin/env bash
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
AUTOSTART_FLAG=""
SKIP_BUILD="no"

print_usage() {
cat <<'USAGE'
Usage:
bash build-and-install-local-linux.sh [--enable-autostart|--disable-autostart] [--skip-build]

Builds Writing Tools with PyInstaller, then installs it locally with:
- Launcher command: ~/.local/bin/writing-tools
- App menu entry: ~/.local/share/applications/writing-tools.desktop

Options:
--enable-autostart Enable autostart after install
--disable-autostart Disable autostart after install
--skip-build Skip PyInstaller build and only run local install
-h, --help Show this help message
USAGE
}

while [[ $# -gt 0 ]]; do
case "$1" in
--enable-autostart|--disable-autostart)
AUTOSTART_FLAG="$1"
;;
--skip-build)
SKIP_BUILD="yes"
;;
-h|--help)
print_usage
exit 0
;;
*)
echo "ERROR: Unknown option: $1"
print_usage
exit 1
;;
esac
shift
done

if ! command -v python3 >/dev/null 2>&1; then
echo "ERROR: python3 is required but was not found."
exit 1
fi

INSTALL_SCRIPT="${SCRIPT_DIR}/install-local-linux.sh"
if [[ ! -f "${INSTALL_SCRIPT}" ]]; then
echo "ERROR: Missing installer script at ${INSTALL_SCRIPT}"
exit 1
fi

pushd "${SCRIPT_DIR}" >/dev/null

if [[ "${SKIP_BUILD}" != "yes" ]]; then
echo "Building with PyInstaller..."
python3 pyinstaller-build-script.py
else
echo "Skipping build as requested."
fi

echo "Installing locally for current user..."
install_args=(--app-source "${SCRIPT_DIR}")
if [[ -n "${AUTOSTART_FLAG}" ]]; then
install_args+=("${AUTOSTART_FLAG}")
fi
bash "${INSTALL_SCRIPT}" "${install_args[@]}"

popd >/dev/null

echo "Done. Launch via: writing-tools"
176 changes: 176 additions & 0 deletions Windows_and_Linux/install-local-linux.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
#!/usr/bin/env bash
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
APP_SOURCE="${SCRIPT_DIR}"
ENABLE_AUTOSTART=""

print_usage() {
cat <<'USAGE'
Usage:
bash install-local-linux.sh [--app-source <dir>] [--enable-autostart|--disable-autostart]

Installs Writing Tools for the current Linux user:
- App files: ~/.local/share/writingtools/app
- Launcher command: ~/.local/bin/writing-tools
- App menu entry: ~/.local/share/applications/writing-tools.desktop

Options:
--app-source <dir> Source directory containing app assets and dist output
--enable-autostart Create ~/.config/autostart/writing-tools.desktop
--disable-autostart Remove ~/.config/autostart/writing-tools.desktop
-h, --help Show this help message
USAGE
}

while [[ $# -gt 0 ]]; do
case "$1" in
--app-source)
shift
if [[ $# -eq 0 ]]; then
echo "ERROR: --app-source requires a value"
exit 1
fi
APP_SOURCE="$1"
;;
--enable-autostart)
ENABLE_AUTOSTART="yes"
;;
--disable-autostart)
ENABLE_AUTOSTART="no"
;;
-h|--help)
print_usage
exit 0
;;
*)
echo "ERROR: Unknown option: $1"
print_usage
exit 1
;;
esac
shift
done

if [[ "${EUID}" -eq 0 ]]; then
echo "ERROR: Please run this as your regular desktop user, not root."
exit 1
fi

if [[ ! -d "${APP_SOURCE}" ]]; then
echo "ERROR: App source directory not found: ${APP_SOURCE}"
exit 1
fi

DIST_EXE=""
if [[ -x "${APP_SOURCE}/Writing Tools" ]]; then
DIST_EXE="${APP_SOURCE}/Writing Tools"
elif [[ -x "${APP_SOURCE}/dist/Writing Tools" ]]; then
DIST_EXE="${APP_SOURCE}/dist/Writing Tools"
else
echo "ERROR: Compiled binary not found in ${APP_SOURCE}"
echo "Build first with: python3 pyinstaller-build-script.py"
exit 1
fi

for required_dir in icons locales; do
if [[ ! -d "${APP_SOURCE}/${required_dir}" ]]; then
echo "ERROR: Missing required directory: ${APP_SOURCE}/${required_dir}"
exit 1
fi
done

for required_file in background.png background_dark.png background_popup.png background_popup_dark.png Latest_Version_for_Update_Check.txt options.json; do
if [[ ! -f "${APP_SOURCE}/${required_file}" ]]; then
echo "ERROR: Missing required file: ${APP_SOURCE}/${required_file}"
exit 1
fi
done

DATA_HOME="${XDG_DATA_HOME:-${HOME}/.local/share}"
CONFIG_HOME="${XDG_CONFIG_HOME:-${HOME}/.config}"
INSTALL_ROOT="${DATA_HOME}/writingtools"
APP_DIR="${INSTALL_ROOT}/app"
BIN_DIR="${HOME}/.local/bin"
APPS_DIR="${DATA_HOME}/applications"
AUTOSTART_DIR="${CONFIG_HOME}/autostart"
LAUNCHER_PATH="${BIN_DIR}/writing-tools"
DESKTOP_PATH="${APPS_DIR}/writing-tools.desktop"
AUTOSTART_PATH="${AUTOSTART_DIR}/writing-tools.desktop"

mkdir -p "${APP_DIR}" "${BIN_DIR}" "${APPS_DIR}" "${AUTOSTART_DIR}"

install -m 0755 "${DIST_EXE}" "${APP_DIR}/Writing Tools"

rm -rf "${APP_DIR}/icons" "${APP_DIR}/locales"
cp -a "${APP_SOURCE}/icons" "${APP_DIR}/icons"
cp -a "${APP_SOURCE}/locales" "${APP_DIR}/locales"

for file_name in background.png background_dark.png background_popup.png background_popup_dark.png Latest_Version_for_Update_Check.txt; do
install -m 0644 "${APP_SOURCE}/${file_name}" "${APP_DIR}/${file_name}"
done

# Preserve user-customized options on upgrades.
if [[ ! -f "${APP_DIR}/options.json" ]]; then
install -m 0644 "${APP_SOURCE}/options.json" "${APP_DIR}/options.json"
fi

cat > "${LAUNCHER_PATH}" <<'EOF'
#!/usr/bin/env bash
set -euo pipefail

APP_DIR="${XDG_DATA_HOME:-${HOME}/.local/share}/writingtools/app"
if [[ -d "${APP_DIR}/lib" ]]; then
export LD_LIBRARY_PATH="${APP_DIR}/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
fi
if [[ -d "${APP_DIR}/bin" ]]; then
export PATH="${APP_DIR}/bin:${PATH}"
fi
cd "${APP_DIR}"
exec "${APP_DIR}/Writing Tools" "$@"
EOF
chmod 0755 "${LAUNCHER_PATH}"

cat > "${DESKTOP_PATH}" <<EOF
[Desktop Entry]
Type=Application
Name=Writing Tools
Comment=AI-powered writing helper with global hotkey popup
Exec=${LAUNCHER_PATH}
Icon=${APP_DIR}/icons/app_icon.png
Terminal=false
Categories=Office;Utility;
StartupNotify=false
EOF
chmod 0644 "${DESKTOP_PATH}"

if [[ "${ENABLE_AUTOSTART}" == "yes" ]]; then
cat > "${AUTOSTART_PATH}" <<EOF
[Desktop Entry]
Type=Application
Name=Writing Tools
Comment=Start Writing Tools in background at login
Exec=${LAUNCHER_PATH}
Icon=${APP_DIR}/icons/app_icon.png
Terminal=false
X-GNOME-Autostart-enabled=true
EOF
chmod 0644 "${AUTOSTART_PATH}"
echo "Autostart enabled at: ${AUTOSTART_PATH}"
elif [[ "${ENABLE_AUTOSTART}" == "no" ]]; then
rm -f "${AUTOSTART_PATH}"
echo "Autostart disabled."
fi

echo "Install complete for user: ${USER}"
echo "Launcher command: writing-tools"
echo "Desktop entry: ${DESKTOP_PATH}"

if ! command -v xclip >/dev/null 2>&1 && ! command -v xsel >/dev/null 2>&1 && ! command -v wl-copy >/dev/null 2>&1; then
echo "WARNING: No clipboard backend detected (xclip/xsel/wl-copy)."
echo " Install one to ensure copy/replace flow works."
fi

if [[ "${XDG_SESSION_TYPE:-}" == "wayland" ]]; then
echo "NOTICE: Running in Wayland session; global hotkey/focus behavior may be limited."
fi
Loading