Files
Nick Vigilante bc77c40296 docs: add front-matter titles to mechanical and no-H1 pages (Phase 3) (#28030)
## Summary

**Batch A of Phase 3** of the H1 → front-matter migration (`DOCS-484`;
parent `DOCS-477`). Adds a front-matter `title` to every navigable docs
page whose title can be migrated **mechanically**, with no editorial
judgment.

This is the content step that Phase 1 (renderers prefer front-matter
title, `DOCS-482`) and Phase 2 (tooling + generators front-matter-aware,
`DOCS-483`) unblocked. Both are merged; coder.com #964/#974 are merged
and live.

**Rendered no-op.** The renderers already resolve the page title from
the manifest and hide the leading body H1 (Phase 1), so no page changes
visually. This just moves the title into front matter where Fumadocs and
the migrated tooling can read it.

## What's in this batch

Dry-run on `main` (464 navigable pages) splits into:

| category | count | this PR |
|----------|-------|---------|
| already has front-matter title (Reference, from Phase 2 generators) |
196 | skipped (idempotent) |
| **mechanical** — leading body H1 equals the manifest label | 138 | 
add front-matter `title`, drop the duplicate H1 |
| **no body H1** — renders under the manifest label only | 4 |  add
front-matter `title` only |
| **mismatch** — body H1 differs from the manifest label | 126 | ⏭️
deferred (needs an editorial decision, see below) |

142 files changed, all under `docs/`.

## Deliberately out of scope: the 126 mismatches

Pages where the body H1 is richer than the short sidebar label (e.g.
label **Modules** / H1 *Contributing modules*, label **Install** / H1
*Installing Coder*) need a canonical-title decision, not a script. A few
even look like the body H1 is the redundant one (`install/cli.md` and
`install/index.md` both carry the H1 *Installing Coder*). These will
land in follow-up batches **by nav section** once the policy is set, so
each gets real review.

## Verification

AI was the primary author of this PR (see disclosure below); per the [AI
Contribution
Guidelines](https://coder.com/docs/about/contributing/AI_CONTRIBUTING)
here is the manual verification.

- Every added front-matter block parses as YAML and its `title`
round-trips to the manifest label (checked programmatically across all
142 files).
- Every removed line is a leading `# H1` that equalled the manifest
title; no body prose was reflowed. Front matter is correctly hoisted
above pre-existing `<!-- markdownlint-disable -->` comments on the two
pages that had them.
- `pnpm check-docs` (markdownlint-cli2 + table formatter) passes on the
changed set: `Summary: 0 error(s)`. `MD041` stays off (re-enabled in
Phase 4); `MD025` is not tripped because the duplicate body H1s are
removed.

```
$ pnpm exec markdownlint-cli2 $(git diff --name-only origin/main)
Linting: 142 file(s)
Summary: 0 error(s)
```

Linear: DOCS-484

> This PR was created with AI assistance (Coder Agents).
2026-08-27 12:34:13 -04:00

5.8 KiB

title
title
Emacs TRAMP

Emacs TRAMP is a method of running editing operations on a remote server.

Connecting To A Workspace

To connect to your workspace first run:

coder config-ssh

Then you can connect to your workspace by its name in the format: coder.<WORKSPACE NAME>.

In Emacs type C-x d and then input: /-:coder.<WORKSPACE NAME>: and hit enter. This will open up Dired on the workspace's home directory.

Using SSH

By default Emacs TRAMP is setup to use SCP to access files on the Coder workspace instance. However you might want to use SSH if you have a jumpbox or some other complex network setup.

To do so set the following in your Emacs init.el file:

(setq tramp-default-method "ssh")

Then when you access the workspace instance via /-:coder.<WORKSPACE NAME> Emacs will use SSH. Setting tramp-default-method will also tell ansi-term mode the correct way to access the remote when directory tracking.

Directory Tracking

ansi-term

If you run your terminal in Emacs via ansi-term then you might run into a problem where while SSH-ed into a workspace Emacs will not change its default-directory to open files in the directory your shell is in.

To fix this:

  1. In your workspace Terraform template be sure to add the following:

    data "coder_workspace" "me" {
    }
    
    resource "coder_agent" "main" {
      # ...
      env = {
        name = "CODER_WORKSPACE_NAME"
        value = data.coder_workspace.me.name
      }
    }
    
  2. Next in the shell profile file on the workspace (ex., ~/.bashrc for Bash and ~/.zshrc for Zsh) add the following:

    ansi_term_announce_host() {
        printf '\033AnSiTh %s\n' "coder.$CODER_WORKSPACE_NAME"
    }
    
    ansi_term_announce_user() {
        printf '\033AnSiTu %s\n' "$USER"
    }
    
    ansi_term_announce_pwd() {
        printf '\033AnSiTc %s\n' "$PWD"
    }
    
    ansi_term_announce() {
        ansi_term_announce_host
        ansi_term_announce_user
        ansi_term_announce_pwd
    }
    
    cd()    { command cd    "$@"; ansi_term_announce_pwd; }
    pushd() { command pushd "$@"; ansi_term_announce_pwd; }
    popd()  { command popd  "$@"; ansi_term_announce_pwd; }
    
    ansi_term_announce
    

    Ansi Term expects the terminal running inside of it to send escape codes to inform Emacs of the hostname, user, and working directory. The above code sends these escape codes and associated data whenever the terminal logs in and whenever the directory changes.

eshell

The eshell mode will perform directory tracking by default, no additional configuration is needed.

Language Servers (Code Completion)

If you use lsp-mode for code intelligence and completion some additional configuration is required.

In your Emacs init.el file you must register a LSP client and tell lsp-mode how to find it on the remote machine using the lsp-register-client function. For each LSP server you want to use in your workspace add the following:

(lsp-register-client (make-lsp-client :new-connection (lsp-tramp-connection "<LSP SERVER BINARY>")
              :major-modes '(<LANGUAGE MODE>)
              :remote? t
              :server-id '<LANGUAGE SERVER ID>))

This tells lsp-mode to look for a language server binary named <LSP SERVER BINARY> for use in <LANGUAGE MODE> on a machine named coder.<WORKSPACE NAME>. Be sure to replace the values between angle brackets:

  • <LSP SERVER BINARY> : The name of the language server binary, without any path components. For example to use the Deno Javascript language server use the value deno.
  • <LANGUAGE MODE>: The name of the Emacs major mode for which the language server should be used. For example to enable the language server for Javascript development use the value web-mode.
  • <LANGUAGE SERVER ID>: This is just the name that lsp-mode will use to refer to this language server. If you are ever looking for output buffers or files they may have this name in them.

Calling the lsp-register-client function will tell lsp-mode the name of the LSP server binary. However this binary must be accessible via the path. If the language server binary is not in the path you must modify tramp-remote-path so that lsp-mode knows in what directories to look for the LSP server. To do this use TRAMP's connection profiles functionality. These connection profiles let you customize variables depending on what machine you are connected to. Add the following to your init.el:

(connection-local-set-profile-variables 'remote-path-lsp-servers
                                 '((tramp-remote-path . ("<PATH TO ADD>" tramp-default-remote-path))))
(connection-local-set-profiles '(:machine "coder.<WORKSPACE NAME>") 'remote-path-lsp-servers)

The connection-local-set-profile-variables function creates a new connection profile by the name remote-path-lsp-servers. The connection-local-set-profiles then indicates this remote-path-lsp-servers connection profile should be used when connecting to a server named coder.<WORKSPACE NAME>. Be sure to replace <PATH TO ADD> with the directory in which a LSP server is present.

TRAMP and lsp-mode are fickle friends, sometimes there is weird behavior. If you find that language servers are hanging in the starting state then it might be helpful to set the lsp-log-io variable to t.

More details on configuring lsp-mode for TRAMP can be found in the lsp-mode documentation. The TRAMP tramp-remote-path documentation contains more examples and details of connection profiles.