codemirror: update to 5.58.1

This commit is contained in:
Silvan Calarco 2020-10-02 13:05:50 +02:00
parent 0c8fa3d288
commit 1c266a68b1
256 changed files with 5417 additions and 1669 deletions

View File

@ -0,0 +1,5 @@
<!--
Do not use this bug tracker for questions. We have a forum (https://discuss.codemirror.net) for those.
In order to get us to look at something, you need to make it easy for us to understand what you are doing and what went wrong. When possible, a code example that demonstrates the problem helps a lot. If there's any chance at all that a problem is related to the browser, include information about which browser(s) you tested with.
-->

View File

@ -0,0 +1,5 @@
<!--
NOTE: We are not accepting pull requests for new modes or addons. Please put such code in a separate repository, and release them as stand-alone npm packages. See for example the [Elixir mode](https://github.com/ianwalter/codemirror-mode-elixir).
Also pull requests that rewrite big chunks of code or adjust code style to your own taste are generally not welcome. Make your changes in focused steps that fix or improve a specific thing.
-->

View File

@ -15,11 +15,13 @@ Adán Lobato
Aditya Toshniwal
Adrian Aichner
Adrian Heine
Adrian Kunz
Adrien Bertrand
aeroson
Ahmad Amireh
Ahmad M. Zawawi
ahoward
Ajin Abraham
Akeksandr Motsjonov
Alasdair Smith
AlbertHilb
@ -31,6 +33,7 @@ Alexander Schepanovski
Alexander Shvets
Alexander Solovyov
Alexandre Bique
Alex Churchill
alexey-k
Alex Piggott
Aliaksei Chapyzhenka
@ -72,11 +75,13 @@ anthonygego
Anthony Gégo
Anthony Grimes
Anton Kovalyov
antosarho
Apollo Zhu
AQNOUCH Mohammed
Aram Shatakhtsyan
areos
Arnab Bose
Arnoud Buzing
Arsène von Wyss
Arthur Müller
Arun Narasani
@ -95,6 +100,9 @@ Bastian Müller
belhaj
Bem Jones-Bey
benbro
Benedikt Meurer
benhormann
Ben Hormann
Beni Cherniavsky-Paskin
Benjamin DeCoste
Benjamin Young
@ -106,6 +114,7 @@ Bert Chang
Bharad
BigBlueHat
Billy Moon
Bin Ni
binny
Bjorn Hansen
B Krishna Chaitanya
@ -115,12 +124,14 @@ Bo
boomyjee
Bo Peng
borawjm
Boris K
Brad Metcalf
Brandon Frohs
Brandon Wamboldt
Bret Little
Brett Zamir
Brian Grinstead
BrianHung
Brian Sletten
brrd
Bruce Mitchener
@ -132,6 +143,7 @@ Calin Barbat
callodacity
Camilo Roca
Casey Klebba
cBiscuit87
César González Íñiguez
Chad Jolly
Chandra Sekhar Pydi
@ -158,6 +170,7 @@ Christopher Pfohl
Christopher Wallis
Chunliang Lyu
ciaranj
clone-it
clso
CodeAnimal
CodeBitt
@ -167,6 +180,7 @@ ComFreek
Cristian Prieto
Curran Kelleher
Curtis Gagliardi
d8888
dagsta
daines
Dale Jung
@ -194,6 +208,7 @@ David Barnett
David H. Bronke
David Mignot
David Pathakjee
David Rodrigues
David Santana
David Vázquez
David Whittington
@ -206,6 +221,7 @@ Dick Choi
Diego Fernandez
dignifiedquire
Dimage Sapelkin
Dinindu D. Wanniarachchi
dmaclach
Dmitry Kiselyov
domagoj412
@ -221,10 +237,13 @@ Dror BG
Duncan Lilley
duralog
dwelle
Ealton
eborden
edoroshenko
edsharp
ekhaled
Elisée
elpnt
Emmanuel Schanzer
Enam Mijbah Noor
Eric Allam
@ -249,11 +268,13 @@ Filype Pereira
finalfantasia
flack
Florian Felten
Fons van der Plas
Forbes Lindesay
ForbesLindesay
Ford_Lawnmower
Forrest Oliphant
Franco Catena
Frank Seifferth
Frank Wiegand
fraxx001
Fredrik Borg
@ -284,20 +305,25 @@ Grant Skinner
greengiant
Gregory Koberger
Grzegorz Mazur
Guang Li
Guan Gui
Guillaume Massé
Guillaume Massé
guraga
Gustavo Rodrigues
Hakan Tunc
Hanno Fellmann
Hans Engel
Hanzhao Deng
Haoran Yu
Harald Schilly
Hardest
Harshvardhan Gupta
Hasan Delibaş
Hasan Karahan
Heanes
Hector Oswaldo Caballero
Hein Htat
Hélio
Hendrik Wallbaum
Henrik Haugbølle
@ -306,22 +332,29 @@ hidaiy
Hiroyuki Makino
hitsthings
Hocdoc
Howard
Howard Jing
Hugues Malphettes
Ian Beck
Ian Davies
Ian Dickinson
ianhi
Ian Rose
Ian Wehrman
Ian Wetherbee
Ice White
ICHIKAWA, Yuji
idleberg
Igor Petruk
ilvalle
Ilya Kharlamov
Ilya Zverev
Ingo Richter
Intervue
Irakli Gozalishvili
Ivan Kurnosov
Ivoah
Jack Douglas
Jacob Lee
Jaimin
Jake Peyser
@ -329,6 +362,7 @@ Jakob Miland
Jakub Vrana
Jakub Vrána
James Campos
James Cockshull
James Howard
James Thorne
Jamie Hill
@ -351,6 +385,7 @@ Jason Johnston
Jason San Jose
Jason Siefken
Jayaprabhakar
Jay Contonio
Jaydeep Solanki
Jean Boussier
Jeff Blaisdell
@ -370,10 +405,13 @@ Joel Einbinder
joelpinheiro
joewalsh
Johan Ask
Johannes
John Chen
John Connor
John-David Dalton
John Engler
John Lees-Miller
John Ryan
John Snelson
John Van Der Loo
Jon Ander Peñalba
@ -386,6 +424,7 @@ Jon Gacnik
jongalloway
Jon Malmaud
Jon Sangster
Joo
Joost-Wim Boekesteijn
Joseph Pecoraro
Josh Barnes
@ -408,6 +447,7 @@ jwallers@gmail.com
kaniga
karevn
Karol
Kaushik Kulkarni
Kayur Patel
Kazuhito Hokamura
kcwiakala
@ -430,6 +470,7 @@ koops
Kris Ciccarello
ks-ifware
kubelsmieci
kvncp
KwanEsq
Kyle Kelley
KyleMcNutt
@ -438,6 +479,7 @@ Lanfei
Lanny
laobubu
Laszlo Vidacs
leaf
leaf corcoran
Lemmon
Leo Baschy
@ -451,10 +493,12 @@ Lior Shub
LloydMilligan
LM
lochel
Lonnie Abelbeck
Lorenzo Simionato
Lorenzo Stoakes
Louis Mauchet
Luca Fabbri
Lucas Buchala
Luciano Longo
Luciano Santana
Lu Fangjian
@ -481,6 +525,7 @@ Mário Gonçalves
Mario Pietsch
Mark Anderson
Mark Dalgleish
Mark Hamstra
Mark Lentczner
Marko Bonaci
Mark Peace
@ -499,11 +544,13 @@ mats cronqvist
Matt Gaide
Matthew Bauer
Matthew Beale
Matthew Casperson
matthewhayes
Matthew Rathbone
Matthew Suozzo
Matthias Bussonnier
Matthias BUSSONNIER
Mattia Astorino
Matt MacPherson
Matt McDonald
Matt Pass
@ -518,6 +565,7 @@ Max Xiantu
mbarkhau
McBrainy
mce2
Mélanie Chauvel
melpon
meshuamam
Metatheos
@ -585,15 +633,21 @@ Nikita Vasilyev
Nikolaj Kappler
Nikolay Kostov
nilp0inter
Nils Knappmeier
Nisarg Jhaveri
nlwillia
noragrossman
Norman Rzepka
Nouzbe
Oleksandr Yakovenko
Olivia Ytterbrink
Opender Singh
opl-
Oreoluwa Onatemowo
orionlee
oscar.lofwenhamn
Oskar Segersvärd
ossdev
overdodactyl
pablo
pabloferz
@ -606,11 +660,13 @@ paris
Paris
Paris Kasidiaris
Patil Arpith
Patrick Kettner
Patrick Stoica
Patrick Strawderman
Paul Garvin
Paul Ivanov
Paul Masson
Paul Schmidt
Pavel
Pavel Feldman
Pavel Petržela
@ -621,6 +677,7 @@ peter
Peter Flynn
peterkroon
Peter Kroon
Peter László
Philipp A
Philipp Markovics
Philip Stadermann
@ -631,6 +688,7 @@ Pontus Melke
prasanthj
Prasanth J
Prayag Verma
prendota
Prendota
Qiang Li
Radek Piórkowski
@ -644,6 +702,7 @@ Randy Luecke
Raphael Amorim
Rasmus Erik Voel Jensen
Rasmus Schultz
raymondf
Raymond Hill
ray ratchup
Ray Ratchup
@ -659,10 +718,14 @@ Robert Crossfield
Robert Martin
Roberto Abdelkader Martínez Pérez
robertop23
Roberto Vidal
Robert Plummer
Roman Janusz
Rrandom
Rrrandom
Ruslan Osmanov
rvalavicius
Ryan Pangrle
Ryan Petrello
Ryan Prior
ryu-sato
@ -705,6 +768,7 @@ Shiv Deepak
Shmuel Englard
Shubham Jain
Siamak Mokhtari
Siddhartha Gunti
silverwind
Simon Edwards
sinkuu
@ -738,7 +802,9 @@ Tako Schotanus
Takuji Shimokawa
Takuya Matsuyama
Tarmil
T. Brandon Ashley
TDaglis
Teja
tel
Tentone
tfjgeorge
@ -754,13 +820,16 @@ thomasmaclean
Thomas Schmid
Tim Alby
Tim Baumann
Tim Gates
Timothy Farrell
Timothy Gu
Timothy Hatcher
Tim van der Lippe
Tobias Bertelsen
TobiasBg
Todd Berman
Todd Kennedy
tokafew420
Tomas-A
Tomas Varaneckas
Tom Erik Støwer
@ -778,9 +847,11 @@ TSUYUSATO Kitsune
Tugrul Elmas
twifkak
Tyler Long
Tyler Makaro
Vadim Dyachenko
Vadzim Ramanenka
Vaibhav Sagar
vamshi.revu
VapidWorx
Vestimir Markov
vf
@ -813,8 +884,10 @@ Yuvi Panda
Yvonnick Esnault
Zac Anger
Zachary Dremann
ZeeshanNoor
Zeno Rocha
Zhang Hao
Ziv
zoobestik
zziuni
魏鹏刚

View File

@ -1,3 +1,263 @@
## 5.58.1 (2020-09-23)
### Bug fixes
[placeholder addon](https://codemirror.net/doc/manual.html#addon_placeholder): Remove arrow function that ended up in the code.
## 5.58.0 (2020-09-21)
### Bug fixes
Make backspace delete by code point, not glyph.
Suppress flickering focus outline when clicking on scrollbars in Chrome.
Fix a bug that prevented attributes added via `markText` from showing up unless the span also had some other styling.
Suppress cut and paste context menu entries in readonly editors in Chrome.
[placeholder addon](https://codemirror.net/doc/manual.html#addon_placeholder): Update placeholder visibility during composition.
### New features
Make it less cumbersome to style new lint message types.
[vim bindings](https://codemirror.net/demo/vim.html): Support black hole register, `gn` and `gN`
## 5.57.0 (2020-08-20)
### Bug fixes
Fix issue that broke binding the macOS Command key.
[comment addon](https://codemirror.net/doc/manual.html#addon_comment): Keep selection in front of inserted markers when adding a block comment.
[css mode](https://codemirror.net/mode/css/): Recognize more properties and value names.
[annotatescrollbar addon](https://codemirror.net/doc/manual.html#addon_annotatescrollbar): Don't hide matches in collapsed content.
### New features
[vim bindings](https://codemirror.net/demo/vim.html): Support tag text objects in xml and html modes.
## 5.56.0 (2020-07-20)
### Bug fixes
Line-wise pasting was fixed on Chrome Windows.
[wast mode](https://codemirror.net/mode/wast/): Follow standard changes.
[soy mode](https://codemirror.net/mode/soy/): Support import expressions, template type, and loop indices.
[sql-hint addon](https://codemirror.net/doc/manual.html#addon_sql-hint): Improve handling of double quotes.
### New features
[show-hint addon](https://codemirror.net/doc/manual.html#addon_show-hint): New option `scrollMargin` to control how many options are visible beyond the selected one.
[hardwrap addon](https://codemirror.net/doc/manual.html#addon_hardwrap): New option `forceBreak` to disable breaking of words that are longer than a line.
## 5.55.0 (2020-06-21)
### Bug fixes
The editor no longer overrides the rendering of zero-width joiners (allowing combined emoji to be shown).
[vim bindings](https://codemirror.net/demo/vim.html): Fix an issue where the `vim-mode-change` event was fired twice.
[javascript mode](https://codemirror.net/mode/javascript/): Only allow `-->`-style comments at the start of a line.
[julia mode](https://codemirror.net/mode/julia/): Improve indentation.
[pascal mode](https://codemirror.net/mode/pascal/index.html): Recognize curly bracket comments.
[runmode addon](https://codemirror.net/doc/manual.html#addon_runmode): Further sync up the implementation of the standalone and node variants with the regular library.
### New features
[loadmode addon](https://codemirror.net/doc/manual.html#addon_loadmode): Allow overriding the way the addon constructs filenames and loads modules.
## 5.54.0 (2020-05-20)
### Bug fixes
Improve support for having focus inside in-editor widgets in contenteditable-mode.
Fix issue where the scroll position could jump when clicking on a selection in Chrome.
[python mode](https://codemirror.net/mode/python/): Better format string support.
[javascript mode](https://codemirror.net/mode/javascript/): Improve parsing of private properties and class fields.
[matchbrackets addon](https://codemirror.net/doc/manual.html#addon_matchbrackets): Disable highlighting when the editor doesn't have focus.
### New features
[runmode addon](https://codemirror.net/doc/manual.html#addon_runmode): Properly support for cross-line lookahead.
[vim bindings](https://codemirror.net/demo/vim.html): Allow Ex-Commands with non-word names.
[gfm mode](https://codemirror.net/mode/gfm/): Add a `fencedCodeBlockDefaultMode` option.
## 5.53.2 (2020-04-21)
### Bug fixes
[show-hint addon](https://codemirror.net/doc/manual.html#addon_show-hint): Fix a regression that broke completion picking.
## 5.53.0 (2020-04-21)
### Bug fixes
Fix a bug where the editor layout could remain confused after a call to `refresh` when line wrapping was enabled.
[dialog addon](https://codemirror.net/doc/manual.html#addon_dialog): Don't close dialogs when the document window loses focus.
[merge addon](https://codemirror.net/doc/manual.html#addon_merge): Compensate for editor top position when aligning lines.
[vim bindings](https://codemirror.net/demo/vim.html): Improve EOL handling.
[emacs bindings](https://codemirror.net/demo/emacs.html): Include default keymap as a fallback.
[julia mode](https://codemirror.net/mode/julia/): Fix an infinite loop bug.
[show-hint addon](https://codemirror.net/doc/manual.html#addon_show-hint): Scroll cursor into view when picking a completion.
### New features
New option: [`screenReaderLabel`](https://codemirror.net/doc/manual.html#option_screenReaderLabel) to add a label to the editor.
New mode: [wast](https://codemirror.net/mode/wast/).
## 5.52.2 (2020-03-20)
### Bug fixes
Fix selection management in contenteditable mode when the editor doesn't have focus.
Fix a bug that would cause the editor to get confused about the visible viewport in some situations in line-wrapping mode.
[markdown mode](https://codemirror.net/mode/markdown/): Don't treat single dashes as setext header markers.
[zenburn theme](https://codemirror.net/demo/theme.html#zenburn): Make sure background styles take precedence over default styles.
[css mode](https://codemirror.net/mode/css/): Recognize a number of new properties.
## 5.52.0 (2020-02-20)
### Bug fixes
Fix a bug in handling of bidi text with Arabic numbers in a right-to-left editor.
Fix a crash when combining file drop with a `"beforeChange"` filter.
Prevent issue when passing negative coordinates to `scrollTo`.
### New features
[lint](https://codemirror.net/doc/manual.html#addon_lint) and [tern](https://codemirror.net/demo/tern.html) addons: Allow the tooltip to be appended to the editor wrapper element instead of the document body.
## 5.51.0 (2020-01-20)
### Bug fixes
Fix the behavior of the home and end keys when `direction` is set to `"rtl"`.
When dropping multiple files, don't abort the drop of the valid files when there's an invalid or binary file among them.
Make sure `clearHistory` clears the history in all linked docs with a shared history.
[vim bindings](https://codemirror.net/demo/vim.html): Fix behavior of `'` and `` ` `` marks, fix `R` in visual mode.
### New features
[vim bindings](https://codemirror.net/demo/vim.html): Support `gi`, `gI`, and `gJ`.
## 5.50.2 (2020-01-01)
### Bug fixes
Fix bug that broke removal of line widgets.
## 5.50.0 (2019-12-20)
### Bug fixes
Make Shift-Delete to cut work on Firefox.
[closetag addon](https://codemirror.net/demo/closetag.html): Properly handle self-closing tags.
[handlebars mode](https://codemirror.net/mode/handlebars/): Fix triple-brace support.
[searchcursor addon](https://codemirror.net/doc/manual.html#addon_searchcursor): Support mathing `$` in reverse regexp search.
[panel addon](https://codemirror.net/doc/manual.html#addon_panel): Don't get confused by changing panel sizes.
[javascript-hint addon](https://codemirror.net/doc/manual.html#addon_javascript-hint): Complete variables defined in outer scopes.
[sublime bindings](https://codemirror.net/demo/sublime.html): Make by-subword motion more consistent with Sublime Text.
[julia mode](https://codemirror.net/mode/julia/): Don't break on zero-prefixed integers.
[elm mode](https://codemirror.net/mode/elm/): Sync with upstream version.
[sql mode](https://codemirror.net/mode/sql/): Support Postgres-style backslash-escaped string literals.
### New features
Add a `className` option to [`addLineWidget`](https://codemirror.net/doc/manual.html#addLineWidget).
[foldcode addon](https://codemirror.net/doc/manual.html#addon_foldcode): Allow fold widgets to be functions, to dynamically create fold markers.
New themes: [ayu-dark](https://codemirror.net/demo/theme.html#ayu-dark) and [ayu-mirage](https://codemirror.net/demo/theme.html#ayu-mirage).
## 5.49.2 (2019-10-21)
### Bug fixes
[sublime bindings](https://codemirror.net/demo/sublime.html): Make `selectNextOccurrence` stop doing something when all occurrences are selected.
[continuecomment addon](https://codemirror.net/doc/manual.html#addon_continuecomment): Respect `indentWithTabs` option.
[foldgutter addon](https://codemirror.net/doc/manual.html#addon_foldgutter): Optimize by reusing DOM when possible.
[markdown mode](https://codemirror.net/mode/markdown/): Don't reset inline styles at the start of a continued list item line.
[clike mode](https://codemirror.net/mode/clike/): Add a configuration for Objective-C++.
## 5.49.0 (2019-09-20)
### Bug fixes
[octave mode](https://codemirror.net/mode/octave/index.html): Don't mark common punctuation as error.
[clike mode](https://codemirror.net/mode/clike/): Support nested comments and properly indent lambdas in Kotlin.
[foldgutter](https://codemirror.net/doc/manual.html#addon_foldgutter) and [annotatescrollbar](https://codemirror.net/doc/manual.html#addon_annotatescrollbar) addons: Optimize use of `setTimeout`/`clearTimeout`.
### New features
New themes: [moxer](https://codemirror.net/demo/theme.html#moxer), [material-darker](https://codemirror.net/demo/theme.html#material-darker), [material-palenight](https://codemirror.net/demo/theme.html#material-palenight), [material-ocean](https://codemirror.net/demo/theme.html#material-ocean).
[xml mode](https://codemirror.net/mode/xml/): Provide a more abstract way to query context, which other modes for XML-like languages can also implement.
## 5.48.4 (2019-08-20)
### Bug fixes
Make default styles for line elements more specific so that they don't apply to all `<pre>` elements inside the editor.
Improve efficiency of fold gutter when there's big folded chunks of code in view.
Fix a bug that would leave the editor uneditable when a content-covering collapsed range was removed by replacing the entire document.
[julia mode](https://codemirror.net/mode/julia/): Support number separators.
[asterisk mode](https://codemirror.net/mode/asterisk/): Improve comment support.
[handlebars mode](https://codemirror.net/mode/handlebars/): Support triple-brace tags.
## 5.48.2 (2019-07-20)
### Bug fixes

View File

@ -13,7 +13,7 @@
var noOptions = {};
var nonWS = /[^\s\u00a0]/;
var Pos = CodeMirror.Pos;
var Pos = CodeMirror.Pos, cmp = CodeMirror.cmpPos;
function firstNonWS(str) {
var found = str.search(nonWS);
@ -126,7 +126,9 @@
if (i != end || lastLineHasText)
self.replaceRange(lead + pad, Pos(i, 0));
} else {
var atCursor = cmp(self.getCursor("to"), to) == 0, empty = !self.somethingSelected()
self.replaceRange(endString, to);
if (atCursor) self.setSelection(empty ? to : self.getCursor("from"), to)
self.replaceRange(startString, from);
}
});

View File

@ -9,6 +9,8 @@
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
var nonspace = /\S/g;
var repeat = String.prototype.repeat || function (n) { return Array(n + 1).join(this); };
function continueComment(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections(), mode, inserts = [];
@ -19,29 +21,57 @@
if (!mode) mode = modeHere;
else if (mode != modeHere) return CodeMirror.Pass;
var insert = null;
if (mode.blockCommentStart && mode.blockCommentContinue) {
var line = cm.getLine(pos.line).slice(0, pos.ch)
var end = line.lastIndexOf(mode.blockCommentEnd), found
if (end != -1 && end == pos.ch - mode.blockCommentEnd.length) {
// Comment ended, don't continue it
} else if ((found = line.lastIndexOf(mode.blockCommentStart)) > -1 && found > end) {
insert = line.slice(0, found)
if (/\S/.test(insert)) {
insert = ""
for (var j = 0; j < found; ++j) insert += " "
var insert = null, line, found;
var blockStart = mode.blockCommentStart, lineCmt = mode.lineComment;
if (blockStart && mode.blockCommentContinue) {
line = cm.getLine(pos.line);
var end = line.lastIndexOf(mode.blockCommentEnd, pos.ch - mode.blockCommentEnd.length);
// 1. if this block comment ended
// 2. if this is actually inside a line comment
if (end != -1 && end == pos.ch - mode.blockCommentEnd.length ||
lineCmt && (found = line.lastIndexOf(lineCmt, pos.ch - 1)) > -1 &&
/\bcomment\b/.test(cm.getTokenTypeAt({line: pos.line, ch: found + 1}))) {
// ...then don't continue it
} else if (pos.ch >= blockStart.length &&
(found = line.lastIndexOf(blockStart, pos.ch - blockStart.length)) > -1 &&
found > end) {
// reuse the existing leading spaces/tabs/mixed
// or build the correct indent using CM's tab/indent options
if (nonspaceAfter(0, line) >= found) {
insert = line.slice(0, found);
} else {
var tabSize = cm.options.tabSize, numTabs;
found = CodeMirror.countColumn(line, found, tabSize);
insert = !cm.options.indentWithTabs ? repeat.call(" ", found) :
repeat.call("\t", (numTabs = Math.floor(found / tabSize))) +
repeat.call(" ", found - tabSize * numTabs);
}
} else if ((found = line.indexOf(mode.blockCommentContinue)) > -1 && !/\S/.test(line.slice(0, found))) {
insert = line.slice(0, found)
} else if ((found = line.indexOf(mode.blockCommentContinue)) > -1 &&
found <= pos.ch &&
found <= nonspaceAfter(0, line)) {
insert = line.slice(0, found);
}
if (insert != null) insert += mode.blockCommentContinue
}
if (insert == null && mode.lineComment && continueLineCommentEnabled(cm)) {
var line = cm.getLine(pos.line), found = line.indexOf(mode.lineComment);
if (found > -1) {
insert = line.slice(0, found);
if (/\S/.test(insert)) insert = null;
else insert += mode.lineComment + line.slice(found + mode.lineComment.length).match(/^\s*/)[0];
if (insert == null && lineCmt && continueLineCommentEnabled(cm)) {
if (line == null) line = cm.getLine(pos.line);
found = line.indexOf(lineCmt);
// cursor at pos 0, line comment also at pos 0 => shift it down, don't continue
if (!pos.ch && !found) insert = "";
// continue only if the line starts with an optional space + line comment
else if (found > -1 && nonspaceAfter(0, line) >= found) {
// don't continue if there's only space(s) after cursor or the end of the line
insert = nonspaceAfter(pos.ch, line) > -1;
// but always continue if the next line starts with a line comment too
if (!insert) {
var next = cm.getLine(pos.line + 1) || '',
nextFound = next.indexOf(lineCmt);
insert = nextFound > -1 && nonspaceAfter(0, next) >= nextFound || null;
}
if (insert) {
insert = line.slice(0, found) + lineCmt +
line.slice(found + lineCmt.length).match(/^\s*/)[0];
}
}
}
if (insert == null) return CodeMirror.Pass;
@ -54,6 +84,12 @@
});
}
function nonspaceAfter(ch, str) {
nonspace.lastIndex = ch;
var m = nonspace.exec(str);
return m ? m.index : -1;
}
function continueLineCommentEnabled(cm) {
var opt = cm.getOption("continueComments");
if (opt && typeof opt == "object")

View File

@ -82,7 +82,9 @@
if (e.keyCode == 13) callback(inp.value, e);
});
if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close);
if (options.closeOnBlur !== false) CodeMirror.on(dialog, "focusout", function (evt) {
if (evt.relatedTarget !== null) close();
});
} else if (button = dialog.getElementsByTagName("button")[0]) {
CodeMirror.on(button, "click", function() {
close();

View File

@ -1,15 +1,15 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
(function (mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
CodeMirror.defineExtension("addPanel", function(node, options) {
})(function (CodeMirror) {
CodeMirror.defineExtension("addPanel", function (node, options) {
options = options || {};
if (!this.state.panels) initPanels(this);
@ -25,8 +25,7 @@
wrapper.insertBefore(node, options.before.node);
} else if (replace) {
wrapper.insertBefore(node, options.replace.node);
info.panels++;
options.replace.clear();
options.replace.clear(true);
} else if (options.position == "bottom") {
wrapper.appendChild(node);
} else if (options.position == "before-bottom") {
@ -38,14 +37,15 @@
}
var height = (options && options.height) || node.offsetHeight;
this._setSize(null, info.heightLeft -= height);
if (!replace) {
info.panels++;
}
if (options.stable && isAtTop(this, node))
this.scrollTo(null, this.getScrollInfo().top + height)
return new Panel(this, node, options, height);
var panel = new Panel(this, node, options, height);
info.panels.push(panel);
this.setSize();
if (options.stable && isAtTop(this, node))
this.scrollTo(null, this.getScrollInfo().top + height);
return panel;
});
function Panel(cm, node, options, height) {
@ -56,22 +56,23 @@
this.cleared = false;
}
Panel.prototype.clear = function() {
/* when skipRemove is true, clear() was called from addPanel().
* Thus removePanels() should not be called (issue 5518) */
Panel.prototype.clear = function (skipRemove) {
if (this.cleared) return;
this.cleared = true;
var info = this.cm.state.panels;
this.cm._setSize(null, info.heightLeft += this.height);
info.panels.splice(info.panels.indexOf(this), 1);
this.cm.setSize();
if (this.options.stable && isAtTop(this.cm, this.node))
this.cm.scrollTo(null, this.cm.getScrollInfo().top - this.height)
info.wrapper.removeChild(this.node);
if (--info.panels == 0) removePanels(this.cm);
if (info.panels.length == 0 && !skipRemove) removePanels(this.cm);
};
Panel.prototype.changed = function(height) {
var newHeight = height == null ? this.node.offsetHeight : height;
var info = this.cm.state.panels;
this.cm._setSize(null, info.heightLeft -= (newHeight - this.height));
this.height = newHeight;
Panel.prototype.changed = function () {
this.height = this.node.getBoundingClientRect().height;
this.cm.setSize();
};
function initPanels(cm) {
@ -80,8 +81,7 @@
var height = parseInt(style.height);
var info = cm.state.panels = {
setHeight: wrap.style.height,
heightLeft: height,
panels: 0,
panels: [],
wrapper: document.createElement("div")
};
wrap.parentNode.insertBefore(info.wrapper, wrap);
@ -90,8 +90,8 @@
if (hasFocus) cm.focus();
cm._setSize = cm.setSize;
if (height != null) cm.setSize = function(width, newHeight) {
if (newHeight == null) return this._setSize(width, newHeight);
if (height != null) cm.setSize = function (width, newHeight) {
if (!newHeight) newHeight = info.wrapper.offsetHeight;
info.setHeight = newHeight;
if (typeof newHeight != "number") {
var px = /^(\d+\.?\d*)px$/.exec(newHeight);
@ -100,10 +100,12 @@
} else {
info.wrapper.style.height = newHeight;
newHeight = info.wrapper.offsetHeight;
info.wrapper.style.height = "";
}
}
cm._setSize(width, info.heightLeft += (newHeight - height));
var editorheight = newHeight - info.panels
.map(function (p) { return p.node.getBoundingClientRect().height; })
.reduce(function (a, b) { return a + b; }, 0);
cm._setSize(width, editorheight);
height = newHeight;
};
}

View File

@ -15,11 +15,13 @@
cm.on("blur", onBlur);
cm.on("change", onChange);
cm.on("swapDoc", onChange);
CodeMirror.on(cm.getInputField(), "compositionupdate", cm.state.placeholderCompose = function() { onComposition(cm) })
onChange(cm);
} else if (!val && prev) {
cm.off("blur", onBlur);
cm.off("change", onChange);
cm.off("swapDoc", onChange);
CodeMirror.off(cm.getInputField(), "compositionupdate", cm.state.placeholderCompose)
clearPlaceholder(cm);
var wrapper = cm.getWrapperElement();
wrapper.className = wrapper.className.replace(" CodeMirror-empty", "");
@ -39,13 +41,25 @@
var elt = cm.state.placeholder = document.createElement("pre");
elt.style.cssText = "height: 0; overflow: visible";
elt.style.direction = cm.getOption("direction");
elt.className = "CodeMirror-placeholder";
elt.className = "CodeMirror-placeholder CodeMirror-line-like";
var placeHolder = cm.getOption("placeholder")
if (typeof placeHolder == "string") placeHolder = document.createTextNode(placeHolder)
elt.appendChild(placeHolder)
cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild);
}
function onComposition(cm) {
setTimeout(function() {
var empty = false, input = cm.getInputField()
if (input.nodeName == "TEXTAREA")
empty = !input.value
else if (cm.lineCount() == 1)
empty = !/[^\u200b]/.test(input.querySelector(".CodeMirror-line").textContent)
if (empty) setPlaceholder(cm)
else clearPlaceholder(cm)
}, 20)
}
function onBlur(cm) {
if (isEmpty(cm)) setPlaceholder(cm);
}

View File

@ -40,9 +40,9 @@
cm.removeKeyMap("autoCloseTags");
if (!val) return;
var map = {name: "autoCloseTags"};
if (typeof val != "object" || val.whenClosing)
if (typeof val != "object" || val.whenClosing !== false)
map["'/'"] = function(cm) { return autoCloseSlash(cm); };
if (typeof val != "object" || val.whenOpening)
if (typeof val != "object" || val.whenOpening !== false)
map["'>'"] = function(cm) { return autoCloseGT(cm); };
cm.addKeyMap(map);
});
@ -60,22 +60,23 @@
if (!ranges[i].empty()) return CodeMirror.Pass;
var pos = ranges[i].head, tok = cm.getTokenAt(pos);
var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
if (inner.mode.name != "xml" || !state.tagName) return CodeMirror.Pass;
var tagInfo = inner.mode.xmlCurrentTag && inner.mode.xmlCurrentTag(state)
var tagName = tagInfo && tagInfo.name
if (!tagName) return CodeMirror.Pass
var html = inner.mode.configuration == "html";
var dontCloseTags = (typeof opt == "object" && opt.dontCloseTags) || (html && htmlDontClose);
var indentTags = (typeof opt == "object" && opt.indentTags) || (html && htmlIndent);
var tagName = state.tagName;
if (tok.end > pos.ch) tagName = tagName.slice(0, tagName.length - tok.end + pos.ch);
var lowerTagName = tagName.toLowerCase();
// Don't process the '>' at the end of an end-tag or self-closing tag
if (!tagName ||
tok.type == "string" && (tok.end != pos.ch || !/[\"\']/.test(tok.string.charAt(tok.string.length - 1)) || tok.string.length == 1) ||
tok.type == "tag" && state.type == "closeTag" ||
tok.string.indexOf("/") == (tok.string.length - 1) || // match something like <someTagName />
tok.type == "tag" && tagInfo.close ||
tok.string.indexOf("/") == (pos.ch - tok.start - 1) || // match something like <someTagName />
dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1 ||
closingTagExists(cm, tagName, pos, state, true))
closingTagExists(cm, inner.mode.xmlCurrentContext && inner.mode.xmlCurrentContext(state) || [], tagName, pos, true))
return CodeMirror.Pass;
var emptyTags = typeof opt == "object" && opt.emptyTags;
@ -120,19 +121,16 @@
// when completing in JS/CSS snippet in htmlmixed mode. Does not
// work for other XML embedded languages (there is no general
// way to go from a mixed mode to its current XML state).
var replacement;
if (inner.mode.name != "xml") {
if (cm.getMode().name == "htmlmixed" && inner.mode.name == "javascript")
replacement = head + "script";
else if (cm.getMode().name == "htmlmixed" && inner.mode.name == "css")
replacement = head + "style";
else
return CodeMirror.Pass;
var replacement, mixed = inner.mode.name != "xml" && cm.getMode().name == "htmlmixed"
if (mixed && inner.mode.name == "javascript") {
replacement = head + "script";
} else if (mixed && inner.mode.name == "css") {
replacement = head + "style";
} else {
if (!state.context || !state.context.tagName ||
closingTagExists(cm, state.context.tagName, pos, state))
var context = inner.mode.xmlCurrentContext && inner.mode.xmlCurrentContext(state)
if (!context || (context.length && closingTagExists(cm, context, context[context.length - 1], pos)))
return CodeMirror.Pass;
replacement = head + state.context.tagName;
replacement = head + context[context.length - 1]
}
if (cm.getLine(pos.line).charAt(tok.end) != ">") replacement += ">";
replacements[i] = replacement;
@ -162,16 +160,19 @@
// If xml-fold is loaded, we use its functionality to try and verify
// whether a given tag is actually unclosed.
function closingTagExists(cm, tagName, pos, state, newTag) {
function closingTagExists(cm, context, tagName, pos, newTag) {
if (!CodeMirror.scanForClosingTag) return false;
var end = Math.min(cm.lastLine() + 1, pos.line + 500);
var nextClose = CodeMirror.scanForClosingTag(cm, pos, null, end);
if (!nextClose || nextClose.tag != tagName) return false;
var cx = state.context;
// If the immediate wrapping context contains onCx instances of
// the same tag, a closing tag only exists if there are at least
// that many closing tags of that type following.
for (var onCx = newTag ? 1 : 0; cx && cx.tagName == tagName; cx = cx.prev) ++onCx;
var onCx = newTag ? 1 : 0
for (var i = context.length - 1; i >= 0; i--) {
if (context[i] == tagName) ++onCx
else break
}
pos = nextClose.to;
for (var i = 1; i < onCx; i++) {
var next = CodeMirror.scanForClosingTag(cm, pos, null, end);

View File

@ -41,7 +41,9 @@
return;
}
if (emptyListRE.test(line)) {
if (!/>\s*$/.test(line)) cm.replaceRange("", {
var endOfQuote = inQuote && />\s*$/.test(line)
var endOfList = !/>\s*$/.test(line)
if (endOfQuote || endOfList) cm.replaceRange("", {
line: pos.line, ch: 0
}, {
line: pos.line, ch: pos.ch + 1

View File

@ -118,16 +118,24 @@
}
CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) {
if (old && old != CodeMirror.Init) {
cm.off("cursorActivity", doMatchBrackets);
function clear(cm) {
if (cm.state.matchBrackets && cm.state.matchBrackets.currentlyHighlighted) {
cm.state.matchBrackets.currentlyHighlighted();
cm.state.matchBrackets.currentlyHighlighted = null;
}
}
if (old && old != CodeMirror.Init) {
cm.off("cursorActivity", doMatchBrackets);
cm.off("focus", doMatchBrackets)
cm.off("blur", clear)
clear(cm);
}
if (val) {
cm.state.matchBrackets = typeof val == "object" ? val : {};
cm.on("cursorActivity", doMatchBrackets);
cm.on("focus", doMatchBrackets)
cm.on("blur", clear)
}
});

View File

@ -42,7 +42,7 @@
}
if (!range || range.cleared || force === "unfold") return;
var myWidget = makeWidget(cm, options);
var myWidget = makeWidget(cm, options, range);
CodeMirror.on(myWidget, "mousedown", function(e) {
myRange.clear();
CodeMirror.e_preventDefault(e);
@ -58,8 +58,13 @@
CodeMirror.signal(cm, "fold", cm, range.from, range.to);
}
function makeWidget(cm, options) {
function makeWidget(cm, options, range) {
var widget = getOption(cm, options, "widget");
if (typeof widget == "function") {
widget = widget(range.from, range.to);
}
if (typeof widget == "string") {
var text = document.createTextNode(widget);
widget = document.createElement("span");

View File

@ -16,7 +16,7 @@
cm.clearGutter(cm.state.foldGutter.options.gutter);
cm.state.foldGutter = null;
cm.off("gutterClick", onGutterClick);
cm.off("change", onChange);
cm.off("changes", onChange);
cm.off("viewportChange", onViewportChange);
cm.off("fold", onFold);
cm.off("unfold", onFold);
@ -26,7 +26,7 @@
cm.state.foldGutter = new State(parseOptions(val));
updateInViewport(cm);
cm.on("gutterClick", onGutterClick);
cm.on("change", onChange);
cm.on("changes", onChange);
cm.on("viewportChange", onViewportChange);
cm.on("fold", onFold);
cm.on("unfold", onFold);
@ -51,8 +51,13 @@
function isFolded(cm, line) {
var marks = cm.findMarks(Pos(line, 0), Pos(line + 1, 0));
for (var i = 0; i < marks.length; ++i)
if (marks[i].__isFold && marks[i].find().from.line == line) return marks[i];
for (var i = 0; i < marks.length; ++i) {
if (marks[i].__isFold) {
var fromPos = marks[i].find(-1);
if (fromPos && fromPos.line === line)
return marks[i];
}
}
}
function marker(spec) {
@ -66,24 +71,36 @@
}
function updateFoldInfo(cm, from, to) {
var opts = cm.state.foldGutter.options, cur = from;
var opts = cm.state.foldGutter.options, cur = from - 1;
var minSize = cm.foldOption(opts, "minFoldSize");
var func = cm.foldOption(opts, "rangeFinder");
// we can reuse the built-in indicator element if its className matches the new state
var clsFolded = typeof opts.indicatorFolded == "string" && classTest(opts.indicatorFolded);
var clsOpen = typeof opts.indicatorOpen == "string" && classTest(opts.indicatorOpen);
cm.eachLine(from, to, function(line) {
++cur;
var mark = null;
var old = line.gutterMarkers;
if (old) old = old[opts.gutter];
if (isFolded(cm, cur)) {
if (clsFolded && old && clsFolded.test(old.className)) return;
mark = marker(opts.indicatorFolded);
} else {
var pos = Pos(cur, 0);
var range = func && func(cm, pos);
if (range && range.to.line - range.from.line >= minSize)
if (range && range.to.line - range.from.line >= minSize) {
if (clsOpen && old && clsOpen.test(old.className)) return;
mark = marker(opts.indicatorOpen);
}
}
if (!mark && !old) return;
cm.setGutterMarker(line, opts.gutter, mark);
++cur;
});
}
// copied from CodeMirror/src/util/dom.js
function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*") }
function updateInViewport(cm) {
var vp = cm.getViewport(), state = cm.state.foldGutter;
if (!state) return;
@ -100,7 +117,7 @@
if (gutter != opts.gutter) return;
var folded = isFolded(cm, line);
if (folded) folded.clear();
else cm.foldCode(Pos(line, 0), opts.rangeFinder);
else cm.foldCode(Pos(line, 0), opts);
}
function onChange(cm) {

View File

@ -11,9 +11,15 @@
})(function(CodeMirror) {
"use strict";
var pseudoClasses = {link: 1, visited: 1, active: 1, hover: 1, focus: 1,
"first-letter": 1, "first-line": 1, "first-child": 1,
before: 1, after: 1, lang: 1};
var pseudoClasses = {"active":1, "after":1, "before":1, "checked":1, "default":1,
"disabled":1, "empty":1, "enabled":1, "first-child":1, "first-letter":1,
"first-line":1, "first-of-type":1, "focus":1, "hover":1, "in-range":1,
"indeterminate":1, "invalid":1, "lang":1, "last-child":1, "last-of-type":1,
"link":1, "not":1, "nth-child":1, "nth-last-child":1, "nth-last-of-type":1,
"nth-of-type":1, "only-of-type":1, "only-child":1, "optional":1, "out-of-range":1,
"placeholder":1, "read-only":1, "read-write":1, "required":1, "root":1,
"selection":1, "target":1, "valid":1, "visited":1
};
CodeMirror.registerHelper("hint", "css", function(cm) {
var cur = cm.getCursor(), token = cm.getTokenAt(cur);

View File

@ -144,10 +144,15 @@
base = base[context.pop().string];
if (base != null) gatherCompletions(base);
} else {
// If not, just look in the global object and any local scope
// If not, just look in the global object, any local scope, and optional additional-context
// (reading into JS mode internals to get at the local and global variables)
for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name);
for (var c = token.state.context; c; c = c.prev)
for (var v = c.vars; v; v = v.next) maybeAdd(v.name)
for (var v = token.state.globalVars; v; v = v.next) maybeAdd(v.name);
if (options && options.additionalContext != null)
for (var key in options.additionalContext)
maybeAdd(key);
if (!options || options.useGlobalScope !== false)
gatherCompletions(global);
forEach(keywords, maybeAdd);

View File

@ -85,11 +85,16 @@
},
pick: function(data, i) {
var completion = data.list[i];
if (completion.hint) completion.hint(this.cm, data, completion);
else this.cm.replaceRange(getText(completion), completion.from || data.from,
completion.to || data.to, "complete");
CodeMirror.signal(data, "pick", completion);
var completion = data.list[i], self = this;
this.cm.operation(function() {
if (completion.hint)
completion.hint(self.cm, data, completion);
else
self.cm.replaceRange(getText(completion), completion.from || data.from,
completion.to || data.to, "complete");
CodeMirror.signal(data, "pick", completion);
self.cm.scrollIntoView();
})
this.close();
},
@ -99,9 +104,14 @@
this.debounce = 0;
}
var identStart = this.startPos;
if(this.data) {
identStart = this.data.from;
}
var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line);
if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||
pos.ch < this.startPos.ch || this.cm.somethingSelected() ||
pos.ch < identStart.ch || this.cm.somethingSelected() ||
(!pos.ch || this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
this.close();
} else {
@ -322,6 +332,7 @@
CodeMirror.on(hints, "mousedown", function() {
setTimeout(function(){cm.focus();}, 20);
});
this.scrollToActive()
CodeMirror.signal(data, "select", completions[this.selectedHint], hints.childNodes[this.selectedHint]);
return true;
@ -363,13 +374,21 @@
if (node) node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
node = this.hints.childNodes[this.selectedHint = i];
node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
if (node.offsetTop < this.hints.scrollTop)
this.hints.scrollTop = node.offsetTop - 3;
else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3;
this.scrollToActive()
CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node);
},
scrollToActive: function() {
var margin = this.completion.options.scrollMargin || 0;
var node1 = this.hints.childNodes[Math.max(0, this.selectedHint - margin)];
var node2 = this.hints.childNodes[Math.min(this.data.list.length - 1, this.selectedHint + margin)];
var firstNode = this.hints.firstChild;
if (node1.offsetTop < this.hints.scrollTop)
this.hints.scrollTop = node1.offsetTop - firstNode.offsetTop;
else if (node2.offsetTop + node2.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
this.hints.scrollTop = node2.offsetTop + node2.offsetHeight - this.hints.clientHeight + firstNode.offsetTop;
},
screenAmount: function() {
return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;
}

View File

@ -264,7 +264,7 @@
token.string = token.string.slice(0, cur.ch - token.start);
}
if (token.string.match(/^[.`"\w@]\w*$/)) {
if (token.string.match(/^[.`"'\w@][\w$#]*$/g)) {
search = token.string;
start = token.start;
end = token.end;

View File

@ -29,7 +29,7 @@
token.string = token.string.slice(0, cur.ch - token.start);
}
var inner = CodeMirror.innerMode(cm.getMode(), token.state);
if (inner.mode.name != "xml") return;
if (!inner.mode.xmlCurrentTag) return
var result = [], replaceToken = false, prefix;
var tag = /\btag\b/.test(token.type) && !/>$/.test(token.string);
var tagName = tag && /^\w/.test(token.string), tagStart;
@ -44,12 +44,15 @@
tagType = "close";
}
if (!tag && !inner.state.tagName || tagType) {
var tagInfo = inner.mode.xmlCurrentTag(inner.state)
if (!tag && !tagInfo || tagType) {
if (tagName)
prefix = token.string;
replaceToken = tagType;
var cx = inner.state.context, curTag = cx && tags[cx.tagName];
var childList = cx ? curTag && curTag.children : tags["!top"];
var context = inner.mode.xmlCurrentContext ? inner.mode.xmlCurrentContext(inner.state) : []
var inner = context.length && context[context.length - 1]
var curTag = inner && tags[inner]
var childList = inner ? curTag && curTag.children : tags["!top"];
if (childList && tagType != "close") {
for (var i = 0; i < childList.length; ++i) if (!prefix || matches(childList[i], prefix, matchInMiddle))
result.push("<" + childList[i]);
@ -58,11 +61,11 @@
if (tags.hasOwnProperty(name) && name != "!top" && name != "!attrs" && (!prefix || matches(name, prefix, matchInMiddle)))
result.push("<" + name);
}
if (cx && (!prefix || tagType == "close" && matches(cx.tagName, prefix, matchInMiddle)))
result.push("</" + cx.tagName + ">");
if (inner && (!prefix || tagType == "close" && matches(inner, prefix, matchInMiddle)))
result.push("</" + inner + ">");
} else {
// Attribute completion
var curTag = tags[inner.state.tagName], attrs = curTag && curTag.attrs;
var curTag = tagInfo && tags[tagInfo.name], attrs = curTag && curTag.attrs;
var globalAttrs = tags["!attrs"];
if (!attrs && !globalAttrs) return;
if (!attrs) {
@ -98,8 +101,14 @@
}
replaceToken = true;
}
for (var i = 0; i < atValues.length; ++i) if (!prefix || matches(atValues[i], prefix, matchInMiddle))
result.push(quote + atValues[i] + quote);
function returnHintsFromAtValues(atValues) {
if (atValues)
for (var i = 0; i < atValues.length; ++i) if (!prefix || matches(atValues[i], prefix, matchInMiddle))
result.push(quote + atValues[i] + quote);
return returnHints();
}
if (atValues && atValues.then) return atValues.then(returnHintsFromAtValues);
return returnHintsFromAtValues(atValues);
} else { // An attribute name
if (token.type == "attribute") {
prefix = token.string;
@ -109,11 +118,14 @@
result.push(attr);
}
}
return {
list: result,
from: replaceToken ? Pos(cur.line, tagStart == null ? token.start : tagStart) : cur,
to: replaceToken ? Pos(cur.line, token.end) : cur
};
function returnHints() {
return {
list: result,
from: replaceToken ? Pos(cur.line, tagStart == null ? token.start : tagStart) : cur,
to: replaceToken ? Pos(cur.line, token.end) : cur
};
}
return returnHints();
}
CodeMirror.registerHelper("hint", "xml", getHints);

View File

@ -25,22 +25,20 @@
-ms-transition: opacity .4s;
}
.CodeMirror-lint-mark-error, .CodeMirror-lint-mark-warning {
.CodeMirror-lint-mark {
background-position: left bottom;
background-repeat: repeat-x;
}
.CodeMirror-lint-mark-error {
background-image:
url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJDw4cOCW1/KIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg==")
;
}
.CodeMirror-lint-mark-warning {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJFhQXEbhTg7YAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAMklEQVQI12NkgIIvJ3QXMjAwdDN+OaEbysDA4MPAwNDNwMCwiOHLCd1zX07o6kBVGQEAKBANtobskNMAAAAASUVORK5CYII=");
}
.CodeMirror-lint-marker-error, .CodeMirror-lint-marker-warning {
.CodeMirror-lint-mark-error {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJDw4cOCW1/KIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg==");
}
.CodeMirror-lint-marker {
background-position: center center;
background-repeat: no-repeat;
cursor: pointer;
@ -51,20 +49,20 @@
position: relative;
}
.CodeMirror-lint-message-error, .CodeMirror-lint-message-warning {
.CodeMirror-lint-message {
padding-left: 18px;
background-position: top left;
background-repeat: no-repeat;
}
.CodeMirror-lint-marker-error, .CodeMirror-lint-message-error {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII=");
}
.CodeMirror-lint-marker-warning, .CodeMirror-lint-message-warning {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAANlBMVEX/uwDvrwD/uwD/uwD/uwD/uwD/uwD/uwD/uwD6twD/uwAAAADurwD2tQD7uAD+ugAAAAD/uwDhmeTRAAAADHRSTlMJ8mN1EYcbmiixgACm7WbuAAAAVklEQVR42n3PUQqAIBBFUU1LLc3u/jdbOJoW1P08DA9Gba8+YWJ6gNJoNYIBzAA2chBth5kLmG9YUoG0NHAUwFXwO9LuBQL1giCQb8gC9Oro2vp5rncCIY8L8uEx5ZkAAAAASUVORK5CYII=");
}
.CodeMirror-lint-marker-error, .CodeMirror-lint-message-error {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII=");
}
.CodeMirror-lint-marker-multiple {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAMAAADzjKfhAAAACVBMVEUAAAAAAAC/v7914kyHAAAAAXRSTlMAQObYZgAAACNJREFUeNo1ioEJAAAIwmz/H90iFFSGJgFMe3gaLZ0od+9/AQZ0ADosbYraAAAAAElFTkSuQmCC");
background-repeat: no-repeat;

View File

@ -12,11 +12,14 @@
"use strict";
var GUTTER_ID = "CodeMirror-lint-markers";
function showTooltip(e, content) {
function showTooltip(cm, e, content) {
var tt = document.createElement("div");
tt.className = "CodeMirror-lint-tooltip";
tt.className = "CodeMirror-lint-tooltip cm-s-" + cm.options.theme;
tt.appendChild(content.cloneNode(true));
document.body.appendChild(tt);
if (cm.state.lint.options.selfContain)
cm.getWrapperElement().appendChild(tt);
else
document.body.appendChild(tt);
function position(e) {
if (!tt.parentNode) return CodeMirror.off(document, "mousemove", position);
@ -38,8 +41,8 @@
setTimeout(function() { rm(tt); }, 600);
}
function showTooltipFor(e, content, node) {
var tooltip = showTooltip(e, content);
function showTooltipFor(cm, e, content, node) {
var tooltip = showTooltip(cm, e, content);
function hide() {
CodeMirror.off(node, "mouseout", hide);
if (tooltip) { hideTooltip(tooltip); tooltip = null; }
@ -78,16 +81,16 @@
state.marked.length = 0;
}
function makeMarker(labels, severity, multiple, tooltips) {
function makeMarker(cm, labels, severity, multiple, tooltips) {
var marker = document.createElement("div"), inner = marker;
marker.className = "CodeMirror-lint-marker-" + severity;
marker.className = "CodeMirror-lint-marker CodeMirror-lint-marker-" + severity;
if (multiple) {
inner = marker.appendChild(document.createElement("div"));
inner.className = "CodeMirror-lint-marker-multiple";
inner.className = "CodeMirror-lint-marker CodeMirror-lint-marker-multiple";
}
if (tooltips != false) CodeMirror.on(inner, "mouseover", function(e) {
showTooltipFor(e, labels, inner);
showTooltipFor(cm, e, labels, inner);
});
return marker;
@ -111,11 +114,11 @@
var severity = ann.severity;
if (!severity) severity = "error";
var tip = document.createElement("div");
tip.className = "CodeMirror-lint-message-" + severity;
tip.className = "CodeMirror-lint-message CodeMirror-lint-message-" + severity;
if (typeof ann.messageHTML != 'undefined') {
tip.innerHTML = ann.messageHTML;
tip.innerHTML = ann.messageHTML;
} else {
tip.appendChild(document.createTextNode(ann.message));
tip.appendChild(document.createTextNode(ann.message));
}
return tip;
}
@ -180,13 +183,13 @@
if (state.hasGutter) tipLabel.appendChild(annotationTooltip(ann));
if (ann.to) state.marked.push(cm.markText(ann.from, ann.to, {
className: "CodeMirror-lint-mark-" + severity,
className: "CodeMirror-lint-mark CodeMirror-lint-mark-" + severity,
__annotation: ann
}));
}
if (state.hasGutter)
cm.setGutterMarker(line, GUTTER_ID, makeMarker(tipLabel, maxSeverity, anns.length > 1,
cm.setGutterMarker(line, GUTTER_ID, makeMarker(cm, tipLabel, maxSeverity, anns.length > 1,
state.options.tooltips));
}
if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm);
@ -199,14 +202,14 @@
state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500);
}
function popupTooltips(annotations, e) {
function popupTooltips(cm, annotations, e) {
var target = e.target || e.srcElement;
var tooltip = document.createDocumentFragment();
for (var i = 0; i < annotations.length; i++) {
var ann = annotations[i];
tooltip.appendChild(annotationTooltip(ann));
}
showTooltipFor(e, tooltip, target);
showTooltipFor(cm, e, tooltip, target);
}
function onMouseOver(cm, e) {
@ -220,7 +223,7 @@
var ann = spans[i].__annotation;
if (ann) annotations.push(ann);
}
if (annotations.length) popupTooltips(annotations, e);
if (annotations.length) popupTooltips(cm, annotations, e);
}
CodeMirror.defineOption("lint", false, function(cm, val, old) {

View File

@ -443,22 +443,26 @@
aligners[i].clear();
aligners.length = 0;
var cm = [dv.edit, dv.orig], scroll = [];
var cm = [dv.edit, dv.orig], scroll = [], offset = []
if (other) cm.push(other.orig);
for (var i = 0; i < cm.length; i++)
for (var i = 0; i < cm.length; i++) {
scroll.push(cm[i].getScrollInfo().top);
offset.push(-cm[i].getScrollerElement().getBoundingClientRect().top)
}
if (offset[0] != offset[1] || cm.length == 3 && offset[1] != offset[2])
alignLines(cm, offset, [0, 0, 0], aligners)
for (var ln = 0; ln < linesToAlign.length; ln++)
alignLines(cm, linesToAlign[ln], aligners);
alignLines(cm, offset, linesToAlign[ln], aligners);
for (var i = 0; i < cm.length; i++)
cm[i].scrollTo(null, scroll[i]);
}
function alignLines(cm, lines, aligners) {
var maxOffset = 0, offset = [];
function alignLines(cm, cmOffset, lines, aligners) {
var maxOffset = -1e8, offset = [];
for (var i = 0; i < cm.length; i++) if (lines[i] != null) {
var off = cm[i].heightAtLine(lines[i], "local");
var off = cm[i].heightAtLine(lines[i], "local") - cmOffset[i];
offset[i] = off;
maxOffset = Math.max(maxOffset, off);
}

View File

@ -16,8 +16,8 @@
var countDown = n;
return function() { if (--countDown == 0) cont(); };
}
function ensureDeps(mode, cont) {
var deps = CodeMirror.modes[mode].dependencies;
function ensureDeps(mode, cont, options) {
var modeObj = CodeMirror.modes[mode], deps = modeObj && modeObj.dependencies;
if (!deps) return cont();
var missing = [];
for (var i = 0; i < deps.length; ++i) {
@ -27,16 +27,18 @@
if (!missing.length) return cont();
var split = splitCallback(cont, missing.length);
for (var i = 0; i < missing.length; ++i)
CodeMirror.requireMode(missing[i], split);
CodeMirror.requireMode(missing[i], split, options);
}
CodeMirror.requireMode = function(mode, cont) {
CodeMirror.requireMode = function(mode, cont, options) {
if (typeof mode != "string") mode = mode.name;
if (CodeMirror.modes.hasOwnProperty(mode)) return ensureDeps(mode, cont);
if (CodeMirror.modes.hasOwnProperty(mode)) return ensureDeps(mode, cont, options);
if (loading.hasOwnProperty(mode)) return loading[mode].push(cont);
var file = CodeMirror.modeURL.replace(/%N/g, mode);
if (env == "plain") {
var file = options && options.path ? options.path(mode) : CodeMirror.modeURL.replace(/%N/g, mode);
if (options && options.loadMode) {
options.loadMode(file, function() { ensureDeps(mode, cont, options) })
} else if (env == "plain") {
var script = document.createElement("script");
script.src = file;
var others = document.getElementsByTagName("script")[0];
@ -44,7 +46,7 @@
CodeMirror.on(script, "load", function() {
ensureDeps(mode, function() {
for (var i = 0; i < list.length; ++i) list[i]();
});
}, options);
});
others.parentNode.insertBefore(script, others);
} else if (env == "cjs") {
@ -55,10 +57,10 @@
}
};
CodeMirror.autoLoadMode = function(instance, mode) {
CodeMirror.autoLoadMode = function(instance, mode, options) {
if (!CodeMirror.modes.hasOwnProperty(mode))
CodeMirror.requireMode(mode, function() {
instance.setOption("mode", instance.getOption("mode"));
});
}, options);
};
});

View File

@ -1,158 +1,333 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function () {
'use strict';
window.CodeMirror = {};
function copyObj(obj, target, overwrite) {
if (!target) { target = {}; }
for (var prop in obj)
{ if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))
{ target[prop] = obj[prop]; } }
return target
}
(function() {
"use strict";
// Counts the column offset in a string, taking tabs into account.
// Used mostly to find indentation.
function countColumn(string, end, tabSize, startIndex, startValue) {
if (end == null) {
end = string.search(/[^\s\u00a0]/);
if (end == -1) { end = string.length; }
}
for (var i = startIndex || 0, n = startValue || 0;;) {
var nextTab = string.indexOf("\t", i);
if (nextTab < 0 || nextTab >= end)
{ return n + (end - i) }
n += nextTab - i;
n += tabSize - (n % tabSize);
i = nextTab + 1;
}
}
function splitLines(string){ return string.split(/\r?\n|\r/); };
function nothing() {}
function StringStream(string) {
this.pos = this.start = 0;
this.string = string;
this.lineStart = 0;
}
StringStream.prototype = {
eol: function() {return this.pos >= this.string.length;},
sol: function() {return this.pos == 0;},
peek: function() {return this.string.charAt(this.pos) || null;},
next: function() {
function createObj(base, props) {
var inst;
if (Object.create) {
inst = Object.create(base);
} else {
nothing.prototype = base;
inst = new nothing();
}
if (props) { copyObj(props, inst); }
return inst
}
// STRING STREAM
// Fed to the mode parsers, provides helper functions to make
// parsers more succinct.
var StringStream = function(string, tabSize, lineOracle) {
this.pos = this.start = 0;
this.string = string;
this.tabSize = tabSize || 8;
this.lastColumnPos = this.lastColumnValue = 0;
this.lineStart = 0;
this.lineOracle = lineOracle;
};
StringStream.prototype.eol = function () {return this.pos >= this.string.length};
StringStream.prototype.sol = function () {return this.pos == this.lineStart};
StringStream.prototype.peek = function () {return this.string.charAt(this.pos) || undefined};
StringStream.prototype.next = function () {
if (this.pos < this.string.length)
return this.string.charAt(this.pos++);
},
eat: function(match) {
{ return this.string.charAt(this.pos++) }
};
StringStream.prototype.eat = function (match) {
var ch = this.string.charAt(this.pos);
if (typeof match == "string") var ok = ch == match;
else var ok = ch && (match.test ? match.test(ch) : match(ch));
if (ok) {++this.pos; return ch;}
},
eatWhile: function(match) {
var ok;
if (typeof match == "string") { ok = ch == match; }
else { ok = ch && (match.test ? match.test(ch) : match(ch)); }
if (ok) {++this.pos; return ch}
};
StringStream.prototype.eatWhile = function (match) {
var start = this.pos;
while (this.eat(match)){}
return this.pos > start;
},
eatSpace: function() {
return this.pos > start
};
StringStream.prototype.eatSpace = function () {
var start = this.pos;
while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
return this.pos > start;
},
skipToEnd: function() {this.pos = this.string.length;},
skipTo: function(ch) {
while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) { ++this.pos; }
return this.pos > start
};
StringStream.prototype.skipToEnd = function () {this.pos = this.string.length;};
StringStream.prototype.skipTo = function (ch) {
var found = this.string.indexOf(ch, this.pos);
if (found > -1) {this.pos = found; return true;}
},
backUp: function(n) {this.pos -= n;},
column: function() {return this.start - this.lineStart;},
indentation: function() {return 0;},
match: function(pattern, consume, caseInsensitive) {
if (found > -1) {this.pos = found; return true}
};
StringStream.prototype.backUp = function (n) {this.pos -= n;};
StringStream.prototype.column = function () {
if (this.lastColumnPos < this.start) {
this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
this.lastColumnPos = this.start;
}
return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0)
};
StringStream.prototype.indentation = function () {
return countColumn(this.string, null, this.tabSize) -
(this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0)
};
StringStream.prototype.match = function (pattern, consume, caseInsensitive) {
if (typeof pattern == "string") {
var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
var cased = function (str) { return caseInsensitive ? str.toLowerCase() : str; };
var substr = this.string.substr(this.pos, pattern.length);
if (cased(substr) == cased(pattern)) {
if (consume !== false) this.pos += pattern.length;
return true;
if (consume !== false) { this.pos += pattern.length; }
return true
}
} else {
var match = this.string.slice(this.pos).match(pattern);
if (match && match.index > 0) return null;
if (match && consume !== false) this.pos += match[0].length;
return match;
if (match && match.index > 0) { return null }
if (match && consume !== false) { this.pos += match[0].length; }
return match
}
},
current: function(){return this.string.slice(this.start, this.pos);},
hideFirstChars: function(n, inner) {
};
StringStream.prototype.current = function (){return this.string.slice(this.start, this.pos)};
StringStream.prototype.hideFirstChars = function (n, inner) {
this.lineStart += n;
try { return inner(); }
try { return inner() }
finally { this.lineStart -= n; }
},
lookAhead: function() { return null }
};
CodeMirror.StringStream = StringStream;
};
StringStream.prototype.lookAhead = function (n) {
var oracle = this.lineOracle;
return oracle && oracle.lookAhead(n)
};
StringStream.prototype.baseToken = function () {
var oracle = this.lineOracle;
return oracle && oracle.baseToken(this.pos)
};
CodeMirror.startState = function (mode, a1, a2) {
return mode.startState ? mode.startState(a1, a2) : true;
};
// Known modes, by name and by MIME
var modes = {}, mimeModes = {};
var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
CodeMirror.defineMode = function (name, mode) {
if (arguments.length > 2)
mode.dependencies = Array.prototype.slice.call(arguments, 2);
modes[name] = mode;
};
CodeMirror.defineMIME = function (mime, spec) { mimeModes[mime] = spec; };
CodeMirror.resolveMode = function(spec) {
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
spec = mimeModes[spec];
} else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
spec = mimeModes[spec.name];
}
if (typeof spec == "string") return {name: spec};
else return spec || {name: "null"};
};
CodeMirror.getMode = function (options, spec) {
spec = CodeMirror.resolveMode(spec);
var mfactory = modes[spec.name];
if (!mfactory) throw new Error("Unknown mode: " + spec);
return mfactory(options, spec);
};
CodeMirror.registerHelper = CodeMirror.registerGlobalHelper = Math.min;
CodeMirror.defineMode("null", function() {
return {token: function(stream) {stream.skipToEnd();}};
});
CodeMirror.defineMIME("text/plain", "null");
CodeMirror.runMode = function (string, modespec, callback, options) {
var mode = CodeMirror.getMode({ indentUnit: 2 }, modespec);
if (callback.nodeType == 1) {
var tabSize = (options && options.tabSize) || 4;
var node = callback, col = 0;
node.innerHTML = "";
callback = function (text, style) {
if (text == "\n") {
node.appendChild(document.createElement("br"));
col = 0;
return;
}
var content = "";
// replace tabs
for (var pos = 0; ;) {
var idx = text.indexOf("\t", pos);
if (idx == -1) {
content += text.slice(pos);
col += text.length - pos;
break;
} else {
col += idx - pos;
content += text.slice(pos, idx);
var size = tabSize - col % tabSize;
col += size;
for (var i = 0; i < size; ++i) content += " ";
pos = idx + 1;
}
}
if (style) {
var sp = node.appendChild(document.createElement("span"));
sp.className = "cm-" + style.replace(/ +/g, " cm-");
sp.appendChild(document.createTextNode(content));
} else {
node.appendChild(document.createTextNode(content));
}
};
// Extra arguments are stored as the mode's dependencies, which is
// used by (legacy) mechanisms like loadmode.js to automatically
// load a mode. (Preferred mechanism is the require/define calls.)
function defineMode(name, mode) {
if (arguments.length > 2)
{ mode.dependencies = Array.prototype.slice.call(arguments, 2); }
modes[name] = mode;
}
var lines = splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
for (var i = 0, e = lines.length; i < e; ++i) {
if (i) callback("\n");
var stream = new CodeMirror.StringStream(lines[i]);
if (!stream.string && mode.blankLine) mode.blankLine(state);
while (!stream.eol()) {
var style = mode.token(stream, state);
callback(stream.current(), style, i, stream.start, state);
stream.start = stream.pos;
function defineMIME(mime, spec) {
mimeModes[mime] = spec;
}
// Given a MIME type, a {name, ...options} config object, or a name
// string, return a mode config object.
function resolveMode(spec) {
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
spec = mimeModes[spec];
} else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
var found = mimeModes[spec.name];
if (typeof found == "string") { found = {name: found}; }
spec = createObj(found, spec);
spec.name = found.name;
} else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
return resolveMode("application/xml")
} else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+json$/.test(spec)) {
return resolveMode("application/json")
}
if (typeof spec == "string") { return {name: spec} }
else { return spec || {name: "null"} }
}
};
})();
// Given a mode spec (anything that resolveMode accepts), find and
// initialize an actual mode object.
function getMode(options, spec) {
spec = resolveMode(spec);
var mfactory = modes[spec.name];
if (!mfactory) { return getMode(options, "text/plain") }
var modeObj = mfactory(options, spec);
if (modeExtensions.hasOwnProperty(spec.name)) {
var exts = modeExtensions[spec.name];
for (var prop in exts) {
if (!exts.hasOwnProperty(prop)) { continue }
if (modeObj.hasOwnProperty(prop)) { modeObj["_" + prop] = modeObj[prop]; }
modeObj[prop] = exts[prop];
}
}
modeObj.name = spec.name;
if (spec.helperType) { modeObj.helperType = spec.helperType; }
if (spec.modeProps) { for (var prop$1 in spec.modeProps)
{ modeObj[prop$1] = spec.modeProps[prop$1]; } }
return modeObj
}
// This can be used to attach properties to mode objects from
// outside the actual mode definition.
var modeExtensions = {};
function extendMode(mode, properties) {
var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
copyObj(properties, exts);
}
function copyState(mode, state) {
if (state === true) { return state }
if (mode.copyState) { return mode.copyState(state) }
var nstate = {};
for (var n in state) {
var val = state[n];
if (val instanceof Array) { val = val.concat([]); }
nstate[n] = val;
}
return nstate
}
// Given a mode and a state (for that mode), find the inner mode and
// state at the position that the state refers to.
function innerMode(mode, state) {
var info;
while (mode.innerMode) {
info = mode.innerMode(state);
if (!info || info.mode == mode) { break }
state = info.state;
mode = info.mode;
}
return info || {mode: mode, state: state}
}
function startState(mode, a1, a2) {
return mode.startState ? mode.startState(a1, a2) : true
}
var modeMethods = {
__proto__: null,
modes: modes,
mimeModes: mimeModes,
defineMode: defineMode,
defineMIME: defineMIME,
resolveMode: resolveMode,
getMode: getMode,
modeExtensions: modeExtensions,
extendMode: extendMode,
copyState: copyState,
innerMode: innerMode,
startState: startState
};
// declare global: globalThis, CodeMirror
// Create a minimal CodeMirror needed to use runMode, and assign to root.
var root = typeof globalThis !== 'undefined' ? globalThis : window;
root.CodeMirror = {};
// Copy StringStream and mode methods into CodeMirror object.
CodeMirror.StringStream = StringStream;
for (var exported in modeMethods) { CodeMirror[exported] = modeMethods[exported]; }
// Minimal default mode.
CodeMirror.defineMode("null", function () { return ({token: function (stream) { return stream.skipToEnd(); }}); });
CodeMirror.defineMIME("text/plain", "null");
CodeMirror.registerHelper = CodeMirror.registerGlobalHelper = Math.min;
CodeMirror.splitLines = function(string) { return string.split(/\r?\n|\r/) };
CodeMirror.defaults = { indentUnit: 2 };
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
{ mod(require("../../lib/codemirror")); }
else if (typeof define == "function" && define.amd) // AMD
{ define(["../../lib/codemirror"], mod); }
else // Plain browser env
{ mod(CodeMirror); }
})(function(CodeMirror) {
CodeMirror.runMode = function(string, modespec, callback, options) {
var mode = CodeMirror.getMode(CodeMirror.defaults, modespec);
var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;
// Create a tokenizing callback function if passed-in callback is a DOM element.
if (callback.appendChild) {
var ie = /MSIE \d/.test(navigator.userAgent);
var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
var node = callback, col = 0;
node.innerHTML = "";
callback = function(text, style) {
if (text == "\n") {
// Emitting LF or CRLF on IE8 or earlier results in an incorrect display.
// Emitting a carriage return makes everything ok.
node.appendChild(document.createTextNode(ie_lt9 ? '\r' : text));
col = 0;
return;
}
var content = "";
// replace tabs
for (var pos = 0;;) {
var idx = text.indexOf("\t", pos);
if (idx == -1) {
content += text.slice(pos);
col += text.length - pos;
break;
} else {
col += idx - pos;
content += text.slice(pos, idx);
var size = tabSize - col % tabSize;
col += size;
for (var i = 0; i < size; ++i) { content += " "; }
pos = idx + 1;
}
}
// Create a node with token style and append it to the callback DOM element.
if (style) {
var sp = node.appendChild(document.createElement("span"));
sp.className = "cm-" + style.replace(/ +/g, " cm-");
sp.appendChild(document.createTextNode(content));
} else {
node.appendChild(document.createTextNode(content));
}
};
}
var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
for (var i = 0, e = lines.length; i < e; ++i) {
if (i) { callback("\n"); }
var stream = new CodeMirror.StringStream(lines[i], null, {
lookAhead: function(n) { return lines[i + n] },
baseToken: function() {}
});
if (!stream.string && mode.blankLine) { mode.blankLine(state); }
while (!stream.eol()) {
var style = mode.token(stream, state);
callback(stream.current(), style, i, stream.start, state);
stream.start = stream.pos;
}
}
};
});
}());

View File

@ -13,11 +13,12 @@
CodeMirror.runMode = function(string, modespec, callback, options) {
var mode = CodeMirror.getMode(CodeMirror.defaults, modespec);
var ie = /MSIE \d/.test(navigator.userAgent);
var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;
// Create a tokenizing callback function if passed-in callback is a DOM element.
if (callback.appendChild) {
var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;
var ie = /MSIE \d/.test(navigator.userAgent);
var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
var node = callback, col = 0;
node.innerHTML = "";
callback = function(text, style) {
@ -45,7 +46,7 @@ CodeMirror.runMode = function(string, modespec, callback, options) {
pos = idx + 1;
}
}
// Create a node with token style and append it to the callback DOM element.
if (style) {
var sp = node.appendChild(document.createElement("span"));
sp.className = "cm-" + style.replace(/ +/g, " cm-");
@ -59,7 +60,10 @@ CodeMirror.runMode = function(string, modespec, callback, options) {
var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
for (var i = 0, e = lines.length; i < e; ++i) {
if (i) callback("\n");
var stream = new CodeMirror.StringStream(lines[i]);
var stream = new CodeMirror.StringStream(lines[i], null, {
lookAhead: function(n) { return lines[i + n] },
baseToken: function() {}
});
if (!stream.string && mode.blankLine) mode.blankLine(state);
while (!stream.eol()) {
var style = mode.token(stream, state);

View File

@ -1,190 +1,323 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
'use strict';
/* Just enough of CodeMirror to run runMode under node.js */
function splitLines(string){return string.split(/\r\n?|\n/);};
function copyObj(obj, target, overwrite) {
if (!target) { target = {}; }
for (var prop in obj)
{ if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))
{ target[prop] = obj[prop]; } }
return target
}
// Counts the column offset in a string, taking tabs into account.
// Used mostly to find indentation.
var countColumn = exports.countColumn = function(string, end, tabSize, startIndex, startValue) {
function countColumn(string, end, tabSize, startIndex, startValue) {
if (end == null) {
end = string.search(/[^\s\u00a0]/);
if (end == -1) end = string.length;
if (end == -1) { end = string.length; }
}
for (var i = startIndex || 0, n = startValue || 0;;) {
var nextTab = string.indexOf("\t", i);
if (nextTab < 0 || nextTab >= end)
return n + (end - i);
{ return n + (end - i) }
n += nextTab - i;
n += tabSize - (n % tabSize);
i = nextTab + 1;
}
};
}
function StringStream(string, tabSize, context) {
function nothing() {}
function createObj(base, props) {
var inst;
if (Object.create) {
inst = Object.create(base);
} else {
nothing.prototype = base;
inst = new nothing();
}
if (props) { copyObj(props, inst); }
return inst
}
// STRING STREAM
// Fed to the mode parsers, provides helper functions to make
// parsers more succinct.
var StringStream = function(string, tabSize, lineOracle) {
this.pos = this.start = 0;
this.string = string;
this.tabSize = tabSize || 8;
this.lastColumnPos = this.lastColumnValue = 0;
this.lineStart = 0;
this.context = context
this.lineOracle = lineOracle;
};
StringStream.prototype = {
eol: function() {return this.pos >= this.string.length;},
sol: function() {return this.pos == this.lineStart;},
peek: function() {return this.string.charAt(this.pos) || undefined;},
next: function() {
if (this.pos < this.string.length)
return this.string.charAt(this.pos++);
},
eat: function(match) {
var ch = this.string.charAt(this.pos);
if (typeof match == "string") var ok = ch == match;
else var ok = ch && (match.test ? match.test(ch) : match(ch));
if (ok) {++this.pos; return ch;}
},
eatWhile: function(match) {
var start = this.pos;
while (this.eat(match)){}
return this.pos > start;
},
eatSpace: function() {
var start = this.pos;
while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
return this.pos > start;
},
skipToEnd: function() {this.pos = this.string.length;},
skipTo: function(ch) {
var found = this.string.indexOf(ch, this.pos);
if (found > -1) {this.pos = found; return true;}
},
backUp: function(n) {this.pos -= n;},
column: function() {
if (this.lastColumnPos < this.start) {
this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
this.lastColumnPos = this.start;
StringStream.prototype.eol = function () {return this.pos >= this.string.length};
StringStream.prototype.sol = function () {return this.pos == this.lineStart};
StringStream.prototype.peek = function () {return this.string.charAt(this.pos) || undefined};
StringStream.prototype.next = function () {
if (this.pos < this.string.length)
{ return this.string.charAt(this.pos++) }
};
StringStream.prototype.eat = function (match) {
var ch = this.string.charAt(this.pos);
var ok;
if (typeof match == "string") { ok = ch == match; }
else { ok = ch && (match.test ? match.test(ch) : match(ch)); }
if (ok) {++this.pos; return ch}
};
StringStream.prototype.eatWhile = function (match) {
var start = this.pos;
while (this.eat(match)){}
return this.pos > start
};
StringStream.prototype.eatSpace = function () {
var start = this.pos;
while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) { ++this.pos; }
return this.pos > start
};
StringStream.prototype.skipToEnd = function () {this.pos = this.string.length;};
StringStream.prototype.skipTo = function (ch) {
var found = this.string.indexOf(ch, this.pos);
if (found > -1) {this.pos = found; return true}
};
StringStream.prototype.backUp = function (n) {this.pos -= n;};
StringStream.prototype.column = function () {
if (this.lastColumnPos < this.start) {
this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
this.lastColumnPos = this.start;
}
return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0)
};
StringStream.prototype.indentation = function () {
return countColumn(this.string, null, this.tabSize) -
(this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0)
};
StringStream.prototype.match = function (pattern, consume, caseInsensitive) {
if (typeof pattern == "string") {
var cased = function (str) { return caseInsensitive ? str.toLowerCase() : str; };
var substr = this.string.substr(this.pos, pattern.length);
if (cased(substr) == cased(pattern)) {
if (consume !== false) { this.pos += pattern.length; }
return true
}
return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
},
indentation: function() {
return countColumn(this.string, null, this.tabSize) -
(this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
},
match: function(pattern, consume, caseInsensitive) {
if (typeof pattern == "string") {
var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
var substr = this.string.substr(this.pos, pattern.length);
if (cased(substr) == cased(pattern)) {
if (consume !== false) this.pos += pattern.length;
return true;
}
} else {
var match = this.string.slice(this.pos).match(pattern);
if (match && match.index > 0) return null;
if (match && consume !== false) this.pos += match[0].length;
return match;
}
},
current: function(){return this.string.slice(this.start, this.pos);},
hideFirstChars: function(n, inner) {
this.lineStart += n;
try { return inner(); }
finally { this.lineStart -= n; }
},
lookAhead: function(n) {
var line = this.context.line + n
return line >= this.context.lines.length ? null : this.context.lines[line]
} else {
var match = this.string.slice(this.pos).match(pattern);
if (match && match.index > 0) { return null }
if (match && consume !== false) { this.pos += match[0].length; }
return match
}
};
exports.StringStream = StringStream;
exports.startState = function(mode, a1, a2) {
return mode.startState ? mode.startState(a1, a2) : true;
StringStream.prototype.current = function (){return this.string.slice(this.start, this.pos)};
StringStream.prototype.hideFirstChars = function (n, inner) {
this.lineStart += n;
try { return inner() }
finally { this.lineStart -= n; }
};
StringStream.prototype.lookAhead = function (n) {
var oracle = this.lineOracle;
return oracle && oracle.lookAhead(n)
};
StringStream.prototype.baseToken = function () {
var oracle = this.lineOracle;
return oracle && oracle.baseToken(this.pos)
};
var modes = exports.modes = {}, mimeModes = exports.mimeModes = {};
exports.defineMode = function(name, mode) {
// Known modes, by name and by MIME
var modes = {}, mimeModes = {};
// Extra arguments are stored as the mode's dependencies, which is
// used by (legacy) mechanisms like loadmode.js to automatically
// load a mode. (Preferred mechanism is the require/define calls.)
function defineMode(name, mode) {
if (arguments.length > 2)
mode.dependencies = Array.prototype.slice.call(arguments, 2);
{ mode.dependencies = Array.prototype.slice.call(arguments, 2); }
modes[name] = mode;
};
exports.defineMIME = function(mime, spec) { mimeModes[mime] = spec; };
}
exports.defineMode("null", function() {
return {token: function(stream) {stream.skipToEnd();}};
});
exports.defineMIME("text/plain", "null");
function defineMIME(mime, spec) {
mimeModes[mime] = spec;
}
exports.resolveMode = function(spec) {
// Given a MIME type, a {name, ...options} config object, or a name
// string, return a mode config object.
function resolveMode(spec) {
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
spec = mimeModes[spec];
} else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
spec = mimeModes[spec.name];
var found = mimeModes[spec.name];
if (typeof found == "string") { found = {name: found}; }
spec = createObj(found, spec);
spec.name = found.name;
} else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
return resolveMode("application/xml")
} else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+json$/.test(spec)) {
return resolveMode("application/json")
}
if (typeof spec == "string") return {name: spec};
else return spec || {name: "null"};
};
function copyObj(obj, target, overwrite) {
if (!target) target = {};
for (var prop in obj)
if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))
target[prop] = obj[prop];
return target;
if (typeof spec == "string") { return {name: spec} }
else { return spec || {name: "null"} }
}
// This can be used to attach properties to mode objects from
// outside the actual mode definition.
var modeExtensions = exports.modeExtensions = {};
exports.extendMode = function(mode, properties) {
var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
copyObj(properties, exts);
};
exports.getMode = function(options, spec) {
var spec = exports.resolveMode(spec);
// Given a mode spec (anything that resolveMode accepts), find and
// initialize an actual mode object.
function getMode(options, spec) {
spec = resolveMode(spec);
var mfactory = modes[spec.name];
if (!mfactory) return exports.getMode(options, "text/plain");
if (!mfactory) { return getMode(options, "text/plain") }
var modeObj = mfactory(options, spec);
if (modeExtensions.hasOwnProperty(spec.name)) {
var exts = modeExtensions[spec.name];
for (var prop in exts) {
if (!exts.hasOwnProperty(prop)) continue;
if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop];
if (!exts.hasOwnProperty(prop)) { continue }
if (modeObj.hasOwnProperty(prop)) { modeObj["_" + prop] = modeObj[prop]; }
modeObj[prop] = exts[prop];
}
}
modeObj.name = spec.name;
if (spec.helperType) modeObj.helperType = spec.helperType;
if (spec.modeProps) for (var prop in spec.modeProps)
modeObj[prop] = spec.modeProps[prop];
if (spec.helperType) { modeObj.helperType = spec.helperType; }
if (spec.modeProps) { for (var prop$1 in spec.modeProps)
{ modeObj[prop$1] = spec.modeProps[prop$1]; } }
return modeObj;
};
return modeObj
}
exports.innerMode = function(mode, state) {
// This can be used to attach properties to mode objects from
// outside the actual mode definition.
var modeExtensions = {};
function extendMode(mode, properties) {
var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
copyObj(properties, exts);
}
function copyState(mode, state) {
if (state === true) { return state }
if (mode.copyState) { return mode.copyState(state) }
var nstate = {};
for (var n in state) {
var val = state[n];
if (val instanceof Array) { val = val.concat([]); }
nstate[n] = val;
}
return nstate
}
// Given a mode and a state (for that mode), find the inner mode and
// state at the position that the state refers to.
function innerMode(mode, state) {
var info;
while (mode.innerMode) {
info = mode.innerMode(state);
if (!info || info.mode == mode) break;
if (!info || info.mode == mode) { break }
state = info.state;
mode = info.mode;
}
return info || {mode: mode, state: state};
return info || {mode: mode, state: state}
}
exports.registerHelper = exports.registerGlobalHelper = Math.min;
function startState(mode, a1, a2) {
return mode.startState ? mode.startState(a1, a2) : true
}
exports.runMode = function(string, modespec, callback, options) {
var mode = exports.getMode({indentUnit: 2}, modespec);
var lines = splitLines(string), state = (options && options.state) || exports.startState(mode);
var context = {lines: lines, line: 0}
for (var i = 0, e = lines.length; i < e; ++i, ++context.line) {
if (i) callback("\n");
var stream = new exports.StringStream(lines[i], 4, context);
if (!stream.string && mode.blankLine) mode.blankLine(state);
var modeMethods = {
__proto__: null,
modes: modes,
mimeModes: mimeModes,
defineMode: defineMode,
defineMIME: defineMIME,
resolveMode: resolveMode,
getMode: getMode,
modeExtensions: modeExtensions,
extendMode: extendMode,
copyState: copyState,
innerMode: innerMode,
startState: startState
};
// Copy StringStream and mode methods into exports (CodeMirror) object.
exports.StringStream = StringStream;
exports.countColumn = countColumn;
for (var exported in modeMethods) { exports[exported] = modeMethods[exported]; }
// Shim library CodeMirror with the minimal CodeMirror defined above.
require.cache[require.resolve("../../lib/codemirror")] = require.cache[require.resolve("./runmode.node")];
require.cache[require.resolve("../../addon/runmode/runmode")] = require.cache[require.resolve("./runmode.node")];
// Minimal default mode.
exports.defineMode("null", function () { return ({token: function (stream) { return stream.skipToEnd(); }}); });
exports.defineMIME("text/plain", "null");
exports.registerHelper = exports.registerGlobalHelper = Math.min;
exports.splitLines = function(string) { return string.split(/\r?\n|\r/) };
exports.defaults = { indentUnit: 2 };
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
{ mod(require("../../lib/codemirror")); }
else if (typeof define == "function" && define.amd) // AMD
{ define(["../../lib/codemirror"], mod); }
else // Plain browser env
{ mod(CodeMirror); }
})(function(CodeMirror) {
CodeMirror.runMode = function(string, modespec, callback, options) {
var mode = CodeMirror.getMode(CodeMirror.defaults, modespec);
var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;
// Create a tokenizing callback function if passed-in callback is a DOM element.
if (callback.appendChild) {
var ie = /MSIE \d/.test(navigator.userAgent);
var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
var node = callback, col = 0;
node.innerHTML = "";
callback = function(text, style) {
if (text == "\n") {
// Emitting LF or CRLF on IE8 or earlier results in an incorrect display.
// Emitting a carriage return makes everything ok.
node.appendChild(document.createTextNode(ie_lt9 ? '\r' : text));
col = 0;
return;
}
var content = "";
// replace tabs
for (var pos = 0;;) {
var idx = text.indexOf("\t", pos);
if (idx == -1) {
content += text.slice(pos);
col += text.length - pos;
break;
} else {
col += idx - pos;
content += text.slice(pos, idx);
var size = tabSize - col % tabSize;
col += size;
for (var i = 0; i < size; ++i) { content += " "; }
pos = idx + 1;
}
}
// Create a node with token style and append it to the callback DOM element.
if (style) {
var sp = node.appendChild(document.createElement("span"));
sp.className = "cm-" + style.replace(/ +/g, " cm-");
sp.appendChild(document.createTextNode(content));
} else {
node.appendChild(document.createTextNode(content));
}
};
}
var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);
for (var i = 0, e = lines.length; i < e; ++i) {
if (i) { callback("\n"); }
var stream = new CodeMirror.StringStream(lines[i], null, {
lookAhead: function(n) { return lines[i + n] },
baseToken: function() {}
});
if (!stream.string && mode.blankLine) { mode.blankLine(state); }
while (!stream.eol()) {
var style = mode.token(stream, state);
callback(stream.current(), style, i, stream.start, state);
@ -193,5 +326,4 @@ exports.runMode = function(string, modespec, callback, options) {
}
};
require.cache[require.resolve("../../lib/codemirror")] = require.cache[require.resolve("./runmode.node")];
require.cache[require.resolve("../../addon/runmode/runmode")] = require.cache[require.resolve("./runmode.node")];
});

View File

@ -43,7 +43,7 @@
cm.on("markerAdded", this.resizeHandler);
cm.on("markerCleared", this.resizeHandler);
if (options.listenForChanges !== false)
cm.on("change", this.changeHandler = function() {
cm.on("changes", this.changeHandler = function() {
scheduleRedraw(250);
});
}
@ -72,10 +72,16 @@
var wrapping = cm.getOption("lineWrapping");
var singleLineH = wrapping && cm.defaultTextHeight() * 1.5;
var curLine = null, curLineObj = null;
function getY(pos, top) {
if (curLine != pos.line) {
curLine = pos.line;
curLineObj = cm.getLineHandle(curLine);
curLine = pos.line
curLineObj = cm.getLineHandle(pos.line)
var visual = cm.getLineHandleVisualStart(curLineObj)
if (visual != curLineObj) {
curLine = cm.getLineNumber(visual)
curLineObj = visual
}
}
if ((curLineObj.widgets && curLineObj.widgets.length) ||
(wrapping && curLineObj.height > singleLineH))
@ -116,7 +122,7 @@
this.cm.off("refresh", this.resizeHandler);
this.cm.off("markerAdded", this.resizeHandler);
this.cm.off("markerCleared", this.resizeHandler);
if (this.changeHandler) this.cm.off("change", this.changeHandler);
if (this.changeHandler) this.cm.off("changes", this.changeHandler);
this.div.parentNode.removeChild(this.div);
};
});

View File

@ -90,7 +90,9 @@
var state = cm.state.matchHighlighter;
cm.addOverlay(state.overlay = makeOverlay(query, hasBoundary, style));
if (state.options.annotateScrollbar && cm.showMatchesOnScrollbar) {
var searchFor = hasBoundary ? new RegExp("\\b" + query.replace(/[\\\[.+*?(){|^$]/g, "\\$&") + "\\b") : query;
var searchFor = hasBoundary ? new RegExp((/\w/.test(query.charAt(0)) ? "\\b" : "") +
query.replace(/[\\\[.+*?(){|^$]/g, "\\$&") +
(/\w/.test(query.charAt(query.length - 1)) ? "\\b" : "")) : query;
state.matchesonscroll = cm.showMatchesOnScrollbar(searchFor, false,
{className: "CodeMirror-selection-highlight-scrollbar"});
}

View File

@ -72,24 +72,26 @@
}
}
function lastMatchIn(string, regexp) {
var cutOff = 0, match
for (;;) {
regexp.lastIndex = cutOff
function lastMatchIn(string, regexp, endMargin) {
var match, from = 0
while (from <= string.length) {
regexp.lastIndex = from
var newMatch = regexp.exec(string)
if (!newMatch) return match
match = newMatch
cutOff = match.index + (match[0].length || 1)
if (cutOff == string.length) return match
if (!newMatch) break
var end = newMatch.index + newMatch[0].length
if (end > string.length - endMargin) break
if (!match || end > match.index + match[0].length)
match = newMatch
from = newMatch.index + 1
}
return match
}
function searchRegexpBackward(doc, regexp, start) {
regexp = ensureFlags(regexp, "g")
for (var line = start.line, ch = start.ch, first = doc.firstLine(); line >= first; line--, ch = -1) {
var string = doc.getLine(line)
if (ch > -1) string = string.slice(0, ch)
var match = lastMatchIn(string, regexp)
var match = lastMatchIn(string, regexp, ch < 0 ? 0 : string.length - ch)
if (match)
return {from: Pos(line, match.index),
to: Pos(line, match.index + match[0].length),
@ -98,16 +100,17 @@
}
function searchRegexpBackwardMultiline(doc, regexp, start) {
if (!maybeMultiline(regexp)) return searchRegexpBackward(doc, regexp, start)
regexp = ensureFlags(regexp, "gm")
var string, chunk = 1
var string, chunkSize = 1, endMargin = doc.getLine(start.line).length - start.ch
for (var line = start.line, first = doc.firstLine(); line >= first;) {
for (var i = 0; i < chunk; i++) {
for (var i = 0; i < chunkSize && line >= first; i++) {
var curLine = doc.getLine(line--)
string = string == null ? curLine.slice(0, start.ch) : curLine + "\n" + string
string = string == null ? curLine : curLine + "\n" + string
}
chunk *= 2
chunkSize *= 2
var match = lastMatchIn(string, regexp)
var match = lastMatchIn(string, regexp, endMargin)
if (match) {
var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n")
var startLine = line + before.length, startCh = before[before.length - 1].length
@ -237,7 +240,7 @@
var result = this.matches(reverse, this.doc.clipPos(reverse ? this.pos.from : this.pos.to))
// Implements weird auto-growing behavior on null-matches for
// backwards-compatiblity with the vim code (unfortunately)
// backwards-compatibility with the vim code (unfortunately)
while (result && CodeMirror.cmpPos(result.from, result.to) == 0) {
if (reverse) {
if (result.from.ch) result.from = Pos(result.from.line, result.from.ch - 1)

View File

@ -231,7 +231,7 @@
var content = ts.options.completionTip ? ts.options.completionTip(cur.data) : cur.data.doc;
if (content) {
tooltip = makeTooltip(node.parentNode.getBoundingClientRect().right + window.pageXOffset,
node.getBoundingClientRect().top + window.pageYOffset, content);
node.getBoundingClientRect().top + window.pageYOffset, content, cm);
tooltip.className += " " + cls + "hint-doc";
}
});
@ -334,7 +334,7 @@
tip.appendChild(document.createTextNode(tp.rettype ? ") ->\u00a0" : ")"));
if (tp.rettype) tip.appendChild(elt("span", cls + "type", tp.rettype));
var place = cm.cursorCoords(null, "page");
var tooltip = ts.activeArgHints = makeTooltip(place.right + 1, place.bottom, tip)
var tooltip = ts.activeArgHints = makeTooltip(place.right + 1, place.bottom, tip, cm)
setTimeout(function() {
tooltip.clear = onEditorActivity(cm, function() {
if (ts.activeArgHints == tooltip) closeArgHints(ts) })
@ -601,7 +601,7 @@
function tempTooltip(cm, content, ts) {
if (cm.state.ternTooltip) remove(cm.state.ternTooltip);
var where = cm.cursorCoords();
var tip = cm.state.ternTooltip = makeTooltip(where.right + 1, where.bottom, content);
var tip = cm.state.ternTooltip = makeTooltip(where.right + 1, where.bottom, content, cm);
function maybeClear() {
old = true;
if (!mouseOnTip) clear();
@ -637,11 +637,12 @@
}
}
function makeTooltip(x, y, content) {
function makeTooltip(x, y, content, cm) {
var node = elt("div", cls + "tooltip", content);
node.style.left = x + "px";
node.style.top = y + "px";
document.body.appendChild(node);
var container = ((cm.options || {}).hintOptions || {}).container || document.body;
container.appendChild(node);
return node;
}

View File

@ -29,11 +29,20 @@
return {from: start, to: end};
}
function findBreakPoint(text, column, wrapOn, killTrailingSpace) {
function findBreakPoint(text, column, wrapOn, killTrailingSpace, forceBreak) {
var at = column
while (at < text.length && text.charAt(at) == " ") at++
for (; at > 0; --at)
if (wrapOn.test(text.slice(at - 1, at + 1))) break;
if (at == 0 && !forceBreak) {
// didn't find a break point before column, in non-forceBreak mode try to
// find one after 'column'.
for (at = column + 1; at < text.length - 1; ++at) {
if (wrapOn.test(text.slice(at - 1, at + 1))) break;
}
}
for (var first = true;; first = false) {
var endOfText = at;
if (killTrailingSpace)
@ -47,6 +56,7 @@
from = cm.clipPos(from); to = cm.clipPos(to);
var column = options.column || 80;
var wrapOn = options.wrapOn || /\s\S|-[^\.\d]/;
var forceBreak = options.forceBreak !== false;
var killTrailing = options.killTrailingSpace !== false;
var changes = [], curLine = "", curNo = from.line;
var lines = cm.getRange(from, to, false);
@ -68,7 +78,7 @@
curLine += text;
if (i) {
var firstBreak = curLine.length > column && leadingSpace == spaceTrimmed &&
findBreakPoint(curLine, column, wrapOn, killTrailing);
findBreakPoint(curLine, column, wrapOn, killTrailing, forceBreak);
// If this isn't broken, or is broken at a different point, remove old break
if (!firstBreak || firstBreak.from != oldLen || firstBreak.to != oldLen + spaceInserted) {
changes.push({text: [spaceInserted ? " " : ""],
@ -80,12 +90,16 @@
}
}
while (curLine.length > column) {
var bp = findBreakPoint(curLine, column, wrapOn, killTrailing);
changes.push({text: ["", leadingSpace],
from: Pos(curNo, bp.from),
to: Pos(curNo, bp.to)});
curLine = leadingSpace + curLine.slice(bp.to);
++curNo;
var bp = findBreakPoint(curLine, column, wrapOn, killTrailing, forceBreak);
if (bp.from != bp.to || forceBreak) {
changes.push({text: ["", leadingSpace],
from: Pos(curNo, bp.from),
to: Pos(curNo, bp.to)});
curLine = leadingSpace + curLine.slice(bp.to);
++curNo;
} else {
break;
}
}
}
if (changes.length) cm.operation(function() {

View File

@ -53,7 +53,23 @@
<div style="max-width: 50em; margin-bottom: 1em">JavaScript:<br>
<textarea id="code" name="code"></textarea></div>
<div style="max-width: 50em; margin-bottom: 1em">HTML:<br>
<textarea id="code-html" name="code-html"></textarea></div>
<textarea id="code-html" name="code-html"></textarea></div>
<div style="max-width: 50em; margin-bottom: 1em">JSON with custom widget:<br>
<textarea id="code-json" name="code-json">
{
"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}
}
</textarea></div>
<div style="max-width: 50em">Python:<br>
<textarea id="code-python" name="code">
def foo():
@ -89,6 +105,7 @@ window.onload = function() {
var te_python = document.getElementById("code-python");
var te_markdown = document.getElementById("code-markdown");
te_markdown.value = "# Foo\n## Bar\n\nblah blah\n\n## Baz\n\nblah blah\n\n# Quux\n\nblah blah\n"
var te_json = document.getElementById("code-json");
window.editor = CodeMirror.fromTextArea(te, {
mode: "javascript",
@ -100,6 +117,40 @@ window.onload = function() {
});
editor.foldCode(CodeMirror.Pos(13, 0));
window.editor_json = CodeMirror.fromTextArea(te_json, {
mode: {name: "javascript", json: true},
lineNumbers: true,
lineWrapping: true,
extraKeys: {"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor()); }},
foldGutter: true,
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
foldOptions: {
widget: (from, to) => {
var count = undefined;
// Get open / close token
var startToken = '{', endToken = '}';
var prevLine = window.editor_json.getLine(from.line);
if (prevLine.lastIndexOf('[') > prevLine.lastIndexOf('{')) {
startToken = '[', endToken = ']';
}
// Get json content
var internal = window.editor_json.getRange(from, to);
var toParse = startToken + internal + endToken;
// Get key count
try {
var parsed = JSON.parse(toParse);
count = Object.keys(parsed).length;
} catch(e) { }
return count ? `\u21A4${count}\u21A6` : '\u2194';
}
}
});
editor_json.foldCode(CodeMirror.Pos(5, 0));
window.editor_html = CodeMirror.fromTextArea(te_html, {
mode: "text/html",
lineNumbers: true,

View File

@ -0,0 +1,61 @@
<!doctype html>
<title>CodeMirror: Mode Runner Demo</title>
<meta charset="utf-8"/>
<link rel=stylesheet href="../doc/docs.css">
<link rel="stylesheet" href="../lib/codemirror.css">
<script src="../addon/runmode/runmode-standalone.js"></script>
<script src="../mode/xml/xml.js"></script>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../doc/logo.png"></a>
<ul>
<li><a href="../index.html">Home</a>
<li><a href="../doc/manual.html">Manual</a>
<li><a href="https://github.com/codemirror/codemirror">Code</a>
</ul>
<ul>
<li><a class=active href="#">Mode Runner</a>
</ul>
</div>
<article>
<h2>Mode Runner Demo</h2>
<textarea id="code" style="width: 90%; height: 7em; border: 1px solid black; padding: .2em .4em;">
<foobar>
<blah>Enter your xml here and press the button below to display
it as highlighted by the CodeMirror XML mode</blah>
<tag2 foo="2" bar="&amp;quot;bar&amp;quot;"/>
</foobar></textarea><br>
<button onclick="doHighlight();">Highlight!</button>
<pre id="output" class="cm-s-default"></pre>
<script>
function doHighlight() {
CodeMirror.runMode(document.getElementById("code").value, "application/xml",
document.getElementById("output"));
}
</script>
<p>Running a CodeMirror mode outside of the editor.
The <code>CodeMirror.runMode</code> function, defined
in <code><a href="../addon/runmode/runmode.js">addon/runmode/runmode.js</a></code> takes the following arguments:</p>
<dl>
<dt><code>text (string)</code></dt>
<dd>The document to run through the highlighter.</dd>
<dt><code>mode (<a href="../doc/manual.html#option_mode">mode spec</a>)</code></dt>
<dd>The mode to use (must be loaded as normal).</dd>
<dt><code>output (function or DOM node)</code></dt>
<dd>If this is a function, it will be called for each token with
two arguments, the token's text and the token's style class (may
be <code>null</code> for unstyled tokens). If it is a DOM node,
the tokens will be converted to <code>span</code> elements as in
an editor, and inserted into the node
(through <code>innerHTML</code>).</dd>
</dl>
</article>

View File

@ -67,7 +67,8 @@ highlighted by the mode shown in it).</p>
will be taken into account when matching the token. This regex
has to capture groups when the <code>token</code> property is
an array. If it captures groups, it must capture <em>all</em> of the string
(since JS provides no way to find out where a group matched).</dd>
(since JS provides no way to find out where a group matched).
Currently negative lookbehind assertion for regex is not supported, regardless of browser support.</dd>
<dt><code><strong>token</strong></code>: string | array&lt;string&gt; | null</dt>
<dd>An optional token style. Multiple styles can be specified by
separating them with dots or spaces. When this property holds an array of token styles,

View File

@ -9,6 +9,8 @@
<link rel="stylesheet" href="../theme/3024-night.css">
<link rel="stylesheet" href="../theme/abcdef.css">
<link rel="stylesheet" href="../theme/ambiance.css">
<link rel="stylesheet" href="../theme/ayu-dark.css">
<link rel="stylesheet" href="../theme/ayu-mirage.css">
<link rel="stylesheet" href="../theme/base16-dark.css">
<link rel="stylesheet" href="../theme/bespin.css">
<link rel="stylesheet" href="../theme/base16-light.css">
@ -29,10 +31,14 @@
<link rel="stylesheet" href="../theme/liquibyte.css">
<link rel="stylesheet" href="../theme/lucario.css">
<link rel="stylesheet" href="../theme/material.css">
<link rel="stylesheet" href="../theme/material-darker.css">
<link rel="stylesheet" href="../theme/material-palenight.css">
<link rel="stylesheet" href="../theme/material-ocean.css">
<link rel="stylesheet" href="../theme/mbo.css">
<link rel="stylesheet" href="../theme/mdn-like.css">
<link rel="stylesheet" href="../theme/midnight.css">
<link rel="stylesheet" href="../theme/monokai.css">
<link rel="stylesheet" href="../theme/moxer.css">
<link rel="stylesheet" href="../theme/neat.css">
<link rel="stylesheet" href="../theme/neo.css">
<link rel="stylesheet" href="../theme/night.css">
@ -102,6 +108,8 @@ function findSequence(goal) {
<option>3024-night</option>
<option>abcdef</option>
<option>ambiance</option>
<option>ayu-dark</option>
<option>ayu-mirage</option>
<option>base16-dark</option>
<option>base16-light</option>
<option>bespin</option>
@ -124,10 +132,14 @@ function findSequence(goal) {
<option>liquibyte</option>
<option>lucario</option>
<option>material</option>
<option>material-darker</option>
<option>material-palenight</option>
<option>material-ocean</option>
<option>mbo</option>
<option>mdn-like</option>
<option>midnight</option>
<option>monokai</option>
<option>moxer</option>
<option>neat</option>
<option>neo</option>
<option>night</option>
@ -181,4 +193,4 @@ function findSequence(goal) {
if (theme) { input.value = theme; selectTheme(); }
});
</script>
</article>
</article>

View File

@ -56,6 +56,7 @@ int getchar(void)
}
</textarea></form>
<div style="font-size: 13px; width: 300px; height: 30px;">Key buffer: <span id="command-display"></span></div>
<div style="font-size: 13px; width: 300px; height: 30px;">Vim mode: <span id="vim-mode"></span></div>
<p>The vim keybindings are enabled by including <code><a
href="../keymap/vim.js">keymap/vim.js</a></code> and setting the
@ -95,19 +96,22 @@ become a complete vim implementation</p>
mode: "text/x-csrc",
keyMap: "vim",
matchBrackets: true,
showCursorWhenSelecting: true,
inputStyle: "contenteditable"
showCursorWhenSelecting: true
});
var commandDisplay = document.getElementById('command-display');
var keys = '';
CodeMirror.on(editor, 'vim-keypress', function(key) {
keys = keys + key;
commandDisplay.innerHTML = keys;
commandDisplay.innerText = keys;
});
CodeMirror.on(editor, 'vim-command-done', function(e) {
keys = '';
commandDisplay.innerHTML = keys;
});
var vimMode = document.getElementById('vim-mode');
CodeMirror.on(editor, 'vim-mode-change', function(e) {
vimMode.innerText = JSON.stringify(e);
});
</script>
</article>

View File

@ -58,6 +58,7 @@
<li><a href="#vimapi">Vim Mode API</a>
<ul>
<li><a href="#vimapi_configuration">Configuration</a></li>
<li><a href="#vimapi_events">Events</a></li>
<li><a href="#vimapi_extending">Extending VIM</a></li>
</ul>
</li>
@ -69,7 +70,7 @@
<section class=first id=overview>
<h2 style="position: relative">
User manual and reference guide
<span style="color: #888; font-size: 1rem; position: absolute; right: 0; bottom: 0">version 5.48.2</span>
<span style="color: #888; font-size: 1rem; position: absolute; right: 0; bottom: 0">version 5.58.1</span>
</h2>
<p>CodeMirror is a code-editor component that can be embedded in
@ -78,9 +79,9 @@
functionality. It does provide a rich API on top of which such
functionality can be straightforwardly implemented. See
the <a href="#addons">addons</a> included in the distribution,
and the <a href="https://github.com/codemirror/CodeMirror/wiki/CodeMirror-addons">list
of externally hosted addons</a>, for reusable
implementations of extra features.</p>
and <a href="https://npms.io/search?q=codemirror">3rd party
packages on npm</a>, for reusable implementations of extra
features.</p>
<p>CodeMirror works with language-specific modes. Modes are
JavaScript programs that help color (and optionally indent) text
@ -223,9 +224,10 @@
first mode that was loaded. It may be a string, which either
simply names the mode or is
a <a href="http://en.wikipedia.org/wiki/MIME">MIME</a> type
associated with the mode. Alternatively, it may be an object
containing configuration options for the mode, with
a <code>name</code> property that names the mode (for
associated with the mode. The value <code>"null"</code>
indicates no highlighting should be applied. Alternatively, it
may be an object containing configuration options for the mode,
with a <code>name</code> property that names the mode (for
example <code>{name: "javascript", json: true}</code>). The demo
pages for each mode contain information about what configuration
parameters the mode supports. You can ask CodeMirror which modes
@ -420,6 +422,10 @@
simply <code>true</code>), focusing of the editor is also
disallowed.</dd>
<dt id="option_screenReaderLabel"><code><strong>screenReaderLabel</strong>: string</code></dt>
<dd>This label is read by the screenreaders when CodeMirror text area is focused. This
is helpful for accessibility.</dd>
<dt id="option_showCursorWhenSelecting"><code><strong>showCursorWhenSelecting</strong>: boolean</code></dt>
<dd>Whether the cursor should be drawn when a selection is
active. Defaults to false.</dd>
@ -557,13 +563,13 @@
always rendered, and thus the browser's text search works on it.
This <em>will</em> have bad effects on performance of big
documents.</dd>
<dt id="option_spellcheck"><code><strong>spellcheck</strong>: boolean</code></dt>
<dd>Specifies whether or not spellcheck will be enabled on the input.</dd>
<dt id="option_autocorrect"><code><strong>autocorrect</strong>: boolean</code></dt>
<dd>Specifies whether or not autocorrect will be enabled on the input.</dd>
<dt id="option_autocapitalize"><code><strong>autocapitalize</strong>: boolean</code></dt>
<dd>Specifies whether or not autocapitalization will be enabled on the input.</dd>
</dl>
@ -1880,6 +1886,9 @@ editor.setOption("extraKeys", {
position (zero for the top, N to put it after the Nth other
widget). Note that this only has effect once, when the
widget is created.
<dt><code><strong>className</strong>: string</code></dt>
<dd>Add an extra CSS class name to the wrapper element
created for the widget.</dd>
</dl>
Note that the widget node will become a descendant of nodes with
CodeMirror-specific CSS classes, and those classes might in some
@ -2563,10 +2572,14 @@ editor.setOption("extraKeys", {
and <code>CodeMirror.fold.xml</code>, for XML-style languages,
and <code>CodeMirror.fold.comment</code>, for folding comment
blocks.</dd>
<dt><code><strong>widget</strong>: string|Element</code></dt>
<dt><code><strong>widget</strong>: string | Element | fn(from: Pos, to: Pos) → string|Element</code></dt>
<dd>The widget to show for folded ranges. Can be either a
string, in which case it'll become a span with
class <code>CodeMirror-foldmarker</code>, or a DOM node.</dd>
class <code>CodeMirror-foldmarker</code>, or a DOM node.
To dynamically generate the widget, this can be a function
that returns a string or DOM node, which will then render
as described. The function will be invoked with parameters
identifying the range to be folded.</dd>
<dt><code><strong>scanUp</strong>: boolean</code></dt>
<dd>When true (default is false), the addon will try to find
foldable ranges on the lines above the current one if there
@ -2777,6 +2790,9 @@ editor.setOption("extraKeys", {
<dd>Like <code>customKeys</code> above, but the bindings will
be added to the set of default bindings, instead of replacing
them.</dd>
<dt><code><strong>scrollMargin</strong>: integer</code></dt>
<dd>Show this many lines before and after the selected item.
Default is 0.</dd>
</dl>
The following events will be fired on the completions object
during completion:
@ -2903,6 +2919,7 @@ editor.setOption("extraKeys", {
will only be executed when the promise resolves.
By default, the linter will run (debounced) whenever the document is changed.
You can pass a <code>lintOnChange: false</code> option to disable that.
You can pass a <code>selfContain: true</code> option to render the tooltip inside the editor instance.
Depends on <code>addon/lint/lint.css</code>. A demo can be
found <a href="../demo/lint.html">here</a>.</dd>
@ -2937,13 +2954,20 @@ editor.setOption("extraKeys", {
see a demo <a href="../mode/htmlmixed/index.html">here</a>.</dd>
<dt id="addon_loadmode"><a href="../addon/mode/loadmode.js"><code>mode/loadmode.js</code></a></dt>
<dd>Defines a <code>CodeMirror.requireMode(modename,
callback)</code> function that will try to load a given mode and
call the callback when it succeeded. You'll have to
set <code>CodeMirror.modeURL</code> to a string that mode paths
can be constructed from, for
example <code>"mode/%N/%N.js"</code>—the <code>%N</code>'s will
be replaced with the mode name. Also
<dd>Defines a <code>CodeMirror.requireMode(modename, callback,
options)</code> function that will try to load a given mode and
call the callback when it succeeded. <code>options</code> is an
optional object that may contain:
<dl>
<dt><code><strong>path</strong>: fn(modeName: string) → string</code></dt>
<dd>Defines the way mode names are mapped to paths.</dd>
<dt><code><strong>loadMode</strong>: fn(path: string, cont: fn())</code></dt>
<dd>Override the way the mode script is loaded. By default,
this will use the CommonJS or AMD module loader if one is
present, and fall back to creating
a <code>&lt;script></code> tag otherwise.</dd>
</dl>
This addon also
defines <code>CodeMirror.autoLoadMode(instance, mode)</code>,
which will ensure the given mode is loaded and cause the given
editor instance to refresh its mode when the loading
@ -3114,10 +3138,20 @@ editor.setOption("extraKeys", {
<dt><code><strong>killTrailingSpace</strong>: boolean</code></dt>
<dd>Whether trailing space caused by wrapping should be
preserved, or deleted. Defaults to true.</dd>
<dt><code><strong>forceBreak</strong>: boolean</code></dt>
<dd>If set to true forces a break at <code>column</code> in the case
when no <code>wrapOn</code> pattern is found in the range. If set to
false allows line to overflow the <code>column</code> limit if no
<code>wrapOn</code> pattern found. Defaults to true.</dd>
</dl>
A demo of the addon is available <a href="../demo/hardwrap.html">here</a>.
</dd>
<dt id="addon_scrollpastend"><a href="../addon/scroll/scrollpastend.js"><code>scroll/scrollpastend.js</code></a></dt>
<dd>Defines an option `"scrollPastEnd"` that, when set to a
truthy value, allows the user to scroll one editor height of
empty space into view at the bottom of the editor.</dd>
<dt id="addon_merge"><a href="../addon/merge/merge.js"><code>merge/merge.js</code></a></dt>
<dd>Implements an interface for merging changes, using either a
2-way or a 3-way view. The <code>CodeMirror.MergeView</code>
@ -3170,14 +3204,14 @@ editor.setOption("extraKeys", {
<dt id="addon_tern"><a href="../addon/tern/tern.js"><code>tern/tern.js</code></a></dt>
<dd>Provides integration with
the <a href="http://ternjs.net">Tern</a> JavaScript analysis
the <a href="https://ternjs.net">Tern</a> JavaScript analysis
engine, for completion, definition finding, and minor
refactoring help. See the <a href="../demo/tern.html">demo</a>
for a very simple integration. For more involved scenarios, see
the comments at the top of
the <a href="../addon/tern/tern.js">addon</a> and the
implementation of the
(multi-file) <a href="http://ternjs.net/doc/demo.html">demonstration
(multi-file) <a href="https://ternjs.net/doc/demo/index.html">demonstration
on the Tern website</a>.</dd>
</dl>
</section>
@ -3517,6 +3551,41 @@ editor.setOption("extraKeys", {
<code>extras.isEdit</code> is applicable only to actions,
determining whether it is recorded for replay for the
<code>.</code> single-repeat command.
<dt id="vimapi_unmap"><strong><code>unmap(lhs: string, ctx: string)</code></strong></dt>
<dd>
Remove the command <code>lhs</code> if it is a user defined command.
If the command is an Ex to Ex or Ex to key mapping then the context
must be <code>undefined</code> or <code>false</code>.
</dd>
<dt id="vimapi_mapclear"><strong><code>mapclear(ctx: string)</code></strong></dt>
<dd>
Remove all user-defined mappings for the provided context.
</dd>
<dt id="vimapi_noremap"><strong><code>noremap(lhs: string, rhs: string, ctx: {string, array&lt;string&gt;})</code></strong></dt>
<dd>
Non-recursive map function. This will not create mappings to key maps
that aren't present in the default key map.
If no context is provided then the mapping will be applied to each of
normal, insert, and visual mode.
</dd>
</dl>
<h3 id="vimapi_events">Events</h3>
<p>VIM mode signals a few events on the editor instance. For an example usage, see <a href="https://github.com/codemirror/CodeMirror/blob/5.55.0/demo/vim.html#L101-L110">demo/vim.html#L101</a>.</p>
<dl>
<dt id="vimapi_commanddone"><code><strong>"vim-command-done"</strong> (reason: undefined)</code></dt>
<dd>Fired on keypress and mousedown where command has completed or no command found.</dd>
<dt id="vimapi_keypress"><code><strong>"vim-keypress"</strong> (vimKey: string)</code></dt>
<dd>Fired on keypress, <code>vimKey</code> is in Vim's key notation.</dd>
<dt id="vimapi_modechange"><code><strong>"vim-mode-change"</strong> (modeObj: object)</code></dt>
<dd>Fired after mode change, <code>modeObj</code> parameter is a <code>{mode: string, ?subMode: string}</code> object. Modes: <code>"insert", "normal", "replace", "visual"</code>. Visual sub-modes: <code>"linewise", "blockwise"</code>.</dd>
</dl>
<h3 id="vimapi_extending">Extending VIM</h3>
@ -3582,7 +3651,74 @@ editor.setOption("extraKeys", {
command was prefixed with a
<code><strong><a href="http://vimdoc.sourceforge.net/htmldoc/cmdline.html#cmdline-ranges">line range</a></strong></code>,
<code>params.line</code> and <code>params.lineEnd</code> will
be set.
be set.</dd>
<dt id="vimapi_getRegisterController"><strong><code>getRegisterController()</code></strong></dt>
<dd>Returns the RegisterController that manages the state of registers
used by vim mode. For the RegisterController api see its
defintion <a href="https://github.com/CodeMirror/CodeMirror/blob/b2d26b4ccb1d0994ae84d18ad8b84018de176da9/keymap/vim.js#L1123">here</a>.
</dd>
<dt id='vimapi_buildkeymap'><strong><code>buildKeyMap()</code></strong></dt>
<dd>
Not currently implemented. If you would like to contribute this please open
a pull request on <a href="https://github.com/codemirror/CodeMirror">Github</a>.
</dd>
<dt id="vimapi_defineRegister"><strong><code>defineRegister()</code></strong></dt>
<dd> Defines an external register. The name should be a single character
that will be used to reference the register. The register should support
<code>setText</code>, <code>pushText</code>, <code>clear</code>, and <code>toString</code>.
See <a href="https://github.com/CodeMirror/CodeMirror/blob/b2d26b4ccb1d0994ae84d18ad8b84018de176da9/keymap/vim.js#L1055">Register</a> for a reference implementation.
</dd>
<dt id="vimapi_getVimGlobalState_"><strong><code>getVimGlobalState_()</code></strong></dt>
<dd>
Return a reference to the VimGlobalState.
</dd>
<dt id="vimapi_resetVimGlobalState_"><strong><code>resetVimGlobalState_()</code></strong></dt>
<dd>
Reset the default values of the VimGlobalState to fresh values. Any options
set with <code>setOption</code> will also be applied to the reset global state.
</dd>
<dt id="vimapi_maybeInitVimState_"><strong><code>maybeInitVimState_(cm: CodeMirror)</code></strong></dt>
<dd>
Initialize <code>cm.state.vim</code> if it does not exist. Returns <code>cm.state.vim</code>.
</dd>
<dt id="vimapi_handleKey"><strong><code>handleKey(cm: CodeMirror, key: string, origin: string)</code></strong></dt>
<dd>
Convenience function to pass the arguments to <code>findKey</code> and
call returned function if it is defined.
</dd>
<dt id="vimapi_findKey"><strong><code>findKey(cm: CodeMirror, key: string, origin: string)</code></strong></dt>
<dd>
This is the outermost function called by CodeMirror, after keys have
been mapped to their Vim equivalents. Finds a command based on the key
(and cached keys if there is a multi-key sequence). Returns <code>undefined</code>
if no key is matched, a noop function if a partial match is found (multi-key),
and a function to execute the bound command if a a key is matched. The
function always returns true.
</dd>
<dt id="vimapi_option_suppressErrorLogging"><code><strong>suppressErrorLogging</strong>: boolean</code></dt>
<dd>Whether to use suppress the use of <code>console.log</code> when catching an
error in the function returned by <code>findKey</code>.
Defaults to false.</dd>
<dt id="vimapi_exitVisualMode"><strong><code>exitVisualMode(cm: CodeMirror, ?moveHead: boolean)</code></strong></dt>
<dd> Exit visual mode. If moveHead is set to false, the CodeMirror selection
will not be touched. The caller assumes the responsibility of putting
the cursor in the right place.
</dd>
<dt id="vimapi_exitInsertMode"><strong><code>exitInsertMode(cm: CodeMirror)</code></strong></dt>
<dd>
Exit insert mode.
</dd>
</dl>
</section>

View File

@ -25,7 +25,9 @@
request</a> if you'd like your project to be added to this list.</p>
<ul>
<li><a href="https://www.adaface.com/pair-pro">Adaface PairPro</a> (Shared code editor with compiler and video conferencing)</li>
<li><a href="http://brackets.io">Adobe Brackets</a> (code editor)</li>
<li><a href="http://adnuntius.com">Adnuntius</a> (used for in-browser code editing and version history)</li>
<li><a href="http://alm.tools">ALM Tools</a> (TypeScript powered IDE)</li>
<li><a href="http://amber-lang.net/">Amber</a> (JavaScript-based Smalltalk system)</li>
<li><a href="http://apeye.org/">APEye</a> (tool for testing &amp; documenting APIs)</li>
@ -39,6 +41,7 @@
<li><a href="http://cargocollective.com/">Cargo Collective</a> (creative publishing platform)</li>
<li><a href="https://developers.google.com/chrome-developer-tools/">Chrome DevTools</a></li>
<li><a href="http://clickhelp.co/">ClickHelp</a> (technical writing tool)</li>
<li><a href="https://clone-it.github.io/">Clone-It</a> (HTML & CSS learning game)</li>
<li><a href="https://electronjs.org/apps/colon">Colon</a> (A flexible text editor or IDE)</li>
<li><a href="http://code.world/">CodeWorld</a> (Haskell playground)</li>
<li><a href="http://complete-ly.appspot.com/playground/code.playground.html">Complete.ly playground</a></li>
@ -49,6 +52,7 @@
<li><a href="http://codefights.com/">CodeFights</a> (practice programming)</li>
<li><a href="https://github.com/angelozerr/CodeMirror-Eclipse">CodeMirror Eclipse</a> (embed CM in Eclipse)</li>
<li><a href="http://emmet.io/blog/codemirror-movie/">CodeMirror movie</a> (scripted editing demos)</li>
<li><a href="https://github.com/haoranyu/codemirror-record/">CodeMirror Record</a> (codemirror activity recording and playback)</li>
<li><a href="http://code.google.com/p/codemirror2-gwt/">CodeMirror2-GWT</a> (Google Web Toolkit wrapper)</li>
<li><a href="http://www.crunchzilla.com/code-monster">Code Monster</a> & <a href="http://www.crunchzilla.com/code-maven">Code Maven</a> (learning environment)</li>
<li><a href="http://codepen.io">Codepen</a> (gallery of animations)</li>
@ -57,7 +61,6 @@
<li><a href="http://sasstwo.codeschool.com/levels/1/challenges/1">Code School</a> (online tech learning environment)</li>
<li><a href="http://code-snippets.bungeshea.com/">Code Snippets</a> (WordPress snippet management plugin)</li>
<li><a href="http://antonmi.github.io/code_together/">Code together</a> (collaborative editing)</li>
<li><a href="http://codev.it/">Codev</a> (collaborative IDE)</li>
<li><a href="https://www.codevolve.com/">Codevolve</a> (programming lessons as-a-service)</li>
<li><a href="http://www.codezample.com">CodeZample</a> (code snippet sharing)</li>
<li><a href="http://codio.com">Codio</a> (Web IDE)</li>
@ -101,6 +104,8 @@
<li><a href="http://megafonweblab.github.com/histone-javascript/">Histone template engine playground</a></li>
<li><a href="http://www.homegenie.it/docs/automation_getstarted.php">Homegenie</a> (home automation server)</li>
<li><a href="http://icecoder.net">ICEcoder</a> (web IDE)</li>
<li><a href="https://innovay.app/formatter/html">Innovay Web Tools</a> (HTML, JS, CSS code beautifier)</li>
<li><a href="https://www.intervue.io">Intervue</a> (Pair programming for interviews)</li>
<li><a href="http://ipython.org/">IPython</a> (interactive computing shell)</li>
<li><a href="https://joelpinheiro.github.io/itrading/">iTrading</a> (Algorithmic Trading)</li>
<li><a href="http://i-mos.org/imos/">i-MOS</a> (modeling and simulation platform)</li>
@ -150,6 +155,7 @@
<li><a href="https://www.realtime.io/">RealTime.io</a> (Internet-of-Things infrastructure)</li>
<li><a href="http://refork.com/">Refork</a> (animation demo gallery and sharing)</li>
<li><a href="http://sagecell.sagemath.org">SageMathCell</a> (interactive mathematical software)</li>
<li><a href="https://www.sass2css.online/">SASS2CSS</a> (SASS, SCSS or LESS to CSS converter and CSS beautifier)</li>
<li><a href="https://cloud.sagemath.com/">SageMathCloud</a> (interactive mathematical software environment)</li>
<li><a href="https://github.com/szekelymilan/salvare">salvare</a> (real-time collaborative code editor)</li>
<li><a href="https://chrome.google.com/webstore/detail/servephp/mnpikomdchjhkhbhmbboehfdjkobbfpo">ServePHP</a> (PHP code testing in Chrome dev tools)</li>
@ -171,11 +177,13 @@
<li><a href="https://thefiletree.com">The File Tree</a> (collab editor)</li>
<li><a href="http://www.mapbox.com/tilemill/">TileMill</a> (map design tool)</li>
<li><a href="http://doc.tiki.org/Syntax+Highlighter">Tiki</a> (wiki CMS groupware)</li>
<li><a href="https://www.tistory.com">Tistory</a> (blog service)</li>
<li><a href="http://www.toolsverse.com/products/data-explorer/">Toolsverse Data Explorer</a> (database management)</li>
<li><a href="http://blog.englard.net/post/39608000629/codeintumblr">Tumblr code highlighting shim</a></li>
<li><a href="http://turbopy.com/">TurboPY</a> (web publishing framework)</li>
<li><a href="http://cruise.eecs.uottawa.ca/umpleonline/">UmpleOnline</a> (model-oriented programming tool)</li>
<li><a href="https://upsource.jetbrains.com/idea-ce/file/idea-ce-7706e7832aa9e2fd0c2decdb5cbef2225692c696/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorFactoryImpl.java">Upsource</a> (code browser and review tool)</li>
<li><a href="https://violentmonkey.github.io/">Violentmonkey</a> (userscript manager / editor)</li>
<li><a href="https://github.com/mgaitan/waliki">Waliki</a> (wiki engine)</li>
<li><a href="http://wamer.net/">Wamer</a> (web application builder)</li>
<li><a href="https://github.com/brettz9/webappfind">webappfind</a> (windows file bindings for webapps)</li>

View File

@ -30,6 +30,178 @@
<h2>Version 5.x</h2>
<p class="rel">21-09-2020: <a href="https://codemirror.net/codemirror-5.58.0.zip">Version 5.58.0</a>:</p>
<ul class="rel-note">
<li><a href="https://codemirror.net/doc/manual.html#addon_placeholder">placeholder addon</a>: Remove arrow function that ended up in the code.</li>
</ul>
<h2>Version 5.x</h2>
<p class="rel">21-09-2020: <a href="https://codemirror.net/codemirror-5.58.0.zip">Version 5.58.0</a>:</p>
<ul class="rel-note">
<li>Make backspace delete by code point, not glyph.</li>
<li>Suppress flickering focus outline when clicking on scrollbars in Chrome.</li>
<li>Fix a bug that prevented attributes added via <code>markText</code> from showing up unless the span also had some other styling.</li>
<li>Suppress cut and paste context menu entries in readonly editors in Chrome.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_placeholder">placeholder addon</a>: Update placeholder visibility during composition.</li>
<li>Make it less cumbersome to style new lint message types.</li>
<li><a href="https://codemirror.net/demo/vim.html">vim bindings</a>: Support black hole register, <code>gn</code> and <code>gN</code></li>
</ul>
<p class="rel">20-08-2020: <a href="https://codemirror.net/codemirror-5.57.0.zip">Version 5.57.0</a>:</p>
<ul class="rel-note">
<li>Fix issue that broke binding the macOS Command key.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_comment">comment addon</a>: Keep selection in front of inserted markers when adding a block comment.</li>
<li><a href="https://codemirror.net/mode/css/">css mode</a>: Recognize more properties and value names.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_annotatescrollbar">annotatescrollbar addon</a>: Dont hide matches in collapsed content.</li>
<li><a href="https://codemirror.net/demo/vim.html">vim bindings</a>: Support tag text objects in xml and html modes.</li>
</ul>
<p class="rel">20-07-2020: <a href="https://codemirror.net/codemirror-5.56.0.zip">Version 5.56.0</a>:</p>
<ul class="rel-note">
<li>Line-wise pasting was fixed on Chrome Windows.</li>
<li><a href="https://codemirror.net/mode/wast/">wast mode</a>: Follow standard changes.</li>
<li><a href="https://codemirror.net/mode/soy/">soy mode</a>: Support import expressions, template type, and loop indices.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_sql-hint">sql-hint addon</a>: Improve handling of double quotes.</li>
<li><h3 id="new-features">New features</h3></li>
<li><a href="https://codemirror.net/doc/manual.html#addon_show-hint">show-hint addon</a>: New option <code>scrollMargin</code> to control how many options are visible beyond the selected one.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_hardwrap">hardwrap addon</a>: New option <code>forceBreak</code> to disable breaking of words that are longer than a line.</li>
</ul>
<p class="rel">21-06-2020: <a href="https://codemirror.net/codemirror-5.55.0.zip">Version 5.55.0</a>:</p>
<ul class="rel-note">
<li>The editor no longer overrides the rendering of zero-width joiners (allowing combined emoji to be shown).</li>
<li><a href="https://codemirror.net/demo/vim.html">vim bindings</a>: Fix an issue where the <code>vim-mode-change</code> event was fired twice.</li>
<li><a href="https://codemirror.net/mode/javascript/">javascript mode</a>: Only allow <code>--&gt;</code>-style comments at the start of a line.</li>
<li><a href="https://codemirror.net/mode/julia/">julia mode</a>: Improve indentation.</li>
<li><a href="https://codemirror.net/mode/pascal/index.html">pascal mode</a>: Recognize curly bracket comments.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_runmode">runmode addon</a>: Further sync up the implementation of the standalone and node variants with the regular library.</li>
<li><h3 id="new-features">New features</h3></li>
<li><a href="https://codemirror.net/doc/manual.html#addon_loadmode">loadmode addon</a>: Allow overriding the way the addon constructs filenames and loads modules.</li>
</ul>
<p class="rel">20-05-2020: <a href="https://codemirror.net/codemirror-5.54.0.zip">Version 5.54.0</a>:</p>
<ul class="rel-note">
<li><a href="https://codemirror.net/doc/manual.html#addon_runmode">runmode addon</a>: Properly support for cross-line lookahead.</li>
<li><a href="https://codemirror.net/demo/vim.html">vim bindings</a>: Allow Ex-Commands with non-word names.</li>
<li><a href="https://codemirror.net/mode/gfm/">gfm mode</a>: Add a <code>fencedCodeBlockDefaultMode</code> option.</li>
<li>Improve support for having focus inside in-editor widgets in contenteditable-mode.</li>
<li>Fix issue where the scroll position could jump when clicking on a selection in Chrome.</li>
<li><a href="https://codemirror.net/mode/python/">python mode</a>: Better format string support.</li>
<li><a href="https://codemirror.net/mode/javascript/">javascript mode</a>: Improve parsing of private properties and class fields.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_matchbrackets">matchbrackets addon</a>: Disable highlighting when the editor doesnt have focus.</li>
</ul>
<p class="rel">21-04-2020: <a href="https://codemirror.net/codemirror-5.53.2.zip">Version 5.53.2</a>:</p>
<ul class="rel-note">
<li><a href="https://codemirror.net/doc/manual.html#addon_show-hint">show-hint addon</a>: Fix a regression that broke completion picking.
</ul>
<p class="rel">21-04-2020: <a href="https://codemirror.net/codemirror-5.53.0.zip">Version 5.53.0</a>:</p>
<ul class="rel-note">
<li>New option: <a href="https://codemirror.net/doc/manual.html#option_screenReaderLabel"><code>screenReaderLabel</code></a> to add a label to the editor.</li>
<li>New mode: <a href="https://codemirror.net/mode/wast/">wast</a>.</li>
<li>Fix a bug where the editor layout could remain confused after a call to <code>refresh</code> when line wrapping was enabled.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_dialog">dialog addon</a>: Dont close dialogs when the document window loses focus.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_merge">merge addon</a>: Compensate for editor top position when aligning lines.</li>
<li><a href="https://codemirror.net/demo/vim.html">vim bindings</a>: Improve EOL handling.</li>
<li><a href="https://codemirror.net/demo/emacs.html">emacs bindings</a>: Include default keymap as a fallback.</li>
<li><a href="https://codemirror.net/mode/julia/">julia mode</a>: Fix an infinite loop bug.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_show-hint">show-hint addon</a>: Scroll cursor into view when picking a completion.</li>
</ul>
<p class="rel">20-03-2020: <a href="https://codemirror.net/codemirror-5.52.2.zip">Version 5.52.2</a>:</p>
<ul class="rel-note">
<li>Fix selection management in contenteditable mode when the editor doesnt have focus.</li>
<li>Fix a bug that would cause the editor to get confused about the visible viewport in some situations in line-wrapping mode.</li>
<li><a href="https://codemirror.net/mode/markdown/">markdown mode</a>: Dont treat single dashes as setext header markers.</li>
<li><a href="https://codemirror.net/demo/theme.html#zenburn">zenburn theme</a>: Make sure background styles take precedence over default styles.</li>
<li><a href="https://codemirror.net/mode/css/">css mode</a>: Recognize a number of new properties.</li>
</ul>
<p class="rel">20-02-2020: <a href="https://codemirror.net/codemirror-5.52.0.zip">Version 5.52.0</a>:</p>
<ul class="rel-note">
<li>Fix a bug in handling of bidi text with Arabic numbers in a right-to-left editor.</li>
<li>Fix a crash when combining file drop with a <code>"beforeChange"</code> filter.</li>
<li>Prevent issue when passing negative coordinates to <code>scrollTo</code>.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_lint">lint</a> and <a href="https://codemirror.net/demo/tern.html">tern</a> addons: Allow the tooltip to be appended to the editor wrapper element instead of the document body.</li>
</ul>
<p class="rel">20-01-2020: <a href="https://codemirror.net/codemirror-5.51.0.zip">Version 5.51.0</a>:</p>
<ul class="rel-note">
<li>Fix the behavior of the home and end keys when <code>direction</code> is set to <code>"rtl"</code>.</li>
<li>When dropping multiple files, dont abort the drop of the valid files when theres an invalid or binary file among them.</li>
<li>Make sure <code>clearHistory</code> clears the history in all linked docs with a shared history.</li>
<li><a href="https://codemirror.net/demo/vim.html">vim bindings</a>: Fix behavior of <code>'</code> and <code>`</code> marks, fix <code>R</code> in visual mode.</li>
<li><a href="https://codemirror.net/demo/vim.html">vim bindings</a>: Support <code>gi</code>, <code>gI<code>, and <code>gJ</code>.</li>
</ul>
<p class="rel">01-01-2020: <a href="https://codemirror.net/codemirror-5.50.2.zip">Version 5.50.2</a>:</p>
<ul class="rel-note">
<li>Fix bug that broke removal of line widgets.</li>
</ul>
<p class="rel">20-12-2019: <a href="https://codemirror.net/codemirror-5.50.0.zip">Version 5.50.0</a>:</p>
<ul class="rel-note">
<li>Add a <code>className</code> option to <a href="https://codemirror.net/doc/manual.html#addLineWidget"><code>addLineWidget</code></a>.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_foldcode">foldcode addon</a>: Allow fold widgets to be functions, to dynamically create fold markers.</li>
<li>New themes: <a href="https://codemirror.net/demo/theme.html#ayu-dark">ayu-dark</a> and <a href="https://codemirror.net/demo/theme.html#ayu-mirage">ayu-mirage</a>.</li>
<li>Make Shift-Delete to cut work on Firefox.</li>
<li><a href="https://codemirror.net/demo/closetag.html">closetag addon</a>: Properly handle self-closing tags.</li>
<li><a href="https://codemirror.net/mode/handlebars/">handlebars mode</a>: Fix triple-brace support.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_searchcursor">searchcursor addon</a>: Support mathing <code>$</code> in reverse regexp search.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_panel">panel addon</a>: Dont get confused by changing panel sizes.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_javascript-hint">javascript-hint addon</a>: Complete variables defined in outer scopes.</li>
<li><a href="https://codemirror.net/demo/sublime.html">sublime bindings</a>: Make by-subword motion more consistent with Sublime Text.</li>
<li><a href="https://codemirror.net/mode/julia/">julia mode</a>: Dont break on zero-prefixed integers.</li>
<li><a href="https://codemirror.net/mode/elm/">elm mode</a>: Sync with upstream version.</li>
<li><a href="https://codemirror.net/mode/sql/">sql mode</a>: Support Postgres-style backslash-escaped string literals.</li>
</ul>
<p class="rel">21-10-2019: <a href="https://codemirror.net/codemirror-5.49.2.zip">Version 5.49.2</a>:</p>
<ul class="rel-note">
<li><a href="https://codemirror.net/demo/sublime.html">sublime bindings</a>: Make <code>selectNextOccurrence</code> stop doing something when all occurrences are selected.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_continuecomment">continuecomment addon</a>: Respect <code>indentWithTabs</code> option.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_foldgutter">foldgutter addon</a>: Optimize by reusing DOM when possible.</li>
<li><a href="https://codemirror.net/mode/markdown/">markdown mode</a>: Dont reset inline styles at the start of a continued list item line.</li>
<li><a href="https://codemirror.net/mode/clike/">clike mode</a>: Add a configuration for Objective-C++.</li>
</ul>
<p class="rel">20-09-2019: <a href="https://codemirror.net/codemirror-5.49.0.zip">Version 5.49.0</a>:</p>
<ul class="rel-note">
<li>New themes: <a href="https://codemirror.net/demo/theme.html#moxer">moxer</a>, <a href="https://codemirror.net/demo/theme.html#material-darker">material-darker</a>, <a href="https://codemirror.net/demo/theme.html#material-palenight">material-palenight</a>, <a href="https://codemirror.net/demo/theme.html#material-ocean">material-ocean</a>.</li>
<li><a href="https://codemirror.net/mode/xml/">xml mode</a>: Provide a more abstract way to query context, which other modes for XML-like languages can also implement.</li>
<li><a href="https://codemirror.net/mode/octave/index.html">octave mode</a>: Dont mark common punctuation as error.</li>
<li><a href="https://codemirror.net/mode/clike/">clike mode</a>: Support nested comments and properly indent lambdas in Kotlin.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_foldgutter">foldgutter</a> and <a href="https://codemirror.net/doc/manual.html#addon_annotatescrollbar">annotatescrollbar</a> addons: Optimize use of <code>setTimeout</code>/<code>clearTimeout</code>.</li>
</ul>
<p class="rel">20-08-2019: <a href="https://codemirror.net/codemirror-5.48.4.zip">Version 5.48.4</a>:</p>
<ul class="rel-note">
<li>Make default styles for line elements more specific so that they dont apply to all <code>&lt;pre&gt;</code> elements inside the editor.</li>
<li>Improve efficiency of fold gutter when theres big folded chunks of code in view.</li>
<li>Fix a bug that would leave the editor uneditable when a content-covering collapsed range was removed by replacing the entire document.</li>
<li><a href="https://codemirror.net/mode/julia/">julia mode</a>: Support number separators.</li>
<li><a href="https://codemirror.net/mode/asterisk/">asterisk mode</a>: Improve comment support.</li>
<li><a href="https://codemirror.net/mode/handlebars/">handlebars mode</a>: Support triple-brace tags.</li>
</ul>
<p class="rel">20-07-2019: <a href="https://codemirror.net/codemirror-5.48.2.zip">Version 5.48.2</a>:</p>
<ul class="rel-note">

View File

@ -99,7 +99,7 @@
</div>
</div>
<div class=actionsleft>
Get the current version: <a href="https://codemirror.net/codemirror.zip">5.48.2</a>.<br>
Get the current version: <a href="https://codemirror.net/codemirror.zip">5.58.1</a>.<br>
You can see the <a href="https://github.com/codemirror/codemirror" title="Github repository">code</a>,<br>
read the <a href="doc/releases.html">release notes</a>,<br>
or study the <a href="doc/manual.html">user manual</a>.
@ -171,11 +171,6 @@
that explicit, we have
a <a href="http://contributor-covenant.org/version/1/1/0/">code of
conduct</a> that applies to communication around the project.</p>
<p>A list of CodeMirror-related software that is not part of the
main distribution is maintained
on <a href="https://github.com/codemirror/CodeMirror/wiki/CodeMirror-addons">our
wiki</a>. Feel free to add your project.</p>
</section>
<section id=browsersupport>
@ -195,4 +190,21 @@
pretty well.</p>
</section>
<section id=sponsors>
<style>
ul.sponsor-list { padding-left: 10px }
ul.sponsor-list li { list-style: none; margin-bottom: 1em }
ul.sponsor-list img { max-width: 80%; max-height: 10em; width: 20em }
</style>
<h2>Sponsors</h2>
<p>These companies support development of this project:</p>
<ul class=sponsor-list>
<li><a href="https://codepen.io/"><img src='data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 138 26"><path fill="none" stroke="black" stroke-width="2.3" stroke-linecap="round" stroke-linejoin="round" d="M15 8a7 7 0 100 10m7-8.7L33 2l11 7.3v7.4L33 24l-11-7.3zm0 0l11 7.4 11-7.4m0 7.4L33 9.3l-11 7.4M33 2v7.3m0 7.4V24M52 6h5a7 7 0 010 14h-5zm28 0h-9v14h9m-9-7h6m11 1h6a4 4 0 000-8h-6v14m26-14h-9v14h9m-9-7h6m11 7V6l11 14V6"/></svg>' alt="CodePen"></a></li>
<li><a href="https://www.jetbrains.com/"><img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='39 0 142.7 119'%3E%3ClinearGradient id='SVGID_1_' gradientUnits='userSpaceOnUse' x1='4.7875' y1='6.8451' x2='75.7999' y2='54.4038'%3E%3Cstop offset='0' stop-color='%23AA4A9B'/%3E%3Cstop offset='1' stop-color='%23F05922'/%3E%3C/linearGradient%3E%3Cpath fill='url(%23SVGID_1_)' d='M81.3,57.6L18.7,3.1c-1.9-1.8-4.5-3-7.3-3.1C5.2-0.2,0.2,4.6,0,10.7c-0.1,4.3,2.3,8.1,5.8,10l70.4,43.7c0.1,0.1,0.2,0.1,0.3,0.2c2.1,1.1,4.6,0.4,5.8-1.6C83.4,61.2,82.9,58.9,81.3,57.6z'/%3E%3ClinearGradient id='SVGID_2_' gradientUnits='userSpaceOnUse' x1='28.3538' y1='119.6551' x2='139.5938' y2='60.2551'%3E%3Cstop offset='0' stop-color='%23FFE42E'/%3E%3Cstop offset='1' stop-color='%23ED417C'/%3E%3C/linearGradient%3E%3Cpath fill='url(%23SVGID_2_)' d='M142.7,66.3c-0.3-8.6-7.6-15.3-16.2-14.9c-2.7,0.1-5.3,0.9-7.5,2.2l-88,50.1c0,0-0.1,0-0.1,0.1c-3,1.2-5,4.2-4.9,7.6c0.2,4.4,3.8,7.8,8.2,7.6c1,0,2-0.3,2.9-0.7l95.9-37c0,0,0.1,0,0.2-0.1C138.9,78.8,142.9,73,142.7,66.3z'/%3E%3ClinearGradient id='SVGID_3_' gradientUnits='userSpaceOnUse' x1='31.6974' y1='114.3816' x2='72.0174' y2='55.3416'%3E%3Cstop offset='0' stop-color='%23FFE42E'/%3E%3Cstop offset='1' stop-color='%23F05922'/%3E%3C/linearGradient%3E%3Cpath fill='url(%23SVGID_3_)' d='M71.8,64c1.1-2.1,0.3-4.7-1.8-5.7c-1.9-1-4.2-0.4-5.4,1.3l-37.1,47.1c0,0,0,0.1-0.1,0.2c-1.8,2.7-1.8,6.3,0.3,9c2.6,3.5,7.5,4.2,11,1.7c1-0.8,1.8-1.8,2.4-2.8l30.5-50.2C71.6,64.3,71.7,64.1,71.8,64z'/%3E%3Crect x='45.5' y='35.7' width='51' height='51'/%3E%3Crect x='49.9' y='77.1' fill='%23fff' width='19.1' height='3.2'/%3E%3Cpath fill='%23fff' d='M49.7,49.1l1.5-1.4c0.4,0.5,0.8,0.8,1.3,0.8c0.6,0,0.9-0.4,0.9-1.2V42h2.3v5.3c0,1-0.3,1.8-0.8,2.3c-0.5,0.5-1.3,0.8-2.3,0.8C51.2,50.5,50.3,49.9,49.7,49.1z'/%3E%3Cpath fill='%23fff' d='M56.3,42h6.7V44h-4.4v1.3h4v1.8h-4v1.3H63v2h-6.7V42z'/%3E%3Cpath fill='%23fff' d='M66,44.1h-2.5v-2h7.3v2h-2.5v6.3H66V44.1z'/%3E%3Cpath fill='%23fff' d='M49.9,52.3h4.3c1,0,1.8,0.3,2.3,0.7c0.3,0.3,0.5,0.8,0.5,1.4v0c0,1-0.5,1.5-1.3,1.9c1,0.3,1.7,0.9,1.7,2v0c0,1.4-1.2,2.3-3.1,2.3h-4.3V52.3z M54.7,54.9c0-0.5-0.4-0.7-1-0.7h-1.5v1.5h1.4C54.3,55.6,54.7,55.4,54.7,54.9L54.7,54.9z M53.9,57.2h-1.8v1.5h1.8c0.7,0,1.1-0.3,1.1-0.8v0C55,57.5,54.7,57.2,53.9,57.2z'/%3E%3Cpath fill='%23fff' d='M57.7,52.3h3.9c1.3,0,2.2,0.3,2.7,0.9c0.5,0.5,0.7,1.1,0.7,1.9v0c0,1.3-0.7,2.1-1.7,2.6l2,2.9h-2.6L61,58.1h-1v2.5h-2.3V52.3z M61.5,56.3c0.8,0,1.2-0.4,1.2-1v0c0-0.7-0.5-1-1.2-1H60v2H61.5z'/%3E%3Cpath fill='%23fff' d='M67.8,52.2H70l3.5,8.4h-2.5l-0.6-1.5h-3.2l-0.6,1.5h-2.4L67.8,52.2z M69.8,57.3L68.9,55l-0.9,2.4H69.8z'/%3E%3Cpath fill='%23fff' d='M73.8,52.3h2.3v8.3h-2.3V52.3z'/%3E%3Cpath fill='%23fff' d='M76.7,52.3h2.2l3.4,4.4v-4.4h2.3v8.3h-2L79,56.1v4.6h-2.3V52.3z'/%3E%3Cpath fill='%23fff' d='M84.7,59.4l1.3-1.5c0.8,0.7,1.7,1,2.7,1c0.6,0,1-0.2,1-0.6v0c0-0.4-0.3-0.5-1.4-0.8c-1.8-0.4-3.1-0.9-3.1-2.6v0c0-1.5,1.2-2.7,3.2-2.7c1.4,0,2.5,0.4,3.4,1.1l-1.2,1.6c-0.8-0.5-1.6-0.8-2.3-0.8c-0.6,0-0.8,0.2-0.8,0.5v0c0,0.4,0.3,0.5,1.4,0.8c1.9,0.4,3.1,1,3.1,2.6v0c0,1.7-1.3,2.7-3.4,2.7C87.1,60.8,85.7,60.3,84.7,59.4z'/%3E%3C/svg%3E%0A" alt="JetBrains"></a>
<li><a href="https://www.desmos.com/"><img src='data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 107.05 22.17" fill="%23187a3d"%3E%3Cpath d="M89.91 7.50c-1.62-1.67-3.64-2.53-5.98-2.53-2.34 0-4.36.85-5.99 2.53s-2.45 3.73-2.45 6.1a8.4 8.4 0 0 0 2.43 6.02 8.13 8.13 0 0 0 6.02 2.51c2.37 0 4.4-.85 6-2.51 1.6-1.68 2.43-3.7 2.43-6.05a8.41 8.41 0 0 0-2.46-6.07m-5.98.41c1.47 0 2.72.56 3.81 1.68a5.6 5.6 0 0 1 1.61 4.01c0 1.58-.52 2.88-1.6 3.98-1.06 1.1-2.32 1.63-3.87 1.63-1.53 0-2.8-.53-3.82-1.61-1.05-1.1-1.56-2.4-1.56-3.97 0-1.58.53-2.90 1.61-4.05 1.07-1.13 2.32-1.68 3.80-1.68M15.25 0a1.47 1.47 0 0 0-1.44 1.25l-.00 5.78c-1.27-1.12-2.75-1.8-4.42-1.97h-.04c-.10-.01-.22-.01-.32-.03l-.33-.03a10.1 10.1 0 0 0-.76.01l-.06.01c-.11 0-.23.01-.34.02l-.43.04-.09.02-.28.04c-.14.01-.26.06-.41.08a7.94 7.94 0 0 0-3.55 1.98l-.04.02-.37.4-.18.21a7.34 7.34 0 0 0-.52.65 1.78 1.78 0 0 0-.15.21l-.04.06C.46 10.17 0 11.79 0 13.55l.00.44.07.78.05.33.07.33.05.26c.36 1.41 1.08 2.7 2.15 3.80a8.59 8.59 0 0 0 1.38 1.17l.23.15c.03.02.06.03.09.05l.03.01c.19.12.4.22.57.32l.38.17c.99.41 2.09.62 3.26.62h.04l.39-.01a1.36 1.36 0 0 0 .19-.01h.05l.18-.01c.04-.01.09-.01.12-.01a7.86 7.86 0 0 0 4.42-1.93v.67l.00.07a1.47 1.47 0 0 0 1.26 1.24h.38c.73-.1 1.27-.73 1.27-1.46V1.47c0-.8-.65-1.47-1.46-1.47M13.74 13.59c0 1.57-.51 2.85-1.57 3.94s-2.30 1.62-3.82 1.62a5.39 5.39 0 0 1-1.87-.32c-.02-.00-.04-.00-.05-.01l-.07-.03c-.64-.25-1.26-.67-1.79-1.23a5.46 5.46 0 0 1-1.38-2.58c-.1-.43-.14-.88-.14-1.34 0-1.57.51-2.87 1.58-4.01C5.66 8.48 6.9 7.94 8.36 7.94c1.47 0 2.69.54 3.77 1.67 1.1 1.13 1.60 2.43 1.60 3.97m21.89-.36c0-.2-.02-.43-.03-.65-.13-1.25-.52-2.41-1.15-3.45-.34-.57-.75-1.11-1.25-1.62-1.2-1.24-2.64-2.05-4.26-2.37l-.13-.01c-.11-.03-.24-.04-.35-.06l-.52-.05-.33-.02a11.34 11.34 0 0 0-.82 0c-1.50.07-2.88.50-4.08 1.30a7.49 7.49 0 0 0-.50.36l-.63.54-.32.31a8.49 8.49 0 0 0-2.45 6.10c0 1.1.19 2.17.57 3.14.39 1.03 1.02 2 1.86 2.86l.62.59a9.28 9.28 0 0 0 1.00.74l.72.39a8.75 8.75 0 0 0 1.96.64l.43.07.42.04c.13.01.26.02.40.02l.06.00a4.88 4.88 0 0 0 .37.01h.04l.39-.01.28-.01.12-.01a7.97 7.97 0 0 0 5.15-2.47c.32-.33.61-.68.86-1.04a4.51 4.51 0 0 0 .27-.40l.04-.08a1.45 1.45 0 0 0 .10-.53 1.5 1.5 0 0 0-1.50-1.49c-.5 0-.95.24-1.24.65a5.5 5.5 0 0 1-.71.89c-1.05 1.1-2.32 1.63-3.87 1.63-1.53 0-2.78-.53-3.83-1.61a7.25 7.25 0 0 1-.50-.6l-.05-.09c-.12-.18-.24-.36-.36-.60a5.01 5.01 0 0 1-.50-1.49h12.45l.11-.02c.62-.13 1.1-.65 1.16-1.30v-.04l-.01-.24m-13.64-1.11a5.36 5.36 0 0 1 .68-1.57l.04-.07c.2-.30.43-.58.7-.87 1.07-1.13 2.31-1.68 3.79-1.68s2.73.56 3.81 1.68c.50.53.89 1.11 1.17 1.74a5.44 5.44 0 0 1 .25.76zm51.46-1.14v9.57a1.48 1.48 0 0 1-1.48 1.47c-.75 0-1.39-.55-1.47-1.32v-9.68a3.2 3.2 0 0 0-.91-2.30c-.56-.57-1.19-.9-1.93-.94-.06-.01-.14-.01-.22-.01-.84 0-1.53.31-2.13.95a3.19 3.19 0 0 0-.91 2.14v.13l.00.09-.00.02v9.45a1.47 1.47 0 0 1-1.47 1.47 1.47 1.47 0 0 1-1.48-1.32l-.00-.05.01-9.64c-.01-.07-.01-.12-.01-.17-.02-.46-.41-1.37-.41-1.37s-.30-.53-.50-.74c-.60-.63-1.31-.95-2.15-.95-.83 0-1.52.31-2.13.95a3.2 3.2 0 0 0-.92 2.3v9.73a1.48 1.48 0 0 1-1.47 1.28 1.48 1.48 0 0 1-1.47-1.47V6.33c0-.82.66-1.48 1.47-1.48.60 0 1.14.38 1.37.91l.32-.21a5.89 5.89 0 0 1 2.83-.7c1.5 0 2.82.5 3.92 1.46a3.73 3.73 0 0 1 .34.34l.27.28.26-.28.35-.34a5.76 5.76 0 0 1 3.90-1.46l.50.02c1.3.1 2.45.58 3.42 1.46l.34.33a5.99 5.99 0 0 1 1.74 4.32"/%3E%3Cpath d="M50.32 17.13c0 2.74-2.21 4.98-4.94 5.03h-5.98a1.45 1.45 0 0 1-1.44-1.45c0-.8.64-1.44 1.45-1.44h5.91a2.13 2.13 0 0 0 2.1-2.13 2.13 2.13 0 0 0-2.12-2.12h-2.86c-2.77 0-5.03-2.24-5.03-5.02a5.04 5.04 0 0 1 5.03-5.03h5.91a1.46 1.46 0 0 1 1.45 1.46 1.46 1.46 0 0 1-1.45 1.44h-5.91c-1.17 0-2.12.95-2.12 2.12 0 1.15.94 2.1 2.1 2.12h.05c.01 0 .04 0 .09-.00h2.73c.70 0 1.39.14 2.03.43a5.04 5.04 0 0 1 3 4.59m56.74-.00c0 2.74-2.22 5-4.95 5.03h-5.98a1.46 1.46 0 0 1-1.45-1.45 1.45 1.45 0 0 1 1.45-1.44h5.9c1.15-.01 2.10-.96 2.10-2.13a2.13 2.13 0 0 0-2.12-2.12h-2.63c-.07.01-.14.01-.22.01-2.77 0-5.03-2.24-5.03-5.03a5.04 5.04 0 0 1 5.03-5.03h5.90a1.47 1.47 0 0 1 1.45 1.46c0 .79-.65 1.45-1.45 1.45h-5.90a2.13 2.13 0 0 0-2.13 2.12 2.14 2.14 0 0 0 2.10 2.12h.05c.01 0 .05 0 .08-.00h2.74a4.87 4.87 0 0 1 2.03.43c1.82.8 3 2.61 3 4.59"/%3E%3C/svg%3E%0A' alt=desmos></a></li>
</ul>
</section>
</article>

View File

@ -404,7 +404,8 @@
"Ctrl-X H": "selectAll",
"Ctrl-Q Tab": repeated("insertTab"),
"Ctrl-U": addPrefixMap
"Ctrl-U": addPrefixMap,
"fallthrough": "default"
});
var prefixMap = {"Ctrl-G": clearPrefix};

View File

@ -22,17 +22,21 @@
if (dir < 0 && start.ch == 0) return doc.clipPos(Pos(start.line - 1));
var line = doc.getLine(start.line);
if (dir > 0 && start.ch >= line.length) return doc.clipPos(Pos(start.line + 1, 0));
var state = "start", type;
for (var pos = start.ch, e = dir < 0 ? 0 : line.length, i = 0; pos != e; pos += dir, i++) {
var state = "start", type, startPos = start.ch;
for (var pos = startPos, e = dir < 0 ? 0 : line.length, i = 0; pos != e; pos += dir, i++) {
var next = line.charAt(dir < 0 ? pos - 1 : pos);
var cat = next != "_" && CodeMirror.isWordChar(next) ? "w" : "o";
if (cat == "w" && next.toUpperCase() == next) cat = "W";
if (state == "start") {
if (cat != "o") { state = "in"; type = cat; }
else startPos = pos + dir
} else if (state == "in") {
if (type != cat) {
if (type == "w" && cat == "W" && dir < 0) pos--;
if (type == "W" && cat == "w" && dir > 0) { type = "w"; continue; }
if (type == "W" && cat == "w" && dir > 0) { // From uppercase to lowercase
if (pos == startPos + 1) { type = "w"; continue; }
else pos--;
}
break;
}
}
@ -144,14 +148,24 @@
cur = cm.getSearchCursor(query, Pos(cm.firstLine(), 0));
found = cur.findNext();
}
if (!found || isSelectedRange(cm.listSelections(), cur.from(), cur.to()))
return CodeMirror.Pass
if (!found || isSelectedRange(cm.listSelections(), cur.from(), cur.to())) return
cm.addSelection(cur.from(), cur.to());
}
if (fullWord)
cm.state.sublimeFindFullWord = cm.doc.sel;
};
cmds.skipAndSelectNextOccurrence = function(cm) {
var prevAnchor = cm.getCursor("anchor"), prevHead = cm.getCursor("head");
cmds.selectNextOccurrence(cm);
if (CodeMirror.cmpPos(prevAnchor, prevHead) != 0) {
cm.doc.setSelections(cm.doc.listSelections()
.filter(function (sel) {
return sel.anchor != prevAnchor || sel.head != prevHead;
}));
}
}
function addCursorToSelection(cm, dir) {
var ranges = cm.listSelections(), newRanges = [];
for (var i = 0; i < ranges.length; i++) {
@ -175,7 +189,8 @@
function isSelectedRange(ranges, from, to) {
for (var i = 0; i < ranges.length; i++)
if (ranges[i].from() == from && ranges[i].to() == to) return true
if (CodeMirror.cmpPos(ranges[i].from(), from) == 0 &&
CodeMirror.cmpPos(ranges[i].to(), to) == 0) return true
return false
}
@ -213,11 +228,15 @@
if (!selectBetweenBrackets(cm)) return CodeMirror.Pass;
};
function puncType(type) {
return !type ? null : /\bpunctuation\b/.test(type) ? type : undefined
}
cmds.goToBracket = function(cm) {
cm.extendSelectionsBy(function(range) {
var next = cm.scanForBracket(range.head, 1);
var next = cm.scanForBracket(range.head, 1, puncType(cm.getTokenTypeAt(range.head)));
if (next && CodeMirror.cmpPos(next.pos, range.head) != 0) return next.pos;
var prev = cm.scanForBracket(range.head, -1);
var prev = cm.scanForBracket(range.head, -1, puncType(cm.getTokenTypeAt(Pos(range.head.line, range.head.ch + 1))));
return prev && Pos(prev.pos.line, prev.pos.ch + 1) || range.head;
});
};
@ -597,6 +616,7 @@
"Shift-Cmd-F2": "clearBookmarks",
"Alt-F2": "selectBookmarks",
"Backspace": "smartBackspace",
"Cmd-K Cmd-D": "skipAndSelectNextOccurrence",
"Cmd-K Cmd-K": "delLineRight",
"Cmd-K Cmd-U": "upcaseAtCursor",
"Cmd-K Cmd-L": "downcaseAtCursor",
@ -608,6 +628,7 @@
"Cmd-K Cmd-C": "showInCenter",
"Cmd-K Cmd-G": "clearBookmarks",
"Cmd-K Cmd-Backspace": "delLineLeft",
"Cmd-K Cmd-1": "foldAll",
"Cmd-K Cmd-0": "unfoldAll",
"Cmd-K Cmd-J": "unfoldAll",
"Ctrl-Shift-Up": "addCursorToPrevLine",
@ -657,6 +678,7 @@
"Shift-Ctrl-F2": "clearBookmarks",
"Alt-F2": "selectBookmarks",
"Backspace": "smartBackspace",
"Ctrl-K Ctrl-D": "skipAndSelectNextOccurrence",
"Ctrl-K Ctrl-K": "delLineRight",
"Ctrl-K Ctrl-U": "upcaseAtCursor",
"Ctrl-K Ctrl-L": "downcaseAtCursor",
@ -668,6 +690,7 @@
"Ctrl-K Ctrl-C": "showInCenter",
"Ctrl-K Ctrl-G": "clearBookmarks",
"Ctrl-K Ctrl-Backspace": "delLineLeft",
"Ctrl-K Ctrl-1": "foldAll",
"Ctrl-K Ctrl-0": "unfoldAll",
"Ctrl-K Ctrl-J": "unfoldAll",
"Ctrl-Alt-Up": "addCursorToPrevLine",

View File

@ -8,7 +8,7 @@
* Supported Ex commands:
* Refer to defaultExCommandMap below.
*
* Registers: unnamed, -, a-z, A-Z, 0-9
* Registers: unnamed, -, ., :, /, _, a-z, A-Z, 0-9
* (Does not respect the special case for number registers when delete
* operator is made with these commands: %, (, ), , /, ?, n, N, {, } )
* TODO: Implement the remaining registers.
@ -141,6 +141,8 @@
{ keys: 'gU', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: false}, isEdit: true },
{ keys: 'n', type: 'motion', motion: 'findNext', motionArgs: { forward: true, toJumplist: true }},
{ keys: 'N', type: 'motion', motion: 'findNext', motionArgs: { forward: false, toJumplist: true }},
{ keys: 'gn', type: 'motion', motion: 'findAndSelectNextInclusive', motionArgs: { forward: true }},
{ keys: 'gN', type: 'motion', motion: 'findAndSelectNextInclusive', motionArgs: { forward: false }},
// Operator-Motion dual commands
{ keys: 'x', type: 'operatorMotion', operator: 'delete', motion: 'moveByCharacters', motionArgs: { forward: true }, operatorMotionArgs: { visualLine: false }},
{ keys: 'X', type: 'operatorMotion', operator: 'delete', motion: 'moveByCharacters', motionArgs: { forward: false }, operatorMotionArgs: { visualLine: true }},
@ -164,7 +166,9 @@
{ keys: 'A', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'eol' }, context: 'normal' },
{ keys: 'A', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'endOfSelectedArea' }, context: 'visual' },
{ keys: 'i', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'inplace' }, context: 'normal' },
{ keys: 'gi', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'lastEdit' }, context: 'normal' },
{ keys: 'I', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'firstNonBlank'}, context: 'normal' },
{ keys: 'gI', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'bol'}, context: 'normal' },
{ keys: 'I', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'startOfSelectedArea' }, context: 'visual' },
{ keys: 'o', type: 'action', action: 'newLineAndEnterInsertMode', isEdit: true, interlaceInsertRepeat: true, actionArgs: { after: true }, context: 'normal' },
{ keys: 'O', type: 'action', action: 'newLineAndEnterInsertMode', isEdit: true, interlaceInsertRepeat: true, actionArgs: { after: false }, context: 'normal' },
@ -174,13 +178,15 @@
{ keys: '<C-q>', type: 'action', action: 'toggleVisualMode', actionArgs: { blockwise: true }},
{ keys: 'gv', type: 'action', action: 'reselectLastSelection' },
{ keys: 'J', type: 'action', action: 'joinLines', isEdit: true },
{ keys: 'gJ', type: 'action', action: 'joinLines', actionArgs: { keepSpaces: true }, isEdit: true },
{ keys: 'p', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: true, isEdit: true }},
{ keys: 'P', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: false, isEdit: true }},
{ keys: 'r<character>', type: 'action', action: 'replace', isEdit: true },
{ keys: '@<character>', type: 'action', action: 'replayMacro' },
{ keys: 'q<character>', type: 'action', action: 'enterMacroRecordMode' },
// Handle Replace-mode as a special case of insert mode.
{ keys: 'R', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { replace: true }},
{ keys: 'R', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { replace: true }, context: 'normal'},
{ keys: 'R', type: 'operator', operator: 'change', operatorArgs: { linewise: true, fullLine: true }, context: 'visual', exitVisualBlock: true},
{ keys: 'u', type: 'action', action: 'undo', context: 'normal' },
{ keys: 'u', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: true}, context: 'visual', isEdit: true },
{ keys: 'U', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: false}, context: 'visual', isEdit: true },
@ -230,7 +236,6 @@
{ name: 'undo', shortName: 'u' },
{ name: 'redo', shortName: 'red' },
{ name: 'set', shortName: 'se' },
{ name: 'set', shortName: 'se' },
{ name: 'setlocal', shortName: 'setl' },
{ name: 'setglobal', shortName: 'setg' },
{ name: 'sort', shortName: 'sor' },
@ -291,16 +296,16 @@
clearFatCursorMark(cm);
var ranges = cm.listSelections(), result = []
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i]
var range = ranges[i];
if (range.empty()) {
if (range.anchor.ch < cm.getLine(range.anchor.line).length) {
var lineLength = cm.getLine(range.anchor.line).length;
if (range.anchor.ch < lineLength) {
result.push(cm.markText(range.anchor, Pos(range.anchor.line, range.anchor.ch + 1),
{className: "cm-fat-cursor-mark"}))
{className: "cm-fat-cursor-mark"}));
} else {
var widget = document.createElement("span")
widget.textContent = "\u00a0"
widget.className = "cm-fat-cursor-mark"
result.push(cm.setBookmark(range.anchor, {widget: widget}))
result.push(cm.markText(Pos(range.anchor.line, lineLength - 1),
Pos(range.anchor.line, lineLength),
{className: "cm-fat-cursor-mark"}));
}
}
}
@ -413,7 +418,7 @@
var lowerCaseAlphabet = makeKeyRange(97, 26);
var numbers = makeKeyRange(48, 10);
var validMarks = [].concat(upperCaseAlphabet, lowerCaseAlphabet, numbers, ['<', '>']);
var validRegisters = [].concat(upperCaseAlphabet, lowerCaseAlphabet, numbers, ['-', '"', '.', ':', '/']);
var validRegisters = [].concat(upperCaseAlphabet, lowerCaseAlphabet, numbers, ['-', '"', '.', ':', '_', '/']);
function isLine(cm, line) {
return line >= cm.firstLine() && line <= cm.lastLine();
@ -594,9 +599,16 @@
}
return mark;
}
function find(cm, offset) {
var oldPointer = pointer;
var mark = move(cm, offset);
pointer = oldPointer;
return mark && mark.find();
}
return {
cachedCursor: undefined, //used for # and * jumps
add: add,
find: find,
move: move
};
};
@ -1118,6 +1130,8 @@
}
RegisterController.prototype = {
pushText: function(registerName, operator, text, linewise, blockwise) {
// The black hole register, "_, means delete/yank to nowhere.
if (registerName === '_') return;
if (linewise && text.charAt(text.length - 1) !== '\n'){
text += '\n';
}
@ -1293,6 +1307,10 @@
}
inputState.operator = command.operator;
inputState.operatorArgs = copyArgs(command.operatorArgs);
if (command.exitVisualBlock) {
vim.visualBlock = false;
updateCmSelection(cm);
}
if (vim.visualMode) {
// Operating on a selection in visual mode. We don't need a motion.
this.evalInput(cm, vim);
@ -1560,7 +1578,7 @@
motionArgs.repeat = repeat;
clearInputState(cm);
if (motion) {
var motionResult = motions[motion](cm, origHead, motionArgs, vim);
var motionResult = motions[motion](cm, origHead, motionArgs, vim, inputState);
vim.lastMotion = motions[motion];
if (!motionResult) {
return;
@ -1588,10 +1606,10 @@
}
if (vim.visualMode) {
if (!(vim.visualBlock && newHead.ch === Infinity)) {
newHead = clipCursorToContent(cm, newHead, vim.visualBlock);
newHead = clipCursorToContent(cm, newHead);
}
if (newAnchor) {
newAnchor = clipCursorToContent(cm, newAnchor, true);
newAnchor = clipCursorToContent(cm, newAnchor);
}
newAnchor = newAnchor || oldAnchor;
sel.anchor = newAnchor;
@ -1758,6 +1776,87 @@
highlightSearchMatches(cm, query);
return findNext(cm, prev/** prev */, query, motionArgs.repeat);
},
/**
* Find and select the next occurrence of the search query. If the cursor is currently
* within a match, then find and select the current match. Otherwise, find the next occurrence in the
* appropriate direction.
*
* This differs from `findNext` in the following ways:
*
* 1. Instead of only returning the "from", this returns a "from", "to" range.
* 2. If the cursor is currently inside a search match, this selects the current match
* instead of the next match.
* 3. If there is no associated operator, this will turn on visual mode.
*/
findAndSelectNextInclusive: function(cm, _head, motionArgs, vim, prevInputState) {
var state = getSearchState(cm);
var query = state.getQuery();
if (!query) {
return;
}
var prev = !motionArgs.forward;
prev = (state.isReversed()) ? !prev : prev;
// next: [from, to] | null
var next = findNextFromAndToInclusive(cm, prev, query, motionArgs.repeat, vim);
// No matches.
if (!next) {
return;
}
// If there's an operator that will be executed, return the selection.
if (prevInputState.operator) {
return next;
}
// At this point, we know that there is no accompanying operator -- let's
// deal with visual mode in order to select an appropriate match.
var from = next[0];
// For whatever reason, when we use the "to" as returned by searchcursor.js directly,
// the resulting selection is extended by 1 char. Let's shrink it so that only the
// match is selected.
var to = Pos(next[1].line, next[1].ch - 1);
if (vim.visualMode) {
// If we were in visualLine or visualBlock mode, get out of it.
if (vim.visualLine || vim.visualBlock) {
vim.visualLine = false;
vim.visualBlock = false;
CodeMirror.signal(cm, "vim-mode-change", {mode: "visual", subMode: ""});
}
// If we're currently in visual mode, we should extend the selection to include
// the search result.
var anchor = vim.sel.anchor;
if (anchor) {
if (state.isReversed()) {
if (motionArgs.forward) {
return [anchor, from];
}
return [anchor, to];
} else {
if (motionArgs.forward) {
return [anchor, to];
}
return [anchor, from];
}
}
} else {
// Let's turn visual mode on.
vim.visualMode = true;
vim.visualLine = false;
vim.visualBlock = false;
CodeMirror.signal(cm, "vim-mode-change", {mode: "visual", subMode: ""});
}
return prev ? [to, from] : [from, to];
},
goToMark: function(cm, _head, motionArgs, vim) {
var pos = getMarkPos(cm, vim, motionArgs.selectedCharacter);
if (pos) {
@ -1843,12 +1942,18 @@
var line = motionArgs.forward ? cur.line + repeat : cur.line - repeat;
var first = cm.firstLine();
var last = cm.lastLine();
var posV = cm.findPosV(cur, (motionArgs.forward ? repeat : -repeat), 'line', vim.lastHSPos);
var hasMarkedText = motionArgs.forward ? posV.line > line : posV.line < line;
if (hasMarkedText) {
line = posV.line;
endCh = posV.ch;
}
// Vim go to line begin or line end when cursor at first/last line and
// move to previous/next line is triggered.
if (line < first && cur.line == first){
return this.moveToStartOfLine(cm, head, motionArgs, vim);
}else if (line > last && cur.line == last){
return this.moveToEol(cm, head, motionArgs, vim, true);
} else if (line > last && cur.line == last){
return moveToEol(cm, head, motionArgs, vim, true);
}
if (motionArgs.toFirstChar){
endCh=findFirstNonWhiteSpaceCharacter(cm.getLine(line));
@ -1950,16 +2055,8 @@
vim.lastHSPos = cm.charCoords(head,'div').left;
return moveToColumn(cm, repeat);
},
moveToEol: function(cm, head, motionArgs, vim, keepHPos) {
var cur = head;
var retval= Pos(cur.line + motionArgs.repeat - 1, Infinity);
var end=cm.clipPos(retval);
end.ch--;
if (!keepHPos) {
vim.lastHPos = Infinity;
vim.lastHSPos = cm.charCoords(end,'div').left;
}
return retval;
moveToEol: function(cm, head, motionArgs, vim) {
return moveToEol(cm, head, motionArgs, vim, false);
},
moveToFirstNonWhiteSpaceCharacter: function(cm, head) {
// Go to the start of the line where the text begins, or the end for
@ -2049,6 +2146,8 @@
if (operatorArgs) { operatorArgs.linewise = true; }
tmp.end.line--;
}
} else if (character === 't') {
tmp = expandTagUnderCursor(cm, head, inclusive);
} else {
// No text object defined for this, don't move.
return null;
@ -2098,9 +2197,9 @@
change: function(cm, args, ranges) {
var finalHead, text;
var vim = cm.state.vim;
var anchor = ranges[0].anchor,
head = ranges[0].head;
if (!vim.visualMode) {
var anchor = ranges[0].anchor,
head = ranges[0].head;
text = cm.getRange(anchor, head);
var lastState = vim.lastEditInputState || {};
if (lastState.motion == "moveByWords" && !isWhiteSpaceString(text)) {
@ -2128,6 +2227,13 @@
anchor.ch = Number.MAX_VALUE;
}
finalHead = anchor;
} else if (args.fullLine) {
head.ch = Number.MAX_VALUE;
head.line--;
cm.setSelection(anchor, head)
text = cm.getSelection();
cm.replaceSelection("");
finalHead = anchor;
} else {
text = cm.getSelection();
var replacement = fillArray('', ranges.length);
@ -2172,8 +2278,7 @@
vimGlobalState.registerController.pushText(
args.registerName, 'delete', text,
args.linewise, vim.visualBlock);
var includeLineBreak = vim.insertMode
return clipCursorToContent(cm, finalHead, includeLineBreak);
return clipCursorToContent(cm, finalHead);
},
indent: function(cm, args, ranges) {
var vim = cm.state.vim;
@ -2355,6 +2460,8 @@
var height = cm.listSelections().length;
if (insertAt == 'eol') {
head = Pos(head.line, lineLength(cm, head.line));
} else if (insertAt == 'bol') {
head = Pos(head.line, 0);
} else if (insertAt == 'charAfter') {
head = offsetCursor(head, 0, 1);
} else if (insertAt == 'firstNonBlank') {
@ -2393,6 +2500,8 @@
if (vim.visualMode){
return;
}
} else if (insertAt == 'lastEdit') {
head = getLastEditPos(cm) || head;
}
cm.setOption('disableInput', false);
if (actionArgs && actionArgs.replace) {
@ -2428,8 +2537,7 @@
vim.visualLine = !!actionArgs.linewise;
vim.visualBlock = !!actionArgs.blockwise;
head = clipCursorToContent(
cm, Pos(anchor.line, anchor.ch + repeat - 1),
true /** includeLineBreak */);
cm, Pos(anchor.line, anchor.ch + repeat - 1));
vim.sel = {
anchor: anchor,
head: head
@ -2501,7 +2609,9 @@
var tmp = Pos(curStart.line + 1,
lineLength(cm, curStart.line + 1));
var text = cm.getRange(curStart, tmp);
text = text.replace(/\n\s*/g, ' ');
text = actionArgs.keepSpaces
? text.replace(/\n\r?/g, '')
: text.replace(/\n\s*/g, ' ');
cm.replaceRange(text, curStart, tmp);
}
var curFinalPos = Pos(curStart.line, finalCh);
@ -2803,10 +2913,11 @@
* Clips cursor to ensure that line is within the buffer's range
* If includeLineBreak is true, then allow cur.ch == lineLength.
*/
function clipCursorToContent(cm, cur, includeLineBreak) {
function clipCursorToContent(cm, cur) {
var vim = cm.state.vim;
var includeLineBreak = vim.insertMode || vim.visualMode;
var line = Math.min(Math.max(cm.firstLine(), cur.line), cm.lastLine() );
var maxCh = lineLength(cm, line) - 1;
maxCh = (includeLineBreak) ? maxCh + 1 : maxCh;
var maxCh = lineLength(cm, line) - 1 + !!includeLineBreak;
var ch = Math.min(Math.max(0, cur.ch), maxCh);
return Pos(line, ch);
}
@ -3171,10 +3282,8 @@
vim.visualMode = false;
vim.visualLine = false;
vim.visualBlock = false;
CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
if (vim.fakeCursor) {
vim.fakeCursor.clear();
}
if (!vim.insertMode) CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
clearFakeCursor(vim);
}
// Remove any trailing newlines from the selection. For
@ -3265,6 +3374,49 @@
return { start: Pos(cur.line, start), end: Pos(cur.line, end) };
}
/**
* Depends on the following:
*
* - editor mode should be htmlmixedmode / xml
* - mode/xml/xml.js should be loaded
* - addon/fold/xml-fold.js should be loaded
*
* If any of the above requirements are not true, this function noops.
*
* This is _NOT_ a 100% accurate implementation of vim tag text objects.
* The following caveats apply (based off cursory testing, I'm sure there
* are other discrepancies):
*
* - Does not work inside comments:
* ```
* <!-- <div>broken</div> -->
* ```
* - Does not work when tags have different cases:
* ```
* <div>broken</DIV>
* ```
* - Does not work when cursor is inside a broken tag:
* ```
* <div><brok><en></div>
* ```
*/
function expandTagUnderCursor(cm, head, inclusive) {
var cur = head;
if (!CodeMirror.findMatchingTag || !CodeMirror.findEnclosingTag) {
return { start: cur, end: cur };
}
var tags = CodeMirror.findMatchingTag(cm, head) || CodeMirror.findEnclosingTag(cm, head);
if (!tags || !tags.open || !tags.close) {
return { start: cur, end: cur };
}
if (inclusive) {
return { start: tags.open.from, end: tags.close.to };
}
return { start: tags.open.to, end: tags.close.from };
}
function recordJumpPosition(cm, oldCur, newCur) {
if (!cursorEqual(oldCur, newCur)) {
vimGlobalState.jumpList.add(cm, oldCur, newCur);
@ -3532,6 +3684,18 @@
}
}
function moveToEol(cm, head, motionArgs, vim, keepHPos) {
var cur = head;
var retval= Pos(cur.line + motionArgs.repeat - 1, Infinity);
var end=cm.clipPos(retval);
end.ch--;
if (!keepHPos) {
vim.lastHPos = Infinity;
vim.lastHSPos = cm.charCoords(end,'div').left;
}
return retval;
}
function moveToCharacter(cm, repeat, forward, character) {
var cur = cm.getCursor();
var start = cur.ch;
@ -3806,7 +3970,7 @@
return Pos(curr_index.ln, curr_index.pos);
}
// TODO: perhaps this finagling of start and end positions belonds
// TODO: perhaps this finagling of start and end positions belongs
// in codemirror/replaceRange?
function selectCompanionObject(cm, head, symb, inclusive) {
var cur = head, start, end;
@ -4152,7 +4316,8 @@
}
function makePrompt(prefix, desc) {
var raw = '<span style="font-family: monospace; white-space: pre">' +
(prefix || "") + '<input type="text"></span>';
(prefix || "") + '<input type="text" autocorrect="off" ' +
'autocapitalize="off" spellcheck="false"></span>';
if (desc)
raw += ' <span style="color: #888">' + desc + '</span>';
return raw;
@ -4272,6 +4437,42 @@
return cursor.from();
});
}
/**
* Pretty much the same as `findNext`, except for the following differences:
*
* 1. Before starting the search, move to the previous search. This way if our cursor is
* already inside a match, we should return the current match.
* 2. Rather than only returning the cursor's from, we return the cursor's from and to as a tuple.
*/
function findNextFromAndToInclusive(cm, prev, query, repeat, vim) {
if (repeat === undefined) { repeat = 1; }
return cm.operation(function() {
var pos = cm.getCursor();
var cursor = cm.getSearchCursor(query, pos);
// Go back one result to ensure that if the cursor is currently a match, we keep it.
var found = cursor.find(!prev);
// If we haven't moved, go back one more (similar to if i==0 logic in findNext).
if (!vim.visualMode && found && cursorEqual(cursor.from(), pos)) {
cursor.find(!prev);
}
for (var i = 0; i < repeat; i++) {
found = cursor.find(prev);
if (!found) {
// SearchCursor may have returned null because it hit EOF, wrap
// around and try again.
cursor = cm.getSearchCursor(query,
(prev) ? Pos(cm.lastLine()) : Pos(cm.firstLine(), 0) );
if (!cursor.find(prev)) {
return;
}
}
}
return [cursor.from(), cursor.to()];
});
}
function clearSearchHighlight(cm) {
var state = getSearchState(cm);
cm.removeOverlay(getSearchState(cm).getOverlay());
@ -4318,25 +4519,25 @@
}
function getMarkPos(cm, vim, markName) {
if (markName == '\'') {
var history = cm.doc.history.done;
var event = history[history.length - 2];
return event && event.ranges && event.ranges[0].head;
if (markName == '\'' || markName == '`') {
return vimGlobalState.jumpList.find(cm, -1) || Pos(0, 0);
} else if (markName == '.') {
if (cm.doc.history.lastModTime == 0) {
return // If no changes, bail out; don't bother to copy or reverse history array.
} else {
var changeHistory = cm.doc.history.done.filter(function(el){ if (el.changes !== undefined) { return el } });
changeHistory.reverse();
var lastEditPos = changeHistory[0].changes[0].to;
}
return lastEditPos;
return getLastEditPos(cm);
}
var mark = vim.marks[markName];
return mark && mark.find();
}
function getLastEditPos(cm) {
var done = cm.doc.history.done;
for (var i = done.length; i--;) {
if (done[i].changes) {
return copyCursor(done[i].changes[0].to);
}
}
}
var ExCommandDispatcher = function() {
this.buildCommandMap_();
};
@ -4425,7 +4626,7 @@
}
// Parse command name.
var commandMatch = inputStream.match(/^(\w+)/);
var commandMatch = inputStream.match(/^(\w+|!!|@@|[!#&*<=>@~])/);
if (commandMatch) {
result.commandName = commandMatch[1];
} else {
@ -5323,14 +5524,34 @@
updateFakeCursor(cm);
}
}
/**
* Keeps track of a fake cursor to support visual mode cursor behavior.
*/
function updateFakeCursor(cm) {
var className = 'cm-animate-fat-cursor';
var vim = cm.state.vim;
var from = clipCursorToContent(cm, copyCursor(vim.sel.head));
var to = offsetCursor(from, 0, 1);
clearFakeCursor(vim);
// In visual mode, the cursor may be positioned over EOL.
if (from.ch == cm.getLine(from.line).length) {
var widget = document.createElement("span");
widget.textContent = "\u00a0";
widget.className = className;
vim.fakeCursorBookmark = cm.setBookmark(from, {widget: widget});
} else {
vim.fakeCursor = cm.markText(from, to, {className: className});
}
}
function clearFakeCursor(vim) {
if (vim.fakeCursor) {
vim.fakeCursor.clear();
vim.fakeCursor = null;
}
if (vim.fakeCursorBookmark) {
vim.fakeCursorBookmark.clear();
vim.fakeCursorBookmark = null;
}
vim.fakeCursor = cm.markText(from, to, {className: 'cm-animate-fat-cursor'});
}
function handleExternalSelection(cm, vim) {
var anchor = cm.getCursor('anchor');

View File

@ -13,7 +13,8 @@
.CodeMirror-lines {
padding: 4px 0; /* Vertical padding around content */
}
.CodeMirror pre {
.CodeMirror pre.CodeMirror-line,
.CodeMirror pre.CodeMirror-line-like {
padding: 0 4px; /* Horizontal padding of content */
}
@ -96,7 +97,7 @@
.CodeMirror-rulers {
position: absolute;
left: 0; right: 0; top: -50px; bottom: -20px;
left: 0; right: 0; top: -50px; bottom: 0;
overflow: hidden;
}
.CodeMirror-ruler {
@ -163,17 +164,17 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
.CodeMirror-scroll {
overflow: scroll !important; /* Things will break if this is overridden */
/* 30px is the magic margin used to hide the element's real scrollbars */
/* 50px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */
margin-bottom: -30px; margin-right: -30px;
padding-bottom: 30px;
margin-bottom: -50px; margin-right: -50px;
padding-bottom: 50px;
height: 100%;
outline: none; /* Prevent dragging from highlighting the element */
position: relative;
}
.CodeMirror-sizer {
position: relative;
border-right: 30px solid transparent;
border-right: 50px solid transparent;
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
@ -183,6 +184,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
position: absolute;
z-index: 6;
display: none;
outline: none;
}
.CodeMirror-vscrollbar {
right: 0; top: 0;
@ -211,7 +213,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
height: 100%;
display: inline-block;
vertical-align: top;
margin-bottom: -30px;
margin-bottom: -50px;
}
.CodeMirror-gutter-wrapper {
position: absolute;
@ -236,7 +238,8 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
cursor: text;
min-height: 1px; /* prevents collapsing before first draw */
}
.CodeMirror pre {
.CodeMirror pre.CodeMirror-line,
.CodeMirror pre.CodeMirror-line-like {
/* Reset some styles that the rest of the page might have set */
-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
border-width: 0;
@ -255,7 +258,8 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
-webkit-font-variant-ligatures: contextual;
font-variant-ligatures: contextual;
}
.CodeMirror-wrap pre {
.CodeMirror-wrap pre.CodeMirror-line,
.CodeMirror-wrap pre.CodeMirror-line-like {
word-wrap: break-word;
white-space: pre-wrap;
word-break: normal;

File diff suppressed because it is too large Load Diff

View File

@ -12,7 +12,7 @@
.CodeMirror { border: 2px inset #dee; }
</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -9,7 +9,7 @@
<script src="asciiarmor.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -16,7 +16,7 @@
</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1>
<img id=logo src="../../doc/logo.png">
<img id=logo src="../../doc/logo.png" alt="">
</a>
<ul>

View File

@ -9,7 +9,7 @@
* Description: CodeMirror mode for Asterisk dialplan
*
* Created: 05/17/2012 09:20:25 PM
* Revision: none
* Revision: 08/05/2019 AstLinux Project: Support block-comments
*
* Author: Stas Kobzar (stas@modulis.ca),
* Company: Modulis.ca Inc.
@ -67,7 +67,26 @@ CodeMirror.defineMode("asterisk", function() {
var cur = '';
var ch = stream.next();
// comment
if (state.blockComment) {
if (ch == "-" && stream.match("-;", true)) {
state.blockComment = false;
} else if (stream.skipTo("--;")) {
stream.next();
stream.next();
stream.next();
state.blockComment = false;
} else {
stream.skipToEnd();
}
return "comment";
}
if(ch == ";") {
if (stream.match("--", true)) {
if (!stream.match("-", false)) { // Except ;--- is not a block comment
state.blockComment = true;
return "comment";
}
}
stream.skipToEnd();
return "comment";
}
@ -124,6 +143,7 @@ CodeMirror.defineMode("asterisk", function() {
return {
startState: function() {
return {
blockComment: false,
extenStart: false,
extenSame: false,
extenInclude: false,
@ -187,7 +207,11 @@ CodeMirror.defineMode("asterisk", function() {
}
return null;
}
},
blockCommentStart: ";--",
blockCommentEnd: "--;",
lineComment: ";"
};
});

View File

@ -13,7 +13,7 @@
.cm-s-default span.cm-arrow { color: red; }
</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -12,7 +12,7 @@
.CodeMirror { border: 2px inset #dee; }
</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -270,6 +270,25 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
"static else struct switch extern typedef union for goto while enum const " +
"volatile inline restrict asm fortran";
// Keywords from https://en.cppreference.com/w/cpp/keyword includes C++20.
var cppKeywords = "alignas alignof and and_eq audit axiom bitand bitor catch " +
"class compl concept constexpr const_cast decltype delete dynamic_cast " +
"explicit export final friend import module mutable namespace new noexcept " +
"not not_eq operator or or_eq override private protected public " +
"reinterpret_cast requires static_assert static_cast template this " +
"thread_local throw try typeid typename using virtual xor xor_eq";
var objCKeywords = "bycopy byref in inout oneway out self super atomic nonatomic retain copy " +
"readwrite readonly strong weak assign typeof nullable nonnull null_resettable _cmd " +
"@interface @implementation @end @protocol @encode @property @synthesize @dynamic @class " +
"@public @package @private @protected @required @optional @try @catch @finally @import " +
"@selector @encode @defs @synchronized @autoreleasepool @compatibility_alias @available";
var objCBuiltins = "FOUNDATION_EXPORT FOUNDATION_EXTERN NS_INLINE NS_FORMAT_FUNCTION " +
" NS_RETURNS_RETAINEDNS_ERROR_ENUM NS_RETURNS_NOT_RETAINED NS_RETURNS_INNER_POINTER " +
"NS_DESIGNATED_INITIALIZER NS_ENUM NS_OPTIONS NS_REQUIRES_NIL_TERMINATION " +
"NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END NS_SWIFT_NAME NS_REFINED_FOR_SWIFT"
// Do not use this. Use the cTypes function below. This is global just to avoid
// excessive calls when cTypes is being called multiple times during a parse.
var basicCTypes = words("int long char short double float unsigned signed " +
@ -420,13 +439,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
def(["text/x-c++src", "text/x-c++hdr"], {
name: "clike",
// Keywords from https://en.cppreference.com/w/cpp/keyword includes C++20.
keywords: words(cKeywords + "alignas alignof and and_eq audit axiom bitand bitor catch " +
"class compl concept constexpr const_cast decltype delete dynamic_cast " +
"explicit export final friend import module mutable namespace new noexcept " +
"not not_eq operator or or_eq override private protected public " +
"reinterpret_cast requires static_assert static_cast template this " +
"thread_local throw try typeid typename using virtual xor xor_eq"),
keywords: words(cKeywords + " " + cppKeywords),
types: cTypes,
blockKeywords: words(cBlockKeywords + " class try catch"),
defKeywords: words(cDefKeywords + " class namespace"),
@ -676,11 +689,16 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
state.tokenize = tokenKotlinString(stream.match('""'));
return state.tokenize(stream, state);
},
"/": function(stream, state) {
if (!stream.eat("*")) return false;
state.tokenize = tokenNestedComment(1);
return state.tokenize(stream, state)
},
indent: function(state, ctx, textAfter, indentUnit) {
var firstChar = textAfter && textAfter.charAt(0);
if ((state.prevToken == "}" || state.prevToken == ")") && textAfter == "")
return state.indented;
if (state.prevToken == "operator" && textAfter != "}" ||
if ((state.prevToken == "operator" && textAfter != "}" && state.context.type != "}") ||
state.prevToken == "variable" && firstChar == "." ||
(state.prevToken == "}" || state.prevToken == ")") && firstChar == ".")
return indentUnit * 2 + ctx.indented;
@ -764,16 +782,9 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
def("text/x-objectivec", {
name: "clike",
keywords: words(cKeywords + " bycopy byref in inout oneway out self super atomic nonatomic retain copy " +
"readwrite readonly strong weak assign typeof nullable nonnull null_resettable _cmd " +
"@interface @implementation @end @protocol @encode @property @synthesize @dynamic @class " +
"@public @package @private @protected @required @optional @try @catch @finally @import " +
"@selector @encode @defs @synchronized @autoreleasepool @compatibility_alias @available"),
keywords: words(cKeywords + " " + objCKeywords),
types: objCTypes,
builtin: words("FOUNDATION_EXPORT FOUNDATION_EXTERN NS_INLINE NS_FORMAT_FUNCTION NS_RETURNS_RETAINED " +
"NS_ERROR_ENUM NS_RETURNS_NOT_RETAINED NS_RETURNS_INNER_POINTER NS_DESIGNATED_INITIALIZER " +
"NS_ENUM NS_OPTIONS NS_REQUIRES_NIL_TERMINATION NS_ASSUME_NONNULL_BEGIN " +
"NS_ASSUME_NONNULL_END NS_SWIFT_NAME NS_REFINED_FOR_SWIFT"),
builtin: words(objCBuiltins),
blockKeywords: words(cBlockKeywords + " @synthesize @try @catch @finally @autoreleasepool @synchronized"),
defKeywords: words(cDefKeywords + " @interface @implementation @protocol @class"),
dontIndentStatements: /^@.*$/,
@ -787,6 +798,46 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
modeProps: {fold: ["brace", "include"]}
});
def("text/x-objectivec++", {
name: "clike",
keywords: words(cKeywords + " " + objCKeywords + " " + cppKeywords),
types: objCTypes,
builtin: words(objCBuiltins),
blockKeywords: words(cBlockKeywords + " @synthesize @try @catch @finally @autoreleasepool @synchronized class try catch"),
defKeywords: words(cDefKeywords + " @interface @implementation @protocol @class class namespace"),
dontIndentStatements: /^@.*$|^template$/,
typeFirstDefinitions: true,
atoms: words("YES NO NULL Nil nil true false nullptr"),
isReservedIdentifier: cIsReservedIdentifier,
hooks: {
"#": cppHook,
"*": pointerHook,
"u": cpp11StringHook,
"U": cpp11StringHook,
"L": cpp11StringHook,
"R": cpp11StringHook,
"0": cpp14Literal,
"1": cpp14Literal,
"2": cpp14Literal,
"3": cpp14Literal,
"4": cpp14Literal,
"5": cpp14Literal,
"6": cpp14Literal,
"7": cpp14Literal,
"8": cpp14Literal,
"9": cpp14Literal,
token: function(stream, state, style) {
if (style == "variable" && stream.peek() == "(" &&
(state.prevToken == ";" || state.prevToken == null ||
state.prevToken == "}") &&
cppLooksLikeConstructor(stream.current()))
return "def";
}
},
namespaceSeparator: "::",
modeProps: {fold: ["brace", "include"]}
});
def("text/x-squirrel", {
name: "clike",
keywords: words("base break clone continue const default delete enum extends function in class" +

View File

@ -12,7 +12,7 @@
<script src="clike.js"></script>
<style>.CodeMirror {border: 2px inset #dee;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -10,7 +10,7 @@
<script src="../../addon/edit/matchbrackets.js"></script>
<script src="clike.js"></script>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -11,7 +11,7 @@
<script src="clojure.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -13,7 +13,7 @@
.cm-s-default span.cm-arrow { color: red; }
</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -39,7 +39,7 @@
.CodeMirror-activeline-background {background: #555555 !important;}
</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -9,7 +9,7 @@
<script src="coffeescript.js"></script>
<style>.CodeMirror {border-top: 1px solid silver; border-bottom: 1px solid silver;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -9,7 +9,7 @@
<script src="commonlisp.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -14,7 +14,7 @@
</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -442,117 +442,149 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"monochrome", "min-monochrome", "max-monochrome", "resolution",
"min-resolution", "max-resolution", "scan", "grid", "orientation",
"device-pixel-ratio", "min-device-pixel-ratio", "max-device-pixel-ratio",
"pointer", "any-pointer", "hover", "any-hover"
"pointer", "any-pointer", "hover", "any-hover", "prefers-color-scheme"
], mediaFeatures = keySet(mediaFeatures_);
var mediaValueKeywords_ = [
"landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover",
"interlace", "progressive"
"interlace", "progressive",
"dark", "light"
], mediaValueKeywords = keySet(mediaValueKeywords_);
var propertyKeywords_ = [
"align-content", "align-items", "align-self", "alignment-adjust",
"alignment-baseline", "anchor-point", "animation", "animation-delay",
"alignment-baseline", "all", "anchor-point", "animation", "animation-delay",
"animation-direction", "animation-duration", "animation-fill-mode",
"animation-iteration-count", "animation-name", "animation-play-state",
"animation-timing-function", "appearance", "azimuth", "backface-visibility",
"background", "background-attachment", "background-blend-mode", "background-clip",
"background-color", "background-image", "background-origin", "background-position",
"background-repeat", "background-size", "baseline-shift", "binding",
"bleed", "bookmark-label", "bookmark-level", "bookmark-state",
"bookmark-target", "border", "border-bottom", "border-bottom-color",
"border-bottom-left-radius", "border-bottom-right-radius",
"border-bottom-style", "border-bottom-width", "border-collapse",
"border-color", "border-image", "border-image-outset",
"animation-timing-function", "appearance", "azimuth", "backdrop-filter",
"backface-visibility", "background", "background-attachment",
"background-blend-mode", "background-clip", "background-color",
"background-image", "background-origin", "background-position",
"background-position-x", "background-position-y", "background-repeat",
"background-size", "baseline-shift", "binding", "bleed", "block-size",
"bookmark-label", "bookmark-level", "bookmark-state", "bookmark-target",
"border", "border-bottom", "border-bottom-color", "border-bottom-left-radius",
"border-bottom-right-radius", "border-bottom-style", "border-bottom-width",
"border-collapse", "border-color", "border-image", "border-image-outset",
"border-image-repeat", "border-image-slice", "border-image-source",
"border-image-width", "border-left", "border-left-color",
"border-left-style", "border-left-width", "border-radius", "border-right",
"border-right-color", "border-right-style", "border-right-width",
"border-spacing", "border-style", "border-top", "border-top-color",
"border-top-left-radius", "border-top-right-radius", "border-top-style",
"border-top-width", "border-width", "bottom", "box-decoration-break",
"box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
"caption-side", "caret-color", "clear", "clip", "color", "color-profile", "column-count",
"column-fill", "column-gap", "column-rule", "column-rule-color",
"column-rule-style", "column-rule-width", "column-span", "column-width",
"columns", "content", "counter-increment", "counter-reset", "crop", "cue",
"cue-after", "cue-before", "cursor", "direction", "display",
"dominant-baseline", "drop-initial-after-adjust",
"drop-initial-after-align", "drop-initial-before-adjust",
"drop-initial-before-align", "drop-initial-size", "drop-initial-value",
"elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
"flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
"float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings",
"font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust",
"font-stretch", "font-style", "font-synthesis", "font-variant",
"font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
"font-variant-ligatures", "font-variant-numeric", "font-variant-position",
"font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow",
"grid-auto-rows", "grid-column", "grid-column-end", "grid-column-gap",
"grid-column-start", "grid-gap", "grid-row", "grid-row-end", "grid-row-gap",
"grid-row-start", "grid-template", "grid-template-areas", "grid-template-columns",
"grid-template-rows", "hanging-punctuation", "height", "hyphens",
"icon", "image-orientation", "image-rendering", "image-resolution",
"inline-box-align", "justify-content", "justify-items", "justify-self", "left", "letter-spacing",
"line-break", "line-height", "line-stacking", "line-stacking-ruby",
"border-image-width", "border-left", "border-left-color", "border-left-style",
"border-left-width", "border-radius", "border-right", "border-right-color",
"border-right-style", "border-right-width", "border-spacing", "border-style",
"border-top", "border-top-color", "border-top-left-radius",
"border-top-right-radius", "border-top-style", "border-top-width",
"border-width", "bottom", "box-decoration-break", "box-shadow", "box-sizing",
"break-after", "break-before", "break-inside", "caption-side", "caret-color",
"clear", "clip", "color", "color-profile", "column-count", "column-fill",
"column-gap", "column-rule", "column-rule-color", "column-rule-style",
"column-rule-width", "column-span", "column-width", "columns", "contain",
"content", "counter-increment", "counter-reset", "crop", "cue", "cue-after",
"cue-before", "cursor", "direction", "display", "dominant-baseline",
"drop-initial-after-adjust", "drop-initial-after-align",
"drop-initial-before-adjust", "drop-initial-before-align", "drop-initial-size",
"drop-initial-value", "elevation", "empty-cells", "fit", "fit-position",
"flex", "flex-basis", "flex-direction", "flex-flow", "flex-grow",
"flex-shrink", "flex-wrap", "float", "float-offset", "flow-from", "flow-into",
"font", "font-family", "font-feature-settings", "font-kerning",
"font-language-override", "font-optical-sizing", "font-size",
"font-size-adjust", "font-stretch", "font-style", "font-synthesis",
"font-variant", "font-variant-alternates", "font-variant-caps",
"font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric",
"font-variant-position", "font-variation-settings", "font-weight", "gap",
"grid", "grid-area", "grid-auto-columns", "grid-auto-flow", "grid-auto-rows",
"grid-column", "grid-column-end", "grid-column-gap", "grid-column-start",
"grid-gap", "grid-row", "grid-row-end", "grid-row-gap", "grid-row-start",
"grid-template", "grid-template-areas", "grid-template-columns",
"grid-template-rows", "hanging-punctuation", "height", "hyphens", "icon",
"image-orientation", "image-rendering", "image-resolution", "inline-box-align",
"inset", "inset-block", "inset-block-end", "inset-block-start", "inset-inline",
"inset-inline-end", "inset-inline-start", "isolation", "justify-content",
"justify-items", "justify-self", "left", "letter-spacing", "line-break",
"line-height", "line-height-step", "line-stacking", "line-stacking-ruby",
"line-stacking-shift", "line-stacking-strategy", "list-style",
"list-style-image", "list-style-position", "list-style-type", "margin",
"margin-bottom", "margin-left", "margin-right", "margin-top",
"marks", "marquee-direction", "marquee-loop",
"marquee-play-count", "marquee-speed", "marquee-style", "max-height",
"max-width", "min-height", "min-width", "mix-blend-mode", "move-to", "nav-down", "nav-index",
"nav-left", "nav-right", "nav-up", "object-fit", "object-position",
"opacity", "order", "orphans", "outline",
"outline-color", "outline-offset", "outline-style", "outline-width",
"overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
"padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
"page", "page-break-after", "page-break-before", "page-break-inside",
"page-policy", "pause", "pause-after", "pause-before", "perspective",
"perspective-origin", "pitch", "pitch-range", "place-content", "place-items", "place-self", "play-during", "position",
"presentation-level", "punctuation-trim", "quotes", "region-break-after",
"region-break-before", "region-break-inside", "region-fragment",
"rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
"right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
"ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin",
"shape-outside", "size", "speak", "speak-as", "speak-header",
"speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
"tab-size", "table-layout", "target", "target-name", "target-new",
"target-position", "text-align", "text-align-last", "text-decoration",
"margin-bottom", "margin-left", "margin-right", "margin-top", "marks",
"marquee-direction", "marquee-loop", "marquee-play-count", "marquee-speed",
"marquee-style", "mask-clip", "mask-composite", "mask-image", "mask-mode",
"mask-origin", "mask-position", "mask-repeat", "mask-size","mask-type",
"max-block-size", "max-height", "max-inline-size",
"max-width", "min-block-size", "min-height", "min-inline-size", "min-width",
"mix-blend-mode", "move-to", "nav-down", "nav-index", "nav-left", "nav-right",
"nav-up", "object-fit", "object-position", "offset", "offset-anchor",
"offset-distance", "offset-path", "offset-position", "offset-rotate",
"opacity", "order", "orphans", "outline", "outline-color", "outline-offset",
"outline-style", "outline-width", "overflow", "overflow-style",
"overflow-wrap", "overflow-x", "overflow-y", "padding", "padding-bottom",
"padding-left", "padding-right", "padding-top", "page", "page-break-after",
"page-break-before", "page-break-inside", "page-policy", "pause",
"pause-after", "pause-before", "perspective", "perspective-origin", "pitch",
"pitch-range", "place-content", "place-items", "place-self", "play-during",
"position", "presentation-level", "punctuation-trim", "quotes",
"region-break-after", "region-break-before", "region-break-inside",
"region-fragment", "rendering-intent", "resize", "rest", "rest-after",
"rest-before", "richness", "right", "rotate", "rotation", "rotation-point",
"row-gap", "ruby-align", "ruby-overhang", "ruby-position", "ruby-span",
"scale", "scroll-behavior", "scroll-margin", "scroll-margin-block",
"scroll-margin-block-end", "scroll-margin-block-start", "scroll-margin-bottom",
"scroll-margin-inline", "scroll-margin-inline-end",
"scroll-margin-inline-start", "scroll-margin-left", "scroll-margin-right",
"scroll-margin-top", "scroll-padding", "scroll-padding-block",
"scroll-padding-block-end", "scroll-padding-block-start",
"scroll-padding-bottom", "scroll-padding-inline", "scroll-padding-inline-end",
"scroll-padding-inline-start", "scroll-padding-left", "scroll-padding-right",
"scroll-padding-top", "scroll-snap-align", "scroll-snap-type",
"shape-image-threshold", "shape-inside", "shape-margin", "shape-outside",
"size", "speak", "speak-as", "speak-header", "speak-numeral",
"speak-punctuation", "speech-rate", "stress", "string-set", "tab-size",
"table-layout", "target", "target-name", "target-new", "target-position",
"text-align", "text-align-last", "text-combine-upright", "text-decoration",
"text-decoration-color", "text-decoration-line", "text-decoration-skip",
"text-decoration-style", "text-emphasis", "text-emphasis-color",
"text-emphasis-position", "text-emphasis-style", "text-height",
"text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
"text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
"text-wrap", "top", "transform", "transform-origin", "transform-style",
"transition", "transition-delay", "transition-duration",
"transition-property", "transition-timing-function", "unicode-bidi",
"user-select", "vertical-align", "visibility", "voice-balance", "voice-duration",
"voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
"voice-volume", "volume", "white-space", "widows", "width", "will-change", "word-break",
"word-spacing", "word-wrap", "z-index",
"text-decoration-skip-ink", "text-decoration-style", "text-emphasis",
"text-emphasis-color", "text-emphasis-position", "text-emphasis-style",
"text-height", "text-indent", "text-justify", "text-orientation",
"text-outline", "text-overflow", "text-rendering", "text-shadow",
"text-size-adjust", "text-space-collapse", "text-transform",
"text-underline-position", "text-wrap", "top", "touch-action", "transform", "transform-origin",
"transform-style", "transition", "transition-delay", "transition-duration",
"transition-property", "transition-timing-function", "translate",
"unicode-bidi", "user-select", "vertical-align", "visibility", "voice-balance",
"voice-duration", "voice-family", "voice-pitch", "voice-range", "voice-rate",
"voice-stress", "voice-volume", "volume", "white-space", "widows", "width",
"will-change", "word-break", "word-spacing", "word-wrap", "writing-mode", "z-index",
// SVG-specific
"clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
"flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
"color-interpolation", "color-interpolation-filters",
"color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
"marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke",
"marker", "marker-end", "marker-mid", "marker-start", "paint-order", "shape-rendering", "stroke",
"stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
"stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
"baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
"glyph-orientation-vertical", "text-anchor", "writing-mode"
"glyph-orientation-vertical", "text-anchor", "writing-mode",
], propertyKeywords = keySet(propertyKeywords_);
var nonStandardPropertyKeywords_ = [
"border-block", "border-block-color", "border-block-end",
"border-block-end-color", "border-block-end-style", "border-block-end-width",
"border-block-start", "border-block-start-color", "border-block-start-style",
"border-block-start-width", "border-block-style", "border-block-width",
"border-inline", "border-inline-color", "border-inline-end",
"border-inline-end-color", "border-inline-end-style",
"border-inline-end-width", "border-inline-start", "border-inline-start-color",
"border-inline-start-style", "border-inline-start-width",
"border-inline-style", "border-inline-width", "margin-block",
"margin-block-end", "margin-block-start", "margin-inline", "margin-inline-end",
"margin-inline-start", "padding-block", "padding-block-end",
"padding-block-start", "padding-inline", "padding-inline-end",
"padding-inline-start", "scroll-snap-stop", "scrollbar-3d-light-color",
"scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
"scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
"scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside",
"searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
"searchfield-results-decoration", "zoom"
"scrollbar-track-color", "searchfield-cancel-button", "searchfield-decoration",
"searchfield-results-button", "searchfield-results-decoration", "shape-inside", "zoom"
], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
var fontProperties_ = [
"font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
"font-stretch", "font-weight", "font-style"
"font-display", "font-family", "src", "unicode-range", "font-variant",
"font-feature-settings", "font-stretch", "font-weight", "font-style"
], fontProperties = keySet(fontProperties_);
var counterDescriptors_ = [
@ -594,7 +626,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate",
"always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
"arabic-indic", "armenian", "asterisks", "attr", "auto", "auto-flow", "avoid", "avoid-column", "avoid-page",
"avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
"avoid-region", "axis-pan", "background", "backwards", "baseline", "below", "bidi-override", "binary",
"bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
"both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel",
"buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian",
@ -618,7 +650,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
"ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig",
"ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed",
"extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes",
"extra-expanded", "fantasy", "fast", "fill", "fill-box", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes",
"forwards", "from", "geometricPrecision", "georgian", "graytext", "grid", "groove",
"gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew",
"help", "hidden", "hide", "higher", "highlight", "highlighttext",
@ -633,7 +665,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem",
"local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
"lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
"lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "match", "matrix", "matrix3d",
"lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "manipulation", "match", "matrix", "matrix3d",
"media-controls-background", "media-current-time-display",
"media-fullscreen-button", "media-mute-button", "media-play-button",
"media-return-to-realtime-button", "media-rewind-button",
@ -642,13 +674,13 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"media-volume-slider-container", "media-volume-sliderthumb", "medium",
"menu", "menulist", "menulist-button", "menulist-text",
"menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
"mix", "mongolian", "monospace", "move", "multiple", "multiply", "myanmar", "n-resize",
"mix", "mongolian", "monospace", "move", "multiple", "multiple_mask_images", "multiply", "myanmar", "n-resize",
"narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
"no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
"ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "opacity", "open-quote",
"optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
"outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
"painted", "page", "paused", "persian", "perspective", "plus-darker", "plus-lighter",
"painted", "page", "paused", "persian", "perspective", "pinch-zoom", "plus-darker", "plus-lighter",
"pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d",
"progress", "push-button", "radial-gradient", "radio", "read-only",
"read-write", "read-write-plaintext-only", "rectangle", "region",
@ -666,8 +698,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
"small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali",
"source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "space-evenly", "spell-out", "square",
"square-button", "start", "static", "status-bar", "stretch", "stroke", "sub",
"subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "system-ui", "table",
"square-button", "start", "static", "status-bar", "stretch", "stroke", "stroke-box", "sub",
"subpixel-antialiased", "svg_masks", "super", "sw-resize", "symbolic", "symbols", "system-ui", "table",
"table-caption", "table-cell", "table-column", "table-column-group",
"table-footer-group", "table-header-group", "table-row", "table-row-group",
"tamil",
@ -677,10 +709,10 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
"trad-chinese-formal", "trad-chinese-informal", "transform",
"translate", "translate3d", "translateX", "translateY", "translateZ",
"transparent", "ultra-condensed", "ultra-expanded", "underline", "unset", "up",
"transparent", "ultra-condensed", "ultra-expanded", "underline", "unidirectional-pan", "unset", "up",
"upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
"upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
"var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
"var", "vertical", "vertical-text", "view-box", "visible", "visibleFill", "visiblePainted",
"visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
"window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor",
"xx-large", "xx-small"

View File

@ -13,7 +13,7 @@
<script src="../../addon/hint/css-hint.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -12,7 +12,7 @@
<script src="../../addon/hint/css-hint.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -10,7 +10,7 @@
<script src="css.js"></script>
<style>.CodeMirror {border: 1px solid #ddd; line-height: 1.2;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -10,7 +10,7 @@
<script src="css.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -46,7 +46,7 @@
var word = stream.current();
if (funcs.test(word)) return "builtin";
if (preds.test(word)) return "def";
if (keywords.test(word)) return "keyword";
if (keywords.test(word) || systemKeywords.test(word)) return "keyword";
return "variable";
}
};
@ -67,6 +67,7 @@
var funcs = wordRegexp(["abs", "acos", "allShortestPaths", "asin", "atan", "atan2", "avg", "ceil", "coalesce", "collect", "cos", "cot", "count", "degrees", "e", "endnode", "exp", "extract", "filter", "floor", "haversin", "head", "id", "keys", "labels", "last", "left", "length", "log", "log10", "lower", "ltrim", "max", "min", "node", "nodes", "percentileCont", "percentileDisc", "pi", "radians", "rand", "range", "reduce", "rel", "relationship", "relationships", "replace", "reverse", "right", "round", "rtrim", "shortestPath", "sign", "sin", "size", "split", "sqrt", "startnode", "stdev", "stdevp", "str", "substring", "sum", "tail", "tan", "timestamp", "toFloat", "toInt", "toString", "trim", "type", "upper"]);
var preds = wordRegexp(["all", "and", "any", "contains", "exists", "has", "in", "none", "not", "or", "single", "xor"]);
var keywords = wordRegexp(["as", "asc", "ascending", "assert", "by", "case", "commit", "constraint", "create", "csv", "cypher", "delete", "desc", "descending", "detach", "distinct", "drop", "else", "end", "ends", "explain", "false", "fieldterminator", "foreach", "from", "headers", "in", "index", "is", "join", "limit", "load", "match", "merge", "null", "on", "optional", "order", "periodic", "profile", "remove", "return", "scan", "set", "skip", "start", "starts", "then", "true", "union", "unique", "unwind", "using", "when", "where", "with", "call", "yield"]);
var systemKeywords = wordRegexp(["access", "active", "assign", "all", "alter", "as", "catalog", "change", "copy", "create", "constraint", "constraints", "current", "database", "databases", "dbms", "default", "deny", "drop", "element", "elements", "exists", "from", "grant", "graph", "graphs", "if", "index", "indexes", "label", "labels", "management", "match", "name", "names", "new", "node", "nodes", "not", "of", "on", "or", "password", "populated", "privileges", "property", "read", "relationship", "relationships", "remove", "replace", "required", "revoke", "role", "roles", "set", "show", "start", "status", "stop", "suspended", "to", "traverse", "type", "types", "user", "users", "with", "write"]);
var operatorChars = /[*+\-<>=&|~%^]/;
return {

View File

@ -16,7 +16,7 @@
}
</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -10,7 +10,7 @@
<script src="d.js"></script>
<style>.CodeMirror {border: 2px inset #dee;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -15,10 +15,10 @@
"implements mixin get native set typedef with enum throw rethrow " +
"assert break case continue default in return new deferred async await covariant " +
"try catch finally do else for if switch while import library export " +
"part of show hide is as").split(" ");
"part of show hide is as extension on yield late required").split(" ");
var blockKeywords = "try catch finally do else for if switch while".split(" ");
var atoms = "true false null".split(" ");
var builtins = "void bool num int double dynamic var String".split(" ");
var builtins = "void bool num int double dynamic var String Null Never".split(" ");
function set(words) {
var obj = {};
@ -78,6 +78,15 @@
if (!stream.eat("*")) return false
state.tokenize = tokenNestedComment(1)
return state.tokenize(stream, state)
},
token: function(stream, _, style) {
if (style == "variable") {
// Assume uppercase symbols are classes using variable-2
var isUpper = RegExp('^[_$]*[A-Z][a-zA-Z0-9_$]*$','g');
if (isUpper.test(stream.current())) {
return 'variable-2';
}
}
}
}
});

View File

@ -9,7 +9,7 @@
<script src="dart.js"></script>
<style>.CodeMirror {border: 1px solid #dee;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -15,7 +15,7 @@
span.cm-error.cm-tag { background-color: #2b2; }
</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -13,7 +13,7 @@
<script src="django.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -10,7 +10,7 @@
<script src="dockerfile.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -9,7 +9,7 @@
<script src="dtd.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -12,7 +12,7 @@
<script src="dylan.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -13,7 +13,7 @@
</head>
<body>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -9,7 +9,7 @@
<script src="ecl.js"></script>
<style>.CodeMirror {border: 1px solid black;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -13,7 +13,7 @@
.cm-s-default span.cm-arrow { color: red; }
</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@ -13,189 +13,227 @@
CodeMirror.defineMode("elm", function() {
function switchState(source, setState, f) {
function switchState(source, setState, f)
{
setState(f);
return f(source, setState);
}
// These should all be Unicode extended, as per the Haskell 2010 report
var smallRE = /[a-z_]/;
var largeRE = /[A-Z]/;
var lowerRE = /[a-z]/;
var upperRE = /[A-Z]/;
var innerRE = /[a-zA-Z0-9_]/;
var digitRE = /[0-9]/;
var hexitRE = /[0-9A-Fa-f]/;
var octitRE = /[0-7]/;
var idRE = /[a-z_A-Z0-9\']/;
var symbolRE = /[-!#$%&*+.\/<=>?@\\^|~:\u03BB\u2192]/;
var specialRE = /[(),;[\]`{}]/;
var whiteCharRE = /[ \t\v\f]/; // newlines are handled in tokenizer
var hexRE = /[0-9A-Fa-f]/;
var symbolRE = /[-&*+.\\/<>=?^|:]/;
var specialRE = /[(),[\]{}]/;
var spacesRE = /[ \v\f]/; // newlines are handled in tokenizer
function normal() {
return function (source, setState) {
if (source.eatWhile(whiteCharRE)) {
function normal()
{
return function(source, setState)
{
if (source.eatWhile(spacesRE))
{
return null;
}
var ch = source.next();
if (specialRE.test(ch)) {
if (ch == '{' && source.eat('-')) {
var t = "comment";
if (source.eat('#')) t = "meta";
return switchState(source, setState, ncomment(t, 1));
}
return null;
var char = source.next();
if (specialRE.test(char))
{
return (char === '{' && source.eat('-'))
? switchState(source, setState, chompMultiComment(1))
: (char === '[' && source.match('glsl|'))
? switchState(source, setState, chompGlsl)
: 'builtin';
}
if (ch == '\'') {
if (source.eat('\\'))
source.next(); // should handle other escapes here
else
source.next();
if (source.eat('\''))
return "string";
return "error";
if (char === '\'')
{
return switchState(source, setState, chompChar);
}
if (ch == '"') {
return switchState(source, setState, stringLiteral);
if (char === '"')
{
return source.eat('"')
? source.eat('"')
? switchState(source, setState, chompMultiString)
: 'string'
: switchState(source, setState, chompSingleString);
}
if (largeRE.test(ch)) {
source.eatWhile(idRE);
if (source.eat('.'))
return "qualifier";
return "variable-2";
if (upperRE.test(char))
{
source.eatWhile(innerRE);
return 'variable-2';
}
if (smallRE.test(ch)) {
if (lowerRE.test(char))
{
var isDef = source.pos === 1;
source.eatWhile(idRE);
return isDef ? "type" : "variable";
source.eatWhile(innerRE);
return isDef ? "def" : "variable";
}
if (digitRE.test(ch)) {
if (ch == '0') {
if (source.eat(/[xX]/)) {
source.eatWhile(hexitRE); // should require at least 1
return "integer";
}
if (source.eat(/[oO]/)) {
source.eatWhile(octitRE); // should require at least 1
if (digitRE.test(char))
{
if (char === '0')
{
if (source.eat(/[xX]/))
{
source.eatWhile(hexRE); // should require at least 1
return "number";
}
}
source.eatWhile(digitRE);
var t = "number";
if (source.eat('.')) {
t = "number";
else
{
source.eatWhile(digitRE);
}
if (source.eat('.'))
{
source.eatWhile(digitRE); // should require at least 1
}
if (source.eat(/[eE]/)) {
t = "number";
if (source.eat(/[eE]/))
{
source.eat(/[-+]/);
source.eatWhile(digitRE); // should require at least 1
}
return t;
return "number";
}
if (symbolRE.test(ch)) {
if (ch == '-' && source.eat(/-/)) {
source.eatWhile(/-/);
if (!source.eat(symbolRE)) {
source.skipToEnd();
return "comment";
}
if (symbolRE.test(char))
{
if (char === '-' && source.eat('-'))
{
source.skipToEnd();
return "comment";
}
source.eatWhile(symbolRE);
return "builtin";
return "keyword";
}
if (char === '_')
{
return "keyword";
}
return "error";
}
}
function ncomment(type, nest) {
if (nest == 0) {
function chompMultiComment(nest)
{
if (nest == 0)
{
return normal();
}
return function(source, setState) {
var currNest = nest;
while (!source.eol()) {
var ch = source.next();
if (ch == '{' && source.eat('-')) {
++currNest;
} else if (ch == '-' && source.eat('}')) {
--currNest;
if (currNest == 0) {
return function(source, setState)
{
while (!source.eol())
{
var char = source.next();
if (char == '{' && source.eat('-'))
{
++nest;
}
else if (char == '-' && source.eat('}'))
{
--nest;
if (nest === 0)
{
setState(normal());
return type;
return 'comment';
}
}
}
setState(ncomment(type, currNest));
return type;
setState(chompMultiComment(nest));
return 'comment';
}
}
function stringLiteral(source, setState) {
while (!source.eol()) {
var ch = source.next();
if (ch == '"') {
function chompMultiString(source, setState)
{
while (!source.eol())
{
var char = source.next();
if (char === '"' && source.eat('"') && source.eat('"'))
{
setState(normal());
return "string";
}
if (ch == '\\') {
if (source.eol() || source.eat(whiteCharRE)) {
setState(stringGap);
return "string";
}
if (!source.eat('&')) source.next(); // should handle other escapes here
return 'string';
}
}
setState(normal());
return "error";
return 'string';
}
function stringGap(source, setState) {
if (source.eat('\\')) {
return switchState(source, setState, stringLiteral);
function chompSingleString(source, setState)
{
while (source.skipTo('\\"')) { source.next(); source.next(); }
if (source.skipTo('"'))
{
source.next();
setState(normal());
return 'string';
}
source.next();
source.skipToEnd();
setState(normal());
return "error";
return 'error';
}
function chompChar(source, setState)
{
while (source.skipTo("\\'")) { source.next(); source.next(); }
if (source.skipTo("'"))
{
source.next();
setState(normal());
return 'string';
}
source.skipToEnd();
setState(normal());
return 'error';
}
var wellKnownWords = (function() {
var wkw = {};
var keywords = [
"case", "of", "as",
"if", "then", "else",
"let", "in",
"infix", "infixl", "infixr",
"type", "alias",
"input", "output", "foreign", "loopback",
"module", "where", "import", "exposing",
"_", "..", "|", ":", "=", "\\", "\"", "->", "<-"
];
for (var i = keywords.length; i--;)
wkw[keywords[i]] = "keyword";
return wkw;
})();
function chompGlsl(source, setState)
{
while (!source.eol())
{
var char = source.next();
if (char === '|' && source.eat(']'))
{
setState(normal());
return 'string';
}
}
return 'string';
}
var wellKnownWords = {
case: 1,
of: 1,
as: 1,
if: 1,
then: 1,
else: 1,
let: 1,
in: 1,
type: 1,
alias: 1,
module: 1,
where: 1,
import: 1,
exposing: 1,
port: 1
};
return {
startState: function () { return { f: normal() }; },
copyState: function (s) { return { f: s.f }; },
token: function(stream, state) {
var t = state.f(stream, function(s) { state.f = s; });
var w = stream.current();
return (wellKnownWords.hasOwnProperty(w)) ? wellKnownWords[w] : t;
var type = state.f(stream, function(s) { state.f = s; });
var word = stream.current();
return (wellKnownWords.hasOwnProperty(word)) ? 'keyword' : type;
}
};

View File

@ -9,7 +9,7 @@
<script src="elm.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -11,7 +11,7 @@
<script src="erlang.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -16,7 +16,7 @@
}
</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -11,7 +11,7 @@
<script src="fcl.js"></script>
<style>.CodeMirror {border:1px solid #999; background:#ffc}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -16,7 +16,7 @@
}
</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -9,7 +9,7 @@
<script src="fortran.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -9,7 +9,7 @@
<script src="gas.js"></script>
<style>.CodeMirror {border: 2px inset #dee;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -20,7 +20,7 @@
.cm-s-default .cm-emoji {color: #009688;}
</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -9,7 +9,7 @@
<script src="gherkin.js"></script>
<style>.CodeMirror { border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; }</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -11,7 +11,7 @@
<script src="go.js"></script>
<style>.CodeMirror {border:1px solid #999; background:#ffc}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -10,7 +10,7 @@
<script src="groovy.js"></script>
<style>.CodeMirror {border-top: 1px solid #500; border-bottom: 1px solid #500;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -13,7 +13,7 @@
<script src="haml.js"></script>
<style>.CodeMirror {background: #f8f8f8;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -13,10 +13,14 @@
CodeMirror.defineSimpleMode("handlebars-tags", {
start: [
{ regex: /\{\{\{/, push: "handlebars_raw", token: "tag" },
{ regex: /\{\{!--/, push: "dash_comment", token: "comment" },
{ regex: /\{\{!/, push: "comment", token: "comment" },
{ regex: /\{\{/, push: "handlebars", token: "tag" }
],
handlebars_raw: [
{ regex: /\}\}\}/, pop: true, token: "tag" },
],
handlebars: [
{ regex: /\}\}/, pop: true, token: "tag" },
@ -58,7 +62,7 @@
if (!parserConfig || !parserConfig.base) return handlebars;
return CodeMirror.multiplexingMode(
CodeMirror.getMode(config, parserConfig.base),
{open: "{{", close: "}}", mode: handlebars, parseDelimiters: true}
{open: "{{", close: /\}\}\}?/, mode: handlebars, parseDelimiters: true}
);
});

View File

@ -13,7 +13,7 @@
<script src="handlebars.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>
@ -41,6 +41,8 @@
{{! one line comment }}
{{{propertyContainingRawHtml}}}
{{#each articles}}
{{~title}}
<p>{{excerpt body size=120 ellipsis=true}}</p>

View File

@ -11,7 +11,7 @@
<script src="haskell.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -9,7 +9,7 @@
<script src="haxe.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -14,7 +14,7 @@
<script src="htmlembedded.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -14,7 +14,7 @@
<script src="htmlmixed.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -9,7 +9,7 @@
<script src="http.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -10,7 +10,7 @@
<script src="idl.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

View File

@ -12,7 +12,7 @@
<script src="javascript.js"></script>
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
<div id=nav>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
<a href="https://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
<ul>
<li><a href="../../index.html">Home</a>

Some files were not shown because too many files have changed in this diff Show More