baseTheme.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. import {
  2. EditorView,
  3. keymap,
  4. highlightSpecialChars,
  5. highlightActiveLine,
  6. drawSelection,
  7. dropCursor,
  8. } from "@codemirror/view"
  9. import {
  10. HighlightStyle,
  11. tags as t,
  12. defaultHighlightStyle,
  13. } from "@codemirror/highlight"
  14. import { foldKeymap, foldGutter } from "@codemirror/fold"
  15. import { Extension, EditorState } from "@codemirror/state"
  16. import { history, historyKeymap } from "@codemirror/history"
  17. import { indentOnInput } from "@codemirror/language"
  18. import { lineNumbers, highlightActiveLineGutter } from "@codemirror/gutter"
  19. import { defaultKeymap } from "@codemirror/commands"
  20. import { bracketMatching } from "@codemirror/matchbrackets"
  21. import { closeBrackets, closeBracketsKeymap } from "@codemirror/closebrackets"
  22. import {
  23. searchKeymap,
  24. highlightSelectionMatches,
  25. search,
  26. } from "@codemirror/search"
  27. import { autocompletion, completionKeymap } from "@codemirror/autocomplete"
  28. import { commentKeymap } from "@codemirror/comment"
  29. import {
  30. rectangularSelection,
  31. crosshairCursor,
  32. } from "@codemirror/rectangular-selection"
  33. import { lintKeymap } from "@codemirror/lint"
  34. export const baseTheme = EditorView.theme({
  35. "&": {
  36. fontSize: "var(--font-size-body)",
  37. height: "100%",
  38. width: "100%",
  39. flex: "1",
  40. },
  41. ".cm-content": {
  42. caretColor: "var(--secondary-dark-color)",
  43. fontFamily: "var(--font-mono)",
  44. backgroundColor: "var(--primary-color)",
  45. },
  46. ".cm-cursor": {
  47. borderColor: "var(--secondary-color)",
  48. },
  49. ".cm-widgetBuffer": {
  50. position: "absolute",
  51. },
  52. ".cm-selectionBackground": {
  53. backgroundColor: "var(--accent-dark-color)",
  54. color: "var(--accent-contrast-color)",
  55. },
  56. ".cm-panels": {
  57. backgroundColor: "var(--primary-light-color)",
  58. color: "var(--secondary-light-color)",
  59. },
  60. ".cm-panels.cm-panels-top": {
  61. borderBottom: "1px solid var(--divider-light-color)",
  62. top: "var(--lower-tertiary-sticky-fold) !important",
  63. "z-index": "10",
  64. },
  65. ".cm-panels.cm-panels-bottom": {
  66. borderTop: "1px solid var(--divider-light-color)",
  67. },
  68. ".cm-search": {
  69. display: "flex",
  70. alignItems: "center",
  71. flexWrap: "nowrap",
  72. flexShrink: 0,
  73. overflow: "auto",
  74. },
  75. ".cm-search label": {
  76. display: "inline-flex",
  77. alignItems: "center",
  78. },
  79. ".cm-textfield": {
  80. backgroundColor: "var(--primary-dark-color)",
  81. color: "var(--secondary-dark-color)",
  82. borderColor: "var(--divider-light-color)",
  83. borderRadius: "3px",
  84. },
  85. ".cm-button": {
  86. backgroundColor: "var(--primary-dark-color)",
  87. color: "var(--secondary-dark-color)",
  88. backgroundImage: "none",
  89. border: "none",
  90. },
  91. ".cm-completionLabel": {
  92. color: "var(--secondary-color)",
  93. },
  94. ".cm-tooltip": {
  95. backgroundColor: "var(--primary-dark-color)",
  96. color: "var(--secondary-light-color)",
  97. border: "none",
  98. borderRadius: "3px",
  99. },
  100. ".cm-tooltip-arrow:after": {
  101. borderColor: "transparent !important",
  102. },
  103. ".cm-tooltip-arrow:before": {
  104. borderColor: "transparent !important",
  105. },
  106. ".cm-tooltip.cm-tooltip-autocomplete > ul": {
  107. fontFamily: "var(--font-mono)",
  108. },
  109. ".cm-tooltip-autocomplete ul li[aria-selected]": {
  110. backgroundColor: "var(--accent-dark-color)",
  111. color: "var(--accent-contrast-color)",
  112. },
  113. ".cm-tooltip-autocomplete ul li[aria-selected] .cm-completionLabel": {
  114. color: "var(--accent-contrast-color)",
  115. },
  116. ".cm-activeLine": { backgroundColor: "transparent" },
  117. ".cm-searchMatch": {
  118. outline: "1px solid var(--accent-dark-color)",
  119. backgroundColor: "var(--divider-dark-color)",
  120. },
  121. ".cm-selectionMatch": {
  122. outline: "1px solid var(--accent-dark-color)",
  123. backgroundColor: "var(--divider-light-color)",
  124. },
  125. ".cm-matchingBracket, .cm-nonmatchingBracket": {
  126. backgroundColor: "var(--divider-color)",
  127. outline: "1px solid var(--accent-dark-color)",
  128. },
  129. ".cm-gutters": {
  130. fontFamily: "var(--font-mono)",
  131. backgroundColor: "var(--primary-color)",
  132. borderColor: "var(--divider-light-color)",
  133. },
  134. ".cm-lineNumbers": {
  135. minWidth: "3em",
  136. color: "var(--secondary-light-color)",
  137. },
  138. ".cm-foldGutter": {
  139. minWidth: "2em",
  140. color: "var(--secondary-light-color)",
  141. },
  142. ".cm-foldGutter .cm-gutterElement": {
  143. textAlign: "center",
  144. },
  145. ".cm-line": {
  146. paddingLeft: "0.5em",
  147. paddingRight: "0.5em",
  148. },
  149. ".cm-activeLineGutter": {
  150. backgroundColor: "transparent",
  151. },
  152. ".cm-scroller::-webkit-scrollbar": {
  153. display: "none",
  154. },
  155. ".cm-foldPlaceholder": {
  156. backgroundColor: "var(--divider-light-color)",
  157. color: "var(--secondary-dark-color)",
  158. borderColor: "var(--divider-dark-color)",
  159. },
  160. })
  161. export const inputTheme = EditorView.theme({
  162. "&": {
  163. fontSize: "var(--font-size-body)",
  164. height: "100%",
  165. width: "100%",
  166. flex: "1",
  167. },
  168. ".cm-content": {
  169. caretColor: "var(--secondary-dark-color)",
  170. fontFamily: "var(--font-sans)",
  171. color: "var(--secondary-dark-color)",
  172. backgroundColor: "transparent",
  173. },
  174. ".cm-cursor": {
  175. borderColor: "var(--secondary-color)",
  176. },
  177. ".cm-widgetBuffer": {
  178. position: "absolute",
  179. },
  180. ".cm-selectionBackground": {
  181. backgroundColor: "var(--accent-dark-color)",
  182. color: "var(--accent-contrast-color)",
  183. },
  184. ".cm-panels": {
  185. backgroundColor: "var(--primary-light-color)",
  186. color: "var(--secondary-light-color)",
  187. },
  188. ".cm-panels.cm-panels-top": {
  189. borderBottom: "1px solid var(--divider-light-color)",
  190. },
  191. ".cm-panels.cm-panels-bottom": {
  192. borderTop: "1px solid var(--divider-light-color)",
  193. },
  194. ".cm-search": {
  195. display: "flex",
  196. alignItems: "center",
  197. flexWrap: "nowrap",
  198. flexShrink: 0,
  199. overflow: "auto",
  200. },
  201. ".cm-search label": {
  202. display: "inline-flex",
  203. alignItems: "center",
  204. },
  205. ".cm-textfield": {
  206. backgroundColor: "var(--primary-dark-color)",
  207. color: "var(--secondary-dark-color)",
  208. borderColor: "var(--divider-light-color)",
  209. borderRadius: "3px",
  210. },
  211. ".cm-button": {
  212. backgroundColor: "var(--primary-dark-color)",
  213. color: "var(--secondary-dark-color)",
  214. backgroundImage: "none",
  215. border: "none",
  216. },
  217. ".cm-completionLabel": {
  218. color: "var(--secondary-color)",
  219. },
  220. ".cm-tooltip": {
  221. backgroundColor: "var(--primary-dark-color)",
  222. color: "var(--secondary-light-color)",
  223. border: "none",
  224. borderRadius: "3px",
  225. },
  226. ".cm-tooltip-arrow:after": {
  227. borderColor: "transparent !important",
  228. },
  229. ".cm-tooltip-arrow:before": {
  230. borderColor: "transparent !important",
  231. },
  232. ".cm-tooltip.cm-tooltip-autocomplete > ul": {
  233. fontFamily: "var(--font-mono)",
  234. },
  235. ".cm-tooltip-autocomplete ul li[aria-selected]": {
  236. backgroundColor: "var(--accent-dark-color)",
  237. color: "var(--accent-contrast-color)",
  238. },
  239. ".cm-tooltip-autocomplete ul li[aria-selected] .cm-completionLabel": {
  240. color: "var(--accent-contrast-color)",
  241. },
  242. ".cm-activeLine": { backgroundColor: "transparent" },
  243. ".cm-searchMatch": {
  244. outline: "1px solid var(--accent-dark-color)",
  245. backgroundColor: "var(--divider-dark-color)",
  246. },
  247. ".cm-selectionMatch": {
  248. outline: "1px solid var(--accent-dark-color)",
  249. backgroundColor: "var(--divider-light-color)",
  250. },
  251. ".cm-matchingBracket, .cm-nonmatchingBracket": {
  252. backgroundColor: "var(--divider-color)",
  253. outline: "1px solid var(--accent-dark-color)",
  254. },
  255. ".cm-gutters": {
  256. fontFamily: "var(--font-mono)",
  257. backgroundColor: "var(--primary-color)",
  258. borderColor: "var(--divider-light-color)",
  259. },
  260. ".cm-lineNumbers": {
  261. minWidth: "3em",
  262. color: "var(--secondary-light-color)",
  263. },
  264. ".cm-foldGutter": {
  265. minWidth: "2em",
  266. color: "var(--secondary-light-color)",
  267. },
  268. ".cm-foldGutter .cm-gutterElement": {
  269. textAlign: "center",
  270. },
  271. ".cm-line": {
  272. paddingLeft: "1rem",
  273. paddingRight: "1rem",
  274. paddingTop: "0.2rem",
  275. paddingBottom: "0.2rem",
  276. },
  277. ".cm-activeLineGutter": {
  278. backgroundColor: "transparent",
  279. },
  280. ".cm-scroller::-webkit-scrollbar": {
  281. display: "none",
  282. },
  283. ".cm-foldPlaceholder": {
  284. backgroundColor: "var(--divider-light-color)",
  285. color: "var(--secondary-dark-color)",
  286. borderColor: "var(--divider-dark-color)",
  287. },
  288. })
  289. const editorTypeColor = "var(--editor-type-color)"
  290. const editorNameColor = "var(--editor-name-color)"
  291. const editorOperatorColor = "var(--editor-operator-color)"
  292. const editorInvalidColor = "var(--editor-invalid-color)"
  293. const editorSeparatorColor = "var(--editor-separator-color)"
  294. const editorMetaColor = "var(--editor-meta-color)"
  295. const editorVariableColor = "var(--editor-variable-color)"
  296. const editorLinkColor = "var(--editor-link-color)"
  297. const editorProcessColor = "var(--editor-process-color)"
  298. const editorConstantColor = "var(--editor-constant-color)"
  299. const editorKeywordColor = "var(--editor-keyword-color)"
  300. export const baseHighlightStyle = HighlightStyle.define([
  301. { tag: t.keyword, color: editorKeywordColor },
  302. {
  303. tag: [t.name, t.deleted, t.character, t.propertyName, t.macroName],
  304. color: editorNameColor,
  305. },
  306. {
  307. tag: [t.function(t.variableName), t.labelName],
  308. color: editorVariableColor,
  309. },
  310. {
  311. tag: [t.color, t.constant(t.name), t.standard(t.name)],
  312. color: editorConstantColor,
  313. },
  314. { tag: [t.definition(t.name), t.separator], color: editorSeparatorColor },
  315. {
  316. tag: [
  317. t.typeName,
  318. t.className,
  319. t.number,
  320. t.changed,
  321. t.annotation,
  322. t.modifier,
  323. t.self,
  324. t.namespace,
  325. ],
  326. color: editorTypeColor,
  327. },
  328. {
  329. tag: [
  330. t.operator,
  331. t.operatorKeyword,
  332. t.url,
  333. t.escape,
  334. t.regexp,
  335. t.link,
  336. t.special(t.string),
  337. ],
  338. color: editorOperatorColor,
  339. },
  340. { tag: [t.meta, t.comment], color: editorMetaColor },
  341. { tag: t.strong, fontWeight: "bold" },
  342. { tag: t.emphasis, fontStyle: "italic" },
  343. { tag: t.strikethrough, textDecoration: "line-through" },
  344. { tag: t.link, color: editorLinkColor, textDecoration: "underline" },
  345. { tag: t.heading, fontWeight: "bold", color: editorNameColor },
  346. {
  347. tag: [t.atom, t.bool, t.special(t.variableName)],
  348. color: editorConstantColor,
  349. },
  350. {
  351. tag: [t.processingInstruction, t.string, t.inserted],
  352. color: editorProcessColor,
  353. },
  354. { tag: t.invalid, color: editorInvalidColor },
  355. ])
  356. export const basicSetup: Extension = [
  357. lineNumbers(),
  358. highlightActiveLineGutter(),
  359. highlightSpecialChars(),
  360. history(),
  361. foldGutter({
  362. openText: "▾",
  363. closedText: "▸",
  364. }),
  365. drawSelection(),
  366. dropCursor(),
  367. EditorState.allowMultipleSelections.of(true),
  368. indentOnInput(),
  369. defaultHighlightStyle.fallback,
  370. bracketMatching(),
  371. closeBrackets(),
  372. autocompletion(),
  373. rectangularSelection(),
  374. crosshairCursor(),
  375. highlightActiveLine(),
  376. highlightSelectionMatches(),
  377. keymap.of([
  378. ...closeBracketsKeymap,
  379. ...defaultKeymap,
  380. ...searchKeymap,
  381. ...historyKeymap,
  382. ...foldKeymap,
  383. ...commentKeymap,
  384. ...completionKeymap,
  385. ...lintKeymap,
  386. ]),
  387. search({
  388. top: true,
  389. }),
  390. ]