From 8cc6b088317232442d068f9dbcb2ec040613bf30 Mon Sep 17 00:00:00 2001 From: MyPrototypeWhat Date: Tue, 16 Sep 2025 13:31:38 +0800 Subject: [PATCH] chore(ui): update package.json and migration status files - Reformatted keywords and files array in package.json for better readability. - Updated migration status to reflect the migration of additional components, increasing the total migrated count to 46 and reducing pending migrations to 190. - Added new components to the migration status table, including ErrorBoundary and ProviderAvatar, while removing deprecated components like ErrorTag, SuccessTag, and WarnTag. --- packages/ui/MIGRATION_STATUS.md | 29 +- packages/ui/MIGRATION_STATUS_EN.md | 8 +- packages/ui/package.json | 3 +- packages/ui/scripts/update-languages.ts | 135 - .../components/base/ErrorBoundary/index.tsx | 101 + .../components/base/ErrorBoundary/utils.ts | 8 + .../ui/src/components/base/ErrorTag/index.tsx | 17 - .../src/components/base/StatusTag/index.tsx | 51 + .../src/components/base/SuccessTag/index.tsx | 17 - .../ui/src/components/base/WarnTag/index.tsx | 19 - .../display/ProviderAvatar/index.tsx | 86 + .../display/ProviderAvatar/utils.ts | 37 + .../src/components/icons/CopyIcon/index.tsx | 6 - .../src/components/icons/DeleteIcon/index.tsx | 6 - .../src/components/icons/EditIcon/index.tsx | 6 - .../ui/src/components/icons/Icon/index.tsx | 41 + .../ui/src/components/icons/OcrIcon/index.tsx | 8 - .../components/icons/RefreshIcon/index.tsx | 6 - .../src/components/icons/ResetIcon/index.tsx | 6 - .../src/components/icons/ToolIcon/index.tsx | 8 - .../src/components/icons/UnWrapIcon/index.tsx | 18 - .../src/components/icons/VisionIcon/index.tsx | 31 - .../components/icons/WebSearchIcon/index.tsx | 32 - .../src/components/icons/WrapIcon/index.tsx | 21 - packages/ui/src/components/index.ts | 34 +- .../interactive/CodeEditor/CodeEditor.tsx | 3 +- .../interactive/CodeEditor/hooks.ts | 17 +- .../interactive/CodeEditor/types.ts | 16 + .../interactive/CodeEditor/utils.ts | 154 +- packages/ui/src/config/languages.ts | 3695 ----------------- packages/ui/src/utils/codeLanguage.ts | 39 - .../components/base/ErrorTag.stories.tsx | 48 - .../components/base/StatusTag.stories.tsx | 176 + .../components/base/SuccessTag.stories.tsx | 110 - .../components/base/WarnTag.stories.tsx | 48 - .../stories/components/icons/Icon.stories.tsx | 290 ++ .../interactive/CodeEditor.stories.tsx | 92 +- packages/ui/tsconfig.json | 31 +- packages/ui/tsdown.config.ts | 3 + 39 files changed, 1108 insertions(+), 4348 deletions(-) delete mode 100644 packages/ui/scripts/update-languages.ts create mode 100644 packages/ui/src/components/base/ErrorBoundary/index.tsx create mode 100644 packages/ui/src/components/base/ErrorBoundary/utils.ts delete mode 100644 packages/ui/src/components/base/ErrorTag/index.tsx create mode 100644 packages/ui/src/components/base/StatusTag/index.tsx delete mode 100644 packages/ui/src/components/base/SuccessTag/index.tsx delete mode 100644 packages/ui/src/components/base/WarnTag/index.tsx create mode 100644 packages/ui/src/components/display/ProviderAvatar/index.tsx create mode 100644 packages/ui/src/components/display/ProviderAvatar/utils.ts delete mode 100644 packages/ui/src/components/icons/CopyIcon/index.tsx delete mode 100644 packages/ui/src/components/icons/DeleteIcon/index.tsx delete mode 100644 packages/ui/src/components/icons/EditIcon/index.tsx create mode 100644 packages/ui/src/components/icons/Icon/index.tsx delete mode 100644 packages/ui/src/components/icons/OcrIcon/index.tsx delete mode 100644 packages/ui/src/components/icons/RefreshIcon/index.tsx delete mode 100644 packages/ui/src/components/icons/ResetIcon/index.tsx delete mode 100644 packages/ui/src/components/icons/ToolIcon/index.tsx delete mode 100644 packages/ui/src/components/icons/UnWrapIcon/index.tsx delete mode 100644 packages/ui/src/components/icons/VisionIcon/index.tsx delete mode 100644 packages/ui/src/components/icons/WebSearchIcon/index.tsx delete mode 100644 packages/ui/src/components/icons/WrapIcon/index.tsx delete mode 100644 packages/ui/src/config/languages.ts delete mode 100644 packages/ui/src/utils/codeLanguage.ts delete mode 100644 packages/ui/stories/components/base/ErrorTag.stories.tsx create mode 100644 packages/ui/stories/components/base/StatusTag.stories.tsx delete mode 100644 packages/ui/stories/components/base/SuccessTag.stories.tsx delete mode 100644 packages/ui/stories/components/base/WarnTag.stories.tsx create mode 100644 packages/ui/stories/components/icons/Icon.stories.tsx diff --git a/packages/ui/MIGRATION_STATUS.md b/packages/ui/MIGRATION_STATUS.md index dac52ab9a3..e823e8e07b 100644 --- a/packages/ui/MIGRATION_STATUS.md +++ b/packages/ui/MIGRATION_STATUS.md @@ -49,9 +49,9 @@ function MyComponent() { ## 迁移概览 - **总组件数**: 236 -- **已迁移**: 43 -- **已重构**: 0 -- **待迁移**: 193 +- **已迁移**: 46 +- **已重构**: 2 +- **待迁移**: 190 ## 组件状态表 @@ -62,12 +62,11 @@ function MyComponent() { | | CustomTag | ✅ | ❌ | 自定义标签 | | | DividerWithText | ✅ | ❌ | 带文本的分隔线 | | | EmojiIcon | ✅ | ❌ | 表情图标 | -| | ErrorTag | ✅ | ❌ | 错误标签 | +| | ErrorBoundary | ✅ | ❌ | 错误边界 (通过 props 解耦) | +| | StatusTag | ✅ | ✅ | 统一状态标签(合并了 ErrorTag、SuccessTag、WarnTag、InfoTag)| | | IndicatorLight | ✅ | ❌ | 指示灯 | | | Spinner | ✅ | ❌ | 加载动画 | -| | SuccessTag | ✅ | ❌ | 成功标签 | | | TextBadge | ✅ | ❌ | 文本徽标 | -| | WarnTag | ✅ | ❌ | 警告标签 | | | CustomCollapse | ✅ | ❌ | 自定义折叠面板 | | **display** | | | | 显示组件 | | | Ellipsis | ✅ | ❌ | 文本省略 | @@ -76,6 +75,7 @@ function MyComponent() { | | EmojiAvatar | ✅ | ❌ | 表情头像 | | | ListItem | ✅ | ❌ | 列表项 | | | MaxContextCount | ✅ | ❌ | 最大上下文数显示 | +| | ProviderAvatar | ✅ | ❌ | 提供者头像 | | | CodeViewer | ❌ | ❌ | 代码查看器 (外部依赖) | | | OGCard | ❌ | ❌ | OG 卡片 | | | MarkdownShadowDOMRenderer | ❌ | ❌ | Markdown 渲染器 | @@ -87,22 +87,11 @@ function MyComponent() { | | Tab/* | ❌ | ❌ | 标签页 (Redux 依赖) | | | TopView | ❌ | ❌ | 顶部视图 (window.api 依赖) | | **icons** | | | | 图标组件 | -| | CopyIcon | ✅ | ❌ | 复制图标 | -| | DeleteIcon | ✅ | ❌ | 删除图标 | -| | EditIcon | ✅ | ❌ | 编辑图标 | -| | FileIcons | ✅ | ❌ | 文件图标 (包含 FileSvgIcon、FilePngIcon) | +| | Icon | ✅ | ✅ | 图标工厂函数和预定义图标(合并了 CopyIcon、DeleteIcon、EditIcon、RefreshIcon、ResetIcon、ToolIcon、VisionIcon、WebSearchIcon、WrapIcon、UnWrapIcon、OcrIcon)| +| | FileIcons | ✅ | ❌ | 文件图标 (FileSvgIcon、FilePngIcon) | | | ReasoningIcon | ✅ | ❌ | 推理图标 | -| | RefreshIcon | ✅ | ❌ | 刷新图标 | -| | ResetIcon | ✅ | ❌ | 重置图标 | | | SvgSpinners180Ring | ✅ | ❌ | 旋转加载图标 | | | ToolsCallingIcon | ✅ | ❌ | 工具调用图标 | -| | VisionIcon | ✅ | ❌ | 视觉图标 | -| | WebSearchIcon | ✅ | ❌ | 网页搜索图标 | -| | WrapIcon | ✅ | ❌ | 换行图标 | -| | UnWrapIcon | ✅ | ❌ | 不换行图标 | -| | OcrIcon | ✅ | ❌ | OCR 图标 | -| | ToolIcon | ✅ | ❌ | 工具图标 | -| | Other icons | ❌ | ❌ | 其他图标文件 | | **interactive** | | | | 交互组件 | | | InfoTooltip | ✅ | ❌ | 信息提示 | | | HelpTooltip | ✅ | ❌ | 帮助提示 | @@ -112,6 +101,7 @@ function MyComponent() { | | CollapsibleSearchBar | ✅ | ❌ | 可折叠搜索栏 | | | ImageToolButton | ✅ | ❌ | 图片工具按钮 | | | DraggableList | ✅ | ❌ | 可拖拽列表 | +| | CodeEditor | ✅ | ❌ | 代码编辑器 | | | EmojiPicker | ❌ | ❌ | 表情选择器 (useTheme 依赖) | | | Selector | ✅ | ❌ | 选择器 (i18n 依赖) | | | ModelSelector | ❌ | ❌ | 模型选择器 (Redux 依赖) | @@ -122,7 +112,6 @@ function MyComponent() { | **未分类** | | | | 需要分类的组件 | | | Popups/* (16+ 文件) | ❌ | ❌ | 弹窗组件 (业务耦合) | | | RichEditor/* (30+ 文件) | ❌ | ❌ | 富文本编辑器 | -| | CodeEditor/* | ❌ | ❌ | 代码编辑器 | | | MarkdownEditor/* | ❌ | ❌ | Markdown 编辑器 | | | MinApp/* | ❌ | ❌ | 迷你应用 (Redux 依赖) | | | Avatar/* | ❌ | ❌ | 头像组件 | diff --git a/packages/ui/MIGRATION_STATUS_EN.md b/packages/ui/MIGRATION_STATUS_EN.md index 240d6d6127..78638ce07a 100644 --- a/packages/ui/MIGRATION_STATUS_EN.md +++ b/packages/ui/MIGRATION_STATUS_EN.md @@ -48,9 +48,9 @@ When submitting PRs, please place components in the correct directory based on t ## Migration Overview - **Total Components**: 236 -- **Migrated**: 43 +- **Migrated**: 46 - **Refactored**: 0 -- **Pending Migration**: 193 +- **Pending Migration**: 190 ## Component Status Table @@ -61,6 +61,7 @@ When submitting PRs, please place components in the correct directory based on t | | CustomTag | ✅ | ❌ | Custom tag | | | DividerWithText | ✅ | ❌ | Divider with text | | | EmojiIcon | ✅ | ❌ | Emoji icon | +| | ErrorBoundary | ✅ | ❌ | Error boundary (decoupled via props) | | | ErrorTag | ✅ | ❌ | Error tag | | | IndicatorLight | ✅ | ❌ | Indicator light | | | Spinner | ✅ | ❌ | Loading spinner | @@ -75,6 +76,7 @@ When submitting PRs, please place components in the correct directory based on t | | EmojiAvatar | ✅ | ❌ | Emoji avatar | | | ListItem | ✅ | ❌ | List item | | | MaxContextCount | ✅ | ❌ | Max context count display | +| | ProviderAvatar | ✅ | ❌ | Provider avatar | | | CodeViewer | ❌ | ❌ | Code viewer (external deps) | | | OGCard | ❌ | ❌ | OG card | | | MarkdownShadowDOMRenderer | ❌ | ❌ | Markdown renderer | @@ -111,6 +113,7 @@ When submitting PRs, please place components in the correct directory based on t | | CollapsibleSearchBar | ✅ | ❌ | Collapsible search bar | | | ImageToolButton | ✅ | ❌ | Image tool button | | | DraggableList | ✅ | ❌ | Draggable list | +| | CodeEditor | ✅ | ❌ | Code editor | | | EmojiPicker | ❌ | ❌ | Emoji picker (useTheme dependency) | | | Selector | ✅ | ❌ | Selector (i18n dependency) | | | ModelSelector | ❌ | ❌ | Model selector (Redux dependency) | @@ -121,7 +124,6 @@ When submitting PRs, please place components in the correct directory based on t | **Uncategorized** | | | | Components needing categorization | | | Popups/* (16+ files) | ❌ | ❌ | Popup components (business coupled) | | | RichEditor/* (30+ files) | ❌ | ❌ | Rich text editor | -| | CodeEditor/* | ❌ | ❌ | Code editor | | | MarkdownEditor/* | ❌ | ❌ | Markdown editor | | | MinApp/* | ❌ | ❌ | Mini app (Redux dependency) | | | Avatar/* | ❌ | ❌ | Avatar components | diff --git a/packages/ui/package.json b/packages/ui/package.json index 00dce3b034..8daeb736c7 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -15,8 +15,7 @@ "lint": "eslint src --ext .ts,.tsx --fix", "type-check": "tsc --noEmit", "storybook": "storybook dev -p 6006", - "build-storybook": "storybook build", - "update:languages": "tsx scripts/update-languages.ts" + "build-storybook": "storybook build" }, "keywords": [ "ui", diff --git a/packages/ui/scripts/update-languages.ts b/packages/ui/scripts/update-languages.ts deleted file mode 100644 index 9b5c98d620..0000000000 --- a/packages/ui/scripts/update-languages.ts +++ /dev/null @@ -1,135 +0,0 @@ -import { exec } from 'child_process' -import * as fs from 'fs/promises' -import * as linguistLanguages from 'linguist-languages' -import * as path from 'path' -import { promisify } from 'util' - -const execAsync = promisify(exec) - -type LanguageData = { - type: string - aliases?: string[] - extensions?: string[] -} - -const LANGUAGES_FILE_PATH = path.join(__dirname, '../src/config/languages.ts') - -/** - * Extracts and filters necessary language data from the linguist-languages package. - * @returns A record of language data. - */ -function extractAllLanguageData(): Record { - console.log('🔍 Extracting language data from linguist-languages...') - const languages = Object.entries(linguistLanguages).reduce( - (acc, [name, langData]) => { - const { type, extensions, aliases } = langData as any - - // Only include languages with extensions or aliases - if ((extensions && extensions.length > 0) || (aliases && aliases.length > 0)) { - acc[name] = { - type: type || 'programming', - ...(extensions && { extensions }), - ...(aliases && { aliases }) - } - } - return acc - }, - {} as Record - ) - console.log(`✅ Extracted ${Object.keys(languages).length} languages.`) - return languages -} - -/** - * Generates the content for the languages.ts file. - * @param languages The language data to include in the file. - * @returns The generated file content as a string. - */ -function generateLanguagesFileContent(languages: Record): string { - console.log('📝 Generating languages.ts file content...') - const sortedLanguages = Object.fromEntries(Object.entries(languages).sort(([a], [b]) => a.localeCompare(b))) - - const languagesObjectString = JSON.stringify(sortedLanguages, null, 2) - - const content = `/** - * Code language list. - * Data source: linguist-languages - * - * ⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - * THIS FILE IS AUTOMATICALLY GENERATED BY A SCRIPT. DO NOT EDIT IT MANUALLY! - * Run \`yarn update:languages\` to update this file. - * ⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - * - */ - -type LanguageData = { - type: string; - aliases?: string[]; - extensions?: string[]; -}; - -export const languages: Record = ${languagesObjectString}; -` - console.log('✅ File content generated.') - return content -} - -/** - * Formats a file using Prettier. - * @param filePath The path to the file to format. - */ -async function formatWithPrettier(filePath: string): Promise { - console.log('🎨 Formatting file with Prettier...') - try { - await execAsync(`yarn prettier --write ${filePath}`) - console.log('✅ Prettier formatting complete.') - } catch (e: any) { - console.error('❌ Prettier formatting failed:', e.stdout || e.stderr) - throw new Error('Prettier formatting failed.') - } -} - -/** - * Checks a file with TypeScript compiler. - * @param filePath The path to the file to check. - */ -async function checkTypeScript(filePath: string): Promise { - console.log('🧐 Checking file with TypeScript compiler...') - try { - await execAsync(`yarn tsc --noEmit --skipLibCheck ${filePath}`) - console.log('✅ TypeScript check passed.') - } catch (e: any) { - console.error('❌ TypeScript check failed:', e.stdout || e.stderr) - throw new Error('TypeScript check failed.') - } -} - -/** - * Main function to update the languages.ts file. - */ -async function updateLanguagesFile(): Promise { - console.log('🚀 Starting to update languages.ts...') - try { - const extractedLanguages = extractAllLanguageData() - const fileContent = generateLanguagesFileContent(extractedLanguages) - - await fs.writeFile(LANGUAGES_FILE_PATH, fileContent, 'utf-8') - console.log(`✅ Successfully wrote to ${LANGUAGES_FILE_PATH}`) - - await formatWithPrettier(LANGUAGES_FILE_PATH) - await checkTypeScript(LANGUAGES_FILE_PATH) - - console.log('🎉 Successfully updated languages.ts file!') - console.log(`📊 Contains ${Object.keys(extractedLanguages).length} languages.`) - } catch (error) { - console.error('❌ An error occurred during the update process:', (error as Error).message) - // No need to restore backup as we write only at the end of successful generation. - process.exit(1) - } -} - -if (require.main === module) { - updateLanguagesFile() -} - -export { updateLanguagesFile } diff --git a/packages/ui/src/components/base/ErrorBoundary/index.tsx b/packages/ui/src/components/base/ErrorBoundary/index.tsx new file mode 100644 index 0000000000..f620e028b5 --- /dev/null +++ b/packages/ui/src/components/base/ErrorBoundary/index.tsx @@ -0,0 +1,101 @@ +// Original path: src/renderer/src/components/ErrorBoundary.tsx +import { Button } from '@heroui/button' +import { Alert, Space } from 'antd' +import { ComponentType, ReactNode } from 'react' +import { ErrorBoundary, FallbackProps } from 'react-error-boundary' +import styled from 'styled-components' + +import { formatErrorMessage } from './utils' + +interface CustomFallbackProps extends FallbackProps { + onDebugClick?: () => void | Promise + onReloadClick?: () => void | Promise + debugButtonText?: string + reloadButtonText?: string + errorMessage?: string +} + +const DefaultFallback: ComponentType = (props: CustomFallbackProps): ReactNode => { + const { + error, + onDebugClick, + onReloadClick, + debugButtonText = 'Open DevTools', + reloadButtonText = 'Reload', + errorMessage = 'An error occurred' + } = props + + return ( + + + {onDebugClick && ( + + )} + {onReloadClick && ( + + )} + + } + /> + + ) +} + +interface ErrorBoundaryCustomizedProps { + children: ReactNode + fallbackComponent?: ComponentType + onDebugClick?: () => void | Promise + onReloadClick?: () => void | Promise + debugButtonText?: string + reloadButtonText?: string + errorMessage?: string +} + +const ErrorBoundaryCustomized = ({ + children, + fallbackComponent, + onDebugClick, + onReloadClick, + debugButtonText, + reloadButtonText, + errorMessage +}: ErrorBoundaryCustomizedProps) => { + const FallbackComponent = fallbackComponent ?? DefaultFallback + + return ( + ( + + )}> + {children} + + ) +} + +const ErrorContainer = styled.div` + display: flex; + justify-content: center; + align-items: center; + width: 100%; + padding: 8px; +` + +export { ErrorBoundaryCustomized as ErrorBoundary } +export type { ErrorBoundaryCustomizedProps, CustomFallbackProps } \ No newline at end of file diff --git a/packages/ui/src/components/base/ErrorBoundary/utils.ts b/packages/ui/src/components/base/ErrorBoundary/utils.ts new file mode 100644 index 0000000000..3493a90d6b --- /dev/null +++ b/packages/ui/src/components/base/ErrorBoundary/utils.ts @@ -0,0 +1,8 @@ +// Utility functions for ErrorBoundary component + +export function formatErrorMessage(error: Error): string { + if (error.message) { + return error.message + } + return error.toString() +} \ No newline at end of file diff --git a/packages/ui/src/components/base/ErrorTag/index.tsx b/packages/ui/src/components/base/ErrorTag/index.tsx deleted file mode 100644 index 5f6b22cf9f..0000000000 --- a/packages/ui/src/components/base/ErrorTag/index.tsx +++ /dev/null @@ -1,17 +0,0 @@ -// Original path: src/renderer/src/components/Tags/ErrorTag.tsx -import { CircleXIcon } from 'lucide-react' - -import CustomTag from '../CustomTag' - -type Props = { - iconSize?: number - message: string -} - -export const ErrorTag = ({ iconSize: size = 14, message }: Props) => { - return ( - } color="var(--color-status-error)"> - {message} - - ) -} diff --git a/packages/ui/src/components/base/StatusTag/index.tsx b/packages/ui/src/components/base/StatusTag/index.tsx new file mode 100644 index 0000000000..dad73a1956 --- /dev/null +++ b/packages/ui/src/components/base/StatusTag/index.tsx @@ -0,0 +1,51 @@ +import { AlertTriangleIcon, CheckIcon, CircleXIcon, InfoIcon, LucideIcon } from 'lucide-react' +import React from 'react' + +import CustomTag from '../CustomTag' + +export type StatusType = 'success' | 'error' | 'warning' | 'info' + +export interface StatusTagProps { + type: StatusType + message: string + iconSize?: number + icon?: React.ReactNode + color?: string +} + +const statusConfig: Record = { + success: { Icon: CheckIcon, color: '#10B981' }, // green-500 + error: { Icon: CircleXIcon, color: '#EF4444' }, // red-500 + warning: { Icon: AlertTriangleIcon, color: '#F59E0B' }, // amber-500 + info: { Icon: InfoIcon, color: '#3B82F6' } // blue-500 +} + +export const StatusTag: React.FC = ({ type, message, iconSize = 14, icon, color }) => { + const config = statusConfig[type] + const Icon = config.Icon + const finalColor = color || config.color + const finalIcon = icon || + + return ( + + {message} + + ) +} + +// 保留原有的导出以保持向后兼容 +export const SuccessTag = ({ iconSize, message }: { iconSize?: number; message: string }) => ( + +) + +export const ErrorTag = ({ iconSize, message }: { iconSize?: number; message: string }) => ( + +) + +export const WarnTag = ({ iconSize, message }: { iconSize?: number; message: string }) => ( + +) + +export const InfoTag = ({ iconSize, message }: { iconSize?: number; message: string }) => ( + +) diff --git a/packages/ui/src/components/base/SuccessTag/index.tsx b/packages/ui/src/components/base/SuccessTag/index.tsx deleted file mode 100644 index a186c38041..0000000000 --- a/packages/ui/src/components/base/SuccessTag/index.tsx +++ /dev/null @@ -1,17 +0,0 @@ -// Original path: src/renderer/src/components/Tags/SuccessTag.tsx -import { CheckIcon } from 'lucide-react' - -import CustomTag from '../CustomTag' - -type Props = { - iconSize?: number - message: string -} - -export const SuccessTag = ({ iconSize: size = 14, message }: Props) => { - return ( - } color="var(--color-status-success)"> - {message} - - ) -} diff --git a/packages/ui/src/components/base/WarnTag/index.tsx b/packages/ui/src/components/base/WarnTag/index.tsx deleted file mode 100644 index 0d5170fcef..0000000000 --- a/packages/ui/src/components/base/WarnTag/index.tsx +++ /dev/null @@ -1,19 +0,0 @@ -// Original path: src/renderer/src/components/Tags/WarnTag.tsx -import { AlertTriangleIcon } from 'lucide-react' - -import CustomTag from '../CustomTag' - -type Props = { - iconSize?: number - message: string -} - -export const WarnTag = ({ iconSize: size = 14, message }: Props) => { - return ( - } - color="var(--color-status-warning)"> - {message} - - ) -} diff --git a/packages/ui/src/components/display/ProviderAvatar/index.tsx b/packages/ui/src/components/display/ProviderAvatar/index.tsx new file mode 100644 index 0000000000..a61a040780 --- /dev/null +++ b/packages/ui/src/components/display/ProviderAvatar/index.tsx @@ -0,0 +1,86 @@ +// Original path: src/renderer/src/components/ProviderAvatar.tsx +import { Avatar } from 'antd' +import React from 'react' +import styled from 'styled-components' + +import { generateColorFromChar, getFirstCharacter, getForegroundColor } from './utils' + +interface ProviderAvatarProps { + providerId: string + providerName: string + logoSrc?: string + size?: number + className?: string + style?: React.CSSProperties + renderCustomLogo?: (providerId: string) => React.ReactNode +} + +const ProviderLogo = styled(Avatar)` + width: 100%; + height: 100%; + border: 0.5px solid var(--color-border); +` + +const ProviderSvgLogo = styled.div` + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + border: 0.5px solid var(--color-border); + border-radius: 100%; + + & > svg { + width: 80%; + height: 80%; + } +` + +export const ProviderAvatar: React.FC = ({ + providerId, + providerName, + logoSrc, + size, + className, + style, + renderCustomLogo +}) => { + // Check if custom logo renderer is provided for special providers + if (renderCustomLogo) { + const customLogo = renderCustomLogo(providerId) + if (customLogo) { + return ( + + {customLogo} + + ) + } + } + + // If logo source is provided, render image avatar + if (logoSrc) { + return ( + + ) + } + + // Default: generate avatar with first character and background color + const backgroundColor = generateColorFromChar(providerName) + const color = providerName ? getForegroundColor(backgroundColor) : 'white' + + return ( + + {getFirstCharacter(providerName)} + + ) +} + +export default ProviderAvatar diff --git a/packages/ui/src/components/display/ProviderAvatar/utils.ts b/packages/ui/src/components/display/ProviderAvatar/utils.ts new file mode 100644 index 0000000000..6e3c6126c9 --- /dev/null +++ b/packages/ui/src/components/display/ProviderAvatar/utils.ts @@ -0,0 +1,37 @@ +// Utility functions for ProviderAvatar component + +export function generateColorFromChar(char: string): string { + const seed = char.charCodeAt(0) + const a = 1664525 + const c = 1013904223 + const m = Math.pow(2, 32) + + let r = (a * seed + c) % m + let g = (a * r + c) % m + let b = (a * g + c) % m + + r = Math.floor((r / m) * 256) + g = Math.floor((g / m) * 256) + b = Math.floor((b / m) * 256) + + const toHex = (n: number) => n.toString(16).padStart(2, '0') + return `#${toHex(r)}${toHex(g)}${toHex(b)}` +} + +export function getFirstCharacter(str: string): string { + for (const char of str) { + return char + } + return '' +} + +export function getForegroundColor(backgroundColor: string): string { + // Simple luminance calculation + const hex = backgroundColor.replace('#', '') + const r = parseInt(hex.substring(0, 2), 16) / 255 + const g = parseInt(hex.substring(2, 4), 16) / 255 + const b = parseInt(hex.substring(4, 6), 16) / 255 + + const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b + return luminance > 0.179 ? '#000000' : '#FFFFFF' +} diff --git a/packages/ui/src/components/icons/CopyIcon/index.tsx b/packages/ui/src/components/icons/CopyIcon/index.tsx deleted file mode 100644 index be0aa1ddc4..0000000000 --- a/packages/ui/src/components/icons/CopyIcon/index.tsx +++ /dev/null @@ -1,6 +0,0 @@ -// Original path: src/renderer/src/components/Icons/CopyIcon.tsx -import { Copy } from 'lucide-react' - -const CopyIcon = (props: React.ComponentProps) => - -export default CopyIcon diff --git a/packages/ui/src/components/icons/DeleteIcon/index.tsx b/packages/ui/src/components/icons/DeleteIcon/index.tsx deleted file mode 100644 index a3c74c2695..0000000000 --- a/packages/ui/src/components/icons/DeleteIcon/index.tsx +++ /dev/null @@ -1,6 +0,0 @@ -// Original path: src/renderer/src/components/Icons/DeleteIcon.tsx -import { Trash } from 'lucide-react' - -const DeleteIcon = (props: React.ComponentProps) => - -export default DeleteIcon diff --git a/packages/ui/src/components/icons/EditIcon/index.tsx b/packages/ui/src/components/icons/EditIcon/index.tsx deleted file mode 100644 index a7ad677fb3..0000000000 --- a/packages/ui/src/components/icons/EditIcon/index.tsx +++ /dev/null @@ -1,6 +0,0 @@ -// Original path: src/renderer/src/components/Icons/EditIcon.tsx -import { Pencil } from 'lucide-react' - -const EditIcon = (props: React.ComponentProps) => - -export default EditIcon diff --git a/packages/ui/src/components/icons/Icon/index.tsx b/packages/ui/src/components/icons/Icon/index.tsx new file mode 100644 index 0000000000..8ab20c4939 --- /dev/null +++ b/packages/ui/src/components/icons/Icon/index.tsx @@ -0,0 +1,41 @@ +import { + AlignLeft, + Copy, + Eye, + LucideIcon, + Pencil, + RefreshCw, + RotateCcw, + ScanLine, + Search, + Trash, + WrapText, + Wrench +} from 'lucide-react' +import React from 'react' + +// 创建一个 Icon 工厂函数 +export function createIcon(IconComponent: LucideIcon, defaultSize: string | number = '1rem') { + const Icon = React.forwardRef>( + (props, ref) => + ) + Icon.displayName = `Icon(${IconComponent.displayName || IconComponent.name})` + return Icon +} + +// 预定义的常用图标(向后兼容,只导入需要的图标) +export const CopyIcon = createIcon(Copy) +export const DeleteIcon = createIcon(Trash) +export const EditIcon = createIcon(Pencil) +export const RefreshIcon = createIcon(RefreshCw) +export const ResetIcon = createIcon(RotateCcw) +export const ToolIcon = createIcon(Wrench) +export const VisionIcon = createIcon(Eye) +export const WebSearchIcon = createIcon(Search) +export const WrapIcon = createIcon(WrapText) +export const UnWrapIcon = createIcon(AlignLeft) +export const OcrIcon = createIcon(ScanLine) + +// 导出 createIcon 以便用户自行创建图标组件 +export type { LucideIcon } +export type { LucideProps } from 'lucide-react' diff --git a/packages/ui/src/components/icons/OcrIcon/index.tsx b/packages/ui/src/components/icons/OcrIcon/index.tsx deleted file mode 100644 index 68a317de33..0000000000 --- a/packages/ui/src/components/icons/OcrIcon/index.tsx +++ /dev/null @@ -1,8 +0,0 @@ -// Original path: src/renderer/src/components/Icons/OcrIcon.tsx -import { FC } from 'react' - -const OcrIcon: FC, HTMLElement>> = (props) => { - return -} - -export default OcrIcon diff --git a/packages/ui/src/components/icons/RefreshIcon/index.tsx b/packages/ui/src/components/icons/RefreshIcon/index.tsx deleted file mode 100644 index b29e5571a2..0000000000 --- a/packages/ui/src/components/icons/RefreshIcon/index.tsx +++ /dev/null @@ -1,6 +0,0 @@ -// Original path: src/renderer/src/components/Icons/RefreshIcon.tsx -import { RefreshCw } from 'lucide-react' - -const RefreshIcon = (props: React.ComponentProps) => - -export default RefreshIcon diff --git a/packages/ui/src/components/icons/ResetIcon/index.tsx b/packages/ui/src/components/icons/ResetIcon/index.tsx deleted file mode 100644 index 364c8ddb91..0000000000 --- a/packages/ui/src/components/icons/ResetIcon/index.tsx +++ /dev/null @@ -1,6 +0,0 @@ -// Original path: src/renderer/src/components/Icons/ResetIcon.tsx -import { RotateCcw } from 'lucide-react' - -const ResetIcon = (props: React.ComponentProps) => - -export default ResetIcon diff --git a/packages/ui/src/components/icons/ToolIcon/index.tsx b/packages/ui/src/components/icons/ToolIcon/index.tsx deleted file mode 100644 index d7486d5d22..0000000000 --- a/packages/ui/src/components/icons/ToolIcon/index.tsx +++ /dev/null @@ -1,8 +0,0 @@ -// Original path: src/renderer/src/components/Icons/ToolIcon.tsx -import { FC } from 'react' - -const ToolIcon: FC, HTMLElement>> = (props) => { - return -} - -export default ToolIcon diff --git a/packages/ui/src/components/icons/UnWrapIcon/index.tsx b/packages/ui/src/components/icons/UnWrapIcon/index.tsx deleted file mode 100644 index 7c9e814d38..0000000000 --- a/packages/ui/src/components/icons/UnWrapIcon/index.tsx +++ /dev/null @@ -1,18 +0,0 @@ -// Original path: src/renderer/src/components/Icons/UnWrapIcon.tsx -const UnWrapIcon = (props: React.SVGProps) => ( - - - -) -export default UnWrapIcon diff --git a/packages/ui/src/components/icons/VisionIcon/index.tsx b/packages/ui/src/components/icons/VisionIcon/index.tsx deleted file mode 100644 index 14de121b3c..0000000000 --- a/packages/ui/src/components/icons/VisionIcon/index.tsx +++ /dev/null @@ -1,31 +0,0 @@ -// Original: src/renderer/src/components/Icons/VisionIcon.tsx -import { Tooltip } from 'antd' -import { ImageIcon } from 'lucide-react' -import React, { FC } from 'react' -import { useTranslation } from 'react-i18next' -import styled from 'styled-components' - -const VisionIcon: FC, HTMLElement>> = (props) => { - const { t } = useTranslation() - - return ( - - - - - - ) -} - -const Container = styled.div` - display: flex; - justify-content: center; - align-items: center; -` - -const Icon = styled(ImageIcon)` - color: var(--color-primary); - margin-right: 6px; -` - -export default VisionIcon diff --git a/packages/ui/src/components/icons/WebSearchIcon/index.tsx b/packages/ui/src/components/icons/WebSearchIcon/index.tsx deleted file mode 100644 index 69646c3dd7..0000000000 --- a/packages/ui/src/components/icons/WebSearchIcon/index.tsx +++ /dev/null @@ -1,32 +0,0 @@ -// Original: src/renderer/src/components/Icons/WebSearchIcon.tsx -import { GlobalOutlined } from '@ant-design/icons' -import { Tooltip } from 'antd' -import React, { FC } from 'react' -import { useTranslation } from 'react-i18next' -import styled from 'styled-components' - -const WebSearchIcon: FC, HTMLElement>> = (props) => { - const { t } = useTranslation() - - return ( - - - - - - ) -} - -const Container = styled.div` - display: flex; - justify-content: center; - align-items: center; -` - -const Icon = styled(GlobalOutlined)` - color: var(--color-link); - font-size: 15px; - margin-right: 6px; -` - -export default WebSearchIcon diff --git a/packages/ui/src/components/icons/WrapIcon/index.tsx b/packages/ui/src/components/icons/WrapIcon/index.tsx deleted file mode 100644 index 8de3b4a350..0000000000 --- a/packages/ui/src/components/icons/WrapIcon/index.tsx +++ /dev/null @@ -1,21 +0,0 @@ -// Original path: src/renderer/src/components/Icons/WrapIcon.tsx -import React from 'react' - -const WrapIcon = (props: React.SVGProps) => ( - - - - -) -export default WrapIcon diff --git a/packages/ui/src/components/index.ts b/packages/ui/src/components/index.ts index ebfb955c1d..1666c132e1 100644 --- a/packages/ui/src/components/index.ts +++ b/packages/ui/src/components/index.ts @@ -4,12 +4,13 @@ export { default as CustomCollapse } from './base/CustomCollapse' export { default as CustomTag } from './base/CustomTag' export { default as DividerWithText } from './base/DividerWithText' export { default as EmojiIcon } from './base/EmojiIcon' -export { ErrorTag } from './base/ErrorTag' +export { ErrorBoundary } from './base/ErrorBoundary' +export type { ErrorBoundaryCustomizedProps, CustomFallbackProps } from './base/ErrorBoundary' export { default as IndicatorLight } from './base/IndicatorLight' export { default as Spinner } from './base/Spinner' -export { SuccessTag } from './base/SuccessTag' +export { StatusTag, ErrorTag, SuccessTag, WarnTag, InfoTag } from './base/StatusTag' +export type { StatusType, StatusTagProps } from './base/StatusTag' export { default as TextBadge } from './base/TextBadge' -export { WarnTag } from './base/WarnTag' // Display Components export { default as Ellipsis } from './display/Ellipsis' @@ -17,6 +18,7 @@ export { default as EmojiAvatar } from './display/EmojiAvatar' export { default as ExpandableText } from './display/ExpandableText' export { default as ListItem } from './display/ListItem' export { default as MaxContextCount } from './display/MaxContextCount' +export { ProviderAvatar } from './display/ProviderAvatar' export { default as ThinkingEffect } from './display/ThinkingEffect' // Layout Components @@ -24,21 +26,25 @@ export { default as HorizontalScrollContainer } from './layout/HorizontalScrollC export { default as Scrollbar } from './layout/Scrollbar' // Icon Components -export { default as CopyIcon } from './icons/CopyIcon' -export { default as DeleteIcon } from './icons/DeleteIcon' -export { default as EditIcon } from './icons/EditIcon' +export { + createIcon, + CopyIcon, + DeleteIcon, + EditIcon, + RefreshIcon, + ResetIcon, + ToolIcon, + VisionIcon, + WebSearchIcon, + WrapIcon, + UnWrapIcon, + OcrIcon +} from './icons/Icon' +export type { LucideIcon, LucideProps } from './icons/Icon' export { FilePngIcon, FileSvgIcon } from './icons/FileIcons' -export { default as OcrIcon } from './icons/OcrIcon' export { default as ReasoningIcon } from './icons/ReasoningIcon' -export { default as RefreshIcon } from './icons/RefreshIcon' -export { default as ResetIcon } from './icons/ResetIcon' export { default as SvgSpinners180Ring } from './icons/SvgSpinners180Ring' -export { default as ToolIcon } from './icons/ToolIcon' export { default as ToolsCallingIcon } from './icons/ToolsCallingIcon' -export { default as UnWrapIcon } from './icons/UnWrapIcon' -export { default as VisionIcon } from './icons/VisionIcon' -export { default as WebSearchIcon } from './icons/WebSearchIcon' -export { default as WrapIcon } from './icons/WrapIcon' // Interactive Components export { diff --git a/packages/ui/src/components/interactive/CodeEditor/CodeEditor.tsx b/packages/ui/src/components/interactive/CodeEditor/CodeEditor.tsx index b202205d5c..79b1a6506a 100644 --- a/packages/ui/src/components/interactive/CodeEditor/CodeEditor.tsx +++ b/packages/ui/src/components/interactive/CodeEditor/CodeEditor.tsx @@ -15,6 +15,7 @@ const CodeEditor = ({ value, placeholder, language, + languageConfig, onSave, onChange, onBlur, @@ -55,7 +56,7 @@ const CodeEditor = ({ const initialContent = useRef(options?.stream ? (value ?? '').trimEnd() : (value ?? '')) const editorViewRef = useRef(null) - const langExtensions = useLanguageExtensions(language, options?.lint) + const langExtensions = useLanguageExtensions(language, options?.lint, languageConfig) const handleSave = useCallback(() => { const currentDoc = editorViewRef.current?.state.doc.toString() ?? '' diff --git a/packages/ui/src/components/interactive/CodeEditor/hooks.ts b/packages/ui/src/components/interactive/CodeEditor/hooks.ts index 7c4f564763..c96c4fdeaf 100644 --- a/packages/ui/src/components/interactive/CodeEditor/hooks.ts +++ b/packages/ui/src/components/interactive/CodeEditor/hooks.ts @@ -3,6 +3,7 @@ import { EditorView } from '@codemirror/view' import { Extension, keymap } from '@uiw/react-codemirror' import { useEffect, useMemo, useState } from 'react' +import { LanguageConfig } from './types' import { getNormalizedExtension } from './utils' /** 语言对应的 linter 加载器 @@ -34,8 +35,8 @@ const specialLanguageLoaders: Record Promise> = { /** * 加载语言扩展 */ -async function loadLanguageExtension(language: string): Promise { - const fileExt = await getNormalizedExtension(language) +async function loadLanguageExtension(language: string, languageConfig?: LanguageConfig): Promise { + const fileExt = await getNormalizedExtension(language, languageConfig) // 尝试加载特殊语言 const specialLoader = specialLanguageLoaders[fileExt] @@ -62,8 +63,8 @@ async function loadLanguageExtension(language: string): Promise { - const fileExt = await getNormalizedExtension(language) +async function loadLinterExtension(language: string, languageConfig?: LanguageConfig): Promise { + const fileExt = await getNormalizedExtension(language, languageConfig) const loader = linterLoaders[fileExt] if (!loader) return null @@ -79,7 +80,7 @@ async function loadLinterExtension(language: string): Promise /** * 加载语言相关扩展 */ -export const useLanguageExtensions = (language: string, lint?: boolean) => { +export const useLanguageExtensions = (language: string, lint?: boolean, languageConfig?: LanguageConfig) => { const [extensions, setExtensions] = useState([]) useEffect(() => { @@ -89,8 +90,8 @@ export const useLanguageExtensions = (language: string, lint?: boolean) => { try { // 加载所有扩展 const [languageResult, linterResult] = await Promise.allSettled([ - loadLanguageExtension(language), - lint ? loadLinterExtension(language) : Promise.resolve(null) + loadLanguageExtension(language, languageConfig), + lint ? loadLinterExtension(language, languageConfig) : Promise.resolve(null) ]) if (cancelled) return @@ -121,7 +122,7 @@ export const useLanguageExtensions = (language: string, lint?: boolean) => { return () => { cancelled = true } - }, [language, lint]) + }, [language, lint, languageConfig]) return extensions } diff --git a/packages/ui/src/components/interactive/CodeEditor/types.ts b/packages/ui/src/components/interactive/CodeEditor/types.ts index bc91377f70..7c1687a74b 100644 --- a/packages/ui/src/components/interactive/CodeEditor/types.ts +++ b/packages/ui/src/components/interactive/CodeEditor/types.ts @@ -2,6 +2,16 @@ import { BasicSetupOptions, Extension } from '@uiw/react-codemirror' export type CodeMirrorTheme = 'light' | 'dark' | 'none' | Extension +/** Language data structure for file extension mapping */ +export interface LanguageData { + type: string + aliases?: string[] + extensions?: string[] +} + +/** Language configuration mapping language names to their data */ +export type LanguageConfig = Record + export interface CodeEditorHandles { save?: () => void } @@ -20,6 +30,12 @@ export interface CodeEditorProps { * - Supports file extensions: .cpp/cpp, .js/js, .py/py, etc. */ language: string + /** + * Language configuration for extension mapping. + * If not provided, will use a default minimal configuration. + * @optional + */ + languageConfig?: LanguageConfig /** Fired when ref.save() is called or the save shortcut is triggered. */ onSave?: (newContent: string) => void /** Fired when the editor content changes. */ diff --git a/packages/ui/src/components/interactive/CodeEditor/utils.ts b/packages/ui/src/components/interactive/CodeEditor/utils.ts index bd7cdc516b..10eb0452f8 100644 --- a/packages/ui/src/components/interactive/CodeEditor/utils.ts +++ b/packages/ui/src/components/interactive/CodeEditor/utils.ts @@ -2,8 +2,7 @@ import * as cmThemes from '@uiw/codemirror-themes-all' import { Extension } from '@uiw/react-codemirror' import diff from 'fast-diff' -import { getExtensionByLanguage } from '../../../utils/codeLanguage' -import { CodeMirrorTheme } from './types' +import { CodeMirrorTheme, LanguageConfig } from './types' /** * Computes code changes using fast-diff and converts them to CodeMirror changes. @@ -50,15 +49,158 @@ const _customLanguageExtensions: Record = { graphviz: 'dot' } +// Default minimal language configuration for common languages +const _defaultLanguageConfig: LanguageConfig = { + JavaScript: { + type: 'programming', + extensions: ['.js', '.mjs', '.cjs'], + aliases: ['js', 'node'] + }, + TypeScript: { + type: 'programming', + extensions: ['.ts'], + aliases: ['ts'] + }, + Python: { + type: 'programming', + extensions: ['.py'], + aliases: ['python3', 'py'] + }, + Java: { + type: 'programming', + extensions: ['.java'] + }, + 'C++': { + type: 'programming', + extensions: ['.cpp', '.cc', '.cxx'], + aliases: ['cpp'] + }, + C: { + type: 'programming', + extensions: ['.c'] + }, + 'C#': { + type: 'programming', + extensions: ['.cs'], + aliases: ['csharp'] + }, + HTML: { + type: 'markup', + extensions: ['.html', '.htm'] + }, + CSS: { + type: 'markup', + extensions: ['.css'] + }, + JSON: { + type: 'data', + extensions: ['.json'] + }, + XML: { + type: 'data', + extensions: ['.xml'] + }, + YAML: { + type: 'data', + extensions: ['.yml', '.yaml'] + }, + SQL: { + type: 'data', + extensions: ['.sql'] + }, + Shell: { + type: 'programming', + extensions: ['.sh', '.bash'], + aliases: ['bash', 'sh'] + }, + Go: { + type: 'programming', + extensions: ['.go'], + aliases: ['golang'] + }, + Rust: { + type: 'programming', + extensions: ['.rs'] + }, + PHP: { + type: 'programming', + extensions: ['.php'] + }, + Ruby: { + type: 'programming', + extensions: ['.rb'], + aliases: ['rb'] + }, + Swift: { + type: 'programming', + extensions: ['.swift'] + }, + Kotlin: { + type: 'programming', + extensions: ['.kt'] + }, + Dart: { + type: 'programming', + extensions: ['.dart'] + }, + R: { + type: 'programming', + extensions: ['.r'] + }, + MATLAB: { + type: 'programming', + extensions: ['.m'] + } +} + +/** + * Get the file extension of the language, by language name + * - First, exact match + * - Then, case-insensitive match + * - Finally, match aliases + * If there are multiple file extensions, only the first one will be returned + * @param language language name + * @param languageConfig optional language configuration, defaults to a minimal config + * @returns file extension + */ +export function getExtensionByLanguage(language: string, languageConfig?: LanguageConfig): string { + const languages = languageConfig || _defaultLanguageConfig + const lowerLanguage = language.toLowerCase() + + // Exact match language name + const directMatch = languages[language] + if (directMatch?.extensions?.[0]) { + return directMatch.extensions[0] + } + + // Case-insensitive match language name + for (const [langName, data] of Object.entries(languages)) { + if (langName.toLowerCase() === lowerLanguage && data.extensions?.[0]) { + return data.extensions[0] + } + } + + // Match aliases + for (const [, data] of Object.entries(languages)) { + if (data.aliases?.some((alias) => alias.toLowerCase() === lowerLanguage)) { + return data.extensions?.[0] || `.${language}` + } + } + + // Fallback to language name + return `.${language}` +} + /** * Get the file extension of the language, for @uiw/codemirror-extensions-langs * - First, search for custom extensions - * - Then, search for github linguist extensions + * - Then, search for language configuration extensions * - Finally, assume the name is already an extension * @param language language name + * @param languageConfig optional language configuration * @returns file extension (without `.` prefix) */ -export async function getNormalizedExtension(language: string) { +export async function getNormalizedExtension(language: string, languageConfig?: LanguageConfig) { let lang = language // If the language name looks like an extension, remove the dot @@ -74,8 +216,8 @@ export async function getNormalizedExtension(language: string) { return customExt } - // 2. Search for github linguist extensions - const linguistExt = getExtensionByLanguage(lang) + // 2. Search for language configuration extensions + const linguistExt = getExtensionByLanguage(lang, languageConfig) if (linguistExt) { return linguistExt.slice(1) } diff --git a/packages/ui/src/config/languages.ts b/packages/ui/src/config/languages.ts deleted file mode 100644 index 7b1a432a33..0000000000 --- a/packages/ui/src/config/languages.ts +++ /dev/null @@ -1,3695 +0,0 @@ -/** - * Code language list. - * Data source: linguist-languages - * - * ⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - * THIS FILE IS AUTOMATICALLY GENERATED BY A SCRIPT. DO NOT EDIT IT MANUALLY! - * Run `yarn update:languages` to update this file. - * ⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - * - */ - -type LanguageData = { - type: string - aliases?: string[] - extensions?: string[] -} - -export const languages: Record = { - '1C Enterprise': { - type: 'programming', - extensions: ['.bsl', '.os'] - }, - '2-Dimensional Array': { - type: 'data', - extensions: ['.2da'] - }, - '4D': { - type: 'programming', - extensions: ['.4dm'] - }, - ABAP: { - type: 'programming', - extensions: ['.abap'] - }, - 'ABAP CDS': { - type: 'programming', - extensions: ['.asddls'] - }, - ABNF: { - type: 'data', - extensions: ['.abnf'] - }, - ActionScript: { - type: 'programming', - extensions: ['.as'], - aliases: ['actionscript 3', 'actionscript3', 'as3'] - }, - Ada: { - type: 'programming', - extensions: ['.adb', '.ada', '.ads'], - aliases: ['ada95', 'ada2005'] - }, - 'Adblock Filter List': { - type: 'data', - extensions: ['.txt'], - aliases: ['ad block filters', 'ad block', 'adb', 'adblock'] - }, - 'Adobe Font Metrics': { - type: 'data', - extensions: ['.afm'], - aliases: ['acfm', 'adobe composite font metrics', 'adobe multiple font metrics', 'amfm'] - }, - Agda: { - type: 'programming', - extensions: ['.agda'] - }, - 'AGS Script': { - type: 'programming', - extensions: ['.asc', '.ash'], - aliases: ['ags'] - }, - AIDL: { - type: 'programming', - extensions: ['.aidl'] - }, - Aiken: { - type: 'programming', - extensions: ['.ak'] - }, - AL: { - type: 'programming', - extensions: ['.al'] - }, - Alloy: { - type: 'programming', - extensions: ['.als'] - }, - 'Alpine Abuild': { - type: 'programming', - aliases: ['abuild', 'apkbuild'] - }, - 'Altium Designer': { - type: 'data', - extensions: ['.OutJob', '.PcbDoc', '.PrjPCB', '.SchDoc'], - aliases: ['altium'] - }, - AMPL: { - type: 'programming', - extensions: ['.ampl', '.mod'] - }, - AngelScript: { - type: 'programming', - extensions: ['.as', '.angelscript'] - }, - 'Answer Set Programming': { - type: 'programming', - extensions: ['.lp'] - }, - Antlers: { - type: 'markup', - extensions: ['.antlers.html', '.antlers.php', '.antlers.xml'] - }, - ANTLR: { - type: 'programming', - extensions: ['.g4'] - }, - ApacheConf: { - type: 'data', - extensions: ['.apacheconf', '.vhost'], - aliases: ['aconf', 'apache'] - }, - Apex: { - type: 'programming', - extensions: ['.cls', '.apex', '.trigger'] - }, - 'API Blueprint': { - type: 'markup', - extensions: ['.apib'] - }, - APL: { - type: 'programming', - extensions: ['.apl', '.dyalog'] - }, - 'Apollo Guidance Computer': { - type: 'programming', - extensions: ['.agc'] - }, - AppleScript: { - type: 'programming', - extensions: ['.applescript', '.scpt'], - aliases: ['osascript'] - }, - Arc: { - type: 'programming', - extensions: ['.arc'] - }, - AsciiDoc: { - type: 'prose', - extensions: ['.asciidoc', '.adoc', '.asc'] - }, - ASL: { - type: 'programming', - extensions: ['.asl', '.dsl'] - }, - 'ASN.1': { - type: 'data', - extensions: ['.asn', '.asn1'] - }, - 'ASP.NET': { - type: 'programming', - extensions: ['.asax', '.ascx', '.ashx', '.asmx', '.aspx', '.axd'], - aliases: ['aspx', 'aspx-vb'] - }, - AspectJ: { - type: 'programming', - extensions: ['.aj'] - }, - Assembly: { - type: 'programming', - extensions: ['.asm', '.a51', '.i', '.inc', '.nas', '.nasm', '.s'], - aliases: ['asm', 'nasm'] - }, - Astro: { - type: 'markup', - extensions: ['.astro'] - }, - Asymptote: { - type: 'programming', - extensions: ['.asy'] - }, - ATS: { - type: 'programming', - extensions: ['.dats', '.hats', '.sats'], - aliases: ['ats2'] - }, - Augeas: { - type: 'programming', - extensions: ['.aug'] - }, - AutoHotkey: { - type: 'programming', - extensions: ['.ahk', '.ahkl'], - aliases: ['ahk'] - }, - AutoIt: { - type: 'programming', - extensions: ['.au3'], - aliases: ['au3', 'AutoIt3', 'AutoItScript'] - }, - 'Avro IDL': { - type: 'data', - extensions: ['.avdl'] - }, - Awk: { - type: 'programming', - extensions: ['.awk', '.auk', '.gawk', '.mawk', '.nawk'] - }, - B4X: { - type: 'programming', - extensions: ['.bas'], - aliases: ['basic for android'] - }, - Ballerina: { - type: 'programming', - extensions: ['.bal'] - }, - BASIC: { - type: 'programming', - extensions: ['.bas'] - }, - Batchfile: { - type: 'programming', - extensions: ['.bat', '.cmd'], - aliases: ['bat', 'batch', 'dosbatch', 'winbatch'] - }, - Beef: { - type: 'programming', - extensions: ['.bf'] - }, - Befunge: { - type: 'programming', - extensions: ['.befunge', '.bf'] - }, - Berry: { - type: 'programming', - extensions: ['.be'], - aliases: ['be'] - }, - BibTeX: { - type: 'markup', - extensions: ['.bib', '.bibtex'] - }, - 'BibTeX Style': { - type: 'programming', - extensions: ['.bst'] - }, - Bicep: { - type: 'programming', - extensions: ['.bicep', '.bicepparam'] - }, - Bikeshed: { - type: 'markup', - extensions: ['.bs'] - }, - Bison: { - type: 'programming', - extensions: ['.bison'] - }, - BitBake: { - type: 'programming', - extensions: ['.bb', '.bbappend', '.bbclass', '.inc'] - }, - Blade: { - type: 'markup', - extensions: ['.blade', '.blade.php'] - }, - BlitzBasic: { - type: 'programming', - extensions: ['.bb', '.decls'], - aliases: ['b3d', 'blitz3d', 'blitzplus', 'bplus'] - }, - BlitzMax: { - type: 'programming', - extensions: ['.bmx'], - aliases: ['bmax'] - }, - Bluespec: { - type: 'programming', - extensions: ['.bsv'], - aliases: ['bluespec bsv', 'bsv'] - }, - 'Bluespec BH': { - type: 'programming', - extensions: ['.bs'], - aliases: ['bh', 'bluespec classic'] - }, - Boo: { - type: 'programming', - extensions: ['.boo'] - }, - Boogie: { - type: 'programming', - extensions: ['.bpl'] - }, - BQN: { - type: 'programming', - extensions: ['.bqn'] - }, - Brainfuck: { - type: 'programming', - extensions: ['.b', '.bf'] - }, - BrighterScript: { - type: 'programming', - extensions: ['.bs'] - }, - Brightscript: { - type: 'programming', - extensions: ['.brs'] - }, - BuildStream: { - type: 'data', - extensions: ['.bst'] - }, - C: { - type: 'programming', - extensions: ['.c', '.cats', '.h', '.h.in', '.idc'] - }, - 'C-ObjDump': { - type: 'data', - extensions: ['.c-objdump'] - }, - 'C#': { - type: 'programming', - extensions: ['.cs', '.cake', '.cs.pp', '.csx', '.linq'], - aliases: ['csharp', 'cake', 'cakescript'] - }, - 'C++': { - type: 'programming', - extensions: [ - '.cpp', - '.c++', - '.cc', - '.cp', - '.cppm', - '.cxx', - '.h', - '.h++', - '.hh', - '.hpp', - '.hxx', - '.inc', - '.inl', - '.ino', - '.ipp', - '.ixx', - '.re', - '.tcc', - '.tpp', - '.txx' - ], - aliases: ['cpp'] - }, - 'C2hs Haskell': { - type: 'programming', - extensions: ['.chs'], - aliases: ['c2hs'] - }, - C3: { - type: 'programming', - extensions: ['.c3'] - }, - 'Cabal Config': { - type: 'data', - extensions: ['.cabal'], - aliases: ['Cabal'] - }, - Caddyfile: { - type: 'data', - extensions: ['.caddyfile'], - aliases: ['Caddy'] - }, - Cadence: { - type: 'programming', - extensions: ['.cdc'] - }, - Cairo: { - type: 'programming', - extensions: ['.cairo'] - }, - 'Cairo Zero': { - type: 'programming', - extensions: ['.cairo'] - }, - CameLIGO: { - type: 'programming', - extensions: ['.mligo'] - }, - 'CAP CDS': { - type: 'programming', - extensions: ['.cds'], - aliases: ['cds'] - }, - "Cap'n Proto": { - type: 'programming', - extensions: ['.capnp'] - }, - Carbon: { - type: 'programming', - extensions: ['.carbon'] - }, - CartoCSS: { - type: 'programming', - extensions: ['.mss'], - aliases: ['Carto'] - }, - Ceylon: { - type: 'programming', - extensions: ['.ceylon'] - }, - Chapel: { - type: 'programming', - extensions: ['.chpl'], - aliases: ['chpl'] - }, - Charity: { - type: 'programming', - extensions: ['.ch'] - }, - Checksums: { - type: 'data', - extensions: [ - '.crc32', - '.md2', - '.md4', - '.md5', - '.sha1', - '.sha2', - '.sha224', - '.sha256', - '.sha256sum', - '.sha3', - '.sha384', - '.sha512' - ], - aliases: ['checksum', 'hash', 'hashes', 'sum', 'sums'] - }, - ChucK: { - type: 'programming', - extensions: ['.ck'] - }, - CIL: { - type: 'data', - extensions: ['.cil'] - }, - Circom: { - type: 'programming', - extensions: ['.circom'] - }, - Cirru: { - type: 'programming', - extensions: ['.cirru'] - }, - Clarion: { - type: 'programming', - extensions: ['.clw'] - }, - Clarity: { - type: 'programming', - extensions: ['.clar'] - }, - 'Classic ASP': { - type: 'programming', - extensions: ['.asp'], - aliases: ['asp'] - }, - Clean: { - type: 'programming', - extensions: ['.icl', '.dcl'] - }, - Click: { - type: 'programming', - extensions: ['.click'] - }, - CLIPS: { - type: 'programming', - extensions: ['.clp'] - }, - Clojure: { - type: 'programming', - extensions: ['.clj', '.bb', '.boot', '.cl2', '.cljc', '.cljs', '.cljs.hl', '.cljscm', '.cljx', '.hic'] - }, - 'Closure Templates': { - type: 'markup', - extensions: ['.soy'], - aliases: ['soy'] - }, - Clue: { - type: 'programming', - extensions: ['.clue'] - }, - CMake: { - type: 'programming', - extensions: ['.cmake', '.cmake.in'] - }, - COBOL: { - type: 'programming', - extensions: ['.cob', '.cbl', '.ccp', '.cobol', '.cpy'] - }, - CodeQL: { - type: 'programming', - extensions: ['.ql', '.qll'], - aliases: ['ql'] - }, - CoffeeScript: { - type: 'programming', - extensions: ['.coffee', '._coffee', '.cake', '.cjsx', '.iced'], - aliases: ['coffee', 'coffee-script'] - }, - ColdFusion: { - type: 'programming', - extensions: ['.cfm', '.cfml'], - aliases: ['cfm', 'cfml', 'coldfusion html'] - }, - 'ColdFusion CFC': { - type: 'programming', - extensions: ['.cfc'], - aliases: ['cfc'] - }, - COLLADA: { - type: 'data', - extensions: ['.dae'] - }, - 'Common Lisp': { - type: 'programming', - extensions: ['.lisp', '.asd', '.cl', '.l', '.lsp', '.ny', '.podsl', '.sexp'], - aliases: ['lisp'] - }, - 'Common Workflow Language': { - type: 'programming', - extensions: ['.cwl'], - aliases: ['cwl'] - }, - 'Component Pascal': { - type: 'programming', - extensions: ['.cp', '.cps'] - }, - 'CoNLL-U': { - type: 'data', - extensions: ['.conllu', '.conll'], - aliases: ['CoNLL', 'CoNLL-X'] - }, - Cooklang: { - type: 'markup', - extensions: ['.cook'] - }, - Cool: { - type: 'programming', - extensions: ['.cl'] - }, - 'Cpp-ObjDump': { - type: 'data', - extensions: ['.cppobjdump', '.c++-objdump', '.c++objdump', '.cpp-objdump', '.cxx-objdump'], - aliases: ['c++-objdump'] - }, - Creole: { - type: 'prose', - extensions: ['.creole'] - }, - crontab: { - type: 'data', - aliases: ['cron', 'cron table'] - }, - Crystal: { - type: 'programming', - extensions: ['.cr'] - }, - CSON: { - type: 'data', - extensions: ['.cson'] - }, - Csound: { - type: 'programming', - extensions: ['.orc', '.udo'], - aliases: ['csound-orc'] - }, - 'Csound Document': { - type: 'programming', - extensions: ['.csd'], - aliases: ['csound-csd'] - }, - 'Csound Score': { - type: 'programming', - extensions: ['.sco'], - aliases: ['csound-sco'] - }, - CSS: { - type: 'markup', - extensions: ['.css'] - }, - CSV: { - type: 'data', - extensions: ['.csv'] - }, - Cuda: { - type: 'programming', - extensions: ['.cu', '.cuh'] - }, - CUE: { - type: 'programming', - extensions: ['.cue'] - }, - 'Cue Sheet': { - type: 'data', - extensions: ['.cue'] - }, - 'cURL Config': { - type: 'data', - aliases: ['curlrc'] - }, - Curry: { - type: 'programming', - extensions: ['.curry'] - }, - CWeb: { - type: 'programming', - extensions: ['.w'] - }, - Cycript: { - type: 'programming', - extensions: ['.cy'] - }, - Cylc: { - type: 'data', - extensions: ['.cylc'] - }, - Cypher: { - type: 'programming', - extensions: ['.cyp', '.cypher'] - }, - Cython: { - type: 'programming', - extensions: ['.pyx', '.pxd', '.pxi'], - aliases: ['pyrex'] - }, - D: { - type: 'programming', - extensions: ['.d', '.di'], - aliases: ['Dlang'] - }, - 'D-ObjDump': { - type: 'data', - extensions: ['.d-objdump'] - }, - D2: { - type: 'markup', - extensions: ['.d2'], - aliases: ['d2lang'] - }, - Dafny: { - type: 'programming', - extensions: ['.dfy'] - }, - 'Darcs Patch': { - type: 'data', - extensions: ['.darcspatch', '.dpatch'], - aliases: ['dpatch'] - }, - Dart: { - type: 'programming', - extensions: ['.dart'] - }, - Daslang: { - type: 'programming', - extensions: ['.das'] - }, - DataWeave: { - type: 'programming', - extensions: ['.dwl'] - }, - 'Debian Package Control File': { - type: 'data', - extensions: ['.dsc'] - }, - DenizenScript: { - type: 'programming', - extensions: ['.dsc'] - }, - desktop: { - type: 'data', - extensions: ['.desktop', '.desktop.in', '.service'] - }, - Dhall: { - type: 'programming', - extensions: ['.dhall'] - }, - Diff: { - type: 'data', - extensions: ['.diff', '.patch'], - aliases: ['udiff'] - }, - 'DIGITAL Command Language': { - type: 'programming', - extensions: ['.com'], - aliases: ['dcl'] - }, - dircolors: { - type: 'data', - extensions: ['.dircolors'] - }, - 'DirectX 3D File': { - type: 'data', - extensions: ['.x'] - }, - DM: { - type: 'programming', - extensions: ['.dm'], - aliases: ['byond'] - }, - 'DNS Zone': { - type: 'data', - extensions: ['.zone', '.arpa'] - }, - Dockerfile: { - type: 'programming', - extensions: ['.dockerfile', '.containerfile'], - aliases: ['Containerfile'] - }, - Dogescript: { - type: 'programming', - extensions: ['.djs'] - }, - Dotenv: { - type: 'data', - extensions: ['.env'] - }, - DTrace: { - type: 'programming', - extensions: ['.d'], - aliases: ['dtrace-script'] - }, - Dylan: { - type: 'programming', - extensions: ['.dylan', '.dyl', '.intr', '.lid'] - }, - E: { - type: 'programming', - extensions: ['.e'] - }, - 'E-mail': { - type: 'data', - extensions: ['.eml', '.mbox'], - aliases: ['email', 'eml', 'mail', 'mbox'] - }, - Eagle: { - type: 'data', - extensions: ['.sch', '.brd'] - }, - Earthly: { - type: 'programming', - aliases: ['Earthfile'] - }, - Easybuild: { - type: 'data', - extensions: ['.eb'] - }, - EBNF: { - type: 'data', - extensions: ['.ebnf'] - }, - eC: { - type: 'programming', - extensions: ['.ec', '.eh'] - }, - 'Ecere Projects': { - type: 'data', - extensions: ['.epj'] - }, - ECL: { - type: 'programming', - extensions: ['.ecl', '.eclxml'] - }, - ECLiPSe: { - type: 'programming', - extensions: ['.ecl'] - }, - Ecmarkup: { - type: 'markup', - extensions: ['.html'], - aliases: ['ecmarkdown'] - }, - Edge: { - type: 'markup', - extensions: ['.edge'] - }, - EdgeQL: { - type: 'programming', - extensions: ['.edgeql', '.esdl'], - aliases: ['esdl'] - }, - EditorConfig: { - type: 'data', - extensions: ['.editorconfig'], - aliases: ['editor-config'] - }, - 'Edje Data Collection': { - type: 'data', - extensions: ['.edc'] - }, - edn: { - type: 'data', - extensions: ['.edn'] - }, - Eiffel: { - type: 'programming', - extensions: ['.e'] - }, - EJS: { - type: 'markup', - extensions: ['.ejs', '.ect', '.ejs.t', '.jst'] - }, - Elixir: { - type: 'programming', - extensions: ['.ex', '.exs'] - }, - Elm: { - type: 'programming', - extensions: ['.elm'] - }, - Elvish: { - type: 'programming', - extensions: ['.elv'] - }, - 'Emacs Lisp': { - type: 'programming', - extensions: ['.el', '.emacs', '.emacs.desktop'], - aliases: ['elisp', 'emacs'] - }, - EmberScript: { - type: 'programming', - extensions: ['.em', '.emberscript'] - }, - EQ: { - type: 'programming', - extensions: ['.eq'] - }, - Erlang: { - type: 'programming', - extensions: ['.erl', '.app', '.app.src', '.es', '.escript', '.hrl', '.xrl', '.yrl'] - }, - Euphoria: { - type: 'programming', - extensions: ['.e', '.ex'] - }, - 'F*': { - type: 'programming', - extensions: ['.fst', '.fsti'], - aliases: ['fstar'] - }, - 'F#': { - type: 'programming', - extensions: ['.fs', '.fsi', '.fsx'], - aliases: ['fsharp'] - }, - Factor: { - type: 'programming', - extensions: ['.factor'] - }, - Fancy: { - type: 'programming', - extensions: ['.fy', '.fancypack'] - }, - Fantom: { - type: 'programming', - extensions: ['.fan'] - }, - Faust: { - type: 'programming', - extensions: ['.dsp'] - }, - Fennel: { - type: 'programming', - extensions: ['.fnl'] - }, - 'FIGlet Font': { - type: 'data', - extensions: ['.flf'], - aliases: ['FIGfont'] - }, - 'Filebench WML': { - type: 'programming', - extensions: ['.f'] - }, - Filterscript: { - type: 'programming', - extensions: ['.fs'] - }, - FIRRTL: { - type: 'programming', - extensions: ['.fir'] - }, - fish: { - type: 'programming', - extensions: ['.fish'] - }, - Fluent: { - type: 'programming', - extensions: ['.ftl'] - }, - FLUX: { - type: 'programming', - extensions: ['.fx', '.flux'] - }, - Formatted: { - type: 'data', - extensions: ['.for', '.eam.fs'] - }, - Forth: { - type: 'programming', - extensions: ['.fth', '.4th', '.f', '.for', '.forth', '.fr', '.frt', '.fs'] - }, - Fortran: { - type: 'programming', - extensions: ['.f', '.f77', '.for', '.fpp'] - }, - 'Fortran Free Form': { - type: 'programming', - extensions: ['.f90', '.f03', '.f08', '.f95'] - }, - FreeBASIC: { - type: 'programming', - extensions: ['.bi', '.bas'], - aliases: ['fb'] - }, - FreeMarker: { - type: 'programming', - extensions: ['.ftl', '.ftlh'], - aliases: ['ftl'] - }, - Frege: { - type: 'programming', - extensions: ['.fr'] - }, - Futhark: { - type: 'programming', - extensions: ['.fut'] - }, - 'G-code': { - type: 'programming', - extensions: ['.g', '.cnc', '.gco', '.gcode'] - }, - 'Game Maker Language': { - type: 'programming', - extensions: ['.gml'] - }, - GAML: { - type: 'programming', - extensions: ['.gaml'] - }, - GAMS: { - type: 'programming', - extensions: ['.gms'] - }, - GAP: { - type: 'programming', - extensions: ['.g', '.gap', '.gd', '.gi', '.tst'] - }, - 'GCC Machine Description': { - type: 'programming', - extensions: ['.md'] - }, - GDB: { - type: 'programming', - extensions: ['.gdb', '.gdbinit'] - }, - GDScript: { - type: 'programming', - extensions: ['.gd'] - }, - GDShader: { - type: 'programming', - extensions: ['.gdshader', '.gdshaderinc'] - }, - GEDCOM: { - type: 'data', - extensions: ['.ged'] - }, - Gemini: { - type: 'prose', - extensions: ['.gmi'], - aliases: ['gemtext'] - }, - 'Genero 4gl': { - type: 'programming', - extensions: ['.4gl'] - }, - 'Genero per': { - type: 'markup', - extensions: ['.per'] - }, - Genie: { - type: 'programming', - extensions: ['.gs'] - }, - Genshi: { - type: 'programming', - extensions: ['.kid'], - aliases: ['xml+genshi', 'xml+kid'] - }, - 'Gentoo Ebuild': { - type: 'programming', - extensions: ['.ebuild'] - }, - 'Gentoo Eclass': { - type: 'programming', - extensions: ['.eclass'] - }, - 'Gerber Image': { - type: 'data', - extensions: [ - '.gbr', - '.cmp', - '.gbl', - '.gbo', - '.gbp', - '.gbs', - '.gko', - '.gml', - '.gpb', - '.gpt', - '.gtl', - '.gto', - '.gtp', - '.gts', - '.ncl', - '.sol' - ], - aliases: ['rs-274x'] - }, - 'Gettext Catalog': { - type: 'prose', - extensions: ['.po', '.pot'], - aliases: ['pot'] - }, - Gherkin: { - type: 'programming', - extensions: ['.feature', '.story'], - aliases: ['cucumber'] - }, - 'Git Attributes': { - type: 'data', - aliases: ['gitattributes'] - }, - 'Git Config': { - type: 'data', - extensions: ['.gitconfig'], - aliases: ['gitconfig', 'gitmodules'] - }, - 'Git Revision List': { - type: 'data', - aliases: ['Git Blame Ignore Revs'] - }, - Gleam: { - type: 'programming', - extensions: ['.gleam'] - }, - 'Glimmer JS': { - type: 'programming', - extensions: ['.gjs'] - }, - 'Glimmer TS': { - type: 'programming', - extensions: ['.gts'] - }, - GLSL: { - type: 'programming', - extensions: [ - '.glsl', - '.fp', - '.frag', - '.frg', - '.fs', - '.fsh', - '.fshader', - '.geo', - '.geom', - '.glslf', - '.glslv', - '.gs', - '.gshader', - '.rchit', - '.rmiss', - '.shader', - '.tesc', - '.tese', - '.vert', - '.vrx', - '.vs', - '.vsh', - '.vshader' - ] - }, - Glyph: { - type: 'programming', - extensions: ['.glf'] - }, - 'Glyph Bitmap Distribution Format': { - type: 'data', - extensions: ['.bdf'] - }, - GN: { - type: 'data', - extensions: ['.gn', '.gni'] - }, - Gnuplot: { - type: 'programming', - extensions: ['.gp', '.gnu', '.gnuplot', '.p', '.plot', '.plt'] - }, - Go: { - type: 'programming', - extensions: ['.go'], - aliases: ['golang'] - }, - 'Go Checksums': { - type: 'data', - aliases: ['go.sum', 'go sum', 'go.work.sum', 'go work sum'] - }, - 'Go Module': { - type: 'data', - aliases: ['go.mod', 'go mod'] - }, - 'Go Workspace': { - type: 'data', - aliases: ['go.work', 'go work'] - }, - 'Godot Resource': { - type: 'data', - extensions: ['.gdnlib', '.gdns', '.tres', '.tscn'] - }, - Golo: { - type: 'programming', - extensions: ['.golo'] - }, - Gosu: { - type: 'programming', - extensions: ['.gs', '.gst', '.gsx', '.vark'] - }, - Grace: { - type: 'programming', - extensions: ['.grace'] - }, - Gradle: { - type: 'data', - extensions: ['.gradle'] - }, - 'Gradle Kotlin DSL': { - type: 'data', - extensions: ['.gradle.kts'] - }, - 'Grammatical Framework': { - type: 'programming', - extensions: ['.gf'], - aliases: ['gf'] - }, - 'Graph Modeling Language': { - type: 'data', - extensions: ['.gml'] - }, - GraphQL: { - type: 'data', - extensions: ['.graphql', '.gql', '.graphqls'] - }, - 'Graphviz (DOT)': { - type: 'data', - extensions: ['.dot', '.gv'] - }, - Groovy: { - type: 'programming', - extensions: ['.groovy', '.grt', '.gtpl', '.gvy'] - }, - 'Groovy Server Pages': { - type: 'programming', - extensions: ['.gsp'], - aliases: ['gsp', 'java server page'] - }, - GSC: { - type: 'programming', - extensions: ['.gsc', '.csc', '.gsh'] - }, - Hack: { - type: 'programming', - extensions: ['.hack', '.hh', '.hhi', '.php'] - }, - Haml: { - type: 'markup', - extensions: ['.haml', '.haml.deface'] - }, - Handlebars: { - type: 'markup', - extensions: ['.handlebars', '.hbs'], - aliases: ['hbs', 'htmlbars'] - }, - HAProxy: { - type: 'data', - extensions: ['.cfg'] - }, - Harbour: { - type: 'programming', - extensions: ['.hb'] - }, - Hare: { - type: 'programming', - extensions: ['.ha'] - }, - Haskell: { - type: 'programming', - extensions: ['.hs', '.hs-boot', '.hsc'] - }, - Haxe: { - type: 'programming', - extensions: ['.hx', '.hxsl'] - }, - HCL: { - type: 'programming', - extensions: ['.hcl', '.nomad', '.tf', '.tfvars', '.workflow'], - aliases: ['HashiCorp Configuration Language', 'terraform'] - }, - HIP: { - type: 'programming', - extensions: ['.hip'] - }, - HiveQL: { - type: 'programming', - extensions: ['.q', '.hql'] - }, - HLSL: { - type: 'programming', - extensions: ['.hlsl', '.cginc', '.fx', '.fxh', '.hlsli'] - }, - HOCON: { - type: 'data', - extensions: ['.hocon'] - }, - HolyC: { - type: 'programming', - extensions: ['.hc'] - }, - hoon: { - type: 'programming', - extensions: ['.hoon'] - }, - 'Hosts File': { - type: 'data', - aliases: ['hosts'] - }, - HTML: { - type: 'markup', - extensions: ['.html', '.hta', '.htm', '.html.hl', '.inc', '.xht', '.xhtml'], - aliases: ['xhtml'] - }, - 'HTML+ECR': { - type: 'markup', - extensions: ['.ecr'], - aliases: ['ecr'] - }, - 'HTML+EEX': { - type: 'markup', - extensions: ['.html.eex', '.heex', '.leex'], - aliases: ['eex', 'heex', 'leex'] - }, - 'HTML+ERB': { - type: 'markup', - extensions: ['.erb', '.erb.deface', '.rhtml'], - aliases: ['erb', 'rhtml', 'html+ruby'] - }, - 'HTML+PHP': { - type: 'markup', - extensions: ['.phtml'] - }, - 'HTML+Razor': { - type: 'markup', - extensions: ['.cshtml', '.razor'], - aliases: ['razor'] - }, - HTTP: { - type: 'data', - extensions: ['.http'] - }, - HXML: { - type: 'data', - extensions: ['.hxml'] - }, - Hy: { - type: 'programming', - extensions: ['.hy'], - aliases: ['hylang'] - }, - HyPhy: { - type: 'programming', - extensions: ['.bf'] - }, - iCalendar: { - type: 'data', - extensions: ['.ics', '.ical'], - aliases: ['iCal'] - }, - IDL: { - type: 'programming', - extensions: ['.pro', '.dlm'] - }, - Idris: { - type: 'programming', - extensions: ['.idr', '.lidr'] - }, - 'Ignore List': { - type: 'data', - extensions: ['.gitignore'], - aliases: ['ignore', 'gitignore', 'git-ignore'] - }, - 'IGOR Pro': { - type: 'programming', - extensions: ['.ipf'], - aliases: ['igor', 'igorpro'] - }, - 'ImageJ Macro': { - type: 'programming', - extensions: ['.ijm'], - aliases: ['ijm'] - }, - Imba: { - type: 'programming', - extensions: ['.imba'] - }, - 'Inform 7': { - type: 'programming', - extensions: ['.ni', '.i7x'], - aliases: ['i7', 'inform7'] - }, - INI: { - type: 'data', - extensions: ['.ini', '.cfg', '.cnf', '.dof', '.frm', '.lektorproject', '.prefs', '.pro', '.properties', '.url'], - aliases: ['dosini'] - }, - Ink: { - type: 'programming', - extensions: ['.ink'] - }, - 'Inno Setup': { - type: 'programming', - extensions: ['.iss', '.isl'] - }, - Io: { - type: 'programming', - extensions: ['.io'] - }, - Ioke: { - type: 'programming', - extensions: ['.ik'] - }, - 'IRC log': { - type: 'data', - extensions: ['.irclog', '.weechatlog'], - aliases: ['irc', 'irc logs'] - }, - Isabelle: { - type: 'programming', - extensions: ['.thy'] - }, - ISPC: { - type: 'programming', - extensions: ['.ispc'] - }, - J: { - type: 'programming', - extensions: ['.ijs'] - }, - Jai: { - type: 'programming', - extensions: ['.jai'] - }, - Janet: { - type: 'programming', - extensions: ['.janet'] - }, - Jasmin: { - type: 'programming', - extensions: ['.j'] - }, - Java: { - type: 'programming', - extensions: ['.java', '.jav', '.jsh'] - }, - 'Java Properties': { - type: 'data', - extensions: ['.properties'] - }, - 'Java Server Pages': { - type: 'programming', - extensions: ['.jsp', '.tag'], - aliases: ['jsp'] - }, - 'Java Template Engine': { - type: 'programming', - extensions: ['.jte'], - aliases: ['jte'] - }, - JavaScript: { - type: 'programming', - extensions: [ - '.js', - '._js', - '.bones', - '.cjs', - '.es', - '.es6', - '.frag', - '.gs', - '.jake', - '.javascript', - '.jsb', - '.jscad', - '.jsfl', - '.jslib', - '.jsm', - '.jspre', - '.jss', - '.jsx', - '.mjs', - '.njs', - '.pac', - '.sjs', - '.ssjs', - '.xsjs', - '.xsjslib' - ], - aliases: ['js', 'node'] - }, - 'JavaScript+ERB': { - type: 'programming', - extensions: ['.js.erb'] - }, - JCL: { - type: 'programming', - extensions: ['.jcl'] - }, - 'Jest Snapshot': { - type: 'data', - extensions: ['.snap'] - }, - 'JetBrains MPS': { - type: 'programming', - extensions: ['.mps', '.mpl', '.msd'], - aliases: ['mps'] - }, - JFlex: { - type: 'programming', - extensions: ['.flex', '.jflex'] - }, - Jinja: { - type: 'markup', - extensions: ['.jinja', '.j2', '.jinja2'], - aliases: ['django', 'html+django', 'html+jinja', 'htmldjango'] - }, - Jison: { - type: 'programming', - extensions: ['.jison'] - }, - 'Jison Lex': { - type: 'programming', - extensions: ['.jisonlex'] - }, - Jolie: { - type: 'programming', - extensions: ['.ol', '.iol'] - }, - jq: { - type: 'programming', - extensions: ['.jq'] - }, - JSON: { - type: 'data', - extensions: [ - '.json', - '.4DForm', - '.4DProject', - '.avsc', - '.geojson', - '.gltf', - '.har', - '.ice', - '.JSON-tmLanguage', - '.json.example', - '.jsonl', - '.mcmeta', - '.sarif', - '.tact', - '.tfstate', - '.tfstate.backup', - '.topojson', - '.webapp', - '.webmanifest', - '.yy', - '.yyp' - ], - aliases: ['geojson', 'jsonl', 'sarif', 'topojson'] - }, - 'JSON with Comments': { - type: 'data', - extensions: [ - '.jsonc', - '.code-snippets', - '.code-workspace', - '.sublime-build', - '.sublime-color-scheme', - '.sublime-commands', - '.sublime-completions', - '.sublime-keymap', - '.sublime-macro', - '.sublime-menu', - '.sublime-mousemap', - '.sublime-project', - '.sublime-settings', - '.sublime-theme', - '.sublime-workspace', - '.sublime_metrics', - '.sublime_session' - ], - aliases: ['jsonc'] - }, - JSON5: { - type: 'data', - extensions: ['.json5'] - }, - JSONiq: { - type: 'programming', - extensions: ['.jq'] - }, - JSONLD: { - type: 'data', - extensions: ['.jsonld'] - }, - Jsonnet: { - type: 'programming', - extensions: ['.jsonnet', '.libsonnet'] - }, - Julia: { - type: 'programming', - extensions: ['.jl'] - }, - 'Jupyter Notebook': { - type: 'markup', - extensions: ['.ipynb'], - aliases: ['IPython Notebook'] - }, - Just: { - type: 'programming', - extensions: ['.just'], - aliases: ['Justfile'] - }, - 'Kaitai Struct': { - type: 'programming', - extensions: ['.ksy'], - aliases: ['ksy'] - }, - KakouneScript: { - type: 'programming', - extensions: ['.kak'], - aliases: ['kak', 'kakscript'] - }, - KDL: { - type: 'data', - extensions: ['.kdl'] - }, - KerboScript: { - type: 'programming', - extensions: ['.ks'] - }, - 'KiCad Layout': { - type: 'data', - extensions: ['.kicad_pcb', '.kicad_mod', '.kicad_wks'], - aliases: ['pcbnew'] - }, - 'KiCad Legacy Layout': { - type: 'data', - extensions: ['.brd'] - }, - 'KiCad Schematic': { - type: 'data', - extensions: ['.kicad_sch', '.kicad_sym', '.sch'], - aliases: ['eeschema schematic'] - }, - Kickstart: { - type: 'data', - extensions: ['.ks'] - }, - Kit: { - type: 'markup', - extensions: ['.kit'] - }, - Koka: { - type: 'programming', - extensions: ['.kk'] - }, - Kotlin: { - type: 'programming', - extensions: ['.kt', '.ktm', '.kts'] - }, - KRL: { - type: 'programming', - extensions: ['.krl'] - }, - Kusto: { - type: 'data', - extensions: ['.csl', '.kql'] - }, - kvlang: { - type: 'markup', - extensions: ['.kv'] - }, - LabVIEW: { - type: 'programming', - extensions: ['.lvproj', '.lvclass', '.lvlib'] - }, - Lark: { - type: 'data', - extensions: ['.lark'] - }, - Lasso: { - type: 'programming', - extensions: ['.lasso', '.las', '.lasso8', '.lasso9'], - aliases: ['lassoscript'] - }, - Latte: { - type: 'markup', - extensions: ['.latte'] - }, - Lean: { - type: 'programming', - extensions: ['.lean', '.hlean'] - }, - 'Lean 4': { - type: 'programming', - extensions: ['.lean'] - }, - Leo: { - type: 'programming', - extensions: ['.leo'] - }, - Less: { - type: 'markup', - extensions: ['.less'], - aliases: ['less-css'] - }, - Lex: { - type: 'programming', - extensions: ['.l', '.lex'], - aliases: ['flex'] - }, - LFE: { - type: 'programming', - extensions: ['.lfe'] - }, - LigoLANG: { - type: 'programming', - extensions: ['.ligo'] - }, - LilyPond: { - type: 'programming', - extensions: ['.ly', '.ily'] - }, - Limbo: { - type: 'programming', - extensions: ['.b', '.m'] - }, - 'Linear Programming': { - type: 'programming', - extensions: ['.lp'] - }, - 'Linker Script': { - type: 'programming', - extensions: ['.ld', '.lds', '.x'] - }, - 'Linux Kernel Module': { - type: 'data', - extensions: ['.mod'] - }, - Liquid: { - type: 'markup', - extensions: ['.liquid'] - }, - 'Literate Agda': { - type: 'programming', - extensions: ['.lagda'] - }, - 'Literate CoffeeScript': { - type: 'programming', - extensions: ['.litcoffee', '.coffee.md'], - aliases: ['litcoffee'] - }, - 'Literate Haskell': { - type: 'programming', - extensions: ['.lhs'], - aliases: ['lhaskell', 'lhs'] - }, - 'LiveCode Script': { - type: 'programming', - extensions: ['.livecodescript'] - }, - LiveScript: { - type: 'programming', - extensions: ['.ls', '._ls'], - aliases: ['live-script', 'ls'] - }, - LLVM: { - type: 'programming', - extensions: ['.ll'] - }, - Logos: { - type: 'programming', - extensions: ['.xm', '.x', '.xi'] - }, - Logtalk: { - type: 'programming', - extensions: ['.lgt', '.logtalk'] - }, - LOLCODE: { - type: 'programming', - extensions: ['.lol'] - }, - LookML: { - type: 'programming', - extensions: ['.lkml', '.lookml'] - }, - LoomScript: { - type: 'programming', - extensions: ['.ls'] - }, - LSL: { - type: 'programming', - extensions: ['.lsl', '.lslp'] - }, - 'LTspice Symbol': { - type: 'data', - extensions: ['.asy'] - }, - Lua: { - type: 'programming', - extensions: ['.lua', '.fcgi', '.nse', '.p8', '.pd_lua', '.rbxs', '.rockspec', '.wlua'] - }, - Luau: { - type: 'programming', - extensions: ['.luau'] - }, - M: { - type: 'programming', - extensions: ['.mumps', '.m'], - aliases: ['mumps'] - }, - M3U: { - type: 'data', - extensions: ['.m3u', '.m3u8'], - aliases: ['hls playlist', 'm3u playlist'] - }, - M4: { - type: 'programming', - extensions: ['.m4', '.mc'] - }, - M4Sugar: { - type: 'programming', - extensions: ['.m4'], - aliases: ['autoconf'] - }, - Macaulay2: { - type: 'programming', - extensions: ['.m2'], - aliases: ['m2'] - }, - Makefile: { - type: 'programming', - extensions: ['.mak', '.d', '.make', '.makefile', '.mk', '.mkfile'], - aliases: ['bsdmake', 'make', 'mf'] - }, - Mako: { - type: 'programming', - extensions: ['.mako', '.mao'] - }, - Markdown: { - type: 'prose', - extensions: [ - '.md', - '.livemd', - '.markdown', - '.mdown', - '.mdwn', - '.mkd', - '.mkdn', - '.mkdown', - '.ronn', - '.scd', - '.workbook' - ], - aliases: ['md', 'pandoc'] - }, - Marko: { - type: 'markup', - extensions: ['.marko'], - aliases: ['markojs'] - }, - Mask: { - type: 'markup', - extensions: ['.mask'] - }, - Mathematica: { - type: 'programming', - extensions: ['.mathematica', '.cdf', '.m', '.ma', '.mt', '.nb', '.nbp', '.wl', '.wlt'], - aliases: ['mma', 'wolfram', 'wolfram language', 'wolfram lang', 'wl'] - }, - MATLAB: { - type: 'programming', - extensions: ['.matlab', '.m'], - aliases: ['octave'] - }, - Max: { - type: 'programming', - extensions: ['.maxpat', '.maxhelp', '.maxproj', '.mxt', '.pat'], - aliases: ['max/msp', 'maxmsp'] - }, - MAXScript: { - type: 'programming', - extensions: ['.ms', '.mcr'] - }, - mcfunction: { - type: 'programming', - extensions: ['.mcfunction'] - }, - mdsvex: { - type: 'markup', - extensions: ['.svx'] - }, - MDX: { - type: 'markup', - extensions: ['.mdx'] - }, - Mercury: { - type: 'programming', - extensions: ['.m', '.moo'] - }, - Mermaid: { - type: 'markup', - extensions: ['.mmd', '.mermaid'], - aliases: ['mermaid example'] - }, - Metal: { - type: 'programming', - extensions: ['.metal'] - }, - 'Microsoft Developer Studio Project': { - type: 'data', - extensions: ['.dsp'] - }, - 'Microsoft Visual Studio Solution': { - type: 'data', - extensions: ['.sln'] - }, - MiniD: { - type: 'programming', - extensions: ['.minid'] - }, - MiniYAML: { - type: 'data', - extensions: ['.yaml', '.yml'] - }, - MiniZinc: { - type: 'programming', - extensions: ['.mzn'] - }, - 'MiniZinc Data': { - type: 'data', - extensions: ['.dzn'] - }, - Mint: { - type: 'programming', - extensions: ['.mint'] - }, - Mirah: { - type: 'programming', - extensions: ['.druby', '.duby', '.mirah'] - }, - 'mIRC Script': { - type: 'programming', - extensions: ['.mrc'] - }, - MLIR: { - type: 'programming', - extensions: ['.mlir'] - }, - Modelica: { - type: 'programming', - extensions: ['.mo'] - }, - 'Modula-2': { - type: 'programming', - extensions: ['.mod'] - }, - 'Modula-3': { - type: 'programming', - extensions: ['.i3', '.ig', '.m3', '.mg'] - }, - 'Module Management System': { - type: 'programming', - extensions: ['.mms', '.mmk'] - }, - Mojo: { - type: 'programming', - extensions: ['.mojo'] - }, - Monkey: { - type: 'programming', - extensions: ['.monkey', '.monkey2'] - }, - 'Monkey C': { - type: 'programming', - extensions: ['.mc'] - }, - Moocode: { - type: 'programming', - extensions: ['.moo'] - }, - MoonBit: { - type: 'programming', - extensions: ['.mbt'] - }, - MoonScript: { - type: 'programming', - extensions: ['.moon'] - }, - Motoko: { - type: 'programming', - extensions: ['.mo'] - }, - 'Motorola 68K Assembly': { - type: 'programming', - extensions: ['.asm', '.i', '.inc', '.s', '.x68'], - aliases: ['m68k'] - }, - Move: { - type: 'programming', - extensions: ['.move'] - }, - MQL4: { - type: 'programming', - extensions: ['.mq4', '.mqh'] - }, - MQL5: { - type: 'programming', - extensions: ['.mq5', '.mqh'] - }, - MTML: { - type: 'markup', - extensions: ['.mtml'] - }, - MUF: { - type: 'programming', - extensions: ['.muf', '.m'] - }, - mupad: { - type: 'programming', - extensions: ['.mu'] - }, - Muse: { - type: 'prose', - extensions: ['.muse'], - aliases: ['amusewiki', 'emacs muse'] - }, - Mustache: { - type: 'markup', - extensions: ['.mustache'] - }, - Myghty: { - type: 'programming', - extensions: ['.myt'] - }, - nanorc: { - type: 'data', - extensions: ['.nanorc'] - }, - Nasal: { - type: 'programming', - extensions: ['.nas'] - }, - NASL: { - type: 'programming', - extensions: ['.nasl', '.inc'] - }, - NCL: { - type: 'programming', - extensions: ['.ncl'] - }, - Nearley: { - type: 'programming', - extensions: ['.ne', '.nearley'] - }, - Nemerle: { - type: 'programming', - extensions: ['.n'] - }, - NEON: { - type: 'data', - extensions: ['.neon'], - aliases: ['nette object notation', 'ne-on'] - }, - nesC: { - type: 'programming', - extensions: ['.nc'] - }, - NetLinx: { - type: 'programming', - extensions: ['.axs', '.axi'] - }, - 'NetLinx+ERB': { - type: 'programming', - extensions: ['.axs.erb', '.axi.erb'] - }, - NetLogo: { - type: 'programming', - extensions: ['.nlogo'] - }, - NewLisp: { - type: 'programming', - extensions: ['.nl', '.lisp', '.lsp'] - }, - Nextflow: { - type: 'programming', - extensions: ['.nf'] - }, - Nginx: { - type: 'data', - extensions: ['.nginx', '.nginxconf', '.vhost'], - aliases: ['nginx configuration file'] - }, - Nickel: { - type: 'programming', - extensions: ['.ncl'] - }, - Nim: { - type: 'programming', - extensions: ['.nim', '.nim.cfg', '.nimble', '.nimrod', '.nims'] - }, - Ninja: { - type: 'data', - extensions: ['.ninja'] - }, - Nit: { - type: 'programming', - extensions: ['.nit'] - }, - Nix: { - type: 'programming', - extensions: ['.nix'], - aliases: ['nixos'] - }, - NL: { - type: 'data', - extensions: ['.nl'] - }, - NMODL: { - type: 'programming', - extensions: ['.mod'] - }, - Noir: { - type: 'programming', - extensions: ['.nr'], - aliases: ['nargo'] - }, - 'NPM Config': { - type: 'data', - aliases: ['npmrc'] - }, - NSIS: { - type: 'programming', - extensions: ['.nsi', '.nsh'] - }, - Nu: { - type: 'programming', - extensions: ['.nu'], - aliases: ['nush'] - }, - NumPy: { - type: 'programming', - extensions: ['.numpy', '.numpyw', '.numsc'] - }, - Nunjucks: { - type: 'markup', - extensions: ['.njk'], - aliases: ['njk'] - }, - Nushell: { - type: 'programming', - extensions: ['.nu'], - aliases: ['nu-script', 'nushell-script'] - }, - NWScript: { - type: 'programming', - extensions: ['.nss'] - }, - 'OASv2-json': { - type: 'data', - extensions: ['.json'] - }, - 'OASv2-yaml': { - type: 'data', - extensions: ['.yaml', '.yml'] - }, - 'OASv3-json': { - type: 'data', - extensions: ['.json'] - }, - 'OASv3-yaml': { - type: 'data', - extensions: ['.yaml', '.yml'] - }, - Oberon: { - type: 'programming', - extensions: ['.ob2'] - }, - ObjDump: { - type: 'data', - extensions: ['.objdump'] - }, - 'Object Data Instance Notation': { - type: 'data', - extensions: ['.odin'] - }, - 'Objective-C': { - type: 'programming', - extensions: ['.m', '.h'], - aliases: ['obj-c', 'objc', 'objectivec'] - }, - 'Objective-C++': { - type: 'programming', - extensions: ['.mm'], - aliases: ['obj-c++', 'objc++', 'objectivec++'] - }, - 'Objective-J': { - type: 'programming', - extensions: ['.j', '.sj'], - aliases: ['obj-j', 'objectivej', 'objj'] - }, - ObjectScript: { - type: 'programming', - extensions: ['.cls'] - }, - OCaml: { - type: 'programming', - extensions: ['.ml', '.eliom', '.eliomi', '.ml4', '.mli', '.mll', '.mly'] - }, - Odin: { - type: 'programming', - extensions: ['.odin'], - aliases: ['odinlang', 'odin-lang'] - }, - Omgrofl: { - type: 'programming', - extensions: ['.omgrofl'] - }, - 'OMNeT++ MSG': { - type: 'programming', - extensions: ['.msg'], - aliases: ['omnetpp-msg'] - }, - 'OMNeT++ NED': { - type: 'programming', - extensions: ['.ned'], - aliases: ['omnetpp-ned'] - }, - ooc: { - type: 'programming', - extensions: ['.ooc'] - }, - Opa: { - type: 'programming', - extensions: ['.opa'] - }, - Opal: { - type: 'programming', - extensions: ['.opal'] - }, - 'Open Policy Agent': { - type: 'programming', - extensions: ['.rego'] - }, - 'OpenAPI Specification v2': { - type: 'data', - aliases: ['oasv2'] - }, - 'OpenAPI Specification v3': { - type: 'data', - aliases: ['oasv3'] - }, - OpenCL: { - type: 'programming', - extensions: ['.cl', '.opencl'] - }, - 'OpenEdge ABL': { - type: 'programming', - extensions: ['.p', '.cls', '.w'], - aliases: ['progress', 'openedge', 'abl'] - }, - OpenQASM: { - type: 'programming', - extensions: ['.qasm'] - }, - 'OpenRC runscript': { - type: 'programming', - aliases: ['openrc'] - }, - OpenSCAD: { - type: 'programming', - extensions: ['.scad'] - }, - 'OpenStep Property List': { - type: 'data', - extensions: ['.plist', '.glyphs'] - }, - 'OpenType Feature File': { - type: 'data', - extensions: ['.fea'], - aliases: ['AFDKO'] - }, - 'Option List': { - type: 'data', - aliases: ['opts', 'ackrc'] - }, - Org: { - type: 'prose', - extensions: ['.org'] - }, - OverpassQL: { - type: 'programming', - extensions: ['.overpassql'] - }, - Ox: { - type: 'programming', - extensions: ['.ox', '.oxh', '.oxo'] - }, - Oxygene: { - type: 'programming', - extensions: ['.oxygene'] - }, - Oz: { - type: 'programming', - extensions: ['.oz'] - }, - P4: { - type: 'programming', - extensions: ['.p4'] - }, - Pact: { - type: 'programming', - extensions: ['.pact'] - }, - Pan: { - type: 'programming', - extensions: ['.pan'] - }, - Papyrus: { - type: 'programming', - extensions: ['.psc'] - }, - Parrot: { - type: 'programming', - extensions: ['.parrot'] - }, - 'Parrot Assembly': { - type: 'programming', - extensions: ['.pasm'], - aliases: ['pasm'] - }, - 'Parrot Internal Representation': { - type: 'programming', - extensions: ['.pir'], - aliases: ['pir'] - }, - Pascal: { - type: 'programming', - extensions: ['.pas', '.dfm', '.dpr', '.inc', '.lpr', '.pascal', '.pp'], - aliases: ['delphi', 'objectpascal'] - }, - Pawn: { - type: 'programming', - extensions: ['.pwn', '.inc', '.sma'] - }, - PDDL: { - type: 'programming', - extensions: ['.pddl'] - }, - 'PEG.js': { - type: 'programming', - extensions: ['.pegjs', '.peggy'] - }, - Pep8: { - type: 'programming', - extensions: ['.pep'] - }, - Perl: { - type: 'programming', - extensions: ['.pl', '.al', '.cgi', '.fcgi', '.perl', '.ph', '.plx', '.pm', '.psgi', '.t'], - aliases: ['cperl'] - }, - PHP: { - type: 'programming', - extensions: ['.php', '.aw', '.ctp', '.fcgi', '.inc', '.php3', '.php4', '.php5', '.phps', '.phpt'], - aliases: ['inc'] - }, - Pic: { - type: 'markup', - extensions: ['.pic', '.chem'], - aliases: ['pikchr'] - }, - Pickle: { - type: 'data', - extensions: ['.pkl'] - }, - PicoLisp: { - type: 'programming', - extensions: ['.l'] - }, - PigLatin: { - type: 'programming', - extensions: ['.pig'] - }, - Pike: { - type: 'programming', - extensions: ['.pike', '.pmod'] - }, - Pkl: { - type: 'programming', - extensions: ['.pkl'] - }, - PlantUML: { - type: 'data', - extensions: ['.puml', '.iuml', '.plantuml'] - }, - PLpgSQL: { - type: 'programming', - extensions: ['.pgsql', '.sql'] - }, - PLSQL: { - type: 'programming', - extensions: [ - '.pls', - '.bdy', - '.ddl', - '.fnc', - '.pck', - '.pkb', - '.pks', - '.plb', - '.plsql', - '.prc', - '.spc', - '.sql', - '.tpb', - '.tps', - '.trg', - '.vw' - ] - }, - Pod: { - type: 'prose', - extensions: ['.pod'] - }, - 'Pod 6': { - type: 'prose', - extensions: ['.pod', '.pod6'] - }, - PogoScript: { - type: 'programming', - extensions: ['.pogo'] - }, - Polar: { - type: 'programming', - extensions: ['.polar'] - }, - Pony: { - type: 'programming', - extensions: ['.pony'] - }, - Portugol: { - type: 'programming', - extensions: ['.por'] - }, - PostCSS: { - type: 'markup', - extensions: ['.pcss', '.postcss'] - }, - PostScript: { - type: 'markup', - extensions: ['.ps', '.eps', '.epsi', '.pfa'], - aliases: ['postscr'] - }, - 'POV-Ray SDL': { - type: 'programming', - extensions: ['.pov', '.inc'], - aliases: ['pov-ray', 'povray'] - }, - PowerBuilder: { - type: 'programming', - extensions: ['.pbt', '.sra', '.sru', '.srw'] - }, - PowerShell: { - type: 'programming', - extensions: ['.ps1', '.psd1', '.psm1'], - aliases: ['posh', 'pwsh'] - }, - Praat: { - type: 'programming', - extensions: ['.praat'] - }, - Prisma: { - type: 'data', - extensions: ['.prisma'] - }, - Processing: { - type: 'programming', - extensions: ['.pde'] - }, - Proguard: { - type: 'data', - extensions: ['.pro'] - }, - Prolog: { - type: 'programming', - extensions: ['.pl', '.plt', '.pro', '.prolog', '.yap'] - }, - Promela: { - type: 'programming', - extensions: ['.pml'] - }, - 'Propeller Spin': { - type: 'programming', - extensions: ['.spin'] - }, - 'Protocol Buffer': { - type: 'data', - extensions: ['.proto'], - aliases: ['proto', 'protobuf', 'Protocol Buffers'] - }, - 'Protocol Buffer Text Format': { - type: 'data', - extensions: ['.textproto', '.pbt', '.pbtxt'], - aliases: ['text proto', 'protobuf text format'] - }, - 'Public Key': { - type: 'data', - extensions: ['.asc', '.pub'] - }, - Pug: { - type: 'markup', - extensions: ['.jade', '.pug'] - }, - Puppet: { - type: 'programming', - extensions: ['.pp'] - }, - 'Pure Data': { - type: 'data', - extensions: ['.pd'] - }, - PureBasic: { - type: 'programming', - extensions: ['.pb', '.pbi'] - }, - PureScript: { - type: 'programming', - extensions: ['.purs'] - }, - Pyret: { - type: 'programming', - extensions: ['.arr'] - }, - Python: { - type: 'programming', - extensions: [ - '.py', - '.cgi', - '.fcgi', - '.gyp', - '.gypi', - '.lmi', - '.py3', - '.pyde', - '.pyi', - '.pyp', - '.pyt', - '.pyw', - '.rpy', - '.spec', - '.tac', - '.wsgi', - '.xpy' - ], - aliases: ['python3', 'rusthon'] - }, - 'Python console': { - type: 'programming', - aliases: ['pycon'] - }, - 'Python traceback': { - type: 'data', - extensions: ['.pytb'] - }, - q: { - type: 'programming', - extensions: ['.q'] - }, - 'Q#': { - type: 'programming', - extensions: ['.qs'], - aliases: ['qsharp'] - }, - QMake: { - type: 'programming', - extensions: ['.pro', '.pri'] - }, - QML: { - type: 'programming', - extensions: ['.qml', '.qbs'] - }, - 'Qt Script': { - type: 'programming', - extensions: ['.qs'] - }, - QuakeC: { - type: 'programming', - extensions: ['.qc'] - }, - QuickBASIC: { - type: 'programming', - extensions: ['.bas'], - aliases: ['qb', 'qbasic', 'qb64', 'classic qbasic', 'classic quickbasic'] - }, - R: { - type: 'programming', - extensions: ['.r', '.rd', '.rsx'], - aliases: ['Rscript', 'splus'] - }, - Racket: { - type: 'programming', - extensions: ['.rkt', '.rktd', '.rktl', '.scrbl'] - }, - Ragel: { - type: 'programming', - extensions: ['.rl'], - aliases: ['ragel-rb', 'ragel-ruby'] - }, - Raku: { - type: 'programming', - extensions: [ - '.6pl', - '.6pm', - '.nqp', - '.p6', - '.p6l', - '.p6m', - '.pl', - '.pl6', - '.pm', - '.pm6', - '.raku', - '.rakumod', - '.t' - ], - aliases: ['perl6', 'perl-6'] - }, - RAML: { - type: 'markup', - extensions: ['.raml'] - }, - Rascal: { - type: 'programming', - extensions: ['.rsc'] - }, - 'Raw token data': { - type: 'data', - extensions: ['.raw'], - aliases: ['raw'] - }, - RBS: { - type: 'data', - extensions: ['.rbs'] - }, - RDoc: { - type: 'prose', - extensions: ['.rdoc'] - }, - 'Readline Config': { - type: 'data', - aliases: ['inputrc', 'readline'] - }, - REALbasic: { - type: 'programming', - extensions: ['.rbbas', '.rbfrm', '.rbmnu', '.rbres', '.rbtbar', '.rbuistate'] - }, - Reason: { - type: 'programming', - extensions: ['.re', '.rei'] - }, - ReasonLIGO: { - type: 'programming', - extensions: ['.religo'] - }, - Rebol: { - type: 'programming', - extensions: ['.reb', '.r', '.r2', '.r3', '.rebol'] - }, - Red: { - type: 'programming', - extensions: ['.red', '.reds'], - aliases: ['red/system'] - }, - Redcode: { - type: 'programming', - extensions: ['.cw'] - }, - 'Redirect Rules': { - type: 'data', - aliases: ['redirects'] - }, - 'Regular Expression': { - type: 'data', - extensions: ['.regexp', '.regex'], - aliases: ['regexp', 'regex'] - }, - "Ren'Py": { - type: 'programming', - extensions: ['.rpy'], - aliases: ['renpy'] - }, - RenderScript: { - type: 'programming', - extensions: ['.rs', '.rsh'] - }, - ReScript: { - type: 'programming', - extensions: ['.res', '.resi'] - }, - reStructuredText: { - type: 'prose', - extensions: ['.rst', '.rest', '.rest.txt', '.rst.txt'], - aliases: ['rst'] - }, - REXX: { - type: 'programming', - extensions: ['.rexx', '.pprx', '.rex'], - aliases: ['arexx'] - }, - Rez: { - type: 'programming', - extensions: ['.r'] - }, - 'Rich Text Format': { - type: 'markup', - extensions: ['.rtf'] - }, - Ring: { - type: 'programming', - extensions: ['.ring'] - }, - Riot: { - type: 'markup', - extensions: ['.riot'] - }, - RMarkdown: { - type: 'prose', - extensions: ['.qmd', '.rmd'] - }, - RobotFramework: { - type: 'programming', - extensions: ['.robot', '.resource'] - }, - 'robots.txt': { - type: 'data', - aliases: ['robots', 'robots txt'] - }, - Roc: { - type: 'programming', - extensions: ['.roc'] - }, - 'Rocq Prover': { - type: 'programming', - extensions: ['.v', '.coq'], - aliases: ['coq', 'rocq'] - }, - Roff: { - type: 'markup', - extensions: [ - '.roff', - '.1', - '.1in', - '.1m', - '.1x', - '.2', - '.3', - '.3in', - '.3m', - '.3p', - '.3pm', - '.3qt', - '.3x', - '.4', - '.5', - '.6', - '.7', - '.8', - '.9', - '.l', - '.man', - '.mdoc', - '.me', - '.ms', - '.n', - '.nr', - '.rno', - '.tmac' - ], - aliases: ['groff', 'man', 'manpage', 'man page', 'man-page', 'mdoc', 'nroff', 'troff'] - }, - 'Roff Manpage': { - type: 'markup', - extensions: [ - '.1', - '.1in', - '.1m', - '.1x', - '.2', - '.3', - '.3in', - '.3m', - '.3p', - '.3pm', - '.3qt', - '.3x', - '.4', - '.5', - '.6', - '.7', - '.8', - '.9', - '.man', - '.mdoc' - ] - }, - RON: { - type: 'data', - extensions: ['.ron'] - }, - 'ROS Interface': { - type: 'data', - extensions: ['.msg', '.action', '.srv'], - aliases: ['rosmsg'] - }, - Rouge: { - type: 'programming', - extensions: ['.rg'] - }, - 'RouterOS Script': { - type: 'programming', - extensions: ['.rsc'] - }, - RPC: { - type: 'programming', - extensions: ['.x'], - aliases: ['rpcgen', 'oncrpc', 'xdr'] - }, - RPGLE: { - type: 'programming', - extensions: ['.rpgle', '.sqlrpgle'], - aliases: ['ile rpg', 'sqlrpgle'] - }, - 'RPM Spec': { - type: 'data', - extensions: ['.spec'], - aliases: ['specfile'] - }, - Ruby: { - type: 'programming', - extensions: [ - '.rb', - '.builder', - '.eye', - '.fcgi', - '.gemspec', - '.god', - '.jbuilder', - '.mspec', - '.pluginspec', - '.podspec', - '.prawn', - '.rabl', - '.rake', - '.rbi', - '.rbuild', - '.rbw', - '.rbx', - '.ru', - '.ruby', - '.spec', - '.thor', - '.watchr' - ], - aliases: ['jruby', 'macruby', 'rake', 'rb', 'rbx'] - }, - RUNOFF: { - type: 'markup', - extensions: ['.rnh', '.rno'] - }, - Rust: { - type: 'programming', - extensions: ['.rs', '.rs.in'], - aliases: ['rs'] - }, - Sage: { - type: 'programming', - extensions: ['.sage', '.sagews'] - }, - Sail: { - type: 'programming', - extensions: ['.sail'] - }, - SaltStack: { - type: 'programming', - extensions: ['.sls'], - aliases: ['saltstate', 'salt'] - }, - SAS: { - type: 'programming', - extensions: ['.sas'] - }, - Sass: { - type: 'markup', - extensions: ['.sass'] - }, - Scala: { - type: 'programming', - extensions: ['.scala', '.kojo', '.sbt', '.sc'] - }, - Scaml: { - type: 'markup', - extensions: ['.scaml'] - }, - Scenic: { - type: 'programming', - extensions: ['.scenic'] - }, - Scheme: { - type: 'programming', - extensions: ['.scm', '.sch', '.sld', '.sls', '.sps', '.ss'] - }, - Scilab: { - type: 'programming', - extensions: ['.sci', '.sce', '.tst'] - }, - SCSS: { - type: 'markup', - extensions: ['.scss'] - }, - sed: { - type: 'programming', - extensions: ['.sed'] - }, - Self: { - type: 'programming', - extensions: ['.self'] - }, - 'SELinux Policy': { - type: 'data', - extensions: ['.te'], - aliases: ['SELinux Kernel Policy Language', 'sepolicy'] - }, - ShaderLab: { - type: 'programming', - extensions: ['.shader'] - }, - Shell: { - type: 'programming', - extensions: [ - '.sh', - '.bash', - '.bats', - '.cgi', - '.command', - '.fcgi', - '.ksh', - '.sh.in', - '.tmux', - '.tool', - '.trigger', - '.zsh', - '.zsh-theme' - ], - aliases: ['sh', 'shell-script', 'bash', 'zsh', 'envrc'] - }, - 'ShellCheck Config': { - type: 'data', - aliases: ['shellcheckrc'] - }, - ShellSession: { - type: 'programming', - extensions: ['.sh-session'], - aliases: ['bash session', 'console'] - }, - Shen: { - type: 'programming', - extensions: ['.shen'] - }, - Sieve: { - type: 'programming', - extensions: ['.sieve'] - }, - 'Simple File Verification': { - type: 'data', - extensions: ['.sfv'], - aliases: ['sfv'] - }, - Slang: { - type: 'programming', - extensions: ['.slang'] - }, - Slash: { - type: 'programming', - extensions: ['.sl'] - }, - Slice: { - type: 'programming', - extensions: ['.ice'] - }, - Slim: { - type: 'markup', - extensions: ['.slim'] - }, - Slint: { - type: 'markup', - extensions: ['.slint'] - }, - Smali: { - type: 'programming', - extensions: ['.smali'] - }, - Smalltalk: { - type: 'programming', - extensions: ['.st', '.cs'], - aliases: ['squeak'] - }, - Smarty: { - type: 'programming', - extensions: ['.tpl'] - }, - Smithy: { - type: 'programming', - extensions: ['.smithy'] - }, - SmPL: { - type: 'programming', - extensions: ['.cocci'], - aliases: ['coccinelle'] - }, - SMT: { - type: 'programming', - extensions: ['.smt2', '.smt', '.z3'] - }, - Snakemake: { - type: 'programming', - extensions: ['.smk', '.snakefile'], - aliases: ['snakefile'] - }, - Solidity: { - type: 'programming', - extensions: ['.sol'] - }, - SourcePawn: { - type: 'programming', - extensions: ['.sp', '.inc'], - aliases: ['sourcemod'] - }, - SPARQL: { - type: 'data', - extensions: ['.sparql', '.rq'] - }, - 'Spline Font Database': { - type: 'data', - extensions: ['.sfd'] - }, - SQF: { - type: 'programming', - extensions: ['.sqf', '.hqf'] - }, - SQL: { - type: 'data', - extensions: ['.sql', '.cql', '.ddl', '.inc', '.mysql', '.prc', '.tab', '.udf', '.viw'] - }, - SQLPL: { - type: 'programming', - extensions: ['.sql', '.db2'] - }, - Squirrel: { - type: 'programming', - extensions: ['.nut'] - }, - 'SRecode Template': { - type: 'markup', - extensions: ['.srt'] - }, - 'SSH Config': { - type: 'data', - aliases: ['sshconfig', 'sshdconfig', 'ssh_config', 'sshd_config'] - }, - Stan: { - type: 'programming', - extensions: ['.stan'] - }, - 'Standard ML': { - type: 'programming', - extensions: ['.ml', '.fun', '.sig', '.sml'], - aliases: ['sml'] - }, - STAR: { - type: 'data', - extensions: ['.star'] - }, - Starlark: { - type: 'programming', - extensions: ['.bzl', '.star'], - aliases: ['bazel', 'bzl'] - }, - Stata: { - type: 'programming', - extensions: ['.do', '.ado', '.doh', '.ihlp', '.mata', '.matah', '.sthlp'] - }, - STL: { - type: 'data', - extensions: ['.stl'], - aliases: ['ascii stl', 'stla'] - }, - STON: { - type: 'data', - extensions: ['.ston'] - }, - StringTemplate: { - type: 'markup', - extensions: ['.st'] - }, - Stylus: { - type: 'markup', - extensions: ['.styl'] - }, - 'SubRip Text': { - type: 'data', - extensions: ['.srt'] - }, - SugarSS: { - type: 'markup', - extensions: ['.sss'] - }, - SuperCollider: { - type: 'programming', - extensions: ['.sc', '.scd'] - }, - 'Survex data': { - type: 'data', - extensions: ['.svx'] - }, - Svelte: { - type: 'markup', - extensions: ['.svelte'] - }, - SVG: { - type: 'data', - extensions: ['.svg'] - }, - Sway: { - type: 'programming', - extensions: ['.sw'] - }, - Sweave: { - type: 'prose', - extensions: ['.rnw'] - }, - Swift: { - type: 'programming', - extensions: ['.swift'] - }, - SWIG: { - type: 'programming', - extensions: ['.i', '.swg', '.swig'] - }, - SystemVerilog: { - type: 'programming', - extensions: ['.sv', '.svh', '.vh'] - }, - Tact: { - type: 'programming', - extensions: ['.tact'] - }, - Talon: { - type: 'programming', - extensions: ['.talon'] - }, - Tcl: { - type: 'programming', - extensions: ['.tcl', '.adp', '.sdc', '.tcl.in', '.tm', '.xdc'], - aliases: ['sdc', 'xdc'] - }, - Tcsh: { - type: 'programming', - extensions: ['.tcsh', '.csh'] - }, - Tea: { - type: 'markup', - extensions: ['.tea'] - }, - templ: { - type: 'markup', - extensions: ['.templ'] - }, - Terra: { - type: 'programming', - extensions: ['.t'] - }, - 'Terraform Template': { - type: 'markup', - extensions: ['.tftpl'] - }, - TeX: { - type: 'markup', - extensions: [ - '.tex', - '.aux', - '.bbx', - '.cbx', - '.cls', - '.dtx', - '.ins', - '.lbx', - '.ltx', - '.mkii', - '.mkiv', - '.mkvi', - '.sty', - '.toc' - ], - aliases: ['latex'] - }, - Texinfo: { - type: 'prose', - extensions: ['.texinfo', '.texi', '.txi'] - }, - Text: { - type: 'prose', - extensions: ['.txt', '.fr', '.nb', '.ncl', '.no'], - aliases: ['fundamental', 'plain text'] - }, - TextGrid: { - type: 'data', - extensions: ['.TextGrid'] - }, - Textile: { - type: 'prose', - extensions: ['.textile'] - }, - 'TextMate Properties': { - type: 'data', - aliases: ['tm-properties'] - }, - Thrift: { - type: 'programming', - extensions: ['.thrift'] - }, - 'TI Program': { - type: 'programming', - extensions: ['.8xp', '.8xp.txt'] - }, - 'TL-Verilog': { - type: 'programming', - extensions: ['.tlv'] - }, - TLA: { - type: 'programming', - extensions: ['.tla'] - }, - Toit: { - type: 'programming', - extensions: ['.toit'] - }, - TOML: { - type: 'data', - extensions: ['.toml', '.toml.example'] - }, - 'Tor Config': { - type: 'data', - aliases: ['torrc'] - }, - 'Tree-sitter Query': { - type: 'programming', - extensions: ['.scm'], - aliases: ['tsq'] - }, - 'TSPLIB data': { - type: 'data', - extensions: ['.tsp'], - aliases: ['travelling salesman problem', 'traveling salesman problem'] - }, - TSQL: { - type: 'programming', - extensions: ['.sql'] - }, - TSV: { - type: 'data', - extensions: ['.tsv', '.vcf'], - aliases: ['tab-seperated values'] - }, - TSX: { - type: 'programming', - extensions: ['.tsx'] - }, - Turing: { - type: 'programming', - extensions: ['.t', '.tu'] - }, - Turtle: { - type: 'data', - extensions: ['.ttl'] - }, - Twig: { - type: 'markup', - extensions: ['.twig'] - }, - TXL: { - type: 'programming', - extensions: ['.txl'] - }, - 'Type Language': { - type: 'data', - extensions: ['.tl'], - aliases: ['tl'] - }, - TypeScript: { - type: 'programming', - extensions: ['.ts', '.cts', '.mts'], - aliases: ['ts'] - }, - TypeSpec: { - type: 'programming', - extensions: ['.tsp'], - aliases: ['tsp'] - }, - Typst: { - type: 'programming', - extensions: ['.typ'], - aliases: ['typ'] - }, - 'Unified Parallel C': { - type: 'programming', - extensions: ['.upc'] - }, - 'Unity3D Asset': { - type: 'data', - extensions: ['.anim', '.asset', '.mask', '.mat', '.meta', '.prefab', '.unity'] - }, - 'Unix Assembly': { - type: 'programming', - extensions: ['.s', '.ms'], - aliases: ['gas', 'gnu asm', 'unix asm'] - }, - Uno: { - type: 'programming', - extensions: ['.uno'] - }, - UnrealScript: { - type: 'programming', - extensions: ['.uc'] - }, - 'Untyped Plutus Core': { - type: 'programming', - extensions: ['.uplc'] - }, - UrWeb: { - type: 'programming', - extensions: ['.ur', '.urs'], - aliases: ['Ur/Web', 'Ur'] - }, - V: { - type: 'programming', - extensions: ['.v'], - aliases: ['vlang'] - }, - Vala: { - type: 'programming', - extensions: ['.vala', '.vapi'] - }, - 'Valve Data Format': { - type: 'data', - extensions: ['.vdf'], - aliases: ['keyvalues', 'vdf'] - }, - VBA: { - type: 'programming', - extensions: ['.bas', '.cls', '.frm', '.vba'], - aliases: ['visual basic for applications'] - }, - VBScript: { - type: 'programming', - extensions: ['.vbs'] - }, - vCard: { - type: 'data', - extensions: ['.vcf'], - aliases: ['virtual contact file', 'electronic business card'] - }, - VCL: { - type: 'programming', - extensions: ['.vcl'] - }, - 'Velocity Template Language': { - type: 'markup', - extensions: ['.vtl'], - aliases: ['vtl', 'velocity'] - }, - Vento: { - type: 'markup', - extensions: ['.vto'] - }, - Verilog: { - type: 'programming', - extensions: ['.v', '.veo'] - }, - VHDL: { - type: 'programming', - extensions: ['.vhdl', '.vhd', '.vhf', '.vhi', '.vho', '.vhs', '.vht', '.vhw'] - }, - 'Vim Help File': { - type: 'prose', - extensions: ['.txt'], - aliases: ['help', 'vimhelp'] - }, - 'Vim Script': { - type: 'programming', - extensions: ['.vim', '.vba', '.vimrc', '.vmb'], - aliases: ['vim', 'viml', 'nvim', 'vimscript'] - }, - 'Vim Snippet': { - type: 'markup', - extensions: ['.snip', '.snippet', '.snippets'], - aliases: ['SnipMate', 'UltiSnip', 'UltiSnips', 'NeoSnippet'] - }, - 'Visual Basic .NET': { - type: 'programming', - extensions: ['.vb', '.vbhtml'], - aliases: ['visual basic', 'vbnet', 'vb .net', 'vb.net'] - }, - 'Visual Basic 6.0': { - type: 'programming', - extensions: ['.bas', '.cls', '.ctl', '.Dsr', '.frm'], - aliases: ['vb6', 'vb 6', 'visual basic 6', 'visual basic classic', 'classic visual basic'] - }, - Volt: { - type: 'programming', - extensions: ['.volt'] - }, - Vue: { - type: 'markup', - extensions: ['.vue'] - }, - Vyper: { - type: 'programming', - extensions: ['.vy'] - }, - 'Wavefront Material': { - type: 'data', - extensions: ['.mtl'] - }, - 'Wavefront Object': { - type: 'data', - extensions: ['.obj'] - }, - WDL: { - type: 'programming', - extensions: ['.wdl'], - aliases: ['Workflow Description Language'] - }, - 'Web Ontology Language': { - type: 'data', - extensions: ['.owl'] - }, - WebAssembly: { - type: 'programming', - extensions: ['.wast', '.wat'], - aliases: ['wast', 'wasm'] - }, - 'WebAssembly Interface Type': { - type: 'data', - extensions: ['.wit'], - aliases: ['wit'] - }, - WebIDL: { - type: 'programming', - extensions: ['.webidl'] - }, - WebVTT: { - type: 'data', - extensions: ['.vtt'], - aliases: ['vtt'] - }, - 'Wget Config': { - type: 'data', - aliases: ['wgetrc'] - }, - WGSL: { - type: 'programming', - extensions: ['.wgsl'] - }, - Whiley: { - type: 'programming', - extensions: ['.whiley'] - }, - Wikitext: { - type: 'prose', - extensions: ['.mediawiki', '.wiki', '.wikitext'], - aliases: ['mediawiki', 'wiki'] - }, - 'Win32 Message File': { - type: 'data', - extensions: ['.mc'] - }, - 'Windows Registry Entries': { - type: 'data', - extensions: ['.reg'] - }, - wisp: { - type: 'programming', - extensions: ['.wisp'] - }, - 'Witcher Script': { - type: 'programming', - extensions: ['.ws'] - }, - Wollok: { - type: 'programming', - extensions: ['.wlk'] - }, - 'World of Warcraft Addon Data': { - type: 'data', - extensions: ['.toc'] - }, - Wren: { - type: 'programming', - extensions: ['.wren'], - aliases: ['wrenlang'] - }, - 'X BitMap': { - type: 'data', - extensions: ['.xbm'], - aliases: ['xbm'] - }, - 'X PixMap': { - type: 'data', - extensions: ['.xpm', '.pm'], - aliases: ['xpm'] - }, - X10: { - type: 'programming', - extensions: ['.x10'], - aliases: ['xten'] - }, - xBase: { - type: 'programming', - extensions: ['.prg', '.ch', '.prw'], - aliases: ['advpl', 'clipper', 'foxpro'] - }, - XC: { - type: 'programming', - extensions: ['.xc'] - }, - XML: { - type: 'data', - extensions: [ - '.xml', - '.adml', - '.admx', - '.ant', - '.axaml', - '.axml', - '.builds', - '.ccproj', - '.ccxml', - '.clixml', - '.cproject', - '.cscfg', - '.csdef', - '.csl', - '.csproj', - '.ct', - '.depproj', - '.dita', - '.ditamap', - '.ditaval', - '.dll.config', - '.dotsettings', - '.filters', - '.fsproj', - '.fxml', - '.glade', - '.gml', - '.gmx', - '.gpx', - '.grxml', - '.gst', - '.hzp', - '.iml', - '.ivy', - '.jelly', - '.jsproj', - '.kml', - '.launch', - '.mdpolicy', - '.mjml', - '.mm', - '.mod', - '.mojo', - '.mxml', - '.natvis', - '.ncl', - '.ndproj', - '.nproj', - '.nuspec', - '.odd', - '.osm', - '.pkgproj', - '.pluginspec', - '.proj', - '.props', - '.ps1xml', - '.psc1', - '.pt', - '.qhelp', - '.rdf', - '.res', - '.resx', - '.rs', - '.rss', - '.sch', - '.scxml', - '.sfproj', - '.shproj', - '.slnx', - '.srdf', - '.storyboard', - '.sublime-snippet', - '.sw', - '.targets', - '.tml', - '.ts', - '.tsx', - '.typ', - '.ui', - '.urdf', - '.ux', - '.vbproj', - '.vcxproj', - '.vsixmanifest', - '.vssettings', - '.vstemplate', - '.vxml', - '.wixproj', - '.workflow', - '.wsdl', - '.wsf', - '.wxi', - '.wxl', - '.wxs', - '.x3d', - '.xacro', - '.xaml', - '.xib', - '.xlf', - '.xliff', - '.xmi', - '.xml.dist', - '.xmp', - '.xproj', - '.xsd', - '.xspec', - '.xul', - '.zcml' - ], - aliases: ['rss', 'xsd', 'wsdl'] - }, - 'XML Property List': { - type: 'data', - extensions: ['.plist', '.stTheme', '.tmCommand', '.tmLanguage', '.tmPreferences', '.tmSnippet', '.tmTheme'] - }, - Xojo: { - type: 'programming', - extensions: ['.xojo_code', '.xojo_menu', '.xojo_report', '.xojo_script', '.xojo_toolbar', '.xojo_window'] - }, - Xonsh: { - type: 'programming', - extensions: ['.xsh'] - }, - XPages: { - type: 'data', - extensions: ['.xsp-config', '.xsp.metadata'] - }, - XProc: { - type: 'programming', - extensions: ['.xpl', '.xproc'] - }, - XQuery: { - type: 'programming', - extensions: ['.xquery', '.xq', '.xql', '.xqm', '.xqy'] - }, - XS: { - type: 'programming', - extensions: ['.xs'] - }, - XSLT: { - type: 'programming', - extensions: ['.xslt', '.xsl'], - aliases: ['xsl'] - }, - Xtend: { - type: 'programming', - extensions: ['.xtend'] - }, - Yacc: { - type: 'programming', - extensions: ['.y', '.yacc', '.yy'] - }, - YAML: { - type: 'data', - extensions: [ - '.yml', - '.mir', - '.reek', - '.rviz', - '.sublime-syntax', - '.syntax', - '.yaml', - '.yaml-tmlanguage', - '.yaml.sed', - '.yml.mysql' - ], - aliases: ['yml'] - }, - YANG: { - type: 'data', - extensions: ['.yang'] - }, - YARA: { - type: 'programming', - extensions: ['.yar', '.yara'] - }, - YASnippet: { - type: 'markup', - extensions: ['.yasnippet'], - aliases: ['snippet', 'yas'] - }, - Yul: { - type: 'programming', - extensions: ['.yul'] - }, - ZAP: { - type: 'programming', - extensions: ['.zap', '.xzap'] - }, - Zeek: { - type: 'programming', - extensions: ['.zeek', '.bro'], - aliases: ['bro'] - }, - ZenScript: { - type: 'programming', - extensions: ['.zs'] - }, - Zephir: { - type: 'programming', - extensions: ['.zep'] - }, - Zig: { - type: 'programming', - extensions: ['.zig', '.zig.zon'] - }, - ZIL: { - type: 'programming', - extensions: ['.zil', '.mud'] - }, - Zimpl: { - type: 'programming', - extensions: ['.zimpl', '.zmpl', '.zpl'] - }, - Zmodel: { - type: 'data', - extensions: ['.zmodel'] - } -} diff --git a/packages/ui/src/utils/codeLanguage.ts b/packages/ui/src/utils/codeLanguage.ts deleted file mode 100644 index 8812714538..0000000000 --- a/packages/ui/src/utils/codeLanguage.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { languages } from '../config/languages' - -/** - * Get the file extension of the language, by language name - * - First, exact match - * - Then, case-insensitive match - * - Finally, match aliases - * If there are multiple file extensions, only the first one will be returned - * @param language language name - * @returns file extension - */ -export function getExtensionByLanguage(language: string): string { - const lowerLanguage = language.toLowerCase() - - // Exact match language name - const directMatch = languages[language] - if (directMatch?.extensions?.[0]) { - return directMatch.extensions[0] - } - - const languageEntries = Object.entries(languages) - - // Case-insensitive match language name - for (const [langName, data] of languageEntries) { - if (langName.toLowerCase() === lowerLanguage && data.extensions?.[0]) { - return data.extensions[0] - } - } - - // Match aliases - for (const [, data] of languageEntries) { - if (data.aliases?.some((alias) => alias.toLowerCase() === lowerLanguage)) { - return data.extensions?.[0] || `.${language}` - } - } - - // Fallback to language name - return `.${language}` -} diff --git a/packages/ui/stories/components/base/ErrorTag.stories.tsx b/packages/ui/stories/components/base/ErrorTag.stories.tsx deleted file mode 100644 index 15d75b78f6..0000000000 --- a/packages/ui/stories/components/base/ErrorTag.stories.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react-vite' - -import { ErrorTag } from '../../../src/components/base/ErrorTag' - -const meta: Meta = { - title: 'Base/ErrorTag', - component: ErrorTag, - parameters: { - layout: 'centered' - }, - tags: ['autodocs'], - argTypes: { - iconSize: { control: { type: 'range', min: 10, max: 20, step: 1 } }, - message: { control: 'text' } - } -} - -export default meta -type Story = StoryObj - -export const Default: Story = { - args: { - message: '错误信息' - } -} - -export const ServerError: Story = { - args: { - message: '服务器连接失败' - } -} - -export const ValidationError: Story = { - args: { - message: '数据验证失败', - iconSize: 16 - } -} - -export const Examples: Story = { - render: () => ( -
- - - -
- ) -} diff --git a/packages/ui/stories/components/base/StatusTag.stories.tsx b/packages/ui/stories/components/base/StatusTag.stories.tsx new file mode 100644 index 0000000000..ab843d4f8e --- /dev/null +++ b/packages/ui/stories/components/base/StatusTag.stories.tsx @@ -0,0 +1,176 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import { ErrorTag, InfoTag, StatusTag, SuccessTag, WarnTag } from '../../../src/components/base/StatusTag' + +const meta: Meta = { + title: 'Base/StatusTag', + component: StatusTag, + parameters: { + layout: 'centered' + }, + tags: ['autodocs'], + argTypes: { + type: { + control: { type: 'select' }, + options: ['success', 'error', 'warning', 'info'] + }, + iconSize: { control: { type: 'range', min: 10, max: 24, step: 1 } }, + message: { control: 'text' }, + color: { control: 'color' } + } +} + +export default meta +type Story = StoryObj + +// Default +export const Default: Story = { + args: { + type: 'success', + message: 'Success' + } +} + +// All Types +export const AllTypes: Story = { + render: () => ( +
+ + + + +
+ ) +} + +// Convenience Components +export const ConvenienceComponents: Story = { + render: () => ( +
+ + + + +
+ ) +} + +// Different Icon Sizes +export const IconSizes: Story = { + render: () => ( +
+
+ + + + +
+
+ + + + +
+
+ ) +} + +// Custom Colors +export const CustomColors: Story = { + render: () => ( +
+ + + + +
+ ) +} + +// In Context +export const InContext: Story = { + render: () => ( +
+
+

Form Submission

+

Your form has been processed.

+ +
+ +
+

Validation Error

+

Please fix the following issues:

+ +
+ +
+

System Status

+
+ + + + +
+
+
+ ) +} + +// Use Cases +export const UseCases: Story = { + render: () => ( +
+
+

Success States

+
+ + + + +
+
+ +
+

Error States

+
+ + + + +
+
+ +
+

Warning States

+
+ + + + +
+
+ +
+

Info States

+
+ + + + +
+
+
+ ) +} + +// Long Messages +export const LongMessages: Story = { + render: () => ( +
+ + + + +
+ ) +} diff --git a/packages/ui/stories/components/base/SuccessTag.stories.tsx b/packages/ui/stories/components/base/SuccessTag.stories.tsx deleted file mode 100644 index 99b2a6a492..0000000000 --- a/packages/ui/stories/components/base/SuccessTag.stories.tsx +++ /dev/null @@ -1,110 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react' - -import { SuccessTag } from '../../../src/components/base/SuccessTag' - -const meta: Meta = { - title: 'Base/SuccessTag', - component: SuccessTag, - parameters: { - layout: 'centered' - }, - tags: ['autodocs'], - argTypes: { - iconSize: { control: { type: 'range', min: 10, max: 24, step: 1 } }, - message: { control: 'text' } - } -} - -export default meta -type Story = StoryObj - -// Default -export const Default: Story = { - args: { - message: 'Success' - } -} - -// Different Messages -export const DifferentMessages: Story = { - render: () => ( -
- - - - - -
- ) -} - -// Different Icon Sizes -export const IconSizes: Story = { - render: () => ( -
- - - - -
- ) -} - -// In Context -export const InContext: Story = { - render: () => ( -
-
-

Form Submission

-

Your form has been processed.

- -
- -
-

File Upload

-
-
document.pdf
-
image.png
-
data.csv
-
- -
- -
-

System Status

-
- - - -
-
-
- ) -} - -// Use Cases -export const UseCases: Story = { - render: () => ( -
-
-

Actions

-
- - - - -
-
- -
-

States

-
- - - - -
-
-
- ) -} diff --git a/packages/ui/stories/components/base/WarnTag.stories.tsx b/packages/ui/stories/components/base/WarnTag.stories.tsx deleted file mode 100644 index c3925128b5..0000000000 --- a/packages/ui/stories/components/base/WarnTag.stories.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react-vite' - -import { WarnTag } from '../../../src/components/base/WarnTag' - -const meta: Meta = { - title: 'Base/WarnTag', - component: WarnTag, - parameters: { - layout: 'centered' - }, - tags: ['autodocs'], - argTypes: { - iconSize: { control: { type: 'range', min: 10, max: 20, step: 1 } }, - message: { control: 'text' } - } -} - -export default meta -type Story = StoryObj - -export const Default: Story = { - args: { - message: '警告信息' - } -} - -export const LongMessage: Story = { - args: { - message: '这是一个比较长的警告信息' - } -} - -export const CustomIconSize: Story = { - args: { - message: '自定义图标大小', - iconSize: 18 - } -} - -export const Examples: Story = { - render: () => ( -
- - - -
- ) -} diff --git a/packages/ui/stories/components/icons/Icon.stories.tsx b/packages/ui/stories/components/icons/Icon.stories.tsx new file mode 100644 index 0000000000..ad0600247f --- /dev/null +++ b/packages/ui/stories/components/icons/Icon.stories.tsx @@ -0,0 +1,290 @@ +import type { Meta, StoryObj } from '@storybook/react' +import { + Copy, + Trash, + Pencil, + RefreshCw, + RotateCcw, + Wrench, + Eye, + Search, + WrapText, + AlignLeft, + ScanLine, + Settings, + Download, + Upload, + ChevronRight +} from 'lucide-react' + +import { + createIcon, + CopyIcon, + DeleteIcon, + EditIcon, + RefreshIcon, + ResetIcon, + ToolIcon, + VisionIcon, + WebSearchIcon, + WrapIcon, + UnWrapIcon, + OcrIcon +} from '../../../src/components/icons/Icon' + +// Create a dummy component for the story +const IconShowcase = () =>
+ +const meta: Meta = { + title: 'Icons/Icon', + component: IconShowcase, + parameters: { + layout: 'centered' + }, + tags: ['autodocs'] +} + +export default meta +type Story = StoryObj + +// Predefined Icons +export const PredefinedIcons: Story = { + render: () => ( +
+
+

Predefined Icons (Default Size: 1rem)

+
+
+ + CopyIcon +
+
+ + DeleteIcon +
+
+ + EditIcon +
+
+ + RefreshIcon +
+
+ + ResetIcon +
+
+ + ToolIcon +
+
+ + VisionIcon +
+
+ + WebSearchIcon +
+
+ + WrapIcon +
+
+ + UnWrapIcon +
+
+ + OcrIcon +
+
+
+
+ ) +} + +// Different Sizes +export const DifferentSizes: Story = { + render: () => ( +
+
+ + + + + + +
+
+ 12px + 16px + 20px + 24px + 32px + 48px +
+
+ ) +} + +// Custom Colors +export const CustomColors: Story = { + render: () => ( +
+ + + + + + +
+ ) +} + +// Custom Icon Creation +export const CustomIconCreation: Story = { + render: () => { + // Create custom icons using the factory + const SettingsIcon = createIcon(Settings, 24) + const DownloadIcon = createIcon(Download, 20) + const UploadIcon = createIcon(Upload, 20) + const ChevronIcon = createIcon(ChevronRight, 16) + + return ( +
+
+

Custom Icons Created with Factory

+
+
+ + Settings (24px) +
+
+ + Download (20px) +
+
+ + Upload (20px) +
+
+ + Chevron (16px) +
+
+
+ +
+

Override Default Size

+
+ + + + +
+
+
+ ) + } +} + +// Icon States +export const IconStates: Story = { + render: () => ( +
+
+ + + +
+
+ Normal + Disabled + Active +
+
+ ) +} + +// In Context +export const InContext: Story = { + render: () => ( +
+
+
+

Document.pdf

+
+ + + +
+
+
+ +
+
+ + Image Processing +
+

Process your images with advanced AI tools

+ +
+ +
+
+ Auto-refresh + +
+
+
+ ) +} + +// Icon Grid +export const IconGrid: Story = { + render: () => { + const AllIcons = [ + { Icon: CopyIcon, name: 'Copy' }, + { Icon: DeleteIcon, name: 'Delete' }, + { Icon: EditIcon, name: 'Edit' }, + { Icon: RefreshIcon, name: 'Refresh' }, + { Icon: ResetIcon, name: 'Reset' }, + { Icon: ToolIcon, name: 'Tool' }, + { Icon: VisionIcon, name: 'Vision' }, + { Icon: WebSearchIcon, name: 'Search' }, + { Icon: WrapIcon, name: 'Wrap' }, + { Icon: UnWrapIcon, name: 'Unwrap' }, + { Icon: OcrIcon, name: 'OCR' } + ] + + return ( +
+ {AllIcons.map(({ Icon, name }) => ( +
+ + {name} +
+ ))} +
+ ) + } +} \ No newline at end of file diff --git a/packages/ui/stories/components/interactive/CodeEditor.stories.tsx b/packages/ui/stories/components/interactive/CodeEditor.stories.tsx index ca8097c28c..b25001f81d 100644 --- a/packages/ui/stories/components/interactive/CodeEditor.stories.tsx +++ b/packages/ui/stories/components/interactive/CodeEditor.stories.tsx @@ -1,7 +1,57 @@ import type { Meta, StoryObj } from '@storybook/react-vite' import { action } from 'storybook/actions' -import CodeEditor, { getCmThemeByName, getCmThemeNames } from '../../../src/components/interactive/CodeEditor' +import CodeEditor, { + getCmThemeByName, + getCmThemeNames, + LanguageConfig +} from '../../../src/components/interactive/CodeEditor' + +// 示例语言配置 - 为 Storybook 提供更丰富的语言支持演示 +const exampleLanguageConfig: LanguageConfig = { + JavaScript: { + type: 'programming', + extensions: ['.js', '.mjs', '.cjs'], + aliases: ['js', 'node'] + }, + TypeScript: { + type: 'programming', + extensions: ['.ts'], + aliases: ['ts'] + }, + Python: { + type: 'programming', + extensions: ['.py'], + aliases: ['python3', 'py'] + }, + JSON: { + type: 'data', + extensions: ['.json'] + }, + Markdown: { + type: 'prose', + extensions: ['.md', '.markdown'], + aliases: ['md'] + }, + HTML: { + type: 'markup', + extensions: ['.html', '.htm'] + }, + CSS: { + type: 'markup', + extensions: ['.css'] + }, + 'Graphviz (DOT)': { + type: 'data', + extensions: ['.dot', '.gv'], + aliases: ['dot', 'graphviz'] + }, + Mermaid: { + type: 'markup', + extensions: ['.mmd', '.mermaid'], + aliases: ['mmd'] + } +} const meta: Meta = { title: 'Interactive/CodeEditor', @@ -11,7 +61,7 @@ const meta: Meta = { argTypes: { language: { control: 'select', - options: ['typescript', 'javascript', 'json', 'markdown', 'python', 'dot', 'mmd'] + options: ['typescript', 'javascript', 'json', 'markdown', 'python', 'dot', 'mmd', 'go', 'rust', 'php'] }, theme: { control: 'select', @@ -23,7 +73,11 @@ const meta: Meta = { wrapped: { control: 'boolean' }, height: { control: 'text' }, maxHeight: { control: 'text' }, - minHeight: { control: 'text' } + minHeight: { control: 'text' }, + languageConfig: { + control: false, + description: 'Optional language configuration. If not provided, uses built-in defaults.' + } } } @@ -46,6 +100,7 @@ export const Default: Story = {
) @@ -97,6 +153,7 @@ export const SaveShortcut: Story = { ) } + +// 使用默认语言配置(展示组件的独立性) +export const DefaultLanguageConfig: Story = { + args: { + language: 'javascript', + theme: 'light', + value: `// 这个示例使用内置的默认语言配置 +function fibonacci(n) { + if (n <= 1) return n; + return fibonacci(n - 1) + fibonacci(n - 2); +} + +console.log(fibonacci(10));`, + wrapped: true + }, + render: (args) => ( +
+ +

此示例未传入 languageConfig,使用组件内置的默认语言配置。

+
+ ) +} diff --git a/packages/ui/tsconfig.json b/packages/ui/tsconfig.json index 3dc3bee863..95b64228cf 100644 --- a/packages/ui/tsconfig.json +++ b/packages/ui/tsconfig.json @@ -1,22 +1,23 @@ { "compilerOptions": { - "target": "ES2020", - "module": "ESNext", - "moduleResolution": "bundler", - "declaration": true, - "outDir": "./dist", - "rootDir": "./src", - "strict": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true, "allowSyntheticDefaultImports": true, - "jsx": "react-jsx", - "lib": ["DOM", "DOM.Iterable", "ES6"], + "baseUrl": ".", + "declaration": true, + "forceConsistentCasingInFileNames": true, "incremental": true, "isolatedModules": true, - "noFallthroughCasesInSwitch": true + "jsx": "react-jsx", + "lib": ["DOM", "DOM.Iterable", "ES6"], + "module": "ESNext", + "moduleResolution": "bundler", + "noFallthroughCasesInSwitch": true, + "outDir": "./dist", + "resolveJsonModule": true, + "rootDir": "./src", + "skipLibCheck": true, + "strict": true, + "target": "ES2020" }, - "include": ["src/**/*"], - "exclude": ["node_modules", "dist", "**/*.test.*", "**/__tests__/**"] + "exclude": ["node_modules", "dist", "**/*.test.*", "**/__tests__/**"], + "include": ["src/**/*"] } diff --git a/packages/ui/tsdown.config.ts b/packages/ui/tsdown.config.ts index 5ec6a3dc93..e6f57dac94 100644 --- a/packages/ui/tsdown.config.ts +++ b/packages/ui/tsdown.config.ts @@ -12,6 +12,9 @@ export default defineConfig({ clean: true, dts: true, tsconfig: 'tsconfig.json', + alias: { + '@shared': '../shared' + }, // 将 HeroUI、Tailwind 和其他 peer dependencies 标记为外部依赖 external: [ 'react',