Skip to content

Instantly share code, notes, and snippets.

View marijnh's full-sized avatar

Marijn Haverbeke marijnh

View GitHub Profile
@marijnh
marijnh / highlight.js
Last active December 23, 2023 08:08
Word highlighting in ProseMirror
import {Pos} from "../src/model"
function rangeFromTransform(tr) {
let from, to
for (let i = 0; i < tr.steps.length; i++) {
let step = tr.steps[i], map = tr.maps[i]
let stepFrom = map.map(step.from || step.pos, -1).pos
let stepTo = map.map(step.to || step.pos, 1).pos
from = from ? map.map(from, -1).pos.min(stepFrom) : stepFrom
to = to ? map.map(to, 1).pos.max(stepTo) : stepTo
@marijnh
marijnh / theme-ttcn.js
Last active March 22, 2023 10:19
TTCN theme for CM6
import {HighlightStyle, syntaxHighlighting} from "@codemirror/language"
import {tags as t} from "@lezer/highlight"
export const ttcnHighlightStyle = HighlightStyle.define([
{tag: t.quote,
color: "#090"},
{tag: t.deleted,
color: "#d44"},
{tag: t.inserted,
color: "#292"},
@marijnh
marijnh / node-view.js
Created October 28, 2016 15:15
Demo of a ProseMirror editor that uses a nested code editor
const {EditorState, Selection} = require("prosemirror-state")
const {MenuBarEditorView} = require("prosemirror-menu")
const {DOMParser, DOMSerializer, Schema} = require("prosemirror-model")
const {schema: baseSchema} = require("prosemirror-schema-basic")
const {exampleSetup} = require("prosemirror-example-setup")
const {keymap} = require("prosemirror-keymap")
const CodeMirror = require("codemirror")
require("codemirror/mode/javascript/javascript")
let view, menuView, schema = new Schema({
@marijnh
marijnh / gist:2488301
Created April 25, 2012 08:53
html + css preview
<!doctype html>
<html>
<head>
<title>HTML&CSS SANDBOX</title>
<meta charset=utf-8>
<script src=lib/codemirror.js></script>
<script src=mode/xml/xml.js></script>
<script src=mode/javascript/javascript.js></script>
<script src=mode/css/css.js></script>
<script src=mode/htmlmixed/htmlmixed.js></script>
@marijnh
marijnh / gist:4202141
Created December 4, 2012 09:23
CodeMirror almost full height
<!DOCTYPE html>
<html>
<head>
<title>Demo</title>
<link href="lib/codemirror.css" rel="stylesheet">
<style type="text/css">
html, body { height: 100%; margin: 0; padding: 0; }
.wrap {
position: relative;
height: 100%;
/*
# Clean UI programming in a vacuum
This app was written for Chapter 19 in the 3rd edition of Eloquent
JavaScript—it aims to demonstrate modern UI programming without
depending on a specific framework or library.
Its convention is that components have an interface like this:
```
@marijnh
marijnh / changedRanges.js
Created August 17, 2016 14:11
Compute changed range from ProseMirror steps
function changedRanges(history, group) {
let ranges = []
history.forEach((step, i) => {
let map = step.posMap()
ranges = ranges.map(range => {
let from = map.map(range.from, 1), to = Math.max(from, map.map(range.to, -1))
return {from, to}
})
if (group.indexOf(i) > -1) {
let newRanges = []
@marijnh
marijnh / gist:9683027
Created March 21, 2014 10:02
CodeMirror merge view resize to fit content
function mergeViewHeight(mergeView) {
function editorHeight(editor) {
if (!editor) return 0;
return editor.getScrollInfo().height;
}
return Math.max(editorHeight(mergeView.leftOriginal()),
editorHeight(mergeView.editor()),
editorHeight(mergeView.rightOriginal()));
}

(This is a response to https://github.com/google/xi-editor/blob/master/doc/rope_science/rope_science_11.md that didn't fit in a tweet.)

CodeMirror uses a largely similar approach, with a somewhat different framing.

Firstly, it stores the mode (highlighter) state directly in the document data structure (which I probably wouldn't do again if I were to redesign this), not in a separate cache. Each line can have an optional 'highlight state after this line' field. During highlighting, a cached state is left every N lines.

The frontier is simply the line number up to which point highlighting has happened. When you edit above the frontier, it it moved back to the line before the change.

Highlighting never proceeds past the end of the viewport. So startup is cheap (only highlight the first screenful), and in the 99% case of changes happening inside the viewport, re-highlighting complexity is bounded by the size of the viewport, since only the area between the change and the end of the viewport needs to be proces

Never see JavaDoc again
Inline documentation is great. JSDoc/JavaDoc syntax is an acquired taste that I never managed to acquire. So I want to show you an alternative tool with alternative syntax that I wrote.