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.

TextPalette only reads and writes the files you drop on it or pick yourself. Nothing is uploaded — even the filler-text generator runs entirely offline.

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.

Everything is undoable with the system undo (⌘Z) — and redoable with ⌘⇧Z. Typing and one-shot transforms share the same undo history, so you can freely experiment and step back. Each step is named, so Edit → Undo tells you what it will take back — Undo Sort A→Z, Undo Smart quotes — and a transform run straight after typing is always its own step, never folded into your typing. There's also an Undo button in the sidebar header, whose tooltip names the step too.

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:

ButtonWhat it does
UPPERCASEEvery letter to capitals
lowercaseEvery letter to small
Title CaseCapitalize the first letter of each word
Sentence caseCapitalize the first letter of each sentence
Code caseA 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 accentsStrip 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.

ButtonWhat it does
Sort A→Z / Sort Z→AAlphabetize lines ascending or descending (locale-aware compare)
ReverseFlip the line order top-to-bottom
ShuffleRandomize the line order
Remove dupesDrop repeated lines, keeping the first occurrence of each
Remove blanksDelete empty lines
JoinCollapse every line into one, space-joined
List typeA 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 breaksInsert a blank line after every line — single-spaced to double-spaced
Unwrap PDFRejoin 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
List type → Ordered writes the numbers into your text — it's an edit you can save. That's different from the line-number gutter under View options, which is a display-only ruler that never changes the file.

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:

ButtonWhat it does
Trim trailingRemove spaces and tabs at the end of every line
Trim linesRemove whitespace from both ends of every line
Collapse blanksRuns of blank lines become a single blank line
Collapse spacesRuns of two or more spaces become one
Tabs → SpacesConvert each tab to four spaces
Spaces → TabsConvert four spaces to a tab

Punctuation

Swap between typewriter and typographic punctuation:

ButtonWhat it does
Smart quotesStraight quotes " ' become curly " " ' ', context-aware about opening vs. closing
Straight quotesCurly quotes back to straight — the exact inverse
EllipsisThree 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.

StepSettings kept in the step
Any task buttonNone — Code case and List type pick their style when you add them
ReplaceFind 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.
WrapThe 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:

ControlWhat it does
NextJump to and highlight the next match, wrapping around at the end
ReplaceReplace the current match, then advance to the next
AllReplace every match at once
AaToggle 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:

ButtonWhat it does
InsertDrop a fresh block of filler at the cursor and start a session
ReplaceSwap the block you just inserted for a fresh generation
AddAppend 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.

The filler is generated locally by a small word model — plausible-looking prose, but not factual. There's no network call, so it works offline and nothing about your document leaves the Mac.

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.

Markdown joins consecutive lines into one paragraph. To keep lines apart in the rendered view, end a line with a backslash \ (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 comparison is read-only: transforms, typing, and undo are all disabled until you switch Diff back off, so there's no way to accidentally edit the comparison instead of your document. Your text is exactly where you left it underneath. Diff only appears — as the checkbox, or as a segment of the Markdown switch — once there are unsaved changes to compare.

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.

Switching documents clears that document's undo history for this version — undo is per editing session, and moving away and back starts fresh. Save before you switch if you might want to step back later.

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.

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:

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:

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.