mirror of
https://github.com/zadam/trilium.git
synced 2025-12-26 17:24:23 +01:00
Icons for code notes by mime type (#8142)
This commit is contained in:
commit
b8d933d308
@ -1,3 +1,5 @@
|
||||
import { MIME_TYPES_DICT } from "@triliumnext/commons";
|
||||
|
||||
import cssClassManager from "../services/css_class_manager.js";
|
||||
import type { Froca } from "../services/froca-interface.js";
|
||||
import noteAttributeCache from "../services/note_attribute_cache.js";
|
||||
@ -597,8 +599,9 @@ export default class FNote {
|
||||
return "bx bx-folder";
|
||||
}
|
||||
return "bx bx-note";
|
||||
} else if (this.type === "code" && this.mime.startsWith("text/x-sql")) {
|
||||
return "bx bx-data";
|
||||
} else if (this.type === "code") {
|
||||
const correspondingMimeType = MIME_TYPES_DICT.find(m => m.mime === this.mime);
|
||||
return correspondingMimeType?.icon ?? NOTE_TYPE_ICONS.code;
|
||||
}
|
||||
return NOTE_TYPE_ICONS[this.type];
|
||||
}
|
||||
|
||||
@ -717,7 +717,6 @@ table.promoted-attributes-in-tooltip th {
|
||||
.tooltip {
|
||||
font-size: var(--main-font-size) !important;
|
||||
z-index: calc(var(--ck-z-panel) - 1) !important;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.tooltip.tooltip-top {
|
||||
|
||||
@ -428,7 +428,7 @@ function CodeNoteSwitcher({ note }: StatusBarContext) {
|
||||
return (note.type === "code" &&
|
||||
<>
|
||||
<StatusBarDropdown
|
||||
icon="bx bx-code-curly"
|
||||
icon={correspondingMimeType?.icon ?? "bx bx-code-curly"}
|
||||
text={correspondingMimeType?.title}
|
||||
title={t("status_bar.code_note_switcher")}
|
||||
dropdownContainerClassName="dropdown-code-note-switcher tn-dropdown-menu-scrollable"
|
||||
|
||||
@ -32,7 +32,8 @@ export function Badge({ icon, className, text, tooltip, href, ...containerProps
|
||||
fallbackPlacements: [ "bottom" ],
|
||||
animation: false,
|
||||
html: true,
|
||||
title: tooltip
|
||||
title: tooltip,
|
||||
customClass: "pre-wrap-text"
|
||||
});
|
||||
|
||||
const content = <>
|
||||
|
||||
@ -1,16 +1,18 @@
|
||||
import { useEffect, useRef, useState } from "preact/hooks";
|
||||
import { getThemeById, default as VanillaCodeMirror } from "@triliumnext/codemirror";
|
||||
import { TypeWidgetProps } from "../type_widget";
|
||||
import "./code.css";
|
||||
import CodeMirror, { CodeMirrorProps } from "./CodeMirror";
|
||||
import utils from "../../../services/utils";
|
||||
import { useEditorSpacedUpdate, useKeyboardShortcuts, useLegacyImperativeHandlers, useNoteBlob, useSyncedRef, useTriliumEvent, useTriliumOption, useTriliumOptionBool } from "../../react/hooks";
|
||||
import { t } from "../../../services/i18n";
|
||||
|
||||
import { default as VanillaCodeMirror, getThemeById } from "@triliumnext/codemirror";
|
||||
import { useEffect, useRef, useState } from "preact/hooks";
|
||||
|
||||
import appContext, { CommandListenerData } from "../../../components/app_context";
|
||||
import TouchBar, { TouchBarButton } from "../../react/TouchBar";
|
||||
import { refToJQuerySelector } from "../../react/react_utils";
|
||||
import { CODE_THEME_DEFAULT_PREFIX as DEFAULT_PREFIX } from "../constants";
|
||||
import FNote from "../../../entities/fnote";
|
||||
import { t } from "../../../services/i18n";
|
||||
import utils from "../../../services/utils";
|
||||
import { useEditorSpacedUpdate, useKeyboardShortcuts, useLegacyImperativeHandlers, useNoteBlob, useNoteProperty, useSyncedRef, useTriliumEvent, useTriliumOption, useTriliumOptionBool } from "../../react/hooks";
|
||||
import { refToJQuerySelector } from "../../react/react_utils";
|
||||
import TouchBar, { TouchBarButton } from "../../react/TouchBar";
|
||||
import { CODE_THEME_DEFAULT_PREFIX as DEFAULT_PREFIX } from "../constants";
|
||||
import { TypeWidgetProps } from "../type_widget";
|
||||
import CodeMirror, { CodeMirrorProps } from "./CodeMirror";
|
||||
|
||||
interface CodeEditorProps {
|
||||
/** By default, the code editor will try to match the color of the scrolling container to match the one from the theme for a full-screen experience. If the editor is embedded, it makes sense not to have this behaviour. */
|
||||
@ -51,7 +53,7 @@ export function ReadOnlyCode({ note, viewScope, ntxId, parentComponent }: TypeWi
|
||||
mime={note.mime}
|
||||
readOnly
|
||||
/>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function formatViewSource(note: FNote, content: string) {
|
||||
@ -74,6 +76,7 @@ export function EditableCode({ note, ntxId, noteContext, debounceUpdate, parentC
|
||||
const editorRef = useRef<VanillaCodeMirror>(null);
|
||||
const containerRef = useRef<HTMLPreElement>(null);
|
||||
const [ vimKeymapEnabled ] = useTriliumOptionBool("vimKeymapEnabled");
|
||||
const mime = useNoteProperty(note, "mime");
|
||||
const spacedUpdate = useEditorSpacedUpdate({
|
||||
note,
|
||||
noteContext,
|
||||
@ -107,7 +110,7 @@ export function EditableCode({ note, ntxId, noteContext, debounceUpdate, parentC
|
||||
<CodeEditor
|
||||
ntxId={ntxId} parentComponent={parentComponent}
|
||||
editorRef={editorRef} containerRef={containerRef}
|
||||
mime={note.mime}
|
||||
mime={mime ?? "text/plain"}
|
||||
className="note-detail-code-editor"
|
||||
placeholder={t("editable_code.placeholder")}
|
||||
vimKeybindings={vimKeymapEnabled}
|
||||
@ -130,7 +133,7 @@ export function EditableCode({ note, ntxId, noteContext, debounceUpdate, parentC
|
||||
)}
|
||||
</TouchBar>
|
||||
</>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export function CodeEditor({ parentComponent, ntxId, containerRef: externalContainerRef, editorRef: externalEditorRef, mime, onInitialized, lineWrapping, noBackgroundChange, ...editorProps }: CodeEditorProps & CodeMirrorProps & Pick<TypeWidgetProps, "parentComponent" | "ntxId">) {
|
||||
|
||||
@ -9,6 +9,7 @@ export interface MimeTypeDefinition {
|
||||
mime: string;
|
||||
/** The name of the language/mime type as defined by highlight.js (or one of the aliases), in order to be used for syntax highlighting such as inside code blocks. */
|
||||
mdLanguageCode?: string;
|
||||
icon?: string;
|
||||
}
|
||||
|
||||
export interface MimeType extends MimeTypeDefinition {
|
||||
@ -34,7 +35,7 @@ export function normalizeMimeTypeForCKEditor(mimeType: string) {
|
||||
*/
|
||||
|
||||
const MIME_TYPES_DICT_RAW = [
|
||||
{ title: "Plain text", mime: "text/plain", mdLanguageCode: "plaintext", default: true },
|
||||
{ title: "Plain text", mime: "text/plain", mdLanguageCode: "plaintext", default: true, icon: "bx bx-file" },
|
||||
|
||||
// Keep sorted alphabetically.
|
||||
{ title: "ABAP (SAP)", mime: "text/x-abap", mdLanguageCode: "abap" },
|
||||
@ -42,29 +43,29 @@ const MIME_TYPES_DICT_RAW = [
|
||||
{ title: "ASN.1", mime: "text/x-ttcn-asn" },
|
||||
{ title: "ASP.NET", mime: "application/x-aspx" },
|
||||
{ title: "Asterisk", mime: "text/x-asterisk" },
|
||||
{ title: "Batch file (DOS)", mime: "application/x-bat", mdLanguageCode: "dos" },
|
||||
{ title: "Batch file (DOS)", mime: "application/x-bat", mdLanguageCode: "dos", icon: "bx bx-terminal" },
|
||||
{ title: "Brainfuck", mime: "text/x-brainfuck", mdLanguageCode: "brainfuck" },
|
||||
{ title: "C", mime: "text/x-csrc", mdLanguageCode: "c", default: true },
|
||||
{ title: "C#", mime: "text/x-csharp", mdLanguageCode: "csharp", default: true },
|
||||
{ title: "C++", mime: "text/x-c++src", mdLanguageCode: "cpp", default: true },
|
||||
{ title: "C++", mime: "text/x-c++src", mdLanguageCode: "cpp", default: true, icon: "bx bxl-c-plus-plus" },
|
||||
{ title: "Clojure", mime: "text/x-clojure", mdLanguageCode: "clojure" },
|
||||
{ title: "ClojureScript", mime: "text/x-clojurescript" },
|
||||
{ title: "Closure Stylesheets (GSS)", mime: "text/x-gss" },
|
||||
{ title: "CMake", mime: "text/x-cmake", mdLanguageCode: "cmake" },
|
||||
{ title: "Cobol", mime: "text/x-cobol" },
|
||||
{ title: "CoffeeScript", mime: "text/coffeescript", mdLanguageCode: "coffeescript" },
|
||||
{ title: "CoffeeScript", mime: "text/coffeescript", mdLanguageCode: "coffeescript", icon: "bx bx-coffee" },
|
||||
{ title: "Common Lisp", mime: "text/x-common-lisp", mdLanguageCode: "lisp" },
|
||||
{ title: "CQL", mime: "text/x-cassandra" },
|
||||
{ title: "Crystal", mime: "text/x-crystal", mdLanguageCode: "crystal" },
|
||||
{ title: "CSS", mime: "text/css", mdLanguageCode: "css", default: true },
|
||||
{ title: "CSS", mime: "text/css", mdLanguageCode: "css", default: true, icon: "bx bxs-file-css" },
|
||||
{ title: "Cypher", mime: "application/x-cypher-query" },
|
||||
{ title: "Cython", mime: "text/x-cython" },
|
||||
{ title: "D", mime: "text/x-d", mdLanguageCode: "d" },
|
||||
{ title: "Dart", mime: "application/dart", mdLanguageCode: "dart" },
|
||||
{ title: "diff", mime: "text/x-diff", mdLanguageCode: "diff" },
|
||||
{ title: "Django", mime: "text/x-django", mdLanguageCode: "django" },
|
||||
{ title: "Dockerfile", mime: "text/x-dockerfile", mdLanguageCode: "dockerfile" },
|
||||
{ title: "DTD", mime: "application/xml-dtd" },
|
||||
{ title: "Django", mime: "text/x-django", mdLanguageCode: "django", icon: "bx bxl-django" },
|
||||
{ title: "Dockerfile", mime: "text/x-dockerfile", mdLanguageCode: "dockerfile", icon: "bx bxl-docker" },
|
||||
{ title: "DTD", mime: "application/xml-dtd", icon: "bx bx-code" },
|
||||
{ title: "Dylan", mime: "text/x-dylan" },
|
||||
{ title: "EBNF", mime: "text/x-ebnf", mdLanguageCode: "ebnf" },
|
||||
{ title: "ECL", mime: "text/x-ecl" },
|
||||
@ -84,44 +85,44 @@ const MIME_TYPES_DICT_RAW = [
|
||||
{ title: "Gas", mime: "text/x-gas" },
|
||||
{ title: "GDScript (Godot)", mime: "text/x-gdscript" },
|
||||
{ title: "Gherkin", mime: "text/x-feature", mdLanguageCode: "gherkin" },
|
||||
{ title: "GitHub Flavored Markdown", mime: "text/x-gfm", mdLanguageCode: "markdown" },
|
||||
{ title: "Go", mime: "text/x-go", mdLanguageCode: "go", default: true },
|
||||
{ title: "GitHub Flavored Markdown", mime: "text/x-gfm", mdLanguageCode: "markdown", icon: "bx bxl-markdown" },
|
||||
{ title: "Go", mime: "text/x-go", mdLanguageCode: "go", default: true, icon: "bx bxl-go-lang" },
|
||||
{ title: "Groovy", mime: "text/x-groovy", mdLanguageCode: "groovy", default: true },
|
||||
{ title: "HAML", mime: "text/x-haml", mdLanguageCode: "haml" },
|
||||
{ title: "Haskell (Literate)", mime: "text/x-literate-haskell" },
|
||||
{ title: "Haskell", mime: "text/x-haskell", mdLanguageCode: "haskell", default: true },
|
||||
{ title: "Haxe", mime: "text/x-haxe", mdLanguageCode: "haxe" },
|
||||
{ title: "HTML", mime: "text/html", mdLanguageCode: "xml", default: true },
|
||||
{ title: "HTML", mime: "text/html", mdLanguageCode: "xml", default: true, icon: "bx bxl-html5" },
|
||||
{ title: "HTTP", mime: "message/http", mdLanguageCode: "http", default: true },
|
||||
{ title: "HXML", mime: "text/x-hxml" },
|
||||
{ title: "IDL", mime: "text/x-idl" },
|
||||
{ title: "Java Server Pages", mime: "application/x-jsp", mdLanguageCode: "java" },
|
||||
{ title: "Java", mime: "text/x-java", mdLanguageCode: "java", default: true },
|
||||
{ title: "Java Server Pages", mime: "application/x-jsp", mdLanguageCode: "java", icon: "bx bxl-java" },
|
||||
{ title: "Java", mime: "text/x-java", mdLanguageCode: "java", default: true, icon: "bx bxl-java" },
|
||||
{ title: "Jinja2", mime: "text/jinja2" },
|
||||
{ title: "JS backend", mime: "application/javascript;env=backend", mdLanguageCode: "javascript", default: true },
|
||||
{ title: "JS frontend", mime: "application/javascript;env=frontend", mdLanguageCode: "javascript", default: true },
|
||||
{ title: "JSON-LD", mime: "application/ld+json", mdLanguageCode: "json" },
|
||||
{ title: "JSON", mime: "application/json", mdLanguageCode: "json", default: true },
|
||||
{ title: "JS backend", mime: "application/javascript;env=backend", mdLanguageCode: "javascript", default: true, icon: "bx bxl-javascript" },
|
||||
{ title: "JS frontend", mime: "application/javascript;env=frontend", mdLanguageCode: "javascript", default: true, icon: "bx bxl-javascript" },
|
||||
{ title: "JSON-LD", mime: "application/ld+json", mdLanguageCode: "json", icon: "bx bxs-file-json" },
|
||||
{ title: "JSON", mime: "application/json", mdLanguageCode: "json", default: true, icon: "bx bxs-file-json" },
|
||||
{ title: "JSX", mime: "text/jsx", mdLanguageCode: "javascript", default: true },
|
||||
{ title: "Julia", mime: "text/x-julia", mdLanguageCode: "julia" },
|
||||
{ title: "Kotlin", mime: "text/x-kotlin", mdLanguageCode: "kotlin", default: true },
|
||||
{ title: "KDL", mime: "application/vnd.kdl", mdLanguageCode: "kdl" },
|
||||
{ title: "LaTeX", mime: "text/x-latex", mdLanguageCode: "latex" },
|
||||
{ title: "LESS", mime: "text/x-less", mdLanguageCode: "less" },
|
||||
{ title: "LESS", mime: "text/x-less", mdLanguageCode: "less", icon: "bx bxl-less" },
|
||||
{ title: "LiveScript", mime: "text/x-livescript", mdLanguageCode: "livescript" },
|
||||
{ title: "Lua", mime: "text/x-lua", mdLanguageCode: "lua" },
|
||||
{ title: "MariaDB SQL", mime: "text/x-mariadb", mdLanguageCode: "sql" },
|
||||
{ title: "Markdown", mime: "text/x-markdown", mdLanguageCode: "markdown", default: true },
|
||||
{ title: "Markdown", mime: "text/x-markdown", mdLanguageCode: "markdown", default: true, icon: "bx bxl-markdown" },
|
||||
{ title: "Mathematica", mime: "text/x-mathematica", mdLanguageCode: "mathematica" },
|
||||
{ title: "mbox", mime: "application/mbox" },
|
||||
{ title: "MIPS Assembler", mime: "text/x-asm-mips", mdLanguageCode: "mips" },
|
||||
{ title: "mIRC", mime: "text/mirc" },
|
||||
{ title: "Modelica", mime: "text/x-modelica" },
|
||||
{ title: "MS SQL", mime: "text/x-mssql", mdLanguageCode: "sql" },
|
||||
{ title: "MS SQL", mime: "text/x-mssql", mdLanguageCode: "sql", icon: "bx bx-data" },
|
||||
{ title: "mscgen", mime: "text/x-mscgen" },
|
||||
{ title: "msgenny", mime: "text/x-msgenny" },
|
||||
{ title: "MUMPS", mime: "text/x-mumps" },
|
||||
{ title: "MySQL", mime: "text/x-mysql", mdLanguageCode: "sql" },
|
||||
{ title: "MySQL", mime: "text/x-mysql", mdLanguageCode: "sql", icon: "bx bx-data" },
|
||||
{ title: "Nix", mime: "text/x-nix", mdLanguageCode: "nix" },
|
||||
{ title: "Nginx", mime: "text/x-nginx-conf", mdLanguageCode: "nginx" },
|
||||
{ title: "NSIS", mime: "text/x-nsis", mdLanguageCode: "nsis" },
|
||||
@ -134,16 +135,16 @@ const MIME_TYPES_DICT_RAW = [
|
||||
{ title: "PEG.js", mime: "text/x-pegjs" },
|
||||
{ title: "Perl", mime: "text/x-perl", default: true },
|
||||
{ title: "PGP", mime: "application/pgp" },
|
||||
{ title: "PHP", mime: "text/x-php", default: true },
|
||||
{ title: "PHP", mime: "text/x-php", default: true, icon: "bx bxl-php" },
|
||||
{ title: "Pig", mime: "text/x-pig" },
|
||||
{ title: "PLSQL", mime: "text/x-plsql", mdLanguageCode: "sql" },
|
||||
{ title: "PostgreSQL", mime: "text/x-pgsql", mdLanguageCode: "pgsql" },
|
||||
{ title: "PowerShell", mime: "application/x-powershell", mdLanguageCode: "powershell" },
|
||||
{ title: "PostgreSQL", mime: "text/x-pgsql", mdLanguageCode: "pgsql", icon: "bx bxl-postgresql" },
|
||||
{ title: "PowerShell", mime: "application/x-powershell", mdLanguageCode: "powershell", icon: "bx bxs-terminal" },
|
||||
{ title: "Properties files", mime: "text/x-properties", mdLanguageCode: "properties" },
|
||||
{ title: "ProtoBuf", mime: "text/x-protobuf", mdLanguageCode: "protobuf" },
|
||||
{ title: "Pug", mime: "text/x-pug" },
|
||||
{ title: "Puppet", mime: "text/x-puppet", mdLanguageCode: "puppet" },
|
||||
{ title: "Python", mime: "text/x-python", mdLanguageCode: "python", default: true },
|
||||
{ title: "Python", mime: "text/x-python", mdLanguageCode: "python", default: true, icon: "bx bxl-python" },
|
||||
{ title: "Q", mime: "text/x-q", mdLanguageCode: "q" },
|
||||
{ title: "R", mime: "text/x-rsrc", mdLanguageCode: "r" },
|
||||
{ title: "reStructuredText", mime: "text/x-rst" },
|
||||
@ -152,11 +153,11 @@ const MIME_TYPES_DICT_RAW = [
|
||||
{ title: "Ruby", mime: "text/x-ruby", mdLanguageCode: "ruby", default: true },
|
||||
{ title: "Rust", mime: "text/x-rustsrc", mdLanguageCode: "rust" },
|
||||
{ title: "SAS", mime: "text/x-sas", mdLanguageCode: "sas" },
|
||||
{ title: "Sass", mime: "text/x-sass" },
|
||||
{ title: "Sass", mime: "text/x-sass", icon: "bx bxl-sass" },
|
||||
{ title: "Scala", mime: "text/x-scala" },
|
||||
{ title: "Scheme", mime: "text/x-scheme" },
|
||||
{ title: "SCSS", mime: "text/x-scss", mdLanguageCode: "scss" },
|
||||
{ title: "Shell (bash)", mime: "text/x-sh", mdLanguageCode: "bash", default: true },
|
||||
{ title: "Shell (bash)", mime: "text/x-sh", mdLanguageCode: "bash", default: true, icon: "bx bx-terminal" },
|
||||
{ title: "Sieve", mime: "application/sieve" },
|
||||
{ title: "Slim", mime: "text/x-slim" },
|
||||
{ title: "Smalltalk", mime: "text/x-stsrc", mdLanguageCode: "smalltalk" },
|
||||
@ -166,9 +167,9 @@ const MIME_TYPES_DICT_RAW = [
|
||||
{ title: "Soy", mime: "text/x-soy" },
|
||||
{ title: "SPARQL", mime: "application/sparql-query" },
|
||||
{ title: "Spreadsheet", mime: "text/x-spreadsheet" },
|
||||
{ title: "SQL", mime: "text/x-sql", mdLanguageCode: "sql", default: true },
|
||||
{ title: "SQLite (Trilium)", mime: "text/x-sqlite;schema=trilium", mdLanguageCode: "sql", default: true },
|
||||
{ title: "SQLite", mime: "text/x-sqlite", mdLanguageCode: "sql" },
|
||||
{ title: "SQL", mime: "text/x-sql", mdLanguageCode: "sql", default: true, icon: "bx bx-data" },
|
||||
{ title: "SQLite (Trilium)", mime: "text/x-sqlite;schema=trilium", mdLanguageCode: "sql", default: true, icon: "bx bx-data" },
|
||||
{ title: "SQLite", mime: "text/x-sqlite", mdLanguageCode: "sql", icon: "bx bx-data" },
|
||||
{ title: "Squirrel", mime: "text/x-squirrel" },
|
||||
{ title: "sTeX", mime: "text/x-stex" },
|
||||
{ title: "Stylus", mime: "text/x-styl", mdLanguageCode: "stylus" },
|
||||
@ -179,7 +180,7 @@ const MIME_TYPES_DICT_RAW = [
|
||||
{ title: "Textile", mime: "text/x-textile" },
|
||||
{ title: "TiddlyWiki ", mime: "text/x-tiddlywiki" },
|
||||
{ title: "Tiki wiki", mime: "text/tiki" },
|
||||
{ title: "TOML", mime: "text/x-toml", mdLanguageCode: "ini" },
|
||||
{ title: "TOML", mime: "text/x-toml", mdLanguageCode: "ini", icon: "bx bx-bracket" },
|
||||
{ title: "Tornado", mime: "text/x-tornado" },
|
||||
{ title: "troff", mime: "text/troff" },
|
||||
{ title: "TTCN_CFG", mime: "text/x-ttcn-cfg" },
|
||||
@ -187,7 +188,7 @@ const MIME_TYPES_DICT_RAW = [
|
||||
{ title: "Turtle", mime: "text/turtle" },
|
||||
{ title: "Twig", mime: "text/x-twig", mdLanguageCode: "twig" },
|
||||
{ title: "TypeScript-JSX", mime: "text/typescript-jsx" },
|
||||
{ title: "TypeScript", mime: "application/typescript", mdLanguageCode: "typescript" },
|
||||
{ title: "TypeScript", mime: "application/typescript", mdLanguageCode: "typescript", icon: "bx bxl-typescript" },
|
||||
{ title: "VB.NET", mime: "text/x-vb", mdLanguageCode: "vbnet" },
|
||||
{ title: "VBScript", mime: "text/vbscript", mdLanguageCode: "vbscript" },
|
||||
{ title: "Velocity", mime: "text/velocity" },
|
||||
@ -195,7 +196,7 @@ const MIME_TYPES_DICT_RAW = [
|
||||
{ title: "VHDL", mime: "text/x-vhdl", mdLanguageCode: "vhdl" },
|
||||
{ title: "Vue.js Component", mime: "text/x-vue" },
|
||||
{ title: "Web IDL", mime: "text/x-webidl" },
|
||||
{ title: "XML", mime: "text/xml", mdLanguageCode: "xml", default: true },
|
||||
{ title: "XML", mime: "text/xml", mdLanguageCode: "xml", default: true, icon: "bx bx-code-alt" },
|
||||
{ title: "XQuery", mime: "application/xquery", mdLanguageCode: "xquery" },
|
||||
{ title: "xu", mime: "text/x-xu" },
|
||||
{ title: "Yacas", mime: "text/x-yacas" },
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user