The concept of an object, record, structure, or product type occurs in almost every programming language. Being able to declare a type of value that groups a number of other values together is a fundamentally useful thing. As similar as the various record-ish constructs are in their basic functionality, the way such values are actually looked at...
CodeMirror 6 is a new code editor library for the web, a from-scratch implementation based on the experience of building and maintaining versions 1 to 5 for the past 13 years. It aims to be more extensible and accessible than previous versions. As of today, version 6.0 is stable. Going forward, probably at least several years, all new releases...
An extensible system, at its base, is a system that allows people to add additional functionality that was not anticipated by the core system. A good extensible system also makes sure multiple extensions that don't know anything about each other can be combined, and compose in ways that don't cause problems. The problem has several aspects....
I'm happy to announce that with version 0.8.0 the CodeMirror 6 project is entering its beta phase, and you're very much invited to start trying it out and poking at it. Roughly, this “beta” status means: I actually like the current programming interface. Apart from the move from a mono-package to a group of separate packages (removing the next/...
This post describes the considerations that came up in designing the document-change data structure and built-in collaborative editing feature in the upcoming version of CodeMirror (a code editor system). It is something of a followup to the Collaborative Editing in ProseMirror post. I won't introduce anything new or exciting here—the design I...
Development of CodeMirror 6 this year has been generously supported by Mozilla through their MOSS program. The MOSS program asks for a closing retrospective blog post describing the progress made during the grant period. I've written about the progress in the first 9 months of the year in my status update post from August. To summarize, in that...
I keep coming across people who consider parser technology a forbidding, scary field of programming. This is nonsense—a small parser can be very, very simple, and provide a wholesome exercise in recursive thinking. At the same time, it is true that you can make parsing extremely complicated. Mostly, this tends to happen when you generalize...
It has been almost a year since we officially announced the CodeMirror 6 project, which aims to rewrite CodeMirror (a code editor for in the browser) to align its design with the technological realities and fashions of the late 2010s. This post is for you if, in the course of that year, you've occasionally wondered what the hell Marijn is doing...
Most code editors have some concept of automatic indentation. For each language, they have some logic that can compute an appropriate indentation for a given line. They may immediately indent when you press Enter, or require some interaction to reindent a line or selection. Even with the cleverest tools, there isn't always a single definite...
(The details at the bottom of this post no longer reflect the way things work in CodeMirror 6. See this post for an updated description.) It has become fashionable to structure big systems as a number of separate packages. The driving idea is that it is better to, instead of locking people into your implementation of a feature, provide the...
Two years ago, I started the ProseMirror project because I wanted to take a stab at a better approach to WYSIWYG-style editing. Today, I'm releasing version 1.0 of the library. The architecture and scope of the project have changed quite a bit during its lifetime, but I feel that the original goal has been met. ProseMirror is a Web interface...
I am looking forward to the time where my node.js and browser can natively run ECMAScript 6 code. Build steps are a pain, and one of the reasons I like JavaScript in the first place is the (traditional) absence of “waiting for the compiler” from my work-flow. You can question whether ECMAScript 6 is worth incurring the inconvenience of a build...
I spent one week being a resident at the Recurse Center in New York this November. The Recurse Center is a somewhat unusual institution. They call themselves a “programmers retreat”. That more or less means they are a space where people who want to improve their programming skills (whether beginners or experienced programmers) hang around for a...
This post describes the algorithm used to make collaborative editing work in ProseMirror. For an introduction to ProseMirror, see another post here. The Problem A real-time collaborative editing system is one where multiple people may work on a document at the same time. The system ensures that the documents stay synchronized—changes made by...
Sometimes I lie awake at night, feverishly searching for new ways to load myself down with more poorly-paying responsibilities. And then it comes to me: I should start another open-source project! Well, that's not really what happens. But the effect is the same. I keep building complex, demanding pieces of code and then giving them away. The...
As a programmer I create artifacts that, unlike classical commodities such as loaves of bread or toothbrushes, can be copied at zero cost. Fitting copyable things into the capitalist market economy is something of an unsolved problem. The standard model of commerce is to sell our products by the unit. But here, everyone who gets their hands on a...
This post is part of the series about the internals of CodeMirror. This time, we'll discuss the way CodeMirror schedules updates to the DOM. The problem is this: CodeMirror has an internal model of the document that is being edited, and is displaying a representation of this model on the screen, using the browser's DOM. These have to be kept...
Four out of five stars. Would read again. ★★★★☆ When Angus Croll first told me that he was working on a book that solves simple programming exercises in the style of various famous literary authors, I couldn't help but suspect that such a book would be completely pointless, and he wouldn't sell ten copies. After reading the result of his efforts,...
A text is not just a string of Unicode. It has structure, and a certain internal coherence. People might want to read it in different formats, and if I am going to hand-edit it, I want its source to be in an editing-friendly format. For the first edition of my book (Eloquent JavaScript), I wrote my own markup format style and a Haskell program to...
This is a brief post to explain why my JavaScript code is full of == null comparison expressions, even though linter software tends to disapprove. JavaScript defines both undefined and null as separate values. The first comes up in many constructs in the core language—an uninitialized variable, a parameter that wasn't passed, a missing field in...
I spend a rather large fraction of my days inside Emacs, writing and editing JavaScript code. Of this time, a significant amount is spent doing things that follow patterns. Pattern which, with a little machine intelligence, could easily be automated. Years ago, before accidentally rolling into this JavaScript career, I mostly programmed Common...
From the very start, CodeMirror was set up as a system with zero unused abstractions. This is a doctrine that I've come to esteem highly: write code that solves the current problem you have, and not a bunch of other, similar problems that you can imagine someone may have in the future. And such a system will have to grow, almost without...
I am writing a tool that tries to enhance a JavaScript code editor by doing some halfway serious static analysis on code, as it is being written. To analyze code, you'll want to parse it, because—believe me—running casual regexps over programs in order to determine their structure is not a healthy direction to go in. But unfortunately, code...
Postmodern is a Common Lisp library for communicating with a PostgreSQL database. Sabra Crolleton recently published a nice collection of examples for the library. That reminded me that it's been over a year since the last release. There have been several major improvements, including support for notifications and bulk copying, so a release was...
When you've lied about something, it tends to take more and more lies to cover up the discrepancies created by the first lie. A very similar thing happened when CodeMirror needed to fake its scrollbars. CodeMirror's viewport First, some background. Why would we want to fake a scrollbar to begin with? In order to remain responsive when huge...
One common feature request that CodeMirror version 1 was fundamentally unable to support (due to its reliance on contentEditable), and which was thus built into version 2 from the start, is programmatically styling stretches of text. In version 2, you can call instance.markText(from, to, className), and it'll style that stretch of text with the...
Acorn is a JavaScript parser written in JavaScript. Another one. Just like: The original UglifyJS parser The new UglifyJS parser ZeParser The Narcissus project's parser Esprima Acorn produces a well-documented, widely used AST format. The same as the last two parsers in that list. Acorn is really fast. Just like the last one in the list: Esprima....
A CodeMirror mode is a module that helps CodeMirror, a code editor, highlight and optionally smart-indent text in a specific programming language or other kind of structured text format. Code editors take widely different approaches to the way syntax highlighting styles are defined. An elegantly simple approach is outlined in Patrick Walton's...
I've just marked the current state of the master branch as version 2.34. The main changes are: New mode: Common Lisp Fix right-click select-all on most browsers. Change the way highlighting happens: Saves memory and CPU cycles. compareStates is no longer needed. onHighlightComplete no longer works. Integrate mode (Markdown, XQuery, CSS, sTex)...
This is a post in the cm-internals series, describing the internals of the CodeMirror editor. The problem it tackles is this: you are writing a JavaScript control that needs to act as a text input field—it must be focusable, support copy and paste, receive typed input—but really isn't. I.e. you want to draw it yourself, and have full control over...
Note: the question asked in this post, "why aren't closures super-fast?", was thorougly answered by Vyacheslav Egorov in his followup. Reading that is probably more informative than reading the text below. I originally structured CodeMirror instances as one huge closure that contained all the internal variables. The constructor would create local...
This post is part of an ongoing series of articles that aim to document the internals of the CodeMirror code editor. I will use the cm-internals tag to distinguish these posts—if you intend to hack on CodeMirror, it might be worthwhile to see what else is there. The problem The initial implementation of CodeMirror 2 represented the document as a...
Last week, the need for a platform to publish my bi-directional text story on forced me to think about blogging software once more. I had heard that all the cool kids are now using Jekyll on their Github pages to publish their blogs. I am not keen on depending on Github for yet another aspect of my online life, but the idea of generating a static...
"Unicode is hard" is a commonplace among developers. And I guess it is hard. Witness the amount of systems that get things like string en- and decoding wrong. And that is the easy part—the real fun starts when you need to actually display those strings. Fortunately, toolkits and libraries are able to hide the horrors of combining characters,...
Read this post at http://marijnhaverbeke.nl/turtle/.
I've just put my Common Lisp Tcl/Tk bindings online. They differ from the existing LTK library in that they... Support for both FFI bindings and talking to a wish shell. Have hardly any 'wrapper' functionality — you're directly driving a Tcl interpreter from Lisp. They've only been used in one medium-sized project so far, but they are so simple...
I've released the JavaScript parser (in Common Lisp) that I had sitting around as a proper package. It's small, fast, and complete, but not terribly well-documented. Get it from the project page.
There were a handful of small fixes still sitting around, as well as the deftable addition. It has been four months since 1.12, so: 1.13! Champagne all around. Download.
After dragging my JSON implementation through various projects, and having several incompatible versions exist at the same time, I got permission to open-source it from the company that originally paid me to write it, so it has a home now: ST-JSON. There already exists a comparable library called CL-JSON. I originally wrote a new one because the...
(This is something I wrote for a now-defunct web publication in 2008. I've inlined the text here.) Giving caches a chance Though it tends to get treated as one, HTTP is not just a dumb file-transfer protocol. It allows you, to a certain degree, to specify an intention with your requests (GET/POST, with PUT and DELETE thrown in if you really want...