mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-05-05 23:42:03 +00:00
Merge branch 'main' into feat/multimodal-input-support
This commit is contained in:
commit
2ec3ec2c38
159 changed files with 4391 additions and 3303 deletions
|
|
@ -12,7 +12,7 @@ import { renderWithProviders } from '../../test-utils/render.js';
|
|||
describe('<MarkdownDisplay />', () => {
|
||||
const baseProps = {
|
||||
isPending: false,
|
||||
terminalWidth: 80,
|
||||
contentWidth: 80,
|
||||
availableTerminalHeight: 40,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ interface MarkdownDisplayProps {
|
|||
text: string;
|
||||
isPending: boolean;
|
||||
availableTerminalHeight?: number;
|
||||
terminalWidth: number;
|
||||
contentWidth: number;
|
||||
textColor?: string;
|
||||
}
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
|
|||
text,
|
||||
isPending,
|
||||
availableTerminalHeight,
|
||||
terminalWidth,
|
||||
contentWidth,
|
||||
textColor = theme.text.primary,
|
||||
}) => {
|
||||
if (!text) return <></>;
|
||||
|
|
@ -79,7 +79,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
|
|||
lang={codeBlockLang}
|
||||
isPending={isPending}
|
||||
availableTerminalHeight={availableTerminalHeight}
|
||||
terminalWidth={terminalWidth}
|
||||
contentWidth={contentWidth}
|
||||
/>,
|
||||
);
|
||||
inCodeBlock = false;
|
||||
|
|
@ -144,7 +144,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
|
|||
key={`table-${contentBlocks.length}`}
|
||||
headers={tableHeaders}
|
||||
rows={tableRows}
|
||||
terminalWidth={terminalWidth}
|
||||
contentWidth={contentWidth}
|
||||
/>,
|
||||
);
|
||||
}
|
||||
|
|
@ -266,7 +266,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
|
|||
lang={codeBlockLang}
|
||||
isPending={isPending}
|
||||
availableTerminalHeight={availableTerminalHeight}
|
||||
terminalWidth={terminalWidth}
|
||||
contentWidth={contentWidth}
|
||||
/>,
|
||||
);
|
||||
}
|
||||
|
|
@ -278,7 +278,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
|
|||
key={`table-${contentBlocks.length}`}
|
||||
headers={tableHeaders}
|
||||
rows={tableRows}
|
||||
terminalWidth={terminalWidth}
|
||||
contentWidth={contentWidth}
|
||||
/>,
|
||||
);
|
||||
}
|
||||
|
|
@ -293,7 +293,7 @@ interface RenderCodeBlockProps {
|
|||
lang: string | null;
|
||||
isPending: boolean;
|
||||
availableTerminalHeight?: number;
|
||||
terminalWidth: number;
|
||||
contentWidth: number;
|
||||
}
|
||||
|
||||
const RenderCodeBlockInternal: React.FC<RenderCodeBlockProps> = ({
|
||||
|
|
@ -301,7 +301,7 @@ const RenderCodeBlockInternal: React.FC<RenderCodeBlockProps> = ({
|
|||
lang,
|
||||
isPending,
|
||||
availableTerminalHeight,
|
||||
terminalWidth,
|
||||
contentWidth,
|
||||
}) => {
|
||||
const settings = useSettings();
|
||||
const MIN_LINES_FOR_MESSAGE = 1; // Minimum lines to show before the "generating more" message
|
||||
|
|
@ -329,7 +329,7 @@ const RenderCodeBlockInternal: React.FC<RenderCodeBlockProps> = ({
|
|||
truncatedContent.join('\n'),
|
||||
lang,
|
||||
availableTerminalHeight,
|
||||
terminalWidth - CODE_BLOCK_PREFIX_PADDING,
|
||||
contentWidth - CODE_BLOCK_PREFIX_PADDING,
|
||||
undefined,
|
||||
settings,
|
||||
);
|
||||
|
|
@ -347,7 +347,7 @@ const RenderCodeBlockInternal: React.FC<RenderCodeBlockProps> = ({
|
|||
fullContent,
|
||||
lang,
|
||||
availableTerminalHeight,
|
||||
terminalWidth - CODE_BLOCK_PREFIX_PADDING,
|
||||
contentWidth - CODE_BLOCK_PREFIX_PADDING,
|
||||
undefined,
|
||||
settings,
|
||||
);
|
||||
|
|
@ -356,7 +356,7 @@ const RenderCodeBlockInternal: React.FC<RenderCodeBlockProps> = ({
|
|||
<Box
|
||||
paddingLeft={CODE_BLOCK_PREFIX_PADDING}
|
||||
flexDirection="column"
|
||||
width={terminalWidth}
|
||||
width={contentWidth}
|
||||
flexShrink={0}
|
||||
>
|
||||
{colorizedCode}
|
||||
|
|
@ -407,15 +407,15 @@ const RenderListItem = React.memo(RenderListItemInternal);
|
|||
interface RenderTableProps {
|
||||
headers: string[];
|
||||
rows: string[][];
|
||||
terminalWidth: number;
|
||||
contentWidth: number;
|
||||
}
|
||||
|
||||
const RenderTableInternal: React.FC<RenderTableProps> = ({
|
||||
headers,
|
||||
rows,
|
||||
terminalWidth,
|
||||
contentWidth,
|
||||
}) => (
|
||||
<TableRenderer headers={headers} rows={rows} terminalWidth={terminalWidth} />
|
||||
<TableRenderer headers={headers} rows={rows} contentWidth={contentWidth} />
|
||||
);
|
||||
|
||||
const RenderTable = React.memo(RenderTableInternal);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { RenderInline, getPlainTextLength } from './InlineMarkdownRenderer.js';
|
|||
interface TableRendererProps {
|
||||
headers: string[];
|
||||
rows: string[][];
|
||||
terminalWidth: number;
|
||||
contentWidth: number;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -22,7 +22,7 @@ interface TableRendererProps {
|
|||
export const TableRenderer: React.FC<TableRendererProps> = ({
|
||||
headers,
|
||||
rows,
|
||||
terminalWidth,
|
||||
contentWidth,
|
||||
}) => {
|
||||
// Calculate column widths using actual display width after markdown processing
|
||||
const columnWidths = headers.map((header, index) => {
|
||||
|
|
@ -35,8 +35,7 @@ export const TableRenderer: React.FC<TableRendererProps> = ({
|
|||
|
||||
// Ensure table fits within terminal width
|
||||
const totalWidth = columnWidths.reduce((sum, width) => sum + width + 1, 1);
|
||||
const scaleFactor =
|
||||
totalWidth > terminalWidth ? terminalWidth / totalWidth : 1;
|
||||
const scaleFactor = totalWidth > contentWidth ? contentWidth / totalWidth : 1;
|
||||
const adjustedWidths = columnWidths.map((width) =>
|
||||
Math.floor(width * scaleFactor),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ import * as fs from 'node:fs/promises';
|
|||
import * as path from 'node:path';
|
||||
import { execCommand } from '@qwen-code/qwen-code-core';
|
||||
|
||||
const MACOS_CLIPBOARD_TIMEOUT_MS = 1500;
|
||||
|
||||
/**
|
||||
* Checks if the system clipboard contains an image (macOS only for now)
|
||||
* @returns true if clipboard contains an image
|
||||
|
|
@ -19,7 +21,13 @@ export async function clipboardHasImage(): Promise<boolean> {
|
|||
|
||||
try {
|
||||
// Use osascript to check clipboard type
|
||||
const { stdout } = await execCommand('osascript', ['-e', 'clipboard info']);
|
||||
const { stdout } = await execCommand(
|
||||
'osascript',
|
||||
['-e', 'clipboard info'],
|
||||
{
|
||||
timeout: MACOS_CLIPBOARD_TIMEOUT_MS,
|
||||
},
|
||||
);
|
||||
const imageRegex =
|
||||
/«class PNGf»|TIFF picture|JPEG picture|GIF picture|«class JPEG»|«class TIFF»/;
|
||||
return imageRegex.test(stdout);
|
||||
|
|
@ -80,7 +88,9 @@ export async function saveClipboardImage(
|
|||
end try
|
||||
`;
|
||||
|
||||
const { stdout } = await execCommand('osascript', ['-e', script]);
|
||||
const { stdout } = await execCommand('osascript', ['-e', script], {
|
||||
timeout: MACOS_CLIPBOARD_TIMEOUT_MS,
|
||||
});
|
||||
|
||||
if (stdout.trim() === 'success') {
|
||||
// Verify the file was created and has content
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue