TabWell User Guide
Version 1.1.0 · A native macOS source-code editor for Windows → Mac migrants
Welcome to TabWell. If you are coming from a classic Windows text editor, this guide is written for you: it walks through every feature, calls out where macOS does things differently, and ends with a "where did X go?" migration table and an honest list of current limitations.
Every behaviour described here matches what actually ships in v1.1.0. Where a feature is incomplete or behaves differently from the Windows editor you're used to, you'll find it under Known limitations rather than glossed over.
Table of contents
- Getting started
- Working with files
- Folder workspace
- Encodings & line endings
- Editing
- Find & Replace
- Find in Files
- Navigation & line operations
- Reading aids & Symbols
- Preferences
- Session restore
- Windows editor → TabWell migration
- Known limitations
1. Getting started
Launching the app
Open TabWell from the Applications folder, Launchpad, or Spotlight. On first launch you get a single window with one empty Untitled tab, a blinking caret, and you can start typing immediately.
The window at a glance
- Toolbar (top): a compact native toolbar with an always-visible sidebar toggle, separate Open File and Open Folder buttons, New, Save, and Find.
- Sidebar (left, collapsible/resizable): switches between the Files workspace tree and the current document's Symbols outline.
- Tab bar: one tab per open document. Click a tab to switch; click the × on a tab (or press ⌘W) to close it. A dedicated unsaved-change dot in the tab title means the document has unsaved changes, and the active tab is automatically revealed when many tabs overflow.
- Editor (centre): where you type. The left gutter shows line numbers, the fold ribbon, and bookmark dots.
- Status bar (bottom): shows, and lets you change, the active document's language, encoding, line-ending style, word-wrap state, and the caret position / selection count. Lower-priority details yield first in a narrow window; line/column and language always stay visible.
Tabs
- New tab: File ▸ New (⌘N).
- Switch tabs: click a tab in the tab bar.
- Close a tab: the × on the tab, or File ▸ Close (⌘W). TabWell always keeps at least one tab open, so the window never disappears out from under you. Use ⌘Q to quit the app.
- Each tab owns its own text, language, encoding, line-ending and word-wrap settings. They never bleed across tabs.
- Save All saves every unsaved tab in one action.
- Reopen Closed Tab brings back the last 20 tabs you closed, most recent first.
- Right-click (or Control-click) a tab for a context menu with Close, Close Others, Close All, and other tab actions. Untitled tabs can be renamed directly from this menu.
2. Working with files
Opening files
- File ▸ Open… (⌘O) shows a file picker. If the current tab is empty and untouched, the file loads into it; otherwise it opens in a new tab.
- The tab title and the window's title bar update to the file's name, and the language mode is auto-detected from the file extension (see Reading aids).
- File ▸ Open Recent lists files you opened before, including across quit and relaunch.
Choose Clear Menu at the bottom to empty the list.
macOS sandbox note: TabWell runs in the macOS App Sandbox, so it can only open files and folders you pick in a panel (or drag in). It remembers your permission to reopen a file later using a secure bookmark, not a raw path, which is why Open Recent keeps working after you quit and relaunch.
Saving
- File ▸ Save (⌘S) writes the file back byte-for-byte and clears the unsaved-changes dot.
Save is greyed out when there is nothing to save.
- Saving a brand-new Untitled tab opens a Save panel so you can choose a name and location.
- File ▸ Save As… (⇧⌘S) writes a copy to a new location and points the tab at the new file; the original is left untouched.
When you close or quit with unsaved changes
- Closing a tab (⌘W or the ×) that has unsaved edits asks Save / Don't Save / Cancel.
- Quitting (⌘Q) asks the same question for each file-backed tab that has unsaved edits.
Choosing Cancel on any prompt stops the quit entirely.
- Untitled tabs are not prompted on quit; their text is preserved automatically by session restore, so nothing is lost.
The "file changed on disk" banner
If a file you have open is modified by another program, TabWell shows a non-blocking yellow banner at the top of the editor: "This file has changed on disk." It offers:
- Reload: discard your in-editor copy and re-read the file from disk.
- Keep Editing: dismiss the banner and keep your version.
The banner never blocks typing, and it tucks neatly below the find bar if both are open.
3. Folder workspace
Open a project folder to browse and jump between its files without leaving TabWell, the classic "project explorer" workflow.
- File ▸ Open Folder… shows a folder picker, or click the Open Folder toolbar button. The folder opens as a read-mostly tree in the left sidebar; the sidebar toggle in the toolbar shows or hides it at any time.
- TabWell supports one workspace root at a time. Opening a new folder replaces the current one.
- Folders sort before files, everything loads lazily as you expand it, and large or irrelevant subtrees (build output, dependency folders) are skipped so the tree stays fast even in big projects.
- Click a file in the tree to open it. If that file already has a tab open, TabWell switches to the existing tab instead of opening a duplicate.
- Right-click a file or folder for Open, Reveal in Finder, Copy Path, and Find in This Folder (scopes Find in Files to that subtree).
- Refresh re-scans the tree if files changed outside TabWell.
- The open workspace and sidebar width are remembered across quit and relaunch, stored as a secure bookmark plus relative paths, the same sandbox-safe approach used for Open Recent.
The workspace is read-mostly: it is for browsing and opening files, not project-wide file management, Git status, a terminal, or build tasks. It also rejects symlink escapes and cycles outside the chosen root as a safety measure.
4. Encodings & line endings
TabWell treats encodings and line endings the way a serious code editor should: it detects them on open, preserves them on save, and lets you change them deliberately.
Detection (on open)
The status bar shows the detected encoding (e.g. UTF-8, UTF-8 with BOM, UTF-16 LE) and the detected line-ending style:
| Style | Used by |
|---|---|
LF (\n) | macOS, Linux |
CRLF (\r\n) | Windows |
CR (\r) | classic Mac OS |
New Untitled documents default to UTF-8 / LF (you can change these defaults in Preferences ▸ New Files).
Preserve on save
If you open a Windows file (CRLF / UTF-8), edit it, and save without touching the popups, it stays CRLF / UTF-8. TabWell never silently "fixes" your line endings or encoding. These settings also survive quit and relaunch with the rest of your session.
Reinterpret vs Convert
Both the encoding and line-ending popups in the status bar offer two distinct operations, and the distinction matters:
- Reinterpret as…: re-reads the same bytes using a different encoding. Use this when a file opened as the wrong encoding (e.g. it looks like gibberish / "mojibake"). It does not change the file's bytes; it changes how TabWell decodes them. If you have unsaved edits, TabWell asks for confirmation first, because re-reading discards them.
- Convert to…: changes the bytes to a new encoding (or line-ending style) on the next save.
Example: open a UTF-16 LE file, choose Convert to ▸ UTF-8, then save. The file is now UTF-8 on disk (no BOM). Convert CRLF → LF the same way.
If a conversion would lose characters (for example, converting text containing an emoji 🚀 to Windows-1252, which can't represent it), TabWell warns you and leaves the encoding unchanged rather than corrupting your text.
Byte-order marks (BOM)
A UTF-16 file with a BOM opens correctly and the BOM is handled invisibly: you won't see a stray glyph at the start of the document.
See Known limitations for the one detection edge case: a UTF-16 file with no BOM.
5. Editing
Typing & the basics
Type and characters appear immediately at the caret. The standard Edit menu is all there with the shortcuts you'd expect: Undo (⌘Z), Redo (⇧⌘Z), Cut (⌘X), Copy (⌘C), Paste (⌘V), Select All (⌘A). The default editor font is a 13-pt monospaced face; text is always drawn clear of the line-number gutter.
Word wrap
The Wrap button in the status bar toggles word wrapping for the current tab. Wrap is per-tab, so you can wrap a prose file while leaving a code file unwrapped. New documents can be set to wrap by default in Preferences ▸ New Files.
Column (rectangular) selection
Hold Option (⌥) and drag vertically to select the same column range on every line, a rectangular block. Press Delete and the selected prefix is removed from all those lines at once; a single ⌘Z restores them all.
Multiple carets
TabWell supports editing at many places at once, a favourite power-user feature:
- ⌘-click anywhere to drop an additional blinking caret there. ⌘-click an existing caret to remove it (you can't remove the last one). (Control+Shift+click also works.)
- Type, and your text is inserted at every caret simultaneously.
- A single ⌘Z undoes the whole multi-caret edit as one step.
Select All Occurrences (⌃⌘G)
- With the caret inside a word (nothing selected), ⌃⌘G selects every whole-word occurrence of that word, each as its own caret.
- With text explicitly selected, ⌃⌘G selects every literal occurrence of that exact substring.
- The status bar's selection count reflects the multiple selections. Type to replace them all at once.
Multiple carets are a live editing state: they are not saved across quit/relaunch and collapse back to a single caret on restore (this matches the classic Windows behavior).
Occurrence highlighting, comments & indent
- Selecting a word or phrase passively highlights its other exact occurrences in the document, so repeated identifiers are easy to spot without running a search.
- Toggle Comment and Indent/Unindent have native Mac shortcuts and act on the current line or selection.
6. Find & Replace
Open the find bar with Find… (⌘F). It has two rows, a Find row and a Replace row, and pre-fills the search field from a single-line selection if you have one.
Searching
- Matches highlight as you type, and a counter shows "1 of N", updating live on every keystroke.
- Find Next: Return or ⌘K. Find Previous: Shift+Tab or ⇧⌘K. Both wrap around the ends of the document.
- Esc or the ✕ closes the bar, clears the highlight, and returns focus to the editor.
- An empty or non-matching query shows "No results", never a crash.
Search toggles
| Toggle | Meaning |
|---|---|
Aa | Match case |
.* | Regular-expression mode |
\b | Whole word only |
In Sel | Restrict the search to the text that was selected when the bar opened |
An invalid regular expression shows a red "Invalid regex" label and simply waits: fix the pattern and matching resumes. (Nothing crashes, nothing is replaced.)
Replacing
- Replace replaces the current match and advances to the next one.
- Replace All replaces every match and reports "Replaced N"; the whole operation is a single ⌘Z undo step.
- Regular-expression capture groups work in replacements (e.g. search
(\w+)=(\w+), replace$2=$1). - With In Sel on, Replace is confined to the selection, and navigation wraps within those matches.
- Replace… (⌥⌘R) opens the bar with the Replace field focused.
7. Find in Files
Search a whole folder tree at once: the classic "Find in Files" workflow.
- Edit ▸ Find ▸ Find in Files… (⌥⌘F) opens a folder picker, or use Find in This Folder from a workspace sidebar item. Choose a folder and a floating results panel appears.
- Results stream in live as
name:line snippet, with the matched text in bold. The header shows "Searching… N matches in M files" and then the final totals. The main window stays fully responsive while the search runs. - Include/exclude glob filters (e.g.
*.swiftto include only Swift files, or*.min.jsto exclude minified bundles) narrow the search before it runs. - Click a result to open that file in a tab, scrolled to the matched line with the match selected.
- Mark All highlights every match in the current document, and Find All lists navigable results for the current document or all open tabs.
node_modules/,.git/, and other hidden directories are skipped, and very large files are passed over, so searches stay fast.
Because of the macOS sandbox, Find in Files searches only the folder you pick in the panel (or your open workspace). TabWell can't silently scan arbitrary paths. This is expected macOS behaviour.
8. Navigation & line operations
Go to Line (⌘G)
Edit ▸ Go to Line… (⌘G) opens a sheet showing the valid line range. Enter a valid number and the editor scrolls there and selects the line; an out-of-range number shows an inline red error and keeps the sheet open. (If the target line is inside a folded block, it is revealed.)
Coming from Windows: yes, ⌘G is Go to Line here, not "Find Next" (which is ⌘K). This is deliberate parity with the classic Windows Ctrl+G.
Line Operations (Edit ▸ Line Operations)
All of these operate on the selected lines, or the whole document if there's no selection, and each is a single undo step:
| Operation | What it does |
|---|---|
| Sort Lines Ascending / Descending | Sort lines A→Z or Z→A |
| Remove Duplicate Lines | Drop duplicates, keeping the first occurrence |
| Trim Trailing Whitespace | Strip trailing spaces/tabs from each line (idempotent) |
| Change Case ▸ UPPERCASE / lowercase / Title Case | Re-case the selection |
| Move Line Up / Down | Swap the current line with the one above/below |
| Duplicate Line | Copy the current line(s) below |
| Join Lines | Join the selected lines into one, separated by spaces |
| Convert Tabs to Spaces | Replace tabs with spaces |
| Convert Spaces to Tabs | Replace runs of spaces with tabs |
Bookmarks (Edit ▸ Bookmarks)
- Toggle Bookmark (⇧⌘B) adds or removes a bookmark on the current line; an accent-coloured dot appears in the left gutter.
- Next Bookmark / Previous Bookmark jump between bookmarks (wrapping around). These are menu-only.
- Clear All Bookmarks removes every dot in the current tab.
- Bookmarks on file-backed tabs persist across quit and relaunch. (If the file got shorter while closed, bookmarks past the new end are quietly dropped.)
9. Reading aids & Symbols
Syntax highlighting
TabWell highlights code with tree-sitter grammars, picked automatically from the file extension. Supported languages:
| Language | Recognised extensions |
|---|---|
| Swift | .swift |
| Python | .py, .pyw, .pyi |
| JavaScript | .js, .cjs, .mjs |
| TypeScript | .ts, .cts, .mts |
| JSON | .json |
| YAML | .yml, .yaml |
| Markdown | .md, .markdown, .mkd, .mkdn, .mdown, .mdwn |
| HTML | .html, .htm, .shtml, .xhtml |
| CSS | .css |
| Shell | .sh, .bash, .zsh, .ksh |
| SQL | .sql |
| Java | .java, .jav |
| C | .c, .h |
| C++ | .cc, .cpp, .cxx, .c++, .hpp, .hh, .hxx |
| Go | .go |
| Rust | .rs |
| Ruby | .rb, .rbw |
| PHP | .php, .phtml |
| TSX | .tsx |
| XML family | .xml, .svg, .plist, .xhtml |
Anything else opens as Plain Text (no colouring). .h is treated as C.
- You can override the detected language with the language popup in the status bar; the buffer re-highlights instantly, without a reload or flicker.
- Each tab keeps its own language mode through tab switches, and the mode survives quit/relaunch.
- Syntax colours update immediately when you switch between Light and Dark appearance.
- For very large files (around 20 MB and up), highlighting is suppressed so the editor stays responsive; the popup may still name the detected language. Multi-megabyte files are parsed in the background so the UI never freezes.
Line numbers, fold ribbon, minimap & whitespace
- Show Line Numbers (View menu / Preferences) toggles the line-number gutter live.
- Show Fold Ribbon (View menu) toggles the fold triangles in the gutter; the setting persists.
Click a fold triangle to collapse or expand that block.
- Show Minimap (View menu, ⌃⌘M / Preferences) toggles a scaled-down map of the whole file alongside the editor, for a quick sense of where you are in a long document. Off by default.
- Show Whitespace (View menu / Preferences) draws spaces as
·, tabs as→, and line endings as¬. Toggle it off and the marks disappear immediately.
Comparing two files (Edit ▸ Compare)
Compare two text files side by side in a dedicated, read-only window — the comparison never edits your documents.
- Edit ▸ Compare Files… (⇧⌘D) opens a small chooser to pick a Left and Right document from your open tabs, then shows the diff. It is available once two or more tabs are open.
- Edit ▸ Compare With File… compares the active document against a file you pick from disk, read through the same secure gateway and encoding/line-ending detection as any other open.
In the compare window, added, removed, and changed lines are shown in distinct colours (adapting to Light/Dark) with the two columns kept row-aligned. The columns scroll together; ◀ / ▶ jump to the previous / next change and a counter shows “N of M”. Swap exchanges the sides and Close dismisses the window; you can select and copy a line from either side. Identical files report “No differences.”, a line-endings-only difference is surfaced rather than called identical, and a very large pair shows a “too large to compare” message instead of hanging. The compare view is compare-only (no merge or write-back), is not a tab, and does not take part in session restore.
Symbols
The sidebar's Symbols tab shows a filterable outline of the active document for Python, JavaScript, TypeScript, and Swift files.
- Declarations (functions, classes, methods, and more) are shown nested to match their structure in the file, with export status indicated.
- Type to filter the outline; click a symbol to jump straight to it with exact, UTF-16-accurate placement.
- The outline updates as you edit or switch tabs, and shows a stale-result guard rather than a wrong jump target if a large edit is still being parsed.
- For other languages, or very large files, the Symbols tab is empty; this is expected, not an error.
10. Preferences
Open Preferences with ⌘, (App menu ▸ Preferences…). Every control applies live and persists across launches. Sections:
Appearance
- Theme: System (follow macOS), Light, or Dark. The editor switches instantly, with no restart.
The caret stays visible in all three modes, and the app follows a macOS-wide appearance change while running.
Editor
- Font family (Menlo, Monaco, System Monospace, …) and size (default 13 pt) apply live.
Zoom (⌘+ / ⌘- / ⌘0, or hold ⌘ / Ctrl and scroll the mouse wheel) drives the same size and stays in sync with this control. Size is clamped between 6 pt and 96 pt.
- Text margin: breathing room between the window edges and the text (0–32 pt, default 6 pt), applied live on both the left and right edges. Set it to 0 for flush-edge text.
Indentation
- Insert spaces instead of tabs and the tab width. With spaces on, the Tab key inserts that many spaces; with it off, Tab inserts a real tab rendered that many columns wide.
New Files
- The default encoding, line endings, and wrap lines for brand-new Untitled documents.
These do not affect existing files you open (those keep their detected settings).
Startup
- Reopen Tabs at Launch: mirror of the File-menu toggle (see below).
11. Session restore
TabWell quietly saves your working state so you can pick up where you left off. State is written about 2 seconds after you stop typing, and again when you quit.
What comes back on relaunch:
- Untitled tab contents (your unsaved scratch text).
- File-backed tabs, reopened through their secure bookmark (so it works even in the sandbox).
- The active tab, and each tab's caret/scroll position (approximately), language mode, encoding, line endings, and bookmarks.
Reopen Tabs at Launch (File menu, and Preferences ▸ Startup) controls this. It is on by default. Turn it off and TabWell starts each time with a single fresh Untitled tab (your saved session file is left intact on disk, not deleted).
If a remembered file was deleted or moved while TabWell was closed, its tab reappears with the filename but an empty buffer marked as unsaved: no crash, no data loss elsewhere.
Unsaved changes are safe across quit. Untitled text is restored automatically; for a file-backed tab with unsaved edits, quitting prompts you to Save / Don't Save / Cancel first.
12. Windows editor → TabWell migration
A quick "where did X go?" map for Windows-editor habits:
| In your Windows editor | In TabWell (Mac) |
|---|---|
| Ctrl for shortcuts | ⌘ (Command) |
| Ctrl+N / Ctrl+O / Ctrl+S | ⌘N / ⌘O / ⌘S |
| Ctrl+Alt+S (Save As) | ⇧⌘S |
| Ctrl+W (close tab) | ⌘W |
| Ctrl+F (Find) / Ctrl+H (Replace) | ⌘F / ⌥⌘R |
| F3 / Shift+F3 (Find Next/Prev) | ⌘K / ⇧⌘K |
| Ctrl+Shift+F (Find in Files) | ⌥⌘F |
| Ctrl+G (Go to Line) | ⌘G (kept the same) |
| Ctrl+F2 (Toggle Bookmark) | ⇧⌘B |
| F2 / Shift+F2 (Next/Prev Bookmark) | Edit ▸ Bookmarks menu |
| Column mode (Alt+drag) | ⌥-drag (same idea) |
| Multi-edit (Ctrl+click) | ⌘-click for extra carets |
| Ctrl+D (Duplicate Line) | Edit ▸ Line Operations ▸ Duplicate Line |
| Ctrl+Shift+Up/Down (Move Line) | Edit ▸ Line Operations ▸ Move Line Up/Down |
| Ctrl+U / Ctrl+Shift+U (case) | Edit ▸ Line Operations ▸ Change Case |
| Encoding menu | Encoding popup in the status bar |
| EOL Conversion | Line-ending popup in the status bar |
| Language menu | Language popup in the status bar |
| View ▸ Word wrap | Wrap button in the status bar |
| Settings ▸ Preferences | App menu ▸ Preferences… (⌘,) |
| Plugins / macros | Not in this release (see below) |
13. Known limitations
These are honest, documented gaps in v1.1.0. Most are waiting on the upstream editor engine and are expected to light up in a later release.
- Folding by keyboard / menu is disabled. You can fold by clicking the gutter triangle, but the View ▸ Folding menu items (Fold at Caret, Fold All, …) are greyed out, and fold state isn't remembered across quit. The underlying editor engine doesn't yet expose a programmatic folding API. (Workaround: use the gutter triangles.)
- No indent guides. The "Show Indent Guides" preference is present but disabled; the engine doesn't draw them yet. Your choice is remembered for when it does.
- A UTF-16 file with no byte-order mark may be detected as UTF-8 and show interleaved "NUL" characters. (Workaround: use the encoding popup ▸ Reinterpret as ▸ UTF-16.) The classic Windows editors have the same ambiguity.
- Bookmark gutter dots can sit slightly off the line baseline at non-default font sizes (cosmetic only).
- Multiple carets don't survive quit/relaunch (they collapse to one), matching the classic Windows editor.
- The folder workspace supports one read-mostly root. File management, Git status, terminals, and build tasks remain in Finder or dedicated developer tools.
- Symbols covers the active Python, JavaScript, TypeScript, or Swift document only — not project-wide indexing, semantic analysis, references, diagnostics, or rename.
Not in this release at all (post-MVP): plugins, macros, User-Defined Languages, and split-editor view.
Need a hand? See the FAQ & Troubleshooting and the Keyboard Shortcut Reference.