mirror of
https://github.com/outline/outline.git
synced 2026-06-13 19:35:02 +03:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7967f10341 |
@@ -10,8 +10,8 @@ import {
|
||||
import { Decoration, DecorationSet } from "prosemirror-view";
|
||||
import * as React from "react";
|
||||
import { v4 } from "uuid";
|
||||
import { LANGUAGES } from "@shared/editor/extensions/Prism";
|
||||
import Extension, { WidgetProps } from "@shared/editor/lib/Extension";
|
||||
import { codeLanguages } from "@shared/editor/lib/code";
|
||||
import isMarkdown from "@shared/editor/lib/isMarkdown";
|
||||
import normalizePastedMarkdown from "@shared/editor/lib/markdown/normalize";
|
||||
import { isRemoteTransaction } from "@shared/editor/lib/multiplayer";
|
||||
@@ -228,7 +228,7 @@ export default class PasteHandler extends Extension {
|
||||
state.tr
|
||||
.replaceSelectionWith(
|
||||
state.schema.nodes.code_block.create({
|
||||
language: Object.keys(LANGUAGES).includes(
|
||||
language: Object.keys(codeLanguages).includes(
|
||||
vscodeMeta.mode
|
||||
)
|
||||
? vscodeMeta.mode
|
||||
|
||||
+13
-12
@@ -2,8 +2,11 @@ import { CopyIcon, ExpandedIcon } from "outline-icons";
|
||||
import { Node as ProseMirrorNode } from "prosemirror-model";
|
||||
import { EditorState } from "prosemirror-state";
|
||||
import * as React from "react";
|
||||
import { LANGUAGES } from "@shared/editor/extensions/Prism";
|
||||
import { getFrequentCodeLanguages } from "@shared/editor/lib/code";
|
||||
import {
|
||||
getFrequentCodeLanguages,
|
||||
codeLanguages,
|
||||
getLabelForLanguage,
|
||||
} from "@shared/editor/lib/code";
|
||||
import { MenuItem } from "@shared/editor/types";
|
||||
import { Dictionary } from "~/hooks/useDictionary";
|
||||
|
||||
@@ -14,20 +17,19 @@ export default function codeMenuItems(
|
||||
): MenuItem[] {
|
||||
const node = state.selection.$from.node();
|
||||
|
||||
const allLanguages = Object.entries(LANGUAGES) as [
|
||||
keyof typeof LANGUAGES,
|
||||
string
|
||||
][];
|
||||
const frequentLanguages = getFrequentCodeLanguages();
|
||||
|
||||
const frequentLangMenuItems = frequentLanguages.map((value) => {
|
||||
const label = LANGUAGES[value];
|
||||
const label = codeLanguages[value]?.label;
|
||||
return langToMenuItem({ node, value, label });
|
||||
});
|
||||
|
||||
const remainingLangMenuItems = allLanguages
|
||||
.filter(([value]) => !frequentLanguages.includes(value))
|
||||
.map(([value, label]) => langToMenuItem({ node, value, label }));
|
||||
const remainingLangMenuItems = Object.entries(codeLanguages)
|
||||
.filter(
|
||||
([value]) =>
|
||||
!frequentLanguages.includes(value as keyof typeof codeLanguages)
|
||||
)
|
||||
.map(([value, item]) => langToMenuItem({ node, value, label: item.label }));
|
||||
|
||||
const languageMenuItems = frequentLangMenuItems.length
|
||||
? [
|
||||
@@ -52,8 +54,7 @@ export default function codeMenuItems(
|
||||
visible: !readOnly,
|
||||
name: "code_block",
|
||||
icon: <ExpandedIcon />,
|
||||
// @ts-expect-error We have a fallback for incorrect mapping
|
||||
label: LANGUAGES[node.attrs.language ?? "none"],
|
||||
label: getLabelForLanguage(node.attrs.language ?? "none"),
|
||||
children: languageMenuItems,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -4,62 +4,10 @@ import { Node } from "prosemirror-model";
|
||||
import { Plugin, PluginKey, Transaction } from "prosemirror-state";
|
||||
import { Decoration, DecorationSet } from "prosemirror-view";
|
||||
import refractor from "refractor/core";
|
||||
import { getPrismLangForLanguage } from "../lib/code";
|
||||
import { isRemoteTransaction } from "../lib/multiplayer";
|
||||
import { findBlockNodes } from "../queries/findChildren";
|
||||
|
||||
export const LANGUAGES = {
|
||||
none: "Plain text", // additional entry to disable highlighting
|
||||
bash: "Bash",
|
||||
clike: "C",
|
||||
cpp: "C++",
|
||||
csharp: "C#",
|
||||
css: "CSS",
|
||||
docker: "Docker",
|
||||
elixir: "Elixir",
|
||||
erlang: "Erlang",
|
||||
go: "Go",
|
||||
graphql: "GraphQL",
|
||||
groovy: "Groovy",
|
||||
haskell: "Haskell",
|
||||
hcl: "HCL",
|
||||
markup: "HTML",
|
||||
ini: "INI",
|
||||
java: "Java",
|
||||
javascript: "JavaScript",
|
||||
json: "JSON",
|
||||
jsx: "JSX",
|
||||
kotlin: "Kotlin",
|
||||
lisp: "Lisp",
|
||||
lua: "Lua",
|
||||
mermaidjs: "Mermaid Diagram",
|
||||
nginx: "Nginx",
|
||||
nix: "Nix",
|
||||
objectivec: "Objective-C",
|
||||
ocaml: "OCaml",
|
||||
perl: "Perl",
|
||||
php: "PHP",
|
||||
powershell: "Powershell",
|
||||
protobuf: "Protobuf",
|
||||
python: "Python",
|
||||
r: "R",
|
||||
ruby: "Ruby",
|
||||
rust: "Rust",
|
||||
scala: "Scala",
|
||||
sass: "Sass",
|
||||
scss: "SCSS",
|
||||
sql: "SQL",
|
||||
solidity: "Solidity",
|
||||
swift: "Swift",
|
||||
toml: "TOML",
|
||||
tsx: "TSX",
|
||||
typescript: "TypeScript",
|
||||
vb: "Visual Basic",
|
||||
verilog: "Verilog",
|
||||
vhdl: "VHDL",
|
||||
yaml: "YAML",
|
||||
zig: "Zig",
|
||||
};
|
||||
|
||||
type ParsedNode = {
|
||||
text: string;
|
||||
classes: string[];
|
||||
@@ -109,12 +57,9 @@ function getDecorations({
|
||||
|
||||
blocks.forEach((block) => {
|
||||
let startPos = block.pos + 1;
|
||||
const language = (
|
||||
block.node.attrs.language === "mermaidjs"
|
||||
? "mermaid"
|
||||
: block.node.attrs.language
|
||||
) as string;
|
||||
if (!language || language === "none" || !refractor.registered(language)) {
|
||||
const language = getPrismLangForLanguage(block.node.attrs.language);
|
||||
|
||||
if (!language || !refractor.registered(language)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+105
-11
@@ -1,14 +1,97 @@
|
||||
import Storage from "../../utils/Storage";
|
||||
import { LANGUAGES } from "../extensions/Prism";
|
||||
|
||||
const RecentStorageKey = "rme-code-language";
|
||||
const StorageKey = "frequent-code-languages";
|
||||
const frequentLanguagesToGet = 5;
|
||||
const frequentLanguagesToTrack = 10;
|
||||
|
||||
export const FrequentlyUsedCount = {
|
||||
Get: 5,
|
||||
Track: 10,
|
||||
/**
|
||||
* List of supported code languages.
|
||||
*
|
||||
* Object key is the language identifier used in the editor, lang is the
|
||||
* language identifier used by Prism. Note mismatches such as `markup` and
|
||||
* `mermaid`.
|
||||
*/
|
||||
export const codeLanguages = {
|
||||
none: { lang: "", label: "Plain text" },
|
||||
bash: { lang: "bash", label: "Bash" },
|
||||
clike: { lang: "clike", label: "C" },
|
||||
cpp: { lang: "cpp", label: "C++" },
|
||||
csharp: { lang: "csharp", label: "C#" },
|
||||
css: { lang: "css", label: "CSS" },
|
||||
docker: { lang: "docker", label: "Docker" },
|
||||
elixir: { lang: "elixir", label: "Elixir" },
|
||||
erlang: { lang: "erlang", label: "Erlang" },
|
||||
go: { lang: "go", label: "Go" },
|
||||
graphql: { lang: "graphql", label: "GraphQL" },
|
||||
groovy: { lang: "groovy", label: "Groovy" },
|
||||
haskell: { lang: "haskell", label: "Haskell" },
|
||||
hcl: { lang: "hcl", label: "HCL" },
|
||||
markup: { lang: "markup", label: "HTML" },
|
||||
ini: { lang: "ini", label: "INI" },
|
||||
java: { lang: "java", label: "Java" },
|
||||
javascript: { lang: "javascript", label: "JavaScript" },
|
||||
json: { lang: "json", label: "JSON" },
|
||||
jsx: { lang: "jsx", label: "JSX" },
|
||||
kotlin: { lang: "kotlin", label: "Kotlin" },
|
||||
lisp: { lang: "lisp", label: "Lisp" },
|
||||
lua: { lang: "lua", label: "Lua" },
|
||||
mermaidjs: { lang: "mermaid", label: "Mermaid Diagram" },
|
||||
nginx: { lang: "nginx", label: "Nginx" },
|
||||
nix: { lang: "nix", label: "Nix" },
|
||||
objectivec: { lang: "objectivec", label: "Objective-C" },
|
||||
ocaml: { lang: "ocaml", label: "OCaml" },
|
||||
perl: { lang: "perl", label: "Perl" },
|
||||
php: { lang: "php", label: "PHP" },
|
||||
powershell: { lang: "powershell", label: "Powershell" },
|
||||
protobuf: { lang: "protobuf", label: "Protobuf" },
|
||||
python: { lang: "python", label: "Python" },
|
||||
r: { lang: "r", label: "R" },
|
||||
ruby: { lang: "ruby", label: "Ruby" },
|
||||
rust: { lang: "rust", label: "Rust" },
|
||||
scala: { lang: "scala", label: "Scala" },
|
||||
sass: { lang: "sass", label: "Sass" },
|
||||
scss: { lang: "scss", label: "SCSS" },
|
||||
sql: { lang: "sql", label: "SQL" },
|
||||
solidity: { lang: "solidity", label: "Solidity" },
|
||||
swift: { lang: "swift", label: "Swift" },
|
||||
toml: { lang: "toml", label: "TOML" },
|
||||
tsx: { lang: "tsx", label: "TSX" },
|
||||
typescript: { lang: "typescript", label: "TypeScript" },
|
||||
vb: { lang: "vb", label: "Visual Basic" },
|
||||
verilog: { lang: "verilog", label: "Verilog" },
|
||||
vhdl: { lang: "vhdl", label: "VHDL" },
|
||||
yaml: { lang: "yaml", label: "YAML" },
|
||||
xml: { lang: "markup", label: "XML" },
|
||||
zig: { lang: "zig", label: "Zig" },
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the human-readable label for a given language.
|
||||
*
|
||||
* @param language The language identifier.
|
||||
* @returns The human-readable label for the language.
|
||||
*/
|
||||
export const getLabelForLanguage = (language: keyof typeof codeLanguages) => {
|
||||
const lang = codeLanguages[language];
|
||||
return lang ? lang.label : language;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the Prism language identifier for a given language.
|
||||
*
|
||||
* @param language The language identifier.
|
||||
* @returns The Prism language identifier for the language.
|
||||
*/
|
||||
export const getPrismLangForLanguage = (
|
||||
language: keyof typeof codeLanguages
|
||||
): string | undefined => codeLanguages[language].lang;
|
||||
|
||||
/**
|
||||
* Set the most recent code language used.
|
||||
*
|
||||
* @param language The language identifier.
|
||||
*/
|
||||
export const setRecentCodeLanguage = (language: string) => {
|
||||
const frequentLangs = (Storage.get(StorageKey) ?? {}) as Record<
|
||||
string,
|
||||
@@ -26,14 +109,14 @@ export const setRecentCodeLanguage = (language: string) => {
|
||||
|
||||
const frequentLangEntries = Object.entries(frequentLangs);
|
||||
|
||||
if (frequentLangEntries.length > FrequentlyUsedCount.Track) {
|
||||
if (frequentLangEntries.length > frequentLanguagesToTrack) {
|
||||
sortFrequencies(frequentLangEntries);
|
||||
|
||||
const lastEntry = frequentLangEntries[FrequentlyUsedCount.Track];
|
||||
const lastEntry = frequentLangEntries[frequentLanguagesToTrack];
|
||||
if (lastEntry[0] === language) {
|
||||
frequentLangEntries.splice(FrequentlyUsedCount.Track - 1, 1);
|
||||
frequentLangEntries.splice(frequentLanguagesToTrack - 1, 1);
|
||||
} else {
|
||||
frequentLangEntries.splice(FrequentlyUsedCount.Track);
|
||||
frequentLangEntries.splice(frequentLanguagesToTrack);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,17 +124,28 @@ export const setRecentCodeLanguage = (language: string) => {
|
||||
Storage.set(RecentStorageKey, language);
|
||||
};
|
||||
|
||||
export const getRecentCodeLanguage = () => Storage.get(RecentStorageKey);
|
||||
/**
|
||||
* Get the most recent code language used.
|
||||
*
|
||||
* @returns The most recent code language used, or undefined if none is set.
|
||||
*/
|
||||
export const getRecentCodeLanguage = () =>
|
||||
Storage.get(RecentStorageKey) as keyof typeof codeLanguages | undefined;
|
||||
|
||||
/**
|
||||
* Get the most frequent code languages used.
|
||||
*
|
||||
* @returns An array of the most frequent code languages used.
|
||||
*/
|
||||
export const getFrequentCodeLanguages = () => {
|
||||
const recentLang = Storage.get(RecentStorageKey);
|
||||
const frequentLangEntries = Object.entries(Storage.get(StorageKey) ?? {}) as [
|
||||
keyof typeof LANGUAGES,
|
||||
keyof typeof codeLanguages,
|
||||
number
|
||||
][];
|
||||
|
||||
const frequentLangs = sortFrequencies(frequentLangEntries)
|
||||
.slice(0, FrequentlyUsedCount.Get)
|
||||
.slice(0, frequentLanguagesToGet)
|
||||
.map(([lang]) => lang);
|
||||
|
||||
const isRecentLangPresent = frequentLangs.includes(recentLang);
|
||||
|
||||
Reference in New Issue
Block a user