update codemirror

This commit is contained in:
fofolee 2020-06-11 10:28:10 +08:00
parent dd3b7818e9
commit c54c3d0138
347 changed files with 4129 additions and 5171 deletions

View File

@ -1,477 +0,0 @@
#out {
padding: 0px 10px;
font-size: 13px;
line-height: 26px;
font-family: Monaco, consolas;
white-space: pre-wrap;
}
#options {
font-size: 15px;
color: #595959;
font-family: consolas, monaco, "微软雅黑";
padding-bottom: 30px;
}
#options * {
box-sizing: border-box;
}
#options .switch-btn {
position: relative;
display: inline-block;
vertical-align: top;
width: 80px;
height: 30px;
border-radius: 5px;
cursor: pointer;
zoom: 0.7;
}
#options .checked-switch {
position: absolute;
top: 0;
left: 0;
opacity: 0;
}
#options .text-switch {
background-color: #cccccc;
border: 1px solid #dddddd;
border-radius: inherit;
color: #fff;
display: block;
font-size: 15px;
width: 60px;
height: inherit;
position: relative;
text-transform: uppercase;
}
#options .text-switch:before,
#options .text-switch:after {
position: absolute;
top: 50%;
margin-top: -.5em;
line-height: 1;
-webkit-transition: inherit;
-moz-transition: inherit;
-o-transition: inherit;
transition: inherit;
}
#options .text-switch:before {
content: 'OF';
right: 6px;
}
#options .text-switch:after {
content: 'ON';
left: 6px;
color: #FFFFFF;
opacity: 0;
}
#options .checked-switch:checked~.text-switch {
background-color: #00af2c;
border: 1px solid #068506;
}
#options .checked-switch:disabled~.text-switch {
cursor: no-drop;
}
#options .checked-switch:disabled~.text-switch~.toggle-btn {
cursor: no-drop;
}
#options .checked-switch:disabled~.text-switch:before {
content: '▬';
right: 11px;
}
#options .checked-switch:checked~.text-switch:before {
opacity: 0;
}
#options .checked-switch:checked~.text-switch:after {
opacity: 1;
}
#options .toggle-btn {
background: linear-gradient(#eee, #fafafa);
border-radius: 5px;
height: 28px;
left: 1px;
position: absolute;
top: 1px;
width: 28px;
}
#options .checked-switch:checked~.toggle-btn {
left: 30px;
}
#options .text-switch,
#options .toggle-btn {
transition: All 0.3s ease;
-webkit-transition: All 0.3s ease;
-moz-transition: All 0.3s ease;
-o-transition: All 0.3s ease;
}
#options .no-radius,
#options .no-radius .toggle-btn {
border-radius: 0;
}
#options .circle-style .toggle-btn::before {
background: linear-gradient(#dedede, #cacaca);
border-radius: 50%;
content: "";
height: 14px;
margin-top: 6px;
padding: 0;
width: 14px;
}
#options table {
border-collapse: collapse;
table-layout:fixed;
width: 100%;
}
#options table td {
border-collapse: collapse;
padding: 3px;
margin-right: 15px;
word-break:keep-all;
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
}
#options table tr:nth-child(odd) {
background-color: #fff !important;
}
#options table tr:nth-child(even) {
background-color: #f8f8f8 !important;
}
#options .keyword {
display: inline-block;
font-size: 14px;
color: #333;
border: 1px solid #eee;
border-radius: 12px;
height: 24px;
line-height: 22px;
padding: 0 10px;
background-color: #f3f3f3;
margin-right: 5px;
}
#options .keyword.re {
color: rgb(105, 40, 97);
}
#options .keyword.win {
color: rgb(48, 21, 122);
}
#options .logo {
width: 32px;
}
#options #customize .keys{
width: 16%;
}
#options #customize .robot.footBtn{
background:#3085d6;
float: none;
}
#options #customize .robot.footBtn:hover{
background:#55aafa;
}
#options .footBtn {
/* right: 5px;
bottom: 2px; */
float: right;
background: #00af2c;
border-radius: 4px;
color: white;
padding: 2px 5px;
margin: 0px 5px;
cursor: pointer;
}
#options .footBtn.danger {
float: left;
/* right: 5px;
bottom: 2px; */
border-radius: 4px;
background: #df3f54;
color: white;
padding: 2px 5px;
margin: 0px 5px;
cursor: pointer;
}
#options .footBtn:hover {
background: #068506;
transition: 0.5s;
}
#options .footBtn.danger:hover {
background: #b32033;
transition: 0.5s;
}
#options .foot {
position: fixed;
height: 30px;
right: 0px;
bottom: 0px;
left: 0px;
background: #f3f3f3;
box-shadow: 0px 0px 9px 0px #00000030;
padding: 3px;
}
#options td span {
margin-right: 10px;
}
#options span.Btn {
font-size: 16px;
cursor: pointer;
}
#options span.Btn img {
height: 20px;
}
#options span.editBtn {
color: #00af2c;
}
#options span.exportBtn {
color: #407abf;
}
#options span.delBtn {
color: #ed5b49
}
#options span.editBtn:hover {
color: #057205;
}
#options span.exportBtn:hover {
color: #2d5586;
}
#options span.delBtn:hover {
color: #bd3523;
}
#options #customize input.customscript {
margin-left: 5px;
width: 20%;
display: none;
}
#options #customize {
position: fixed;
z-index: 999;
height: 100%;
top: 100%;
left: 0;
right: 0;
padding: 0px 30px;
box-shadow: 0px 0px 9px 0px #00000030;
color: black;
background: white;
}
#options .varoutput{
display: none;
}
#options #customize p {
line-height: 1.25rem;
}
#options #customize .word {
color: #2196F3;
display: inline-block;
font-size: 14px;
border: 1px solid #1E88E5;
height: 24px;
line-height: 22px;
padding: 0 5px;
background-color: #E3F2FD;
}
#options #customize input {
width: 90%;
height: 25px;
border-bottom: 1px solid #dbdbdb;
border-top: 0px;
border-left: 0px;
border-right: 0px;
font-size: 15px;
margin-left: 13px
}
#options #customize input#rule {
width: 40%;
}
#options #customize input:hover {
border-bottom-color: #9e9e9ec7;
transition: 0.25s;
}
#options #customize input:focus {
outline: none;
border-bottom-color: #0277BD;
transition: 0.5s;
}
input::-webkit-input-placeholder {
color: #999;
font-size: 15px
}
#options #customize .CodeMirror {
font-size: 13px;
font-family: "Monaco", "consolas";
width: 100%;
height: 23rem;
border: 1px solid #dbdbdb;
border-radius: 3px;
}
#options #customize .CodeMirror:hover {
border: 1px solid #9e9e9ec7;
transition: 0.25s;
}
#options #customize .CodeMirror-focused {
border: 1px solid #0277BD !important;
box-shadow: 0px 0px 2px 0px #0277BD;
transition: 0.25s;
}
#options #customize .CodeMirror-placeholder {
color: #999;
font-size: 15px
}
#options #customize select {
width: 40%;
height: 25px;
margin-left: 3px;
border-bottom: 1px solid #dbdbdb;
border-top: 0px;
border-left: 0px;
border-right: 0px;
background-color: #ffffff;
border-radius: 0px;
outline: none;
font-size: 15px;
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAJAgMAAAB71iXHAAAADFBMVEUAAAAqPz8rN0csOEgGlpD7AAAAA3RSTlMABvwYJ91vAAAAGklEQVQI12OAgQNAaMDMwMAjw8DAVAAWgAEAPFADDsXseo4AAAAASUVORK5CYII=") no-repeat scroll right center transparent;
-webkit-appearance: none
}
#options #customize select:hover {
border-bottom-color: #9e9e9ec7;
transition: 0.25s;
}
#options #customize select:focus {
border-bottom-color: #0277BD;
transition: 0.5s;
}
#options #customize select#vars,#action {
color: #999;
}
#options #customize select option {
color: black;
}
#options #customize select option.var {
display: none;
color: rgb(129, 76, 226);
}
#options #customize input#iconame {
width: 35%;
cursor: pointer;
}
#options #customize #icon {
float: right;
width: 28px;
cursor: pointer;
}
#options #customize .selectBtn {
padding: 4px 10px;
font-size: 11px;
color: #1E88C7;
background: #D0EEFF;
border: 1px solid #99D3F5;
border-radius: 4px;
cursor: pointer;
}
#options #customize .selectBtn:hover {
background: #AADFFD;
border-color: #78C3F3;
color: #004974;
transition: 0.5s;
}
#options #customize button {
width: 150px;
height: 30px;
border-width: 0px;
border-radius: 3px;
cursor: pointer;
outline: none;
color: white;
}
#options #customize button.cancelBtn {
float: right;
margin-right: 30px;
background: #808080c9;
}
#options #customize button.saveBtn {
float: right;
background: #1E90FF;
}
#options #customize button.saveBtn:hover {
background: #5599FF;
transition: 0.5s;
}
#options #customize button.cancelBtn:hover {
background: #a5a2a2c9;
transition: 0.5s;
}
::-webkit-scrollbar {
height: 0;
}

View File

View File

View File

@ -20,6 +20,7 @@ aeroson
Ahmad Amireh
Ahmad M. Zawawi
ahoward
Ajin Abraham
Akeksandr Motsjonov
Alasdair Smith
AlbertHilb
@ -31,6 +32,7 @@ Alexander Schepanovski
Alexander Shvets
Alexander Solovyov
Alexandre Bique
Alex Churchill
alexey-k
Alex Piggott
Aliaksei Chapyzhenka
@ -72,11 +74,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 +99,9 @@ Bastian Müller
belhaj
Bem Jones-Bey
benbro
Benedikt Meurer
benhormann
Ben Hormann
Beni Cherniavsky-Paskin
Benjamin DeCoste
Benjamin Young
@ -115,21 +122,26 @@ 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
Bruno Logerfo
Bryan Gin-ge Chen
Bryan Massoth
Caitlin Potter
Calin Barbat
callodacity
Camilo Roca
Casey Klebba
cBiscuit87
César González Íñiguez
Chad Jolly
Chandra Sekhar Pydi
@ -156,6 +168,7 @@ Christopher Pfohl
Christopher Wallis
Chunliang Lyu
ciaranj
clone-it
clso
CodeAnimal
CodeBitt
@ -165,6 +178,7 @@ ComFreek
Cristian Prieto
Curran Kelleher
Curtis Gagliardi
d8888
dagsta
daines
Dale Jung
@ -192,16 +206,20 @@ David Barnett
David H. Bronke
David Mignot
David Pathakjee
David Rodrigues
David Santana
David Vázquez
David Whittington
deebugger
Deep Thought
Denis Ovsienko
Devin Abbott
Devon Carew
Dick Choi
Diego Fernandez
dignifiedquire
Dimage Sapelkin
Dinindu D. Wanniarachchi
dmaclach
Dmitry Kiselyov
domagoj412
@ -214,12 +232,15 @@ Drew Hintz
Drew Khoury
Drini Cami
Dror BG
Duncan Lilley
duralog
dwelle
eborden
edoroshenko
edsharp
ekhaled
Elisée
elpnt
Emmanuel Schanzer
Enam Mijbah Noor
Eric Allam
@ -227,6 +248,7 @@ Eric Bogard
Erik Demaine
Erik Welander
eustas
Evan Minsk
Fabien Dubosson
Fabien O'Carroll
Fabio Zendhi Nagao
@ -243,11 +265,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
@ -278,20 +302,24 @@ 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
Harald Schilly
Hardest
Harshvardhan Gupta
Hasan Delibaş
Hasan Karahan
Heanes
Hector Oswaldo Caballero
Hein Htat
Hélio
Hendrik Wallbaum
Henrik Haugbølle
@ -304,13 +332,17 @@ 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
Irakli Gozalishvili
Ivan Kurnosov
@ -322,6 +354,7 @@ Jakob Miland
Jakub Vrana
Jakub Vrána
James Campos
James Cockshull
James Howard
James Thorne
Jamie Hill
@ -344,6 +377,7 @@ Jason Johnston
Jason San Jose
Jason Siefken
Jayaprabhakar
Jay Contonio
Jaydeep Solanki
Jean Boussier
Jeff Blaisdell
@ -363,10 +397,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
@ -379,6 +416,7 @@ Jon Gacnik
jongalloway
Jon Malmaud
Jon Sangster
Joo
Joost-Wim Boekesteijn
Joseph Pecoraro
Josh Barnes
@ -403,6 +441,7 @@ karevn
Karol
Kayur Patel
Kazuhito Hokamura
kcwiakala
Kees de Kooter
Kenan Christian Dimas
Ken Newman
@ -422,6 +461,7 @@ koops
Kris Ciccarello
ks-ifware
kubelsmieci
kvncp
KwanEsq
Kyle Kelley
KyleMcNutt
@ -430,6 +470,7 @@ Lanfei
Lanny
laobubu
Laszlo Vidacs
leaf
leaf corcoran
Lemmon
Leo Baschy
@ -443,6 +484,7 @@ Lior Shub
LloydMilligan
LM
lochel
Lonnie Abelbeck
Lorenzo Simionato
Lorenzo Stoakes
Louis Mauchet
@ -473,6 +515,7 @@ Mário Gonçalves
Mario Pietsch
Mark Anderson
Mark Dalgleish
Mark Hamstra
Mark Lentczner
Marko Bonaci
Mark Peace
@ -491,11 +534,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
@ -505,10 +550,12 @@ Maximilian Hils
Maxim Kraev
Max Kirsch
Max Schaefer
Max Wu
Max Xiantu
mbarkhau
McBrainy
mce2
Mélanie Chauvel
melpon
meshuamam
Metatheos
@ -576,14 +623,20 @@ 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
oscar.lofwenhamn
Oskar Segersvärd
ossdev
overdodactyl
pablo
pabloferz
@ -596,6 +649,7 @@ paris
Paris
Paris Kasidiaris
Patil Arpith
Patrick Kettner
Patrick Stoica
Patrick Strawderman
Paul Garvin
@ -611,6 +665,7 @@ peter
Peter Flynn
peterkroon
Peter Kroon
Peter László
Philipp A
Philipp Markovics
Philip Stadermann
@ -621,6 +676,7 @@ Pontus Melke
prasanthj
Prasanth J
Prayag Verma
prendota
Prendota
Qiang Li
Radek Piórkowski
@ -634,6 +690,7 @@ Randy Luecke
Raphael Amorim
Rasmus Erik Voel Jensen
Rasmus Schultz
raymondf
Raymond Hill
ray ratchup
Ray Ratchup
@ -649,10 +706,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
@ -667,6 +728,7 @@ Sander Verweij
santec
Sarah McAlear and Wenlin Zhang
Sascha Peilicke
Sasha Varlamov
satamas
satchmorun
sathyamoorthi
@ -676,6 +738,7 @@ SCLINIC\jdecker
Scott Aikin
Scott Feeney
Scott Goodhew
Seb35
Sebastian Wilzbach
Sebastian Zaha
Seren D
@ -714,6 +777,7 @@ Stephen Lavelle
Steve Champagne
Steve Hoover
Steve O'Hara
stockiNail
stoskov
Stryder Crown
Stu Kennedy
@ -725,7 +789,9 @@ Tako Schotanus
Takuji Shimokawa
Takuya Matsuyama
Tarmil
T. Brandon Ashley
TDaglis
Teja
tel
Tentone
tfjgeorge
@ -741,9 +807,11 @@ thomasmaclean
Thomas Schmid
Tim Alby
Tim Baumann
Tim Gates
Timothy Farrell
Timothy Gu
Timothy Hatcher
Tim van der Lippe
Tobias Bertelsen
TobiasBg
Todd Berman
@ -765,9 +833,11 @@ TSUYUSATO Kitsune
Tugrul Elmas
twifkak
Tyler Long
Tyler Makaro
Vadim Dyachenko
Vadzim Ramanenka
Vaibhav Sagar
vamshi.revu
VapidWorx
Vestimir Markov
vf
@ -791,6 +861,7 @@ Wojtek Ptak
wonderboyjon
Wu Cheng-Han
Xavier Mendez
Yang Guo
Yassin N. Hassan
YNH Webdev
yoongu
@ -802,5 +873,6 @@ Zachary Dremann
Zeno Rocha
Zhang Hao
Ziv
zoobestik
zziuni
魏鹏刚

View File

@ -1,3 +1,223 @@
## 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
[vim bindings](https://codemirror.net/demo/vim.html): Adjust char escape substitution to match vim, support `&/$0`.
[search addon](https://codemirror.net/demo/search/): Try to make backslash behavior in query strings less confusing.
[javascript mode](https://codemirror.net/mode/javascript/): Handle numeric separators, strings in arrow parameter defaults, and TypeScript `in` operator in index types.
[sparql mode](https://codemirror.net/mode/sparql/index.html): Allow non-ASCII identifier characters.
## 5.48.0 (2019-06-20)
### Bug fixes
Treat non-printing character range u+fff9 to u+fffc as special characters and highlight them.
[show-hint addon](https://codemirror.net/doc/manual.html#addon_show-hint): Fix positioning when the dialog is placed in a scrollable container.
### New features
Add [`selectLeft`](https://codemirror.net/doc/manual.html#mark_selectLeft)/[`selectRight`](https://codemirror.net/doc/manual.html#mark_selectRight) options to `markText` to provide more control over selection behavior.
## 5.47.0 (2019-05-21)
### Bug fixes
[python mode](https://codemirror.net/mode/python/): Properly handle `...` syntax.
[ruby mode](https://codemirror.net/mode/ruby): Fix indenting before closing brackets.
[vim bindings](https://codemirror.net/demo/vim.html): Fix repeat for `C-v I`, fix handling of fat cursor `C-v c Esc` and `0`, fix `@@`, fix block-wise yank.
### New features
[vim bindings](https://codemirror.net/demo/vim.html): Add support for `` ` `` text object.
## 5.46.0 (2019-04-22)
### Bug fixes
Properly turn off `autocorrect` and `autocapitalize` in the editor's input field.
@ -12,7 +232,7 @@ Remove a legacy key code for delete that is used for F16 on keyboards that have
### New features
Allow [gutters](https://codemirror.net/doc/manual.html#option_gutters) to specify direct CSS stings.
Allow [gutters](https://codemirror.net/doc/manual.html#option_gutters) to specify direct CSS strings.
## 5.45.0 (2019-03-20)

View File

View File

View File

@ -0,0 +1,114 @@
// 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) {
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 = [];
for (var i = 0; i < ranges.length; i++) {
var pos = ranges[i].head
if (!/\bcomment\b/.test(cm.getTokenTypeAt(pos))) return CodeMirror.Pass;
var modeHere = cm.getModeAt(pos)
if (!mode) mode = modeHere;
else if (mode != modeHere) return CodeMirror.Pass;
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 &&
found <= pos.ch &&
found <= nonspaceAfter(0, line)) {
insert = line.slice(0, found);
}
if (insert != null) insert += mode.blockCommentContinue
}
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;
inserts[i] = "\n" + insert;
}
cm.operation(function() {
for (var i = ranges.length - 1; i >= 0; i--)
cm.replaceRange(inserts[i], ranges[i].from(), ranges[i].to(), "+insert");
});
}
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")
return opt.continueLineComment !== false;
return true;
}
CodeMirror.defineOption("continueComments", null, function(cm, val, prev) {
if (prev && prev != CodeMirror.Init)
cm.removeKeyMap("continueComment");
if (val) {
var key = "Enter";
if (typeof val == "string")
key = val;
else if (typeof val == "object" && val.key)
key = val.key;
var map = {name: "continueComment"};
map[key] = continueComment;
cm.addKeyMap(map);
}
});
});

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

@ -39,7 +39,7 @@
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)

View File

@ -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 {
@ -229,14 +239,26 @@
elt.hintId = i;
}
var container = completion.options.container || ownerDocument.body;
var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null);
var left = pos.left, top = pos.bottom, below = true;
hints.style.left = left + "px";
hints.style.top = top + "px";
var offsetLeft = 0, offsetTop = 0;
if (container !== ownerDocument.body) {
// We offset the cursor position because left and top are relative to the offsetParent's top left corner.
var isContainerPositioned = ['absolute', 'relative', 'fixed'].indexOf(parentWindow.getComputedStyle(container).position) !== -1;
var offsetParent = isContainerPositioned ? container : container.offsetParent;
var offsetParentPosition = offsetParent.getBoundingClientRect();
var bodyPosition = ownerDocument.body.getBoundingClientRect();
offsetLeft = (offsetParentPosition.left - bodyPosition.left - offsetParent.scrollLeft);
offsetTop = (offsetParentPosition.top - bodyPosition.top - offsetParent.scrollTop);
}
hints.style.left = (left - offsetLeft) + "px";
hints.style.top = (top - offsetTop) + "px";
// If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
var winW = parentWindow.innerWidth || Math.max(ownerDocument.body.offsetWidth, ownerDocument.documentElement.offsetWidth);
var winH = parentWindow.innerHeight || Math.max(ownerDocument.body.offsetHeight, ownerDocument.documentElement.offsetHeight);
(completion.options.container || ownerDocument.body).appendChild(hints);
container.appendChild(hints);
var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
var scrolls = hints.scrollHeight > hints.clientHeight + 1
var startScroll = cm.getScrollInfo();
@ -244,15 +266,15 @@
if (overlapY > 0) {
var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);
if (curTop - height > 0) { // Fits above cursor
hints.style.top = (top = pos.top - height) + "px";
hints.style.top = (top = pos.top - height - offsetTop) + "px";
below = false;
} else if (height > winH) {
hints.style.height = (winH - 5) + "px";
hints.style.top = (top = pos.bottom - box.top) + "px";
hints.style.top = (top = pos.bottom - box.top - offsetTop) + "px";
var cursor = cm.getCursor();
if (data.from.ch != cursor.ch) {
pos = cm.cursorCoords(cursor);
hints.style.left = (left = pos.left) + "px";
hints.style.left = (left = pos.left - offsetLeft) + "px";
box = hints.getBoundingClientRect();
}
}
@ -263,7 +285,7 @@
hints.style.width = (winW - 5) + "px";
overlapX -= (box.right - box.left) - winW;
}
hints.style.left = (left = pos.left - overlapX) + "px";
hints.style.left = (left = pos.left - overlapX - offsetLeft) + "px";
}
if (scrolls) for (var node = hints.firstChild; node; node = node.nextSibling)
node.style.paddingRight = cm.display.nativeBarWidth + "px"
@ -310,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;
@ -351,13 +374,19 @@
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 node = this.hints.childNodes[this.selectedHint]
var firstNode = this.hints.firstChild;
if (node.offsetTop < this.hints.scrollTop)
this.hints.scrollTop = node.offsetTop - firstNode.offsetTop;
else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + firstNode.offsetTop;
},
screenAmount: function() {
return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;
}

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) {

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,7 +81,7 @@
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;
if (multiple) {
@ -87,7 +90,7 @@
}
if (tooltips != false) CodeMirror.on(inner, "mouseover", function(e) {
showTooltipFor(e, labels, inner);
showTooltipFor(cm, e, labels, inner);
});
return marker;
@ -113,9 +116,9 @@
var tip = document.createElement("div");
tip.className = "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;
}
@ -186,7 +189,7 @@
}
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);
}
@ -918,7 +922,7 @@
hasMarker: function(n) {
var handle = this.cm.getLineHandle(n)
if (handle.markedSpans) for (var i = 0; i < handle.markedSpans.length; i++)
if (handle.markedSpans[i].mark.collapsed && handle.markedSpans[i].to != null)
if (handle.markedSpans[i].marker.collapsed && handle.markedSpans[i].to != null)
return true
return false
},

View File

@ -1,16 +1,19 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
window.CodeMirror = {};
var root = typeof globalThis !== 'undefined' ? globalThis : window;
root.CodeMirror = {};
(function() {
"use strict";
function splitLines(string){ return string.split(/\r?\n|\r/); };
function StringStream(string) {
function StringStream(strings, i) {
this.pos = this.start = 0;
this.string = string;
this.string = strings[i];
this.strings = strings
this.i = i
this.lineStart = 0;
}
StringStream.prototype = {
@ -66,7 +69,7 @@ StringStream.prototype = {
try { return inner(); }
finally { this.lineStart -= n; }
},
lookAhead: function() { return null }
lookAhead: function(n) { return this.strings[this.i + n] }
};
CodeMirror.StringStream = StringStream;
@ -104,14 +107,18 @@ CodeMirror.defineMIME("text/plain", "null");
CodeMirror.runMode = function (string, modespec, callback, options) {
var mode = CodeMirror.getMode({ indentUnit: 2 }, modespec);
var ie = /MSIE \d/.test(navigator.userAgent);
var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
if (callback.nodeType == 1) {
if (callback.appendChild) {
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"));
// 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;
}
@ -146,7 +153,7 @@ CodeMirror.runMode = function (string, modespec, callback, options) {
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]);
var stream = new CodeMirror.StringStream(lines, i);
if (!stream.string && mode.blankLine) mode.blankLine(state);
while (!stream.eol()) {
var style = mode.token(stream, state);

View File

@ -59,7 +59,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

@ -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);
});
}
@ -116,7 +116,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

@ -78,10 +78,12 @@
}
function parseString(string) {
return string.replace(/\\(.)/g, function(_, ch) {
return string.replace(/\\([nrt\\])/g, function(match, ch) {
if (ch == "n") return "\n"
if (ch == "r") return "\r"
return ch
if (ch == "t") return "\t"
if (ch == "\\") return "\\"
return match
})
}

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

View File

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 9.1 KiB

View File

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@ -69,7 +69,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.46.0</span>
<span style="color: #888; font-size: 1rem; position: absolute; right: 0; bottom: 0">version 5.54.0</span>
</h2>
<p>CodeMirror is a code-editor component that can be embedded in
@ -223,9 +223,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
@ -284,7 +285,7 @@
should be replaced by a
special <a href="#option_specialCharPlaceholder">placeholder</a>.
Mostly useful for non-printing special characters. The default
is <code>/[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff]/</code>.</dd>
is <code>/[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff\ufff9-\ufffc]/</code>.</dd>
<dt id="option_specialCharPlaceholder"><code><strong>specialCharPlaceholder</strong>: function(char)  Element</code></dt>
<dd>A function that, given a special character identified by
the <a href="#option_specialChars"><code>specialChars</code></a>
@ -420,6 +421,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 +562,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>
@ -1674,13 +1679,21 @@ editor.setOption("extraKeys", {
<dt id="mark_inclusiveRight"><code><strong>inclusiveRight</strong>: boolean</code></dt>
<dd>Like <code>inclusiveLeft</code>,
but for the right side.</dd>
<dt id="mark_selectLeft"><code><strong>selectLeft</strong>: boolean</code></dt>
<dd>For atomic ranges, determines whether the cursor is allowed
to be placed directly to the left of the range. Has no effect on
non-atomic ranges.</dd>
<dt id="mark_selectRight"><code><strong>selectRight</strong>: boolean</code></dt>
<dd>Like <code>selectLeft</code>,
but for the right side.</dd>
<dt id="mark_atomic"><code><strong>atomic</strong>: boolean</code></dt>
<dd>Atomic ranges act as a single unit when cursor movement is
concerned—i.e. it is impossible to place the cursor inside of
them. In atomic ranges, <code>inclusiveLeft</code>
and <code>inclusiveRight</code> have a different meaning—they
will prevent the cursor from being placed respectively
directly before and directly after the range.</dd>
them. You can control whether the cursor is allowed to be placed
directly before or after them using <code>selectLeft</code>
or <code>selectRight</code>. If <code>selectLeft</code>
(or right) is not provided, then <code>inclusiveLeft</code> (or
right) will control this behavior.</dd>
<dt id="mark_collapsed"><code><strong>collapsed</strong>: boolean</code></dt>
<dd>Collapsed ranges do not show up in the display. Setting a
range to be collapsed will automatically make it atomic.</dd>
@ -1872,6 +1885,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
@ -2555,10 +2571,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
@ -2895,6 +2915,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>
@ -3162,14 +3183,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>
@ -3509,6 +3530,26 @@ 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_extending">Extending VIM</h3>
@ -3574,7 +3615,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

@ -26,6 +26,7 @@
<ul>
<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 +40,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>
@ -52,11 +54,11 @@
<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>
<li><a href="https://github.com/pepstock-org/Coderba">Coderba</a> Google Web Toolkit (GWT) wrapper</li>
<li><a href="https://coderpad.io/">Coderpad</a> (interviewing tool)</li>
<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>
@ -76,6 +78,7 @@
<li><a href="http://eloquentjavascript.net/chapter1.html">Eloquent JavaScript</a> (book)</li>
<li><a href="http://emmet.io">Emmet</a> (fast XML editing)</li>
<li><a href="https://github.com/espruino/EspruinoWebIDE">Espruino Web IDE</a> (Chrome App for writing code on Espruino devices)</li>
<li><a href="https://exlskills.com/learn-en/talent/interviews">EXLskills Live Interivews</a></li>
<li><a href="http://www.fastfig.com/">Fastfig</a> (online computation/math tool)</li>
<li><a href="https://metacpan.org/module/Farabi">Farabi</a> (modern Perl IDE)</li>
<li><a href="http://blog.pamelafox.org/2012/02/interactive-html5-slides-with-fathomjs.html">FathomJS integration</a> (slides with editors, again)</li>
@ -118,6 +121,7 @@
<li><a href="http://try.kotlinlang.org">Kotlin</a> (web-based mini-IDE for Kotlin)</li>
<li><a href="http://lighttable.com/">Light Table</a> (experimental IDE)</li>
<li><a href="http://liveweave.com/">Liveweave</a> (HTML/CSS/JS scratchpad)</li>
<li><a href="https://liveuml.com/">LiveUML</a> (PlantUML online editor)</li>
<li><a href="https://github.com/TuvaLabs/markdown-delight-editor">Markdown Delight Editor</a> (extensible markdown editor polymer component)</li>
<li><a href="http://marklighteditor.com/">Marklight editor</a> (lightweight markup editor)</li>
<li><a href="http://www.mergely.com/">Mergely</a> (interactive diffing)</li>
@ -142,10 +146,12 @@
<li><a href="https://chrome.google.com/webstore/detail/quantum/hmnlklahndgbhdoclhdnoafhafbhmnkm?hl=en-US">Quantum</a> (code editor for Chrome OS)</li>
<li><a href="http://ariya.ofilabs.com/2011/09/hybrid-webnative-desktop-codemirror.html">Qt+Webkit integration</a> (building a desktop CodeMirror app)</li>
<li><a href="http://www.quivive-file-manager.com">Quivive File Manager</a></li>
<li><a href="https://racktables.org">RackTables</a> (data centre resources manager)</li>
<li><a href="http://rascalmicro.com/docs/basic-tutorial-getting-started.html">Rascal</a> (tiny computer)</li>
<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>
@ -167,6 +173,7 @@
<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>

View File

@ -30,6 +30,149 @@
<h2>Version 5.x</h2>
<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">
<li><a href="https://codemirror.net/demo/vim.html">vim bindings</a>: Adjust char escape substitution to match vim, support <code>&amp;/$0</code>.</li>
<li><a href="https://codemirror.net/demo/search/">search addon</a>: Try to make backslash behavior in query strings less confusing.</li>
<li><a href="https://codemirror.net/mode/javascript/">javascript mode</a>: Handle numeric separators, strings in arrow parameter defaults, and TypeScript <code>in</code> operator in index types.</li>
<li><a href="https://codemirror.net/mode/sparql/index.html">sparql mode</a>: Allow non-ASCII identifier characters.</li>
</ul>
<p class="rel">20-06-2019: <a href="https://codemirror.net/codemirror-5.48.0.zip">Version 5.48.0</a>:</p>
<ul class="rel-note">
<li>Treat non-printing character range u+fff9 to u+fffc as special characters and highlight them.</li>
<li><a href="https://codemirror.net/doc/manual.html#addon_show-hint">show-hint addon</a>: Fix positioning when the dialog is placed in a scrollable container.</li>
<li>Add <a href="https://codemirror.net/doc/manual.html#mark_selectLeft"><code>selectLeft</code></a>/<a href="https://codemirror.net/doc/manual.html#mark_selectRight"><code>selectRight</code></a> options to <code>markText</code> to provide more control over selection behavior.</li>
</ul>
<p class="rel">21-05-2019: <a href="https://codemirror.net/codemirror-5.47.0.zip">Version 5.47.0</a>:</p>
<ul class="rel-note">
<li><a href="https://codemirror.net/mode/python/">python mode</a>: Properly handle <code>...</code> syntax.</li>
<li><a href="https://codemirror.net/mode/ruby">ruby mode</a>: Fix indenting before closing brackets.</li>
<li><a href="https://codemirror.net/demo/vim.html">vim bindings</a>: Fix repeat for <code>C-v I</code>, fix handling of fat cursor <code>C-v c Esc</code> and <code>0</code>, fix <code>@@</code>, fix block-wise yank.</li>
<li><a href="https://codemirror.net/demo/vim.html">vim bindings</a>: Add support for <code>`</code> text object.</li>
</ul>
<p class="rel">22-04-2019: <a href="https://codemirror.net/codemirror-5.46.0.zip">Version 5.46.0</a>:</p>
<ul class="rel-note">

View File

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@ -99,7 +99,7 @@
</div>
</div>
<div class=actionsleft>
Get the current version: <a href="https://codemirror.net/codemirror.zip">5.46.0</a>.<br>
Get the current version: <a href="https://codemirror.net/codemirror.zip">5.54.0</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>.
@ -195,4 +195,19 @@
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>
</ul>
</section>
</article>

View File

@ -369,6 +369,7 @@
"Ctrl-/": repeated("undo"), "Shift-Ctrl--": repeated("undo"),
"Ctrl-Z": repeated("undo"), "Cmd-Z": repeated("undo"),
"Shift-Ctrl-Z": "redo",
"Shift-Alt-,": "goDocStart", "Shift-Alt-.": "goDocEnd",
"Ctrl-S": "findPersistentNext", "Ctrl-R": "findPersistentPrev", "Ctrl-G": quit, "Shift-Alt-5": "replace",
"Alt-/": "autocomplete",
@ -403,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

@ -164,7 +164,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 +176,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 +234,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' },
@ -286,41 +289,44 @@
enterVimMode(cm);
}
function fatCursorMarks(cm) {
function updateFatCursorMark(cm) {
if (!cm.state.fatCursorMarks) return;
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"}));
}
}
}
return result
cm.state.fatCursorMarks = result;
}
function updateFatCursorMark(cm) {
var marks = cm.state.fatCursorMarks
if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear()
cm.state.fatCursorMarks = fatCursorMarks(cm)
function clearFatCursorMark(cm) {
var marks = cm.state.fatCursorMarks;
if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear();
}
function enableFatCursorMark(cm) {
cm.state.fatCursorMarks = fatCursorMarks(cm)
cm.state.fatCursorMarks = [];
updateFatCursorMark(cm)
cm.on("cursorActivity", updateFatCursorMark)
}
function disableFatCursorMark(cm) {
var marks = cm.state.fatCursorMarks
if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear()
cm.state.fatCursorMarks = null
cm.off("cursorActivity", updateFatCursorMark)
clearFatCursorMark(cm);
cm.off("cursorActivity", updateFatCursorMark);
// explicitly set fatCursorMarks to null because event listener above
// can be invoke after removing it, if off is called from operation
cm.state.fatCursorMarks = null;
}
// Deprecated, simply setting the keymap works again.
@ -591,9 +597,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
};
};
@ -1290,6 +1303,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);
@ -1585,10 +1602,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;
@ -1714,6 +1731,7 @@
vim.lastEditActionCommand = actionCommand;
macroModeState.lastInsertModeChanges.changes = [];
macroModeState.lastInsertModeChanges.expectCursorActivityForChange = false;
macroModeState.lastInsertModeChanges.visualBlock = vim.visualBlock ? vim.sel.head.line - vim.sel.anchor.line : 0;
}
};
@ -1839,12 +1857,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);
return this.moveToEol(cm, head, motionArgs, vim, true);
}
if (motionArgs.toFirstChar){
endCh=findFirstNonWhiteSpaceCharacter(cm.getLine(line));
@ -1946,13 +1970,15 @@
vim.lastHSPos = cm.charCoords(head,'div').left;
return moveToColumn(cm, repeat);
},
moveToEol: function(cm, head, motionArgs, vim) {
moveToEol: function(cm, head, motionArgs, vim, keepHPos) {
var cur = head;
vim.lastHPos = Infinity;
var retval= Pos(cur.line + motionArgs.repeat - 1, Infinity);
var end=cm.clipPos(retval);
end.ch--;
vim.lastHSPos = cm.charCoords(end,'div').left;
if (!keepHPos) {
vim.lastHPos = Infinity;
vim.lastHSPos = cm.charCoords(end,'div').left;
}
return retval;
},
moveToFirstNonWhiteSpaceCharacter: function(cm, head) {
@ -2004,7 +2030,7 @@
'{': '}', '}': '{',
'[': ']', ']': '[',
'<': '>', '>': '<'};
var selfPaired = {'\'': true, '"': true};
var selfPaired = {'\'': true, '"': true, '`': true};
var character = motionArgs.selectedCharacter;
// 'b' refers to '()' block.
@ -2092,10 +2118,9 @@
change: function(cm, args, ranges) {
var finalHead, text;
var vim = cm.state.vim;
vimGlobalState.macroModeState.lastInsertModeChanges.inVisualBlock = vim.visualBlock;
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)) {
@ -2123,6 +2148,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);
@ -2167,8 +2199,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;
@ -2315,6 +2346,8 @@
var macroModeState = vimGlobalState.macroModeState;
if (registerName == '@') {
registerName = macroModeState.latestRegister;
} else {
macroModeState.latestRegister = registerName;
}
while(repeat--){
executeMacroRegister(cm, vim, macroModeState, registerName);
@ -2348,11 +2381,15 @@
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') {
head = motions.moveToFirstNonWhiteSpaceCharacter(cm, head);
} else if (insertAt == 'startOfSelectedArea') {
if (!vim.visualMode)
return;
if (!vim.visualBlock) {
if (sel.head.line < sel.anchor.line) {
head = sel.head;
@ -2366,6 +2403,8 @@
height = Math.abs(sel.head.line - sel.anchor.line) + 1;
}
} else if (insertAt == 'endOfSelectedArea') {
if (!vim.visualMode)
return;
if (!vim.visualBlock) {
if (sel.head.line >= sel.anchor.line) {
head = offsetCursor(sel.head, 0, 1);
@ -2382,6 +2421,8 @@
if (vim.visualMode){
return;
}
} else if (insertAt == 'lastEdit') {
head = getLastEditPos(cm) || head;
}
cm.setOption('disableInput', false);
if (actionArgs && actionArgs.replace) {
@ -2417,8 +2458,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
@ -2490,7 +2530,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);
@ -2559,7 +2601,17 @@
}
var linewise = register.linewise;
var blockwise = register.blockwise;
if (linewise) {
if (blockwise) {
text = text.split('\n');
if (linewise) {
text.pop();
}
for (var i = 0; i < text.length; i++) {
text[i] = (text[i] == '') ? ' ' : text[i];
}
cur.ch += actionArgs.after ? 1 : 0;
cur.ch = Math.min(lineLength(cm, cur.line), cur.ch);
} else if (linewise) {
if(vim.visualMode) {
text = vim.visualLine ? text.slice(0, -1) : '\n' + text.slice(0, text.length - 1) + '\n';
} else if (actionArgs.after) {
@ -2571,12 +2623,6 @@
cur.ch = 0;
}
} else {
if (blockwise) {
text = text.split('\n');
for (var i = 0; i < text.length; i++) {
text[i] = (text[i] == '') ? ' ' : text[i];
}
}
cur.ch += actionArgs.after ? 1 : 0;
}
var curPosFinal;
@ -2788,10 +2834,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);
}
@ -2811,12 +2858,6 @@
}
return Pos(cur.line + offsetLine, cur.ch + offsetCh);
}
function getOffset(anchor, head) {
return {
line: head.line - anchor.line,
ch: head.line - anchor.line
};
}
function commandMatches(keys, keyMap, context, inputState) {
// Partial matches are not applied. They inform the key handler
// that the current key sequence is a subsequence of a valid key
@ -3163,9 +3204,7 @@
vim.visualLine = false;
vim.visualBlock = false;
CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"});
if (vim.fakeCursor) {
vim.fakeCursor.clear();
}
clearFakeCursor(vim);
}
// Remove any trailing newlines from the selection. For
@ -4064,7 +4103,7 @@
}
// Unescape \ and / in the replace part, for PCRE mode.
var unescapes = {'\\/': '/', '\\\\': '\\', '\\n': '\n', '\\r': '\r', '\\t': '\t'};
var unescapes = {'\\/': '/', '\\\\': '\\', '\\n': '\n', '\\r': '\r', '\\t': '\t', '\\&':'&'};
function unescapeRegexReplace(str) {
var stream = new CodeMirror.StringStream(str);
var output = [];
@ -4143,7 +4182,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;
@ -4220,23 +4260,27 @@
query: query
};
}
var highlightTimeout = 0;
function highlightSearchMatches(cm, query) {
var searchState = getSearchState(cm);
var overlay = searchState.getOverlay();
if (!overlay || query != overlay.query) {
if (overlay) {
cm.removeOverlay(overlay);
}
overlay = searchOverlay(query);
cm.addOverlay(overlay);
if (cm.showMatchesOnScrollbar) {
if (searchState.getScrollbarAnnotate()) {
searchState.getScrollbarAnnotate().clear();
clearTimeout(highlightTimeout);
highlightTimeout = setTimeout(function() {
var searchState = getSearchState(cm);
var overlay = searchState.getOverlay();
if (!overlay || query != overlay.query) {
if (overlay) {
cm.removeOverlay(overlay);
}
searchState.setScrollbarAnnotate(cm.showMatchesOnScrollbar(query));
overlay = searchOverlay(query);
cm.addOverlay(overlay);
if (cm.showMatchesOnScrollbar) {
if (searchState.getScrollbarAnnotate()) {
searchState.getScrollbarAnnotate().clear();
}
searchState.setScrollbarAnnotate(cm.showMatchesOnScrollbar(query));
}
searchState.setOverlay(overlay);
}
searchState.setOverlay(overlay);
}
}, 50);
}
function findNext(cm, prev, query, repeat) {
if (repeat === undefined) { repeat = 1; }
@ -4305,25 +4349,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_();
};
@ -4412,7 +4456,7 @@
}
// Parse command name.
var commandMatch = inputStream.match(/^(\w+)/);
var commandMatch = inputStream.match(/^(\w+|!!|@@|[!#&*<=>@~])/);
if (commandMatch) {
result.commandName = commandMatch[1];
} else {
@ -4848,6 +4892,9 @@
var global = false; // True to replace all instances on a line, false to replace only 1.
if (tokens.length) {
regexPart = tokens[0];
if (getOption('pcre') && regexPart !== '') {
regexPart = new RegExp(regexPart).source; //normalize not escaped characters
}
replacePart = tokens[1];
if (regexPart && regexPart[regexPart.length - 1] === '$') {
regexPart = regexPart.slice(0, regexPart.length - 1) + '\\n';
@ -4855,7 +4902,7 @@
}
if (replacePart !== undefined) {
if (getOption('pcre')) {
replacePart = unescapeRegexReplace(replacePart);
replacePart = unescapeRegexReplace(replacePart.replace(/([^\\])&/g,"$1$$&"));
} else {
replacePart = translateRegexReplace(replacePart);
}
@ -4886,7 +4933,11 @@
global = true;
flagsPart.replace('g', '');
}
regexPart = regexPart.replace(/\//g, "\\/") + '/' + flagsPart;
if (getOption('pcre')) {
regexPart = regexPart + '/' + flagsPart;
} else {
regexPart = regexPart.replace(/\//g, "\\/") + '/' + flagsPart;
}
}
}
if (regexPart) {
@ -5303,14 +5354,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');
@ -5436,18 +5507,15 @@
return true;
}
var head = cm.getCursor('head');
var inVisualBlock = vimGlobalState.macroModeState.lastInsertModeChanges.inVisualBlock;
if (inVisualBlock) {
var visualBlock = vimGlobalState.macroModeState.lastInsertModeChanges.visualBlock;
if (visualBlock) {
// Set up block selection again for repeating the changes.
var vim = cm.state.vim;
var lastSel = vim.lastSelection;
var offset = getOffset(lastSel.anchor, lastSel.head);
selectForInsert(cm, head, offset.line + 1);
selectForInsert(cm, head, visualBlock + 1);
repeat = cm.listSelections().length;
cm.setCursor(head);
}
for (var i = 0; i < repeat; i++) {
if (inVisualBlock) {
if (visualBlock) {
cm.setCursor(offsetCursor(head, i, 0));
}
for (var j = 0; j < changes.length; j++) {
@ -5464,7 +5532,7 @@
}
}
}
if (inVisualBlock) {
if (visualBlock) {
cm.setCursor(offsetCursor(head, 0, 1));
}
}

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