---
title: "Files and Notes"
description: "Browsing, previewing and transferring files over SFTP, dropping and pasting files into remote terminals, the Markdown editor bound to an Obsidian-compatible Vault, and saved snippets."
url: "https://docs.closex.org/thinkterm/files-and-notes.html"
markdown_url: "https://docs.closex.org/thinkterm/files-and-notes.md"
site: "CloseX Docs"
product: "ThinkTerm"
language: "en"
last_updated: "2026-11-08T12:04:16.000Z"
alternates:
  en: "https://docs.closex.org/thinkterm/files-and-notes.md"
  zh-Hans: "https://docs.closex.org/zh/thinkterm/files-and-notes.md"
  ja: "https://docs.closex.org/ja/thinkterm/files-and-notes.md"
---

# Files and Notes

> **Documentation in progress**
> Some sections are still incomplete.

Three panels sit alongside the terminal: a file browser that reaches local and remote directories alike, a Markdown editor bound to a notes Vault you already own, and a library of saved commands. The same right sidebar can also hold the [Status](https://docs.closex.org/thinkterm/agents.md) panel and panels that [plugins](https://docs.closex.org/thinkterm/plugins.md) add.

## Files

The file browser shows a tree for the current Project, with a syntax-highlighted preview for the file you select and a filter box that searches the whole Project. Files dropped on the panel from elsewhere are copied into the folder they land on, a row dragged onto a terminal pastes its path, and `Open With` hands a file to another application.

The filter is not fuzzy. It matches part of a file's name, ignoring case; once the query contains a `/`, it matches against the path relative to the Project instead, so `src/main` matches `src/main.rs` but not `tests/main.rs`.

### What search looks through

Search walks the Project by one set of rules, the same for a local Project and a remote one:

- dotfiles such as `.github` are included
- symbolic links are not followed
- version control, build and dependency folders are skipped: `.git`, `.hg`, `.svn`, `target`, `node_modules`, `.next`, `.nuxt`, `.turbo`, `.cache`, `dist`, `build`, `coverage`, `vendor`, `.venv`, `venv` and `__pycache__`
- what the Project's own `.gitignore` excludes is left out, unless `right_sidebar_search_respects_gitignore` is set to `false`
- the walk stops at 100,000 entries

The `.gitignore` rule applies to search alone: an ignored file is still in the tree, it just does not come up when you search for it. The skipped folders are another matter — a local Project's tree leaves them out as well.

The list behind the filter is built the first time you search, not when the panel opens, so the first query of a large Project takes a moment.

### The tree

While the panel is on screen, a local Project's tree is read again every 90 seconds. The refresh button reads the tree at once, local or remote.

Each Project keeps its own view: switching to another Project and back brings back the folders you had open, the file you had selected, where you had scrolled, and what was in the filter. This lasts while ThinkTerm runs.

Right-clicking a row offers what can be done to the file itself:

| Local row | Remote row |
|---|---|
| `Open` (files only), in the system's default application | `Download` (files and folders) |
| `Reveal in Finder` — `Show in File Explorer` on Windows, `Show in Folder` on Linux | `New Folder` (folders only) |
| `Copy Path` | `Copy Path` |
| `Rename…` | `Rename…` |
| `Move to Trash` | `Delete…` |

Renaming happens in the row itself, and a remote rename refuses a name that is already in use.

### Previews

Selecting a file opens its preview in a wider pane to the left of the tree. Drag the edge between them to change its width; ThinkTerm keeps the width for next time.

What the preview shows depends on the file:

| File | Preview |
|---|---|
| Text | The first 1.5 MiB, syntax-highlighted. A longer file says `Preview truncated to 1.5 MiB` |
| Image — PNG, JPEG, GIF, WebP, BMP, ICO, TIFF | The picture, for files up to 16 MiB and pictures up to 16 megapixels |
| Anything containing a zero byte | `Preview unavailable for binary file` |
| Text that is not UTF-8 | `Preview unavailable for non-UTF-8 text` |

A file up to 64 KiB opens already coloured. A larger one appears as plain text at once and takes its colours a moment later. A text preview scrolls sideways with a horizontal gesture, or with Shift and the mouse wheel.

The preview's header holds the open button. It reads `Open With` and the name of an application: the one you last chose from its list, or the file's default application until you have chosen one. The arrow beside it lists the other applications that can open the file, and `Open With Other…` to pick any application on the computer; one picked that way joins the list. The application you choose becomes the button's application for every file afterwards, until you choose another.

Right-clicking a local preview offers `Copy`, `Copy All`, `Copy Path`, the reveal item and `Open With`. A remote preview offers `Copy`, `Copy All`, `Copy Path` and `Download` instead: a file on a server has to be downloaded before another application can open it.

### Markdown previews

A Markdown file is previewed rendered rather than as source. A button in the preview's header switches between the two, and the choice is kept for the next file.

The rendered view can be selected and copied, opens links, and resolves `[[wiki links]]` among the Project's files. A wiki link that matches more than one file opens a short list of the candidates to choose from; one that matches nothing does nothing, because a preview never creates files. Code blocks carry a button that copies the block and one that folds it away. The preview never fetches an image from the network.

### Editing in the Markdown preview

A local Markdown file that the preview holds whole — up to 1.5 MiB, and not read-only — is edited right in the rendered view, with the same keys as a Note (see [Keyboard](#keyboard)). Clicking a task's checkbox ticks it, and right-clicking offers a note's editing menu followed by the file's own. Esc gives the keyboard back. A remote file, a file longer than the preview holds, and a file nobody may write stay read-only.

Edits are saved as a Note's are: shortly after each one, and again when you leave the file, switch to the source view or close the window. A Note and a preview of the same file, in this window or another, share one text. A file with Windows line endings keeps them.

The file is checked every couple of seconds. If another program writes it while it is open here, that version replaces the preview's, unless you have typed since the check began. A file that has grown past what the preview holds, or been deleted, is loaded again as it now is.

When a save fails, or the file has changed into something that cannot be read, editing stops. A line above the text says why — it begins `Couldn’t save, so editing stopped` or `The file changed and can’t be read, so editing stopped` — and the text stays on screen to be copied out. An unreadable file is never saved over. The preview stays until you leave it: going back or closing the window shows the line first, and doing it again gives the edits up.

### Remote files over SFTP

When a Project lives on a remote host, the same browser works over SFTP. It supports:

- browsing remote directories
- uploads and downloads, including whole directories transferred recursively
- retry after a failed transfer
- dropping a file straight onto a remote terminal to upload it there
- searching the remote Project with the same filter box

By default the panel does not dial the host by itself. Until you ask, it shows `Not connected` and a `Connect` button; while it dials it says `Connecting…`, and if that fails, `Connection failed` with `Retry`. Once you have connected to a host, ThinkTerm reconnects to it on its own for as long as it runs, and asks again after a restart. Dropping or pasting files into one of that host's terminals counts as asking.

A host can also be told to connect without being asked. With `Connect Files automatically` turned on in its [editor](https://docs.closex.org/thinkterm/remote.md#the-remote-hosts-page), the panel connects as soon as a terminal on that host is beside it, whether that terminal reaches the host directly or through its ThinkTerm Connect domain. The switch is per host and off until you turn it on. It exists only for the hosts in ThinkTerm's own list; one that appears only in `~/.ssh/config` always waits for `Connect`.

A transfer never overwrites anything on the server. An upload whose name is already taken there fails rather than replacing the file, and a folder upload stops at the first such name and says how far it got. A download never overwrites anything on your computer either: a name already in use gets ` (1)`, ` (2)` and so on, before the extension for a file and at the end for a folder.

Downloads are saved to `Settings › Workspaces › Download Folder`. If none is set, or after `Use the System Downloads Folder`, ThinkTerm uses the system's Downloads folder.

### Searching a remote Project

A remote Project is not walked over SFTP one directory at a time. The first time you search it, ThinkTerm asks the host to list the Project itself, by running `thinkterm list-files` there over the SSH connection the file browser already holds. Typing then searches what came back; the Project is listed again once that listing has aged. A Markdown preview of a remote file resolves its wiki links against the same listing.

So search needs ThinkTerm installed on the host, and recent enough to have `list-files`. ThinkTerm runs the host's `remote_wezterm_path` when one is set, and otherwise looks in the usual install places. A host with no ThinkTerm, or one too old, gets a message asking you to update ThinkTerm there and refresh, rather than an empty result. A listing that takes longer than 20 seconds is abandoned.

### Idle connections close by themselves

An SFTP connection that has gone unused is closed rather than held open. The timeout is `Settings › Workspaces › Remote Files Connection Idle Timeout`, which defaults to **15 minutes** and can be set anywhere from 1 to 120 minutes. Reopening a remote directory after a timeout reconnects without asking, as long as ThinkTerm has not been restarted since you connected; nothing is lost.

### Changing files, not only reading them

A file can be renamed, have its path copied, or be deleted, locally and remotely alike. A new folder can be made on a remote host only, where it starts as `untitled folder`; locally, use Finder or your file manager.

One asymmetry is worth carrying in your head: a local delete moves the file to the Trash, and a delete over SFTP is permanent, because there is no remote Trash to fall back on. ThinkTerm asks first in that case and counts what is about to go, a folder counting itself and everything under it.

## Dropping and pasting files

Where a file dropped from Finder or your file manager ends up depends on what it lands on:

| Dropped on | What happens |
|---|---|
| The note editor, while it has the focus | An image is copied into the Vault and linked from the note — see [Images in a note](#images-in-a-note) |
| The local file tree | Copied into the folder under the pointer; a file row means the folder that holds it, empty space means the Project's root |
| The remote file tree | Uploaded over SFTP to the folder under the pointer, by the same rule. The panel must be connected first |
| A terminal on the remote host the current Project lives on | Uploaded to the Remote Drop Destination, and the uploaded path pasted at the prompt |
| Any other terminal | The local paths pasted, quoted for the shell |

A copy into the local tree that would land on names already there stops and asks once for the whole drop: `Replace N existing files`, `Skip N existing files`, or `Cancel the copy`.

### Uploading by dropping on a terminal

Dropping onto the terminal of a remote session would be useless if it pasted a local path, since the server has no such file. So when the terminal belongs to the same host as the current remote Project — over ThinkTerm Connect or a plain SSH host — ThinkTerm uploads the files first and pastes the paths they now have on the server, POSIX-quoted, whatever `quote_dropped_files` says. A Mosh session's terminal runs on your computer, so a drop there pastes the local path as before.

The files go to `Settings › Workspaces › Remote Drop Destination`, which defaults to `~/ThinkTerm_Uploads` and is created on the server if it is missing. Setting it to `cwd` uploads into the shell's current directory instead, as the shell last reported it; a shell that has not reported one sends the files to `~/ThinkTerm_Uploads`. A dropped file never overwrites anything: when its name is taken it becomes `name (1).ext`, then `name (2).ext`, and the path pasted is the one it actually received. A dropped folder is uploaded whole.

### Pasting files and images

Paste reads the clipboard for files and pictures as well as text. In a terminal on the current remote Project's host, files copied in Finder or a file manager are uploaded exactly as if they had been dropped there, and a copied picture — a screenshot, say — is converted to PNG, uploaded as `Pasted 2026-10-02 at 14.03.05.png` with the date and time of the paste, and its path pasted. In a local shell, copied files paste as quoted local paths and a copied picture does nothing. Text pastes as it always has.

### Folders and the transfer strip

A folder is read in full before anything moves, so the size of the job is known up front, and a copy into the local tree finds every name clash before the first byte is written. A folder of more than 1,000 items asks first — `Upload N items` or `Download N items` — because every item on a server costs a round trip. Reading stops at 100,000 items for a folder on your computer and 10,000 for one on a server. Symbolic links inside a folder are not followed; they are skipped, and the transfer says how many.

Transfers and local copies show as rows in a strip in the Files panel, with their progress. Finished rows make way for new ones, a running transfer is never dropped, and rows that do not fit are counted rather than shown. Clicking a running row cancels it. Clicking a finished one offers `Retry` and `Dismiss`, or simply clears it when there is nothing to retry.

## Notes

The Notes panel is a Markdown editor bound to a **Vault** — a directory of ordinary Markdown files, in the layout Obsidian uses. Nothing is imported and nothing is converted: ThinkTerm records the binding and edits the files where they already are. The same Vault can be open in Obsidian at the same time.

The editor draws Markdown as it will read and shows the syntax again where the caret is, so it can be edited. It handles:

- headings, emphasis, ~~strikethrough~~, lists and quotes
- task lists, drawn as checkboxes
- tables
- syntax-highlighted code blocks
- horizontal rules
- a front-matter block at the top of a note, shown as a list of properties
- callouts such as `> [!warning]`, drawn as cards
- `#tags` and block IDs such as `^my-block`
- images, including images loaded from a remote URL
- `[[wiki links]]`, resolved against the whole Vault, and `![[embeds]]` drawn inline
- spell check, on macOS
- autosave, shortly after each edit

Text is set like a document: body text in the regular weight, bold in semibold, headings larger and bold, with spacing around headings, lists and blank lines, and inline code on a rounded background. A table's cells wrap, inside a rounded frame; a table scrolls sideways only when even its longest words do not fit. A rendered Markdown file in the Files preview is set the same way.

Following a link that matches nothing creates the note it names — except where that name could not be a file on this platform, where ThinkTerm refuses rather than inventing a different name behind your back.

A note it creates is readable by you alone. A note that already exists keeps the permissions it has, so a Vault you deliberately made group-readable stays that way.

Because a Vault is just a directory, it is yours to move, sync, or put under version control. If ThinkTerm cannot open one it says why rather than showing an empty panel. A folder it cannot find is reported as missing — moved, renamed, or deleted, which it cannot tell apart. One it can find but cannot read is reported as a permissions problem, with the check to make for your platform, and `Choose Another Vault…`, `Create New Vault…` and `Retry` to get out of it.

### Binding a Vault

A Space is bound to one Vault. Until it has one, the Notes panel offers two buttons: `Choose Existing Vault…` points the Space at a directory you already keep notes in, and `Create New Vault…` picks a place for a new one and makes the directory if it does not exist yet. Either way nothing outside the bound directory is touched. `Choose Another Vault…` in the note menu changes the binding later.

Inside a Space, each Project remembers the note it last had open, so switching Projects switches notes. The first time a Project opens Notes it shows a note from the Vault, or starts `Untitled.md` in a Vault that has none.

### The note menu

The menu button in the Notes toolbar holds:

| Item | What it does |
|---|---|
| `New Note` | Creates `Untitled.md` at the Vault's root, or `Untitled 2.md` and onwards when that name is taken, and opens it |
| `Save` | Saves now rather than waiting for autosave |
| `Source Mode` | Shows the plain Markdown instead of the drawn note; ticked while on |
| `Show Vault Sidebar` / `Hide Vault Sidebar` | Shows or hides the list of the Vault's files beside the note. When the panel is too narrow for both, the item reads `Show Vault` / `Hide Vault` and swaps the note for the list |
| `Choose Another Vault…` | Binds the Space to a different directory |
| `Reveal in Finder` | Shows the Vault in Finder — `Show in File Explorer` on Windows, `Show in Folder` on Linux |

Choosing a Markdown file in the Vault's list opens it as a note; any other file opens in its default application.

A second button in the toolbar moves the note into a wider pane to the left of the sidebar, leaving the Vault's list in the sidebar, and back again. ThinkTerm remembers which you chose, and the pane's width once you drag it. In a wide pane the text column stops at `note_reading_max_width`, 820 by default, and is centred.

### Keyboard

On macOS the shortcuts use Cmd; on Windows and Linux, Ctrl.

| Keys | Action |
|---|---|
| Cmd S | Save now |
| Cmd E | Switch between the drawn note and its source |
| Cmd B / Cmd I | Wrap the selection in `**bold**` / `*italic*` |
| Cmd Z / Shift Cmd Z | Undo / redo; Ctrl Y also redoes on Windows and Linux |
| Cmd A, Cmd C, Cmd X, Cmd V | Select all, copy, cut, paste |
| Home / End | Start / end of the line |
| Cmd ← / Cmd → on macOS | Start / end of the row as drawn: in a wrapped paragraph, the row rather than the whole line |
| Cmd ↑ / Cmd ↓ on macOS, Ctrl Home / Ctrl End elsewhere | Start / end of the note |
| ↑ / ↓ | Up and down a row, including rows that are off screen. Up on the first row goes to the start of the note, Down on the last to its end |
| Page Up / Page Down | Scroll a page; the caret stays where it is |
| Option ← / Option → on macOS, Ctrl ← / Ctrl → elsewhere | Move by word; with Backspace, delete the word before the caret; with Delete, the word after it |
| Cmd Backspace on macOS | Delete back to the start of the row |
| Ctrl A / Ctrl E / Ctrl K on macOS | Start of the line / end of the line / delete to the end of the line |
| Ctrl B, F, P, N and Ctrl D, H on macOS | As ← → ↑ ↓ and Delete, Backspace |
| Enter | New line, continuing a list, quote, numbered list or task list; on an empty item, ends the list |
| Tab / Shift Tab | In a table, the next / previous cell. On a list or quote line, or across several lines, indent / outdent. Elsewhere Tab inserts four spaces |
| Esc | Leave the editor |

Holding Shift with a movement key extends the selection.

Typing is undone a word at a time: one undo takes back the word just typed along with the space after it. A run of Backspace or Delete is undone as one step. A pause of more than two seconds, moving the caret, or an undo or redo starts a new step, and a paste is undone whole. A phrase committed by an input method is a step of its own.

Text an input method is still composing appears at the caret in the note's own font, and the rest of its row moves aside for it. A click in the editor does nothing until the text is committed or cancelled with Esc.

### Links and code blocks

Clicking a link opens it. A wiki link that matches more than one note opens a short list of the candidates to choose from rather than guessing. Each code block carries a button that copies the block and one that folds it away.

### Images in a note

A picture dropped onto the window while the note editor has the focus is copied into an `attachments` folder beside the note, and a link such as `![diagram](attachments/diagram.png)` is inserted where the caret is. A name already taken in that folder becomes `diagram-2.png` and so on. PNG, JPEG, GIF, WebP, BMP, ICO and TIFF files up to 25 MiB are taken; other files are left alone.

An image linked by an `http://` or `https://` address is fetched and drawn, up to 16 MiB, from public addresses only — never from your own machine or local network. `note_remote_images_enabled = false` stops notes from fetching anything.

### Spelling

Spell check uses the macOS system spelling checker, so on Windows and Linux there is none; `note_spellcheck_enabled = false` turns it off on macOS as well. Right-clicking a misspelt word offers up to five suggestions, `Ignore Spelling`, which lets the word pass in this note, and `Learn Spelling`, which adds it to the system dictionary. With text selected, `Look Up` opens the macOS dictionary for it.

### Mermaid diagrams

A fenced code block marked `mermaid` is drawn as its diagram, both in a note and in a Markdown file preview. In a note the block shows its code again while the caret is inside it, or while its closing fence is still missing, so it can be edited. Diagrams follow the light or dark look of the note, and a picture a diagram names is never loaded.

A block that cannot be parsed, or is too large to draw — over 16 KB of source or more than 150 links — stays as code, and its header says which of the two it is.

## Snippets

The third panel is a library of saved commands and text — each one a title and a body, searchable from the panel. A snippet can be pasted into the pane you are in, or run.

`New Snippet` opens the editor. `Action description` is the title, and may be left empty, in which case the first non-empty line of the script stands in for it, shortened to 48 characters; a title you type is kept to 80. `Script` is the body and is required. Clicking a snippet in the list opens it for editing, and the trash button deletes it at once, without asking.

The newest snippet is at the top. Search looks through titles and bodies, ignoring case.

Running one sends the body and presses Enter at the end of every line, so a multi-line snippet is executed line by line rather than arriving as one block. Blank lines at either end are trimmed.

Run and Paste go to the pane that was focused when you pressed the button, not whichever is focused when the text arrives. If that pane has gone by then, nothing is sent.

Snippets are kept in `snippets.json` in ThinkTerm's data directory, on the computer the desktop runs on; on macOS and Linux the file is readable by you alone. They are not a secret store, and nothing in them is encrypted. The panel holds no copy of its own: the snippets belong to ThinkTerm's plugin server, where Snippets is a built-in plugin, and every window — and a browser's Snippets tab — shows what that server has. A browser connected to a host sees the snippets kept on that host. [Plugins](https://docs.closex.org/thinkterm/plugins.md) describes the plugin server.

## The panels are optional

`Settings › Sidebar & Plugins` chooses which panels the right sidebar offers. Turn all of them off and the sidebar itself goes away. Snippets' switch there is also the switch of the Snippets plugin.

The changes in a git repository are shown by the Diff plugin rather than by the Files panel; see [Plugins](https://docs.closex.org/thinkterm/plugins.md).

## Related

- [Remote](https://docs.closex.org/thinkterm/remote.md) — connecting to the host whose files you are browsing
- [Configuration](https://docs.closex.org/thinkterm/configuration.md) — where the Vault binding is recorded
- [Plugins](https://docs.closex.org/thinkterm/plugins.md) — the plugin server Snippets runs in, and panels such as Diff
- [Agent Status](https://docs.closex.org/thinkterm/agents.md) — the fourth built-in panel
