Terminal-based note-taking app for computer science students
Project description
OpenPad
█▀▀█ █▀▀█ █▀▀▀ █▀▀▄ █▀▀█ █▀▀█ █▀▀▄
█ █ █▀▀▀ █▀▀▀ █ █ █▀▀▀ █▀▀█ █ █
▀▀▀▀ ▀ ▀▀▀▀ ▀ ▀ ▀ ▀ ▀ ▀▀▀▀
A fast, terminal-based note-taking app designed for computer science students. Write, organize, and search Markdown notes — directly from your terminal.
Features
- Folder-based note organization — hierarchical tree sidebar with expand/collapse
- Tabbed editing — open multiple notes, switch with
shift+left/shift+right - Markdown rendering — headings, lists, code blocks, bold, italic, inline code, blockquotes, horizontal rules
- Syntax highlighting — 20+ languages in code blocks (Rich Monokai theme)
- Live search — debounced full-text search across all notes, jump-to-position with yellow highlight
- Move notes & folders — reorganize with
ctrl+m, pick a destination folder - Auto-save — every keystroke writes to disk immediately
- Auto-rename — changing the first
# Titlerenames the file on exit - 11 built-in themes — Tokyo Night, Catppuccin, Gruvbox, Nord, Matrix, and more
- Google Calendar integration — optional, view events/exams/deadlines in-app
- Session log — on quit, see a summary of every note created, edited, deleted, moved, or renamed
- Lightweight — Textual-based TUI, no Electron, runs in any terminal
- Plain Markdown files — no lock-in, notes are just
.mdfiles on disk
Install
Requires Python 3.10 or newer.
pip install openpad # basic install
pip install "openpad[calendar]" # with Google Calendar support
Calendar support is optional. Without it, the app runs normally — only the calendar view will show a message asking for credentials.
Linux (Debian / Ubuntu / Mint)
python3 --version # check Python version
sudo apt update
sudo apt install python3 python3-pip -y
pip install openpad # or: pip install "openpad[calendar]"
openpad
Linux (Arch / Manjaro)
python --version
sudo pacman -S python python-pip
pip install openpad # or: pip install "openpad[calendar]"
openpad
Linux (Fedora)
python3 --version
sudo dnf install python3 python3-pip
pip install openpad # or: pip install "openpad[calendar]"
openpad
Windows
OpenPad works best with Windows Terminal (free from the Microsoft Store).
The standard Command Prompt (cmd) will also work but colours may look worse.
# Install Python 3.10+ from https://python.org
# IMPORTANT: check "Add Python to PATH" during installation
python --version
pip --version
pip install openpad # or: pip install "openpad[calendar]"
openpad
WSL alternative: If you use WSL (Ubuntu), follow the Ubuntu steps above instead.
macOS
python3 --version
brew install python@3 # if missing or < 3.10
pip3 install openpad # or: pip install "openpad[calendar]"
openpad
Upgrading
All your notes, settings, and credentials are stored in ~/.openpad/ — upgrading the app never touches them.
# Basic upgrade
pip install --upgrade openpad
# With calendar support
pip install --upgrade "openpad[calendar]"
# If installed from source
git pull
pip install -e . # or: pip install -e ".[calendar]"
Quick Start
On first launch, OpenPad creates sample notes in ~/.openpad/notes/ that serve as an interactive tutorial:
| Folder | Notes |
|---|---|
Welcome/ |
Getting Started |
Guide/ |
Key Bindings, Markdown Reference, Working with Folders |
Features/ |
Tabs & Search, Themes, Google Calendar |
Examples/ |
Python, JavaScript, SQL |
Basic workflow:
- Navigate — arrow keys in the sidebar to browse notes
- Open — press
Enteron a note to open it in a tab - Edit — press
eto enter edit mode, start typing - Switch tabs —
shift+left/shift+right - Search —
ctrl+f, type a query, pressEnteron a result - Quit — press
qto exit (see a summary of your session)
Key Bindings
Global
| Key | Action |
|---|---|
n |
Create new note (or name/ for a folder) |
d |
Delete selected note / highlighted folder |
e |
Toggle edit mode |
ctrl+f |
Open search |
ctrl+m |
Move note or folder |
ctrl+t |
Open theme picker |
ctrl+c |
Open calendar |
escape |
Exit edit mode / close modal |
t |
Focus the note tree |
q |
Quit (shows session summary) |
shift+left |
Previous tab |
shift+right |
Next tab |
space then e |
Toggle sidebar visibility |
Calendar Modal (ctrl+c)
| Key | Action |
|---|---|
shift+left |
Previous month |
shift+right |
Next month |
left |
Previous day |
right |
Next day |
up |
Previous week (7 days) |
down |
Next week (7 days) |
escape |
Close calendar |
| Click a day | Select that day |
Move Modal (ctrl+m)
| Key | Action |
|---|---|
up / down |
Navigate folder list |
enter |
Confirm move to selected folder |
escape |
Cancel |
Theme Picker (ctrl+t)
| Key | Action |
|---|---|
up / down |
Browse themes |
enter |
Select theme |
escape |
Close without changing |
Confirm Modal (deletions)
| Key | Action |
|---|---|
y |
Confirm |
n |
Cancel |
escape |
Cancel |
Text Editor
| Key | Action |
|---|---|
tab |
Insert 4 spaces |
Features in Depth
Note Tree & Sidebar
The sidebar shows all notes organized in folders. Each note has an icon ().
Navigation:
- Arrow keys — move highlight, preview note content (no tab created)
- Enter — select a note, opening it in a new tab
- Click on a folder name to highlight it for delete/move operations
The sidebar auto-resizes its width (max 45 characters). Press space then e to toggle it.
Tab System
Each opened note appears as a tab at the top. Key behaviors:
- Tab bar appears when 2+ tabs are open
- Scrolling — left/right arrow buttons appear when tabs overflow
- Persistence — each tab remembers scroll position (view) and cursor position (edit)
- Close — click the
✕button on any tab - Active tab — highlighted in bold white
Editor (View / Edit Modes)
Notes have two modes:
| Mode | What you see | What you can do |
|---|---|---|
| View | Rendered Markdown | Navigate, scroll, double-click to edit |
| Edit | Raw Markdown (TextArea) | Type, auto-save, auto-rename |
- Toggle: press
e - Auto-save: every keystroke saves to disk immediately
- Auto-rename: if the first
# Headingchanges, the file is renamed on exit - Exit edit mode:
escape, or click outside the editor
Markdown Rendering
| Syntax | Appearance |
|---|---|
# Heading 1 |
Bold, primary color |
## Heading 2 |
Bold, secondary color |
### Heading 3 |
Bold, accent color |
#### Heading 4 |
Accent color |
**bold** / __bold__ |
Bold text |
*italic* / _italic_ |
Italic text |
`code` |
Inline code in syntax string color |
- list / * list |
Bulleted list |
1. numbered |
Numbered list |
> quote |
Blockquote with │ prefix |
--- |
Horizontal rule |
```lang ``` |
Syntax-highlighted code block |
Code block language aliases: js, py, sh, ts, md, rb, rs, cs and more.
Search
- Press
ctrl+fto open the search modal - Typing triggers a 300ms debounced search
- Searches both filenames and file content (case-insensitive)
- Shows up to 20 results with folder path, filename, and 50-character snippet
- Press
Enteron a result to open the note and jump to the match position - The matched text is highlighted in bold reverse yellow for 1.5 seconds
Move Notes & Folders
- Highlight a note in the tree (or a folder by clicking its name)
- Press
ctrl+m - Navigate the folder list with
up/down - Press
enterto move — orescapeto cancel
The root / option moves items out of any subfolder.
Theme System
11 themes, each defining 18 color slots:
| Theme | Vibe |
|---|---|
opencode |
Warm amber default |
tokyonight |
Deep blue/purple nights |
everforest |
Warm green forest tones |
ayu |
Orange & teal on deep dark |
catppuccin |
Soft pastel dark |
catppuccin-macchiato |
Darker catppuccin variant |
gruvbox |
Retro warm brown & yellow |
kanagawa |
Japanese ink-inspired blues |
nord |
Arctic cold blue-grey |
matrix |
Hacker green on black |
one-dark |
Atom One Dark |
Press ctrl+t to open the theme picker. Restart the app for the theme to fully apply — some residual colours from the previous theme may persist until restart.
Calendar
Press ctrl+c to open the calendar modal. Navigate months, weeks, and individual days using the arrow keys (see key bindings above).
If Google Calendar is configured, events appear overlaid on the calendar grid:
- Exams, tests, deadlines — shown in red
- Other events — shown in secondary colour
- All-day events — marked as "All day"
- Timed events — shown with
HH:MM → HH:MMformat
If not configured, the calendar still works for planning — it just won't show events.
Status Bar
The bottom of the screen shows:
VIEW ▸ Guide/Key Bindings ▸ 42 lines ▸ 14:32
- Mode badge —
VIEWorEDIT(coloured with theme primary) - File path — current note's folder and name
- Line count — number of lines in the current note
- Time — 24-hour, updates every 60 seconds
Session Log & Exit Summary
When you press q to quit, OpenPad prints a session summary showing every change:
~ edited: Guide/Key Bindings
+ created note: Welcome/Getting Started
+ created folder: Examples
- deleted note: Old Note/Todo
* renamed: Draft → Final
→ moved note: Notes/File → Guide
This gives you a complete record of what you did during the session.
Google Calendar Setup
This is optional — OpenPad works perfectly without it. When configured, the calendar view shows your events, with exams and deadlines highlighted in red.
Prerequisite: You need the calendar extras installed:
pip install "openpad[calendar]"(orpip install -e ".[calendar]"if building from source).
Step 1: Enable the Google Calendar API
- Go to the Google Cloud Console
- Create a new project (or select an existing one)
- Navigate to APIs & Services → Library
- Search for "Google Calendar API" and click Enable
Step 2: Create OAuth 2.0 credentials
- In the Cloud Console, go to APIs & Services → Credentials
- Click + Create Credentials → OAuth client ID
- If prompted, configure the OAuth consent screen first:
- Choose External user type
- Fill in the app name and your email address
- Under Scopes, add
.../auth/calendar.readonly(or skip — it will be requested at runtime) - Under Test users, add your email address
- Save and continue
- For Application type, select Desktop app
- Give it a name (e.g. "OpenPad Calendar")
- Click Create
- Click the Download JSON button
Step 3: Place credentials.json
Create the directory and move the downloaded file:
mkdir -p ~/.openpad
mv ~/Downloads/client_secret_*.json ~/.openpad/credentials.json
The file should contain a JSON object with an "installed" key (not "web"). It will look like this:
{
"installed": {
"client_id": "YOUR_CLIENT_ID.apps.googleusercontent.com",
"project_id": "YOUR_PROJECT_ID",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"client_secret": "YOUR_CLIENT_SECRET",
"redirect_uris": ["http://localhost"]
}
}
Step 4: Authenticate (one-time)
You have two options:
Option A — Authenticate from within OpenPad:
- Launch OpenPad:
openpad - Press
ctrl+cto open the calendar - A browser tab will open asking you to log into Google and grant read-only calendar access
- After authorizing,
~/.openpad/token.pickleis created automatically
Option B — Run the standalone auth script:
python auth_calendar.py
Step 5: Verify
After setup, you should have these files:
~/.openpad/credentials.json # OAuth client secret (yours to keep safe)
~/.openpad/token.pickle # OAuth token (auto-generated)
Open the calendar (ctrl+c) — your events should appear with exams and deadlines in red.
What the scope allows: Read-only access (
calendar.readonly). OpenPad can view your events but cannot create, modify, or delete anything on your calendar.
If you skip this setup: OpenPad works normally with no errors. The calendar simply shows a message asking you to configure credentials.
Data Storage
| Path | Contents |
|---|---|
~/.openpad/notes/ |
All notes as .md files, organized in folders |
~/.openpad/meta.json |
Settings ({"theme": "theme_name"}) |
~/.openpad/credentials.json |
Google Calendar OAuth credentials (optional) |
~/.openpad/token.pickle |
Google Calendar OAuth token (auto-generated) |
Build from Source
git clone <repo-url>
cd openpad
pip install -e . # basic install
pip install -e ".[calendar]" # with Google Calendar support
openpad
Troubleshooting
Colors look wrong
echo $TERM
# should show xterm-256color or similar
If your terminal doesn't support true colour, some theme colours may not display correctly.
"pip: command not found"
Linux: use python3 -m pip instead of pip:
python3 -m pip install openpad
Windows: make sure you checked Add Python to PATH during Python installation, or use:
python -m pip install openpad
Google Calendar doesn't open
- Verify
~/.openpad/credentials.jsonexists and has the"installed"key - Delete
~/.openpad/token.pickleand re-authenticate if the token expired - Check that the Google Calendar API is enabled in your Cloud Console project
Permission issues
ls -la ~/.openpad/
Ensure your user owns the directory and files.
License
MIT License
Built with Textual
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file openpad-1.1.0.tar.gz.
File metadata
- Download URL: openpad-1.1.0.tar.gz
- Upload date:
- Size: 36.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2a3eeed2de09e6846e19b76acbed6b6d6d993b10f3465eac34ea844002fdbb5d
|
|
| MD5 |
a23292faa233e2290456112e32b6ea88
|
|
| BLAKE2b-256 |
959edc7990c5ca20f19c69e7660769783525d2ac32ffa140735580f1e738757d
|
Provenance
The following attestation bundles were made for openpad-1.1.0.tar.gz:
Publisher:
publish.yml on xela-prog/openpad-full
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
openpad-1.1.0.tar.gz -
Subject digest:
2a3eeed2de09e6846e19b76acbed6b6d6d993b10f3465eac34ea844002fdbb5d - Sigstore transparency entry: 1705531234
- Sigstore integration time:
-
Permalink:
xela-prog/openpad-full@76a6aa0291990688f1aacd6ce0fb882a7332090f -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/xela-prog
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@76a6aa0291990688f1aacd6ce0fb882a7332090f -
Trigger Event:
push
-
Statement type:
File details
Details for the file openpad-1.1.0-py3-none-any.whl.
File metadata
- Download URL: openpad-1.1.0-py3-none-any.whl
- Upload date:
- Size: 32.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8eec67419cebbfa2448eb7fbdb790d14ec8bb2e0ece603202adf6f5d28bc2f8c
|
|
| MD5 |
3d6279fde62baea6e42fc573c300c0fa
|
|
| BLAKE2b-256 |
a3f8986ec2eef5ee26354d52e904b23ebca74b23b3734c03bc1706e0be2b2a2a
|
Provenance
The following attestation bundles were made for openpad-1.1.0-py3-none-any.whl:
Publisher:
publish.yml on xela-prog/openpad-full
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
openpad-1.1.0-py3-none-any.whl -
Subject digest:
8eec67419cebbfa2448eb7fbdb790d14ec8bb2e0ece603202adf6f5d28bc2f8c - Sigstore transparency entry: 1705531300
- Sigstore integration time:
-
Permalink:
xela-prog/openpad-full@76a6aa0291990688f1aacd6ce0fb882a7332090f -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/xela-prog
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@76a6aa0291990688f1aacd6ce0fb882a7332090f -
Trigger Event:
push
-
Statement type: