TextPalette documentation
TextPalette was called TextBuddy until version 2.0. If you already had it, updating keeps your documents, settings and license; a direct-download copy keeps its old TextBuddy.app file name in your Applications folder.
A plain-text editor with a sidebar of one-shot fixes. Change case, sort and dedupe lines, tame whitespace, straighten or curl punctuation, find & replace, wrap text in tags, and drop in filler copy — and chain any of those fixes into a workflow you run in one click. Select a passage and any fix stays inside it. This page walks through how to use each one.
Installation
The download from bendansby.com/apps/textbuddy is a standard .dmg — open it and drag TextPalette.app to your Applications folder. The store version installs and updates the usual way.
Requires macOS 13 Ventura or later, on Apple Silicon or Intel. The direct-download build auto-updates via Sparkle; you can also check anytime via the app menu's Check for Updates…. The store build updates through its own channel. The direct download comes with a free 7-day trial with every feature unlocked — after that, a one-time license (bought on its own or as part of the Surprisingly Useful bundle) keeps it going; the store build is paid once through the usual pipeline, with no separate key.
The editor & the Tasks sidebar
TextPalette is a single window. The middle is a plain-text editor — type, paste, or drop a text file onto it to get started. The header shows the filename, a dot when there are unsaved changes, a Diff checkbox once there are changes to compare (or, for a Markdown document, the Plain / Formatted / Diff switch), and a Copy button. Along the bottom runs a footer with a live word / character / line count and the Save and Save As… buttons. The right-hand Tasks sidebar holds every one-shot fix, grouped into Workflows, Find & Replace, Case, Lines, Whitespace, Punctuation, Wrap, and Generate.
Every transform is a single button. Click it and the fix happens immediately — no dialog, no confirmation.
Two shortcuts have no button: ⌘B and ⌘I wrap the selection in Markdown bold or italic markers — or, with nothing selected, drop an empty pair at the cursor for you to type between. Press the same shortcut again on emphasized text to take the markers back off; the two stack, so bold over italic gives you ***both***.
Whole document, or just the selection
This is the thing to internalize: if you have text selected, a transform only touches the selection. If nothing is selected, it acts on the whole document. A Selection badge appears in the footer and the sidebar whenever you have text highlighted, so you always know which mode a button is about to run in. The word / character / line counts switch to counting the selection too.
Line-based tasks (sort, dedupe, list type, and the rest) are smart about partial selections: if your highlight starts or ends mid-line, it grows out to whole lines first, so you never split a line in half. Character-level tasks (case, punctuation, find & replace) use your selection exactly as drawn.
Copying the whole document
The Copy button at the right of the header copies the entire document to the clipboard — unlike the transforms, this one always grabs everything regardless of any selection. It reads Copied for a moment to confirm, and is disabled on an empty document. It's a shortcut for ⌘A ⌘C when you just want the whole file on the clipboard. With Diff switched on it copies the comparison instead, as unified-diff text you can paste into a message or a pull request.
Change case
Six case buttons, each applied to the selection or the whole document:
| Button | What it does |
|---|---|
| UPPERCASE | Every letter to capitals |
| lowercase | Every letter to small |
| Title Case | Capitalize the first letter of each word |
| Sentence case | Capitalize the first letter of each sentence |
| Code case | A menu of programming styles — camelCase, PascalCase, snake_case, kebab-case, CONSTANT_CASE. Converts line by line, so a list of names converts name by name, and reads any of those styles as input (userID → user_id) |
| Remove accents | Strip accents and other marks — “Crème brûlée” becomes “Creme brulee”. Letters like ø and ł are mapped too; Japanese voicing marks are left alone |
Lines
Line operations treat your text as a list of lines. With a selection, they act on the lines your selection touches (expanded to whole lines); otherwise on the whole document.
| Button | What it does |
|---|---|
| Sort A→Z / Sort Z→A | Alphabetize lines ascending or descending (locale-aware compare) |
| Reverse | Flip the line order top-to-bottom |
| Shuffle | Randomize the line order |
| Remove dupes | Drop repeated lines, keeping the first occurrence of each |
| Remove blanks | Delete empty lines |
| Join | Collapse every line into one, space-joined |
| List type | A menu that restyles lines as a list: Plain (no markers), Markdown plain (no markers, but each line ends in a \ line break so Markdown shows them one per line), Unordered (- bullets), or Ordered (1. , numbered per indent level). Existing bullets and numbers are replaced rather than stacked, so you can switch freely between the four |
| Double breaks | Insert a blank line after every line — single-spaced to double-spaced |
| Unwrap PDF | Rejoin text copied out of a PDF, where every line was broken mid-sentence: runs of lines merge into one, blank lines (real paragraph breaks) stay |
Line tasks normalize Windows line endings to Unix on the way in: a file opened with CRLF line endings is rewritten LF-only the first time any line task runs on it.
Whitespace
Cleanup for the invisible characters that make text look ragged:
| Button | What it does |
|---|---|
| Trim trailing | Remove spaces and tabs at the end of every line |
| Trim lines | Remove whitespace from both ends of every line |
| Collapse blanks | Runs of blank lines become a single blank line |
| Collapse spaces | Runs of two or more spaces become one |
| Tabs → Spaces | Convert each tab to four spaces |
| Spaces → Tabs | Convert four spaces to a tab |
Punctuation
Swap between typewriter and typographic punctuation:
| Button | What it does |
|---|---|
| Smart quotes | Straight quotes " ' become curly " " ' ', context-aware about opening vs. closing |
| Straight quotes | Curly quotes back to straight — the exact inverse |
| Ellipsis | Three dots ... become a single ellipsis character … |
| Dashes | -- and --- become an em dash — |
Smart quotes and straight quotes are a matched pair, so you can flip a document to typographic quotes for publishing and back to straight quotes for code or a plain-text export.
Wrap in tags
The Wrap section surrounds each unit of your text with an opening and closing tag. Pick the granularity — word, sentence, or paragraph — and supply the tag, and TextPalette brackets each unit with it. Handy for turning a stack of paragraphs into <p>…</p> blocks, marking up list items, or quoting each line. Like the other transforms, it honours a selection when you have one.
Workflows
A workflow is a saved chain of fixes that runs in one click. The Workflows section sits at the top of the sidebar: click a workflow's name to run it, or use the ⋯ button beside it to Edit, Duplicate, reorder, or Delete it.
Click + to make one. Give it a name, then click Add Step: a panel laid out like the sidebar opens, and each button you click adds a step to the end of the list. It stays open so you can build the whole chain in one go. Drag steps to reorder them (or right-click a step for Move Up and Move Down), and click ⊖ to remove one.
Order matters. Steps run top to bottom, each on the result of the one before. Unwrapping a PDF paste before trimming lines gives you clean paragraphs; the other way round, the trim has nothing to fix yet.
| Step | Settings kept in the step |
|---|---|
| Any task button | None — Code case and List type pick their style when you add them |
| Replace | Find and Replace text, plus the .* regular-expression and Aa match-case toggles. With a regular expression, $1, $2… in the replacement insert the captured groups. |
| Wrap | The opening and closing text, and whether to wrap each word, sentence, or paragraph |
A workflow runs on your selection, or on the whole document when nothing is selected. If any of its steps works line by line, a partial selection grows to whole lines first and every step works on that same span. The whole run is one undo step, named after the workflow, so ⌘Z takes it all back at once.
Workflows also live in the Workflows menu in the menu bar, where the first nine get shortcuts: ⌥⌘1 through ⌥⌘9, in sidebar order. The same menu has New Workflow…. Workflows are saved with TextPalette's settings rather than in any document, so they're there whichever file you have open.
Find & replace
Find & replace sits near the top of the sidebar, just under Workflows. Type a term into Find, an optional replacement into Replace, and use the action row:
| Control | What it does |
|---|---|
| Next | Jump to and highlight the next match, wrapping around at the end |
| Replace | Replace the current match, then advance to the next |
| All | Replace every match at once |
| Aa | Toggle case-sensitive matching on or off |
| .* | Treat the Find term as a regular expression |
A live match count sits alongside the fields. If text is selected, both the count and All stay inside that selection — a quick way to replace within a single paragraph or block without touching the rest of the file.
The pop-out window
⌘F focuses the inline Find field. When you need more room — searching or replacing across multiple lines — press ⇧⌘F (or click the pop-out button in the section header) to pop Find & Replace out into its own window with multiline Find and Replace fields. It stays above the document window while you work, and hides along with TextPalette when you switch to another app. Inside that window, ⌘↩ runs Replace All. The panel shares state with the sidebar and drives the same editor, so whichever surface you use, you're working on the same document.
Generate filler
The Generate section drops in placeholder copy — useful for mocking up a layout or padding out a draft. It works even on an empty document. Pick a count (1–9) and a unit (Words, Sentences, or Paragraphs), then:
| Button | What it does |
|---|---|
| Insert | Drop a fresh block of filler at the cursor and start a session |
| Replace | Swap the block you just inserted for a fresh generation |
| Add | Append another generation, growing the block |
After you insert, the buttons become Replace and Add so you can dial the amount up or down until it looks right. As soon as you make any manual edit — typing, running a transform, or undoing — the session ends and the row goes back to Insert. Choosing the Words unit produces Title-Cased words with no punctuation, so it reads as a label or title; Sentences and Paragraphs get normal casing and punctuation.
Markdown: Plain / Formatted / Diff
When a document is Markdown — a .md file, or text that clearly uses Markdown, like # headings, links, **bold**, code or tables — the header's Diff checkbox becomes a Plain / Formatted / Diff switch. (A note with just a few - bullets isn't enough on its own to count.)
Formatted splits the editor in two: your plain text on the left, still fully editable, and the rendered document on the right — headings, bold and italics, links, bulleted, numbered and checkbox lists, quotes, code blocks, tables and rules — updating as you type. The Tasks sidebar stays put, so you can run a fix and watch the result render. Diff appears in the switch once you have unsaved changes and works as described below.
\ (or two spaces), or leave a blank line between them — List type → Markdown plain adds the backslashes for you.
See what changed
Tick Diff in the header and the editor is replaced by a side-by-side comparison: the file as it was last saved on the left, your current edits on the right, lined up row by row with line numbers down each side. Removed and edited lines carry a red wash on the left, added and edited ones a green wash on the right — and within an edited line, only the characters that actually changed are highlighted, so a one-character fix like a smart quote doesn't light up the whole line.
The Tasks sidebar collapses while the comparison is up, giving the two columns the full window. The footer swaps its word / character / line counts for a tally of how many lines were added, removed, and changed. A line counts as changed when it exists on both sides but isn't identical; removed and added mean the line has no counterpart on the other side. The comparison opens scrolled to the first change, so you don't have to hunt for it in a long file.
The file queue & Open Recent
Open several files at once — File → Open… (⌘O) is multi-select, and you can drop several files onto the window — and they load into a queue. A drawer appears down the left with a row per open document; click a row to switch to it. Only one document is active at a time. File → New (⌘N) adds a fresh Untitled document to the queue.
The queue always keeps at least one document: close the last one and it's replaced by a fresh Untitled.
Opening the same file only once
TextPalette won't open a file that's already in the queue a second time — asking for it again just brings the existing copy forward instead of creating a duplicate tab. That keeps you from accidentally editing two out-of-sync copies of the same file.
Open Recent
File → Open Recent lists the files you've opened lately (it also feeds the Dock menu). Clear Menu empties the list. The menu hides itself when there's nothing to show. If the window is closed — possible when the menu-bar icon keeps TextPalette running — opening a recent file, or dropping one on the Dock icon, brings the window back with it.
Closing the window
⌘W and the window's close button share one set of rules. With more than one document open, ⌘W closes just the active one — the same as clicking a row's hover-close button in the drawer — and the queue stays open on whatever's left. With a single document open, closing closes that document and leaves a fresh blank Untitled one in its place, keeping the window open; if it has unsaved changes you're asked to save first, and Cancel keeps it open. Close again on that blank document and the window closes — which quits TextPalette, unless the menu-bar icon is keeping it running.
The menu-bar scratch pad
Turn on Show Menu Bar Icon in the app menu to get a TextPalette icon in the menu bar. Clicking it drops down a small scratch pad — a throwaway text buffer, separate from your open documents, with a live word / character / line count and clusters of the Case, Punctuation, and Generate buttons.
It's for the quick one-off: paste a snippet from another app, fix its case or straighten its quotes, drop in a line of filler, and copy the result back — all without leaving whatever you were doing. The Generate cluster here includes a Copy Filler button that puts a fresh block straight on the clipboard. Hovering over the scratch text area itself reveals a matching Copy pill in its lower-right corner — it copies whatever's currently in the buffer, typed, pasted, or generated, rather than a fresh filler block. The scratch pad's contents are independent of your document queue and persist on their own.
View options
The View menu tunes how the editor looks — display only, none of it changes your file:
- Font — Monospaced, Sans-Serif, or Serif.
- Text Size — grow with ⌘+, shrink with ⌘-, reset with ⌘0 (8–48 pt).
- Show Line Numbers (⇧⌘L) — a line-number gutter down the left of the editor. It's a display ruler and never touches the text; use the List type → Ordered task if you want the numbers written into the file.
Workspace restore
TextPalette remembers the files you had open. Quit with a few documents in the queue and they reopen on your next launch, so you pick up where you left off. Together with the unsaved-changes prompt below, it means you rarely have to think about setting the window back up.
Saving
Two buttons sit at the right of the editor's footer:
- Save — write changes back to the file. It's disabled when the document has never been saved or has no unsaved changes; for a brand-new Untitled document, Save opens a save panel to pick a location and name.
- Save As… — write the current text to a new file, leaving the original untouched. Available whenever there's text to save.
Dirtiness is tracked by comparing content, not by a flag — so if you edit a document and then undo all the way back to how it was, the unsaved-changes dot disappears and Save disables again.
TextPalette won't let you lose work by accident. Close a document with unsaved changes and you're prompted to Save, Cancel, or Don't Save. Quit with several unsaved documents and it offers to Review each one in turn, Discard everything, or Cancel the quit.
Languages
TextPalette is localized into English, Deutsch, Español, Français, Italiano, 日本語, 한국어, Português (Brasil), Русский, and 简体中文. It picks the right language automatically based on your System Settings → General → Language & Region preferences.
To pin TextPalette to a specific language without changing system preferences, open System Settings → General → Language & Region → Applications, click the + button, and pick TextPalette.
Support
Questions or bug reports? Email ben.dansby@gmail.com and you'll get a reply, usually within a day or two. For privacy questions, see the privacy policy.