diff --git a/apps/web/src/components/chat/ChatComposer.tsx b/apps/web/src/components/chat/ChatComposer.tsx
index 56c73bcec16a6..d7878cc29a165 100644
--- a/apps/web/src/components/chat/ChatComposer.tsx
+++ b/apps/web/src/components/chat/ChatComposer.tsx
@@ -133,7 +133,6 @@ import {
import { attachmentUploadBlockReason } from "../../lib/attachmentUploadState";
import type { AssistantCitationSourceAnchor } from "~/lib/assistantTextSelection";
import { shortcutLabelForCommand } from "../../keybindings";
-import { persistClientSettingsUpdate } from "../../hooks/useSettings";
import {
type TerminalContextDraft,
type TerminalContextSelection,
@@ -199,7 +198,6 @@ import {
ComposerRestingImagePreviews,
} from "./ComposerAttachmentStrip";
import { ComposerPrimaryActions } from "./ComposerPrimaryActions";
-import { ComposerRichTextToggle } from "./ComposerRichTextToggle";
import { ComposerFooterPrimaryActions } from "./ComposerFooterControls";
import { ComposerPendingUserInputPanel } from "./ComposerPendingUserInputPanel";
import { ComposerPlanFollowUpBanner } from "./ComposerPlanFollowUpBanner";
@@ -306,7 +304,6 @@ export interface ChatComposerHandle {
openModelPicker: () => void;
stepReasoningEffort: (direction: 1 | -1) => void;
toggleModelPicker: () => void;
- toggleRichText: () => void;
openControl: (command: KeybindingCommand) => void;
isModelPickerOpen: () => boolean;
isCaretAtStart: () => boolean;
@@ -2855,13 +2852,6 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps)
openModelPickerStable();
}
},
- toggleRichText: () => {
- if (isLiteralPendingAnswer) return;
- persistClientSettingsUpdate((current) => ({
- ...current,
- composerRichTextEnabled: !current.composerRichTextEnabled,
- })).catch(console.error);
- },
openControl: (command) => {
if (composerBlurFrameRef.current !== null) {
window.cancelAnimationFrame(composerBlurFrameRef.current);
@@ -3439,23 +3429,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps)
showMobilePendingAnswerActions && "hidden sm:flex",
)}
>
- {composerAttachButton || !isLiteralPendingAnswer ? (
-
- {composerAttachButton}
- {isLiteralPendingAnswer ? null : (
-
- )}
-
- ) : null}
+ {composerAttachButton ?
-
event.preventDefault()}
- onClick={() => void updateClientSettings({ composerRichTextEnabled: showingSource })}
- />
- }
- >
-
-
-
- {showingSource ? "Show formatting" : "Show Markdown source"}
- {shortcutLabel ? ` · ${shortcutLabel}` : null}
-
-
- );
-}
diff --git a/apps/web/src/components/chat/composerShortcuts.ts b/apps/web/src/components/chat/composerShortcuts.ts
index e55398996cea9..30beb9771968f 100644
--- a/apps/web/src/components/chat/composerShortcuts.ts
+++ b/apps/web/src/components/chat/composerShortcuts.ts
@@ -18,12 +18,6 @@ export function composerShortcutCommands(
"modelPicker.toggle": ({ event }) => {
if (!event.repeat) composerRef.current?.toggleModelPicker();
},
- "composer.toggleRichText": ({ event }) => {
- // The flip remounts the editor, which would drop an unsaved citation comment.
- if (event.target instanceof Element && event.target.closest("[data-citation-comment-editor]"))
- return false;
- if (!event.repeat) composerRef.current?.toggleRichText();
- },
"composer.increaseEffort": ({ event }) => {
if (!event.repeat) composerRef.current?.stepReasoningEffort(1);
},
diff --git a/apps/web/src/keybindings.test.ts b/apps/web/src/keybindings.test.ts
index 96ae09296dea5..a0ba7fa7ee043 100644
--- a/apps/web/src/keybindings.test.ts
+++ b/apps/web/src/keybindings.test.ts
@@ -768,21 +768,12 @@ describe("composer and pull request shortcuts", () => {
});
it.each(["MacIntel", "Win32", "Linux"])(
- "resolves composer toggle and alternate send chords in their contexts on %s",
+ "reserves the alternate send chord for the focused composer on %s",
(platform) => {
const modifier = {
metaKey: platform === "MacIntel",
ctrlKey: platform !== "MacIntel",
};
- for (const terminalFocus of [false, true]) {
- assert.strictEqual(
- resolveShortcutCommand(event({ key: "/", ...modifier }), DEFAULT_RESOLVED_KEYBINDINGS, {
- platform,
- context: { terminalFocus },
- }),
- terminalFocus ? null : "composer.toggleRichText",
- );
- }
const shiftedEnter = event({ key: "Enter", shiftKey: true, ...modifier });
for (const composerRequiresModifier of [false, true]) {
const context = {
diff --git a/docs/user/composer.md b/docs/user/composer.md
index 6156a126ca246..714572dfd5005 100644
--- a/docs/user/composer.md
+++ b/docs/user/composer.md
@@ -19,9 +19,7 @@ The composer writes Markdown and shows it styled as you type. Markers such as
them. Lines starting with `- `, `1. `, `- [ ] `, `> `, `# ` or `---` become lists,
task lists, quotes, headings and rules; ` ``` ` followed by Enter opens a code
block. What you typed is what the agent receives, markers and numbering
-included, and `#1234` without a space still looks up a pull request. To see the
-plain Markdown instead, press the **¶** button beside attach; it is the same
-switch as **Settings → Chat → Rich text composer**.
+included, and `#1234` without a space still looks up a pull request.
Enter sends. In a list or quote, **Shift+Enter** continues it, and Shift+Enter
on an empty line moves out one level, then leaves it; **Tab** nests a list item
diff --git a/docs/user/keybindings.md b/docs/user/keybindings.md
index 0e8e17744019e..83989762c5b07 100644
--- a/docs/user/keybindings.md
+++ b/docs/user/keybindings.md
@@ -28,7 +28,6 @@ Use `mod+shift+e` for effort, `mod+shift+a` for permissions, `mod+shift+x` for t
workspace, and `mod+shift+g` for the Git branch. The workspace menu includes the
current checkout, a new worktree, and the previous worktree when available.
Use `mod+shift+l` to reuse the previous worktree directly.
-Use `mod+/` to switch the composer between rich text and its Markdown source.
To change effort one step without opening the picker, bind
**Composer: Increase Effort** and **Composer: Decrease Effort** in Keybindings.
diff --git a/packages/contracts/src/keybindings.ts b/packages/contracts/src/keybindings.ts
index cc55adb9ca81b..714e0a1d486a1 100644
--- a/packages/contracts/src/keybindings.ts
+++ b/packages/contracts/src/keybindings.ts
@@ -87,7 +87,6 @@ export const STATIC_KEYBINDING_COMMANDS = [
"appearance.cycle",
"themeEditor.toggle",
"composer.stash",
- "composer.toggleRichText",
"composer.sendAlternate",
"composer.sendBackground",
"composer.sendAndNewThread",
diff --git a/packages/shared/src/keybindings.ts b/packages/shared/src/keybindings.ts
index 8ae3f052afede..32292c0f9ef21 100644
--- a/packages/shared/src/keybindings.ts
+++ b/packages/shared/src/keybindings.ts
@@ -179,7 +179,6 @@ export const DEFAULT_KEYBINDINGS: ReadonlyArray
= [
{ key: "mod+alt+shift+a", command: "appearance.cycle", when: "!terminalFocus" },
{ key: "mod+alt+shift+t", command: "themeEditor.toggle" },
{ key: "mod+s", command: "composer.stash", when: "!terminalFocus" },
- { key: "mod+/", command: "composer.toggleRichText", when: "!terminalFocus" },
{ key: "mod+shift+enter", command: "thread.steerQueuedMessage", when: "!terminalFocus" },
{ key: "alt+arrowup", command: "thread.editQueuedMessage", when: "composerFocus" },
{ key: "mod+enter", command: "composer.sendAlternate", when: "composerFocus && turnRunning" },