diff --git a/.github/workflows/deploy-website.yml b/.github/workflows/deploy-website.yml index 00c23126ce60..1b14c33edea9 100644 --- a/.github/workflows/deploy-website.yml +++ b/.github/workflows/deploy-website.yml @@ -27,12 +27,12 @@ jobs: - name: Setup Node and Pnpm uses: ./.github/actions/setup-node with: - node-version: 20.x + node-version: 'lts/*' - name: Build website run: | pnpm i - pnpm run build + pnpm run build:prod cd website pnpm run build:site diff --git a/.github/workflows/website-lint.yml b/.github/workflows/website-lint.yml index 3bd788764cb6..775590d39c9f 100644 --- a/.github/workflows/website-lint.yml +++ b/.github/workflows/website-lint.yml @@ -24,6 +24,9 @@ jobs: - name: Setup uses: ./.github/actions/setup + with: + node-version: 'lts/*' + - run: pnpm run build:prod - run: pnpm run install-website - run: pnpm run website-lint diff --git a/.github/workflows/website-test.yml b/.github/workflows/website-test.yml index 27a4d86f9a60..48981c3b5622 100644 --- a/.github/workflows/website-test.yml +++ b/.github/workflows/website-test.yml @@ -28,6 +28,8 @@ jobs: - name: Setup uses: ./.github/actions/setup + with: + node-version: 'lts/*' - name: Build website run: | diff --git a/.vscode/settings.json b/.vscode/settings.json index f2a1dc88612e..2abc9f9b4aac 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,8 +1,12 @@ { - "json.schemas": [{ - "fileMatch": [ - "cspell.json", ".cspell.json", "cSpell.json" - ], - "url": "./cspell.schema.json" - }] + "json.schemas": [ + { + "fileMatch": [ + "cspell.json", + ".cspell.json", + "cSpell.json" + ], + "url": "./cspell.schema.json" + } + ] } diff --git a/package.json b/package.json index 36ecd4808208..054940582431 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "cspell": "bin.mjs", "cspell-tools": "cspell-tools.mjs" }, - "packageManager": "pnpm@10.27.0+sha512.72d699da16b1179c14ba9e64dc71c9a40988cbdc65c264cb0e489db7de917f20dcf4d64d8723625f2969ba52d4b7e2a1170682d9ac2a5dcaeaab732b7e16f04a", + "packageManager": "pnpm@10.28.1", "private": true, "scripts": { "bp": "pnpm build:prod", @@ -61,7 +61,7 @@ "test:bin-spell-cache-metadata": "node ./bin.mjs -c cspell.test.json --cache --cache-strategy metadata --cache-location temp/.cspellcache-meta", "test:bin-trace": "node ./bin.mjs trace test", "test:prep": "cspell-tools btrie node_modules/@cspell/dict-en_us/en_US.trie.gz", - "test-build-docs": "cd website && pnpm run build:site", + "test-build-docs": "pnpm run build:prod && cd website && pnpm run build:site", "test-integrations": "cd ./integration-tests && pnpm run integration-tests", "test-schema": "node ./test-packages/cspell-types/validate-schema/validate-schema.mjs", "test:deno": "deno run -A ./bin.mjs lint rfc packages/cspell/src", diff --git a/packages/cspell-filetypes/src/filetypes.ts b/packages/cspell-filetypes/src/filetypes.ts index c651ece3eed1..43c7471b2737 100644 --- a/packages/cspell-filetypes/src/filetypes.ts +++ b/packages/cspell-filetypes/src/filetypes.ts @@ -22,6 +22,8 @@ export const generatedFiles: Set = new Set([ export const languageIds: FileTypeId[] = definitions.map(({ id }) => id); +export const fileTypeDefinitions: FileTypeDefinitions = definitions; + const mapExtensionToSetOfLanguageIds: ExtensionToFileTypeIdMapSet = buildLanguageExtensionMapSet(definitions); const mapExtensionToLanguageIds: ExtensionToFileTypeIdMap = buildExtensionToLanguageIdMap(mapExtensionToSetOfLanguageIds); diff --git a/packages/cspell-filetypes/src/index.ts b/packages/cspell-filetypes/src/index.ts index 550edcf11e54..05161ff8d8a1 100644 --- a/packages/cspell-filetypes/src/index.ts +++ b/packages/cspell-filetypes/src/index.ts @@ -1,4 +1,5 @@ export { + fileTypeDefinitions, findMatchingFileTypes as findMatchingFileTypes, getFileTypesForExt, isBinaryExt, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f6118c97f5e4..c4a370fea0ae 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1424,6 +1424,9 @@ importers: website: dependencies: + '@cspell/filetypes': + specifier: workspace:* + version: link:../packages/cspell-filetypes '@docusaurus/core': specifier: ^3.9.2 version: 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.8)(react@19.2.3))(@swc/core@1.7.26)(esbuild@0.27.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3) diff --git a/website/_scripts/extract-properties.mjs b/website/_scripts/extract-properties.mjs index 58c81a57b0a4..c5cb8d8a5f47 100644 --- a/website/_scripts/extract-properties.mjs +++ b/website/_scripts/extract-properties.mjs @@ -27,6 +27,8 @@ async function run() { title: Properties slug: properties toc_max_heading_level: 5 + sidebar_position: 1 + sidebar_label: Properties format: md --- diff --git a/website/docs/Configuration/auto_properties.md b/website/docs/Configuration/auto_properties.md index 187f6128d99c..0f8d7f384fad 100644 --- a/website/docs/Configuration/auto_properties.md +++ b/website/docs/Configuration/auto_properties.md @@ -4,6 +4,8 @@ title: Properties slug: properties toc_max_heading_level: 5 +sidebar_position: 1 +sidebar_label: Properties format: md --- diff --git a/website/docs/Configuration/document-settings.md b/website/docs/Configuration/document-settings.md index 0e2295c858d1..b322412ed937 100644 --- a/website/docs/Configuration/document-settings.md +++ b/website/docs/Configuration/document-settings.md @@ -1,8 +1,7 @@ --- title: 'Document Settings' -categories: configuration -parent: Configuration -nav_order: 11 +sidebar_position: 1 +sidebar_label: Document Settings --- # Inline Document Settings diff --git a/website/docs/Configuration/file-types.mdx b/website/docs/Configuration/file-types.mdx new file mode 100644 index 000000000000..ead5dccbe728 --- /dev/null +++ b/website/docs/Configuration/file-types.mdx @@ -0,0 +1,98 @@ +--- +title: 'File Types and Extensions' +sidebar_position: 12 +sidebar_label: File Types +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +import { FileTypeTable } from '@site/src/components/FileTypeTable'; + +# File Types and Extensions + +This page provides a reference for how CSpell associates file extensions with file type IDs (also called `languageId` in configuration files for historical reasons). + +## Understanding File Type Ids + +:::info Terminology Note +In CSpell configuration files, the field is called `languageId` for historical reasons (to match VSCode's convention). However, this refers to **file types** (like `javascript`, `python`, `markdown`), not spoken languages (like English, German or Spanish). +::: + +## How CSpell Determines File Types + +CSpell uses file extensions and filenames to determine the file type, which then influences: +1. Which dictionaries are enabled +2. Which patterns and rules apply +3. Whether the file should be spell-checked + +## Usage Examples + +### Using Overrides + +Force a specific file type for certain file patterns: + + + + ```yaml + overrides: + - filename: "**/*.xyz" + languageId: javascript # Treat .xyz files as JavaScript + ``` + + + ```json + { + "overrides": [ + { + "filename": "**/*.xyz", + "languageId": "javascript" + } + ] + } + ``` + + + + +### Using Language Settings + +Apply specific settings based on file type: + + + + + ```yaml + languageSettings: + - languageId: python,javascript + dictionaries: + - html + - lorem-ipsum + ``` + + + ```json + { + "languageSettings": [ + { + "languageId": "python,javascript", + "dictionaries": ["html", "lorem-ipsum"] + } + ] + } + ``` + + + + +## Related Documentation + +- [Language Settings](./language-settings.mdx) - Configure settings per file type +- [Overrides](./overrides.md) - Override settings for specific files +- [Searching Dictionaries](../dictionaries/searching-dictionaries.md) - Find which dictionaries contain words + +## Supported File Types + +The table below shows the mapping between file extensions/filenames and their associated file type Ids. + + diff --git a/website/docs/Configuration/githubaction.md b/website/docs/Configuration/githubaction.md index 977630bbaf69..4a7a4a570e79 100644 --- a/website/docs/Configuration/githubaction.md +++ b/website/docs/Configuration/githubaction.md @@ -1,13 +1,14 @@ --- title: 'Github Action Settings' -categories: configuration -parent: Configuration -nav_order: 11 +sidebar_position: 20 +sidebar_label: cspell-action --- # Github Action Settings -## Github Job Settings +Settings for [cspell-action](https://github.com/streetsidesoftware/cspell-action). + +## Github Workflow Job Settings - `files` -- Define glob patterns to filter the files to be checked. Use a new line between patterns to define multiple patterns. The default is to check ALL files that were changed in in the pull_request or push. Note: `ignorePaths` defined in cspell.json still apply. - `check_dot_files` -- Check files and directories starting with `.`. diff --git a/website/docs/Configuration/imports.md b/website/docs/Configuration/imports.md index 1d44149109e7..680c06ea29a2 100644 --- a/website/docs/Configuration/imports.md +++ b/website/docs/Configuration/imports.md @@ -1,13 +1,9 @@ --- -layout: default title: Importing / Extending Configuration -categories: configuration -parent: Configuration -nav_order: 11 +sidebar_position: 3 +sidebar_label: Importing Configuration --- - - # Importing Configuration By default the spell checker searches the current directory and up the hierarchy for the following files: diff --git a/website/docs/Configuration/language-settings.mdx b/website/docs/Configuration/language-settings.mdx index 1b3dd31ee5e2..6d81bee7e5e0 100644 --- a/website/docs/Configuration/language-settings.mdx +++ b/website/docs/Configuration/language-settings.mdx @@ -1,9 +1,7 @@ --- -layout: default title: Language Settings -categories: configuration -parent: Configuration -nav_order: 11 +sidebar_position: 8 +sidebar_label: Language Settings --- # Language Settings diff --git a/website/docs/Configuration/overrides.md b/website/docs/Configuration/overrides.md index 68f9a321ea7b..c07af57feea3 100644 --- a/website/docs/Configuration/overrides.md +++ b/website/docs/Configuration/overrides.md @@ -1,9 +1,7 @@ --- -layout: default title: Overrides -categories: configuration -parent: Configuration -nav_order: 11 +sidebar_position: 8 +sidebar_label: Overrides --- diff --git a/website/docs/Configuration/patterns.md b/website/docs/Configuration/patterns.md index 9ec996b069e0..a50c432e096a 100644 --- a/website/docs/Configuration/patterns.md +++ b/website/docs/Configuration/patterns.md @@ -1,13 +1,9 @@ --- -layout: default title: Exclude / Include Patterns -categories: configuration -parent: Configuration -nav_order: 11 +sidebar_position: 9 +sidebar_label: Exclude / Include --- - - # Exclude / Include Patterns **Covers:** diff --git a/website/package.json b/website/package.json index ea8d89d1b9d5..5f6a320850e5 100644 --- a/website/package.json +++ b/website/package.json @@ -19,6 +19,7 @@ "typecheck": "tsc" }, "dependencies": { + "@cspell/filetypes": "workspace:*", "@docusaurus/core": "^3.9.2", "@docusaurus/plugin-client-redirects": "^3.9.2", "@docusaurus/preset-classic": "^3.9.2", diff --git a/website/src/components/FileTypeTable.tsx b/website/src/components/FileTypeTable.tsx new file mode 100644 index 000000000000..3f39b2e54884 --- /dev/null +++ b/website/src/components/FileTypeTable.tsx @@ -0,0 +1,93 @@ +import React, { useState, useMemo } from 'react'; +import { fileTypeDefinitions, isBinaryFileType } from '@cspell/filetypes'; + +import './file-type-table.scss'; + +export const FileTypeTable = () => { + const [searchTerm, setSearchTerm] = useState(''); + const [showBinary, setShowBinary] = useState(false); + + const filteredFileTypes = useMemo(() => { + let filtered = fileTypeDefinitions; + + if (!showBinary) { + filtered = filtered.filter((f) => !isBinaryFileType(f.id)); + } + + if (searchTerm) { + const term = searchTerm.toLowerCase(); + filtered = filtered.filter((f) => { + const extensions = [...f.extensions, ...(f.filenames || [])].join(' ').toLowerCase(); + return ( + f.id.toLowerCase().includes(term) || + (f.description && f.description.toLowerCase().includes(term)) || + extensions.includes(term) + ); + }); + } + + return filtered; + }, [searchTerm, showBinary]); + + const binaryCount = fileTypeDefinitions.filter((f) => isBinaryFileType(f.id)).length; + const textCount = fileTypeDefinitions.length - binaryCount; + + return ( +
+
+ setSearchTerm(e.target.value)} + className="search-input" + /> +
+ +
+ + + Showing {filteredFileTypes.length} of {showBinary ? fileTypeDefinitions.length : textCount} file types + +
+ +
+
+
File Type ID
+
Description
+
Filenames
+
Extensions
+
+ +
+ {filteredFileTypes.map((m, index) => ( +
+
+ {m.id} + {m.format === 'Binary' && Binary} +
+
{m.description || '-'}
+
+ {m.filenames && {m.filenames.join(', ')}} + {!m.filenames && <>-} +
+
+ {m.extensions && {m.extensions.join(', ')}} + {!m.extensions && <>-} +
+
+ ))} +
+
+ + {filteredFileTypes.length === 0 &&

No file types found matching "{searchTerm}"

} + +

+ Total: {filteredFileTypes.length} file type{filteredFileTypes.length !== 1 ? 's' : ''} +

+
+ ); +}; diff --git a/website/src/components/file-type-table.scss b/website/src/components/file-type-table.scss new file mode 100644 index 000000000000..446ed8e2e924 --- /dev/null +++ b/website/src/components/file-type-table.scss @@ -0,0 +1,189 @@ +.languages-table-container { + width: 100%; + box-sizing: border-box; + + .search-box { + margin-bottom: 1.5rem; + + .search-input { + width: 100%; + padding: 0.75rem; + font-size: 1rem; + border: 1px solid var(--ifm-color-emphasis-300); + border-radius: 0.5rem; + background-color: var(--ifm-background-color); + color: var(--ifm-font-color-base); + transition: border-color 0.2s ease; + + &:focus { + outline: none; + border-color: var(--ifm-color-primary); + } + + &::placeholder { + color: var(--ifm-color-emphasis-600); + } + } + } + + .filter-controls { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 1rem; + padding: 0.75rem; + background-color: var(--ifm-color-emphasis-100); + border-radius: 0.5rem; + + .checkbox-label { + display: flex; + align-items: center; + gap: 0.5rem; + cursor: pointer; + font-size: 0.95rem; + + input[type='checkbox'] { + cursor: pointer; + } + } + + .info-text { + font-size: 0.9rem; + color: var(--ifm-color-emphasis-700); + } + } + + .table-wrapper { + width: 100%; + border: 1px solid var(--ifm-color-emphasis-500); + border-radius: 0.5rem; + overflow: hidden; + } + + .table-header { + display: grid; + grid-template-columns: 200px 250px 1fr 1fr; + background-color: var(--ifm-table-head-background); + font-weight: bold; + + .table-cell { + min-width: 0; + display: flex; + overflow: hidden; + align-items: center; + padding: 0.75rem 1rem; + justify-content: center; + border-right: 1px solid var(--ifm-color-emphasis-500); + + &:last-child { + border-right: none; + } + } + } + + .table-body { + .table-row { + display: grid; + grid-template-columns: 200px 250px 1fr 1fr; + border-top: 1px solid var(--ifm-color-emphasis-500); + + &.striped { + background-color: var(--ifm-table-head-background); + } + + .table-cell { + display: flex; + overflow: hidden; + align-items: center; + padding: 0.75rem 1rem; + min-width: 0; // Allow content to shrink + border-right: 1px solid var(--ifm-color-emphasis-500); + + &:last-child { + border-right: none; + } + + code { + display: flex; + align-items: center; + max-width: fit-content; + justify-content: center; + + &.extensions { + display: block; + white-space: pre-wrap; + word-break: break-word; + } + } + } + } + } + + .no-results { + text-align: center; + padding: 2rem; + color: var(--ifm-color-emphasis-600); + } + + .total-count { + margin-top: 1.5rem; + font-size: 0.9rem; + color: var(--ifm-color-emphasis-600); + } +} + +@media (max-width: 768px) { + .languages-table-container { + .table-header, + .table-body .table-row { + grid-template-columns: 150px 200px 1fr 1fr; + } + } +} + +@media (max-width: 576px) { + .languages-table-container { + .table-header, + .table-body .table-row { + grid-template-columns: 1fr; + + .table-cell { + border-right: none; + border-bottom: 1px solid var(--ifm-color-emphasis-400); + + &:last-child { + border-bottom: none; + } + } + } + + .table-body .table-row { + padding: 0.5rem 0; + + .table-cell { + &:before { + content: attr(data-label); + font-weight: bold; + display: block; + margin-bottom: 0.25rem; + } + } + } + } +} + +// Badge styles +.badge { + display: inline-block; + margin-left: 0.5rem; + padding: 0.125rem 0.5rem; + font-size: 0.75rem; + font-weight: 600; + border-radius: 0.25rem; + vertical-align: middle; + + &.binary-badge { + background-color: var(--ifm-color-warning-contrast-background); + color: var(--ifm-color-warning-contrast-foreground); + } +}