Преглед изворни кода

tweak(tui): remove italics from thinking labels (#28737)

Aiden Cline пре 3 месеци
родитељ
комит
3e931152d1

+ 4 - 1
packages/opencode/src/cli/cmd/tui/context/theme.tsx

@@ -49,6 +49,7 @@ type Theme = TuiThemeCurrent & {
   _hasSelectedListItemText: boolean
 }
 type ThemeColor = Exclude<keyof TuiThemeCurrent, "thinkingOpacity">
+type SyntaxStyleOverrides = Record<string, { italic?: boolean }>
 
 export function selectedForeground(theme: Theme, bg?: RGBA): RGBA {
   // If theme explicitly defines selectedListItemText, use it
@@ -718,16 +719,18 @@ export function generateSyntax(theme: Theme) {
   return SyntaxStyle.fromTheme(getSyntaxRules(theme))
 }
 
-export function generateSubtleSyntax(theme: Theme) {
+export function generateSubtleSyntax(theme: Theme, overrides?: SyntaxStyleOverrides) {
   const rules = getSyntaxRules(theme)
   return SyntaxStyle.fromTheme(
     rules.map((rule) => {
+      const override = rule.scope.reduce((acc, scope) => ({ ...acc, ...overrides?.[scope] }), {})
       if (rule.style.foreground) {
         const fg = rule.style.foreground
         return {
           ...rule,
           style: {
             ...rule.style,
+            ...override,
             foreground: RGBA.fromInts(
               Math.round(fg.r * 255),
               Math.round(fg.g * 255),

+ 8 - 4
packages/opencode/src/cli/cmd/tui/routes/session/index.tsx

@@ -21,7 +21,7 @@ import { useSync } from "@tui/context/sync"
 import { useEvent } from "@tui/context/event"
 import { SplitBorder } from "@tui/component/border"
 import { Spinner } from "@tui/component/spinner"
-import { selectedForeground, useTheme } from "@tui/context/theme"
+import { generateSubtleSyntax, selectedForeground, useTheme } from "@tui/context/theme"
 import { BoxRenderable, ScrollBoxRenderable, addDefaultParsers, TextAttributes, RGBA } from "@opentui/core"
 import { Prompt, type PromptRef } from "@tui/component/prompt"
 import type {
@@ -1497,7 +1497,7 @@ const PART_MAPPING = {
 }
 
 function ReasoningPart(props: { last: boolean; part: ReasoningPart; message: AssistantMessage }) {
-  const { theme, subtleSyntax } = useTheme()
+  const { theme } = useTheme()
   const ctx = use()
   // Collapsed by default in hide mode: a single line throughout, so the
   // layout never shifts. Click to open the full markdown block, click to close.
@@ -1519,6 +1519,8 @@ function ReasoningPart(props: { last: boolean; part: ReasoningPart; message: Ass
   // blocks. Surface the title both while streaming and after settling so the
   // collapsed line carries real signal, not just a duration.
   const title = createMemo(() => reasoningTitle(content()))
+  // Keep markdown emphasis for the existing thinking color/concealment, but render it without italics.
+  const syntax = createMemo(() => generateSubtleSyntax(theme, { "markup.italic": { italic: false } }))
 
   const toggle = () => {
     if (!inMinimal()) return
@@ -1535,7 +1537,9 @@ function ReasoningPart(props: { last: boolean; part: ReasoningPart; message: Ass
               filetype="markdown"
               drawUnstyledText={false}
               streaming={true}
-              syntaxStyle={subtleSyntax()}
+              syntaxStyle={syntax()}
+              // `_Thinking:_`/`_Thought:_` still drives markdown emphasis color and conceals the underscores;
+              // the syntax override above removes only the italic attribute from that emphasis token.
               content={(inMinimal() ? "- " : "") + (isDone() ? "_Thought:_ " : "_Thinking:_ ") + content()}
               conceal={ctx.conceal()}
               fg={theme.textMuted}
@@ -1563,7 +1567,7 @@ function CollapsedReasoningText(props: { title: string | null; duration: number
 
   return (
     <text fg={theme.warning} wrapMode="none">
-      <span style={{ fg: theme.warning, italic: true }}>
+      <span style={{ fg: theme.warning }}>
         {props.title ? "+ Thought: " + props.title + " · " + duration() : "+ Thought: " + duration()}
       </span>
     </text>