baseTheme.ts 11 KB

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